// // Generated from bindings/c/include/wickra.h. Do not edit by hand. using System.Runtime.InteropServices; namespace Wickra; public readonly record struct AccelerationBandsOutput(double Upper, double Middle, double Lower); public readonly record struct AdxOutput(double PlusDi, double MinusDi, double Adx); public readonly record struct AlligatorOutput(double Jaw, double Teeth, double Lips); public readonly record struct AndrewsPitchforkOutput(double Median, double Upper, double Lower); public readonly record struct AroonOutput(double Up, double Down); public readonly record struct AtrBandsOutput(double Upper, double Middle, double Lower); public readonly record struct AtrRatchetOutput(double Value, double Direction); public readonly record struct AutoFibOutput(double Level0, double Level236, double Level382, double Level500, double Level618, double Level786, double Level1000); public readonly record struct BollingerOutput(double Upper, double Middle, double Lower, double Stddev); public readonly record struct BomarBandsOutput(double Upper, double Middle, double Lower); public readonly record struct CamarillaPivotsOutput(double Pp, double R1, double R2, double R3, double R4, double S1, double S2, double S3, double S4); public readonly record struct CandleVolumeOutput(double Body, double Width); public readonly record struct CentralPivotRangeOutput(double Pivot, double Tc, double Bc); public readonly record struct ChandeKrollStopOutput(double StopLong, double StopShort); public readonly record struct ChandelierExitOutput(double LongStop, double ShortStop); public readonly record struct ClassicPivotsOutput(double Pp, double R1, double R2, double R3, double S1, double S2, double S3); public readonly record struct CointegrationOutput(double HedgeRatio, double Spread, double AdfStat); public readonly record struct CompositeProfileOutput(double Poc, double Vah, double Val); public readonly record struct DemarkPivotsOutput(double Pp, double R1, double S1); public readonly record struct DollarBar(double Open, double High, double Low, double Close, double Volume, double Dollar); public readonly record struct DonchianOutput(double Upper, double Middle, double Lower); public readonly record struct DonchianStopOutput(double StopLong, double StopShort); public readonly record struct DoubleBollingerOutput(double UpperOuter, double UpperInner, double Middle, double LowerInner, double LowerOuter); public readonly record struct ElderRayOutput(double BullPower, double BearPower); public readonly record struct ElderSafeZoneOutput(double Value, double Direction); public readonly record struct EquivolumeOutput(double Height, double Width); public readonly record struct FibArcsOutput(double Arc382, double Arc500, double Arc618); public readonly record struct FibChannelOutput(double Base, double Level618, double Level1000, double Level1618); public readonly record struct FibConfluenceOutput(double Price, double Strength); public readonly record struct FibExtensionOutput(double Level1272, double Level1414, double Level1618, double Level2000, double Level2618); public readonly record struct FibFanOutput(double Fan382, double Fan500, double Fan618); public readonly record struct FibProjectionOutput(double Level618, double Level1000, double Level1618, double Level2618); public readonly record struct FibRetracementOutput(double Level0, double Level236, double Level382, double Level500, double Level618, double Level786, double Level1000); public readonly record struct FibTimeZonesOutput(double OnZone, double BarsToNext); public readonly record struct FibonacciPivotsOutput(double Pp, double R1, double R2, double R3, double S1, double S2, double S3); public readonly record struct FootprintLevel(double Price, double BidVol, double AskVol); public readonly record struct FractalChaosBandsOutput(double Upper, double Lower); public readonly record struct GatorOscillatorOutput(double Upper, double Lower); public readonly record struct GoldenPocketOutput(double Low, double Mid, double High); public readonly record struct HeikinAshiOutput(double Open, double High, double Low, double Close); public readonly record struct HighLowVolumeNodesOutput(double Hvn, double Lvn); public readonly record struct HtPhasorOutput(double Inphase, double Quadrature); public readonly record struct HurstChannelOutput(double Upper, double Middle, double Lower); public readonly record struct IchimokuOutput(double Tenkan, double Kijun, double SenkouA, double SenkouB, double Chikou); public readonly record struct ImbalanceBar(double Open, double High, double Low, double Close, double Imbalance, double Direction); public readonly record struct InitialBalanceOutput(double High, double Low); public readonly record struct KagiBar(double Start, double End, double Direction); public readonly record struct KalmanHedgeRatioOutput(double HedgeRatio, double Intercept, double Spread); public readonly record struct KaseDevStopOutput(double Value, double Direction); public readonly record struct KasePermissionStochasticOutput(double Fast, double Slow); public readonly record struct KeltnerOutput(double Upper, double Middle, double Lower); public readonly record struct KstOutput(double Kst, double Signal); public readonly record struct LeadLagCrossCorrelationOutput(double Lag, double Correlation); public readonly record struct LinRegChannelOutput(double Upper, double Middle, double Lower); public readonly record struct LineBreakBar(double Open, double Close, double Direction); public readonly record struct LiquidationFeaturesOutput(double Long, double Short, double Net, double Total, double Imbalance); public readonly record struct MaEnvelopeOutput(double Upper, double Middle, double Lower); public readonly record struct MacdOutput(double Macd, double Signal, double Histogram); public readonly record struct MamaOutput(double Mama, double Fama); public readonly record struct MedianChannelOutput(double Upper, double Middle, double Lower); public readonly record struct ModifiedMaStopOutput(double Value, double Direction); public readonly record struct MurreyMathLinesOutput(double Mm88, double Mm78, double Mm68, double Mm58, double Mm48, double Mm38, double Mm28, double Mm18, double Mm08); public readonly record struct NrtrOutput(double Value, double Direction); public readonly record struct OpeningRangeOutput(double High, double Low, double BreakoutDistance); public readonly record struct OvernightIntradayReturnOutput(double Overnight, double Intraday); public readonly record struct PnfColumn(double Direction, double High, double Low); public readonly record struct ProjectionBandsOutput(double Upper, double Middle, double Lower); public readonly record struct QqeOutput(double RsiMa, double TrailingLine); public readonly record struct QuartileBandsOutput(double Upper, double Middle, double Lower); public readonly record struct RangeBar(double Open, double Close, double Direction); public readonly record struct RelativeStrengthOutput(double Ratio, double RatioMa, double RatioRsi); public readonly record struct RenkoBrick(double Open, double Close, double Direction); public readonly record struct RunBar(double Open, double High, double Low, double Close, double Length, double Direction); public readonly record struct RwiOutput(double High, double Low); public readonly record struct SessionHighLowOutput(double High, double Low); public readonly record struct SessionRangeOutput(double Asia, double Eu, double Us); public readonly record struct SmoothedHeikinAshiOutput(double Open, double High, double Low, double Close); public readonly record struct SpreadBollingerBandsOutput(double Middle, double Upper, double Lower, double PercentB); public readonly record struct StandardErrorBandsOutput(double Upper, double Middle, double Lower); public readonly record struct StarcBandsOutput(double Upper, double Middle, double Lower); public readonly record struct StochasticOutput(double K, double D); public readonly record struct SuperTrendOutput(double Value, double Direction); public readonly record struct TdLinesOutput(double Resistance, double Support); public readonly record struct TdMovingAverageOutput(double St1, double St2); public readonly record struct TdRangeProjectionOutput(double High, double Low); public readonly record struct TdRiskLevelOutput(double BuyRisk, double SellRisk); public readonly record struct TdSequentialOutput(double Setup, double Countdown, double Direction); public readonly record struct TickBar(double Open, double High, double Low, double Close, double Volume); public readonly record struct TpoProfileOutputScalars(double PriceLow, double PriceHigh, double[] Values); public readonly record struct TtmSqueezeOutput(double Squeeze, double Momentum); public readonly record struct ValueAreaOutput(double Poc, double Vah, double Val); public readonly record struct VolatilityConeOutput(double Current, double Min, double Median, double Max, double Percentile); public readonly record struct VolumeBar(double Open, double High, double Low, double Close, double Volume); public readonly record struct VolumeProfileOutputScalars(double PriceLow, double PriceHigh, double[] Values); public readonly record struct VolumeWeightedMacdOutput(double Macd, double Signal, double Histogram); public readonly record struct VolumeWeightedSrOutput(double Support, double Resistance); public readonly record struct VortexOutput(double Plus, double Minus); public readonly record struct VwapStdDevBandsOutput(double Upper, double Middle, double Lower, double Stddev); public readonly record struct WaveTrendOutput(double Wt1, double Wt2); public readonly record struct WilliamsFractalsOutput(double Up, double Down); public readonly record struct WoodiePivotsOutput(double Pp, double R1, double R2, double S1, double S2); public readonly record struct ZeroLagMacdOutput(double Macd, double Signal, double Histogram); public readonly record struct ZigZagOutput(double Swing, double Direction); public sealed class AbandonedBaby : IDisposable { private readonly WickraHandle _handle; public AbandonedBaby() { var ptr = NativeMethods.wickra_abandoned_baby_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid AbandonedBaby parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_abandoned_baby_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_abandoned_baby_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_abandoned_baby_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_abandoned_baby_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Abcd : IDisposable { private readonly WickraHandle _handle; public Abcd() { var ptr = NativeMethods.wickra_abcd_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Abcd parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_abcd_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_abcd_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_abcd_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_abcd_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AbsoluteBreadthIndex : IDisposable { private readonly WickraHandle _handle; public AbsoluteBreadthIndex() { var ptr = NativeMethods.wickra_absolute_breadth_index_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid AbsoluteBreadthIndex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_absolute_breadth_index_free); } public double Update(ReadOnlySpan change, ReadOnlySpan volume, ReadOnlySpan newHigh, ReadOnlySpan newLow, ReadOnlySpan aboveMa, ReadOnlySpan onBuySignal, long timestamp) { if (volume.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newHigh.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newLow.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (aboveMa.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (onBuySignal.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* changePtr = change) fixed (double* volumePtr = volume) fixed (bool* newHighPtr = newHigh) fixed (bool* newLowPtr = newLow) fixed (bool* aboveMaPtr = aboveMa) fixed (bool* onBuySignalPtr = onBuySignal) { result = NativeMethods.wickra_absolute_breadth_index_update(_handle.DangerousGetHandle(), changePtr, volumePtr, newHighPtr, newLowPtr, aboveMaPtr, onBuySignalPtr, (nuint)change.Length, timestamp); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_absolute_breadth_index_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AccelerationBands : IDisposable { private readonly WickraHandle _handle; public AccelerationBands(int period, double factor) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_acceleration_bands_new((nuint)period, factor); if (ptr == nint.Zero) { throw new ArgumentException("invalid AccelerationBands parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_acceleration_bands_free); } public AccelerationBandsOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraAccelerationBandsOutput native; bool ok; unsafe { ok = NativeMethods.wickra_acceleration_bands_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new AccelerationBandsOutput(native.upper, native.middle, native.lower) : null; } public void Reset() { NativeMethods.wickra_acceleration_bands_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AcceleratorOscillator : IDisposable { private readonly WickraHandle _handle; public AcceleratorOscillator(int aoFast, int aoSlow, int signalPeriod) { ArgumentOutOfRangeException.ThrowIfNegative(aoFast); ArgumentOutOfRangeException.ThrowIfNegative(aoSlow); ArgumentOutOfRangeException.ThrowIfNegative(signalPeriod); var ptr = NativeMethods.wickra_accelerator_oscillator_new((nuint)aoFast, (nuint)aoSlow, (nuint)signalPeriod); if (ptr == nint.Zero) { throw new ArgumentException("invalid AcceleratorOscillator parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_accelerator_oscillator_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_accelerator_oscillator_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_accelerator_oscillator_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_accelerator_oscillator_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AdOscillator : IDisposable { private readonly WickraHandle _handle; public AdOscillator() { var ptr = NativeMethods.wickra_ad_oscillator_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid AdOscillator parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_ad_oscillator_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_ad_oscillator_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_ad_oscillator_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_ad_oscillator_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AdVolumeLine : IDisposable { private readonly WickraHandle _handle; public AdVolumeLine() { var ptr = NativeMethods.wickra_ad_volume_line_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid AdVolumeLine parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_ad_volume_line_free); } public double Update(ReadOnlySpan change, ReadOnlySpan volume, ReadOnlySpan newHigh, ReadOnlySpan newLow, ReadOnlySpan aboveMa, ReadOnlySpan onBuySignal, long timestamp) { if (volume.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newHigh.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newLow.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (aboveMa.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (onBuySignal.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* changePtr = change) fixed (double* volumePtr = volume) fixed (bool* newHighPtr = newHigh) fixed (bool* newLowPtr = newLow) fixed (bool* aboveMaPtr = aboveMa) fixed (bool* onBuySignalPtr = onBuySignal) { result = NativeMethods.wickra_ad_volume_line_update(_handle.DangerousGetHandle(), changePtr, volumePtr, newHighPtr, newLowPtr, aboveMaPtr, onBuySignalPtr, (nuint)change.Length, timestamp); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_ad_volume_line_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AdaptiveCci : IDisposable { private readonly WickraHandle _handle; public AdaptiveCci(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_adaptive_cci_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid AdaptiveCci parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_adaptive_cci_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_adaptive_cci_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_adaptive_cci_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_adaptive_cci_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AdaptiveCycle : IDisposable { private readonly WickraHandle _handle; public AdaptiveCycle() { var ptr = NativeMethods.wickra_adaptive_cycle_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid AdaptiveCycle parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_adaptive_cycle_free); } public double Update(double @value) { var result = NativeMethods.wickra_adaptive_cycle_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_adaptive_cycle_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_adaptive_cycle_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AdaptiveLaguerreFilter : IDisposable { private readonly WickraHandle _handle; public AdaptiveLaguerreFilter(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_adaptive_laguerre_filter_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid AdaptiveLaguerreFilter parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_adaptive_laguerre_filter_free); } public double Update(double @value) { var result = NativeMethods.wickra_adaptive_laguerre_filter_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_adaptive_laguerre_filter_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_adaptive_laguerre_filter_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AdaptiveRsi : IDisposable { private readonly WickraHandle _handle; public AdaptiveRsi(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_adaptive_rsi_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid AdaptiveRsi parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_adaptive_rsi_free); } public double Update(double @value) { var result = NativeMethods.wickra_adaptive_rsi_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_adaptive_rsi_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_adaptive_rsi_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Adl : IDisposable { private readonly WickraHandle _handle; public Adl() { var ptr = NativeMethods.wickra_adl_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Adl parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_adl_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_adl_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_adl_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_adl_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AdvanceBlock : IDisposable { private readonly WickraHandle _handle; public AdvanceBlock() { var ptr = NativeMethods.wickra_advance_block_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid AdvanceBlock parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_advance_block_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_advance_block_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_advance_block_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_advance_block_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AdvanceDecline : IDisposable { private readonly WickraHandle _handle; public AdvanceDecline() { var ptr = NativeMethods.wickra_advance_decline_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid AdvanceDecline parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_advance_decline_free); } public double Update(ReadOnlySpan change, ReadOnlySpan volume, ReadOnlySpan newHigh, ReadOnlySpan newLow, ReadOnlySpan aboveMa, ReadOnlySpan onBuySignal, long timestamp) { if (volume.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newHigh.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newLow.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (aboveMa.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (onBuySignal.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* changePtr = change) fixed (double* volumePtr = volume) fixed (bool* newHighPtr = newHigh) fixed (bool* newLowPtr = newLow) fixed (bool* aboveMaPtr = aboveMa) fixed (bool* onBuySignalPtr = onBuySignal) { result = NativeMethods.wickra_advance_decline_update(_handle.DangerousGetHandle(), changePtr, volumePtr, newHighPtr, newLowPtr, aboveMaPtr, onBuySignalPtr, (nuint)change.Length, timestamp); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_advance_decline_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AdvanceDeclineRatio : IDisposable { private readonly WickraHandle _handle; public AdvanceDeclineRatio() { var ptr = NativeMethods.wickra_advance_decline_ratio_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid AdvanceDeclineRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_advance_decline_ratio_free); } public double Update(ReadOnlySpan change, ReadOnlySpan volume, ReadOnlySpan newHigh, ReadOnlySpan newLow, ReadOnlySpan aboveMa, ReadOnlySpan onBuySignal, long timestamp) { if (volume.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newHigh.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newLow.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (aboveMa.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (onBuySignal.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* changePtr = change) fixed (double* volumePtr = volume) fixed (bool* newHighPtr = newHigh) fixed (bool* newLowPtr = newLow) fixed (bool* aboveMaPtr = aboveMa) fixed (bool* onBuySignalPtr = onBuySignal) { result = NativeMethods.wickra_advance_decline_ratio_update(_handle.DangerousGetHandle(), changePtr, volumePtr, newHighPtr, newLowPtr, aboveMaPtr, onBuySignalPtr, (nuint)change.Length, timestamp); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_advance_decline_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Adx : IDisposable { private readonly WickraHandle _handle; public Adx(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_adx_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Adx parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_adx_free); } public AdxOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraAdxOutput native; bool ok; unsafe { ok = NativeMethods.wickra_adx_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new AdxOutput(native.plus_di, native.minus_di, native.adx) : null; } public void Reset() { NativeMethods.wickra_adx_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Adxr : IDisposable { private readonly WickraHandle _handle; public Adxr(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_adxr_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Adxr parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_adxr_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_adxr_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_adxr_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_adxr_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Alligator : IDisposable { private readonly WickraHandle _handle; public Alligator(int jawPeriod, int teethPeriod, int lipsPeriod) { ArgumentOutOfRangeException.ThrowIfNegative(jawPeriod); ArgumentOutOfRangeException.ThrowIfNegative(teethPeriod); ArgumentOutOfRangeException.ThrowIfNegative(lipsPeriod); var ptr = NativeMethods.wickra_alligator_new((nuint)jawPeriod, (nuint)teethPeriod, (nuint)lipsPeriod); if (ptr == nint.Zero) { throw new ArgumentException("invalid Alligator parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_alligator_free); } public AlligatorOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraAlligatorOutput native; bool ok; unsafe { ok = NativeMethods.wickra_alligator_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new AlligatorOutput(native.jaw, native.teeth, native.lips) : null; } public void Reset() { NativeMethods.wickra_alligator_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Alma : IDisposable { private readonly WickraHandle _handle; public Alma(int period, double offset, double sigma) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_alma_new((nuint)period, offset, sigma); if (ptr == nint.Zero) { throw new ArgumentException("invalid Alma parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_alma_free); } public double Update(double @value) { var result = NativeMethods.wickra_alma_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_alma_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_alma_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Alpha : IDisposable { private readonly WickraHandle _handle; public Alpha(int period, double riskFree) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_alpha_new((nuint)period, riskFree); if (ptr == nint.Zero) { throw new ArgumentException("invalid Alpha parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_alpha_free); } public double Update(double x, double y) { var result = NativeMethods.wickra_alpha_update(_handle.DangerousGetHandle(), x, y); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan x, ReadOnlySpan y) { var n = x.Length; if (y.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* xPtr = x) fixed (double* yPtr = y) fixed (double* outputPtr = output) { NativeMethods.wickra_alpha_batch(_handle.DangerousGetHandle(), xPtr, yPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_alpha_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AmihudIlliquidity : IDisposable { private readonly WickraHandle _handle; public AmihudIlliquidity(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_amihud_illiquidity_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid AmihudIlliquidity parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_amihud_illiquidity_free); } public double Update(double price, double size, bool isBuy, long timestamp) { var result = NativeMethods.wickra_amihud_illiquidity_update(_handle.DangerousGetHandle(), price, size, isBuy, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_amihud_illiquidity_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AnchoredRsi : IDisposable { private readonly WickraHandle _handle; public AnchoredRsi() { var ptr = NativeMethods.wickra_anchored_rsi_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid AnchoredRsi parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_anchored_rsi_free); } public double Update(double @value) { var result = NativeMethods.wickra_anchored_rsi_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_anchored_rsi_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_anchored_rsi_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AnchoredVwap : IDisposable { private readonly WickraHandle _handle; public AnchoredVwap() { var ptr = NativeMethods.wickra_anchored_vwap_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid AnchoredVwap parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_anchored_vwap_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_anchored_vwap_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_anchored_vwap_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_anchored_vwap_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AndrewsPitchfork : IDisposable { private readonly WickraHandle _handle; public AndrewsPitchfork(int strength) { ArgumentOutOfRangeException.ThrowIfNegative(strength); var ptr = NativeMethods.wickra_andrews_pitchfork_new((nuint)strength); if (ptr == nint.Zero) { throw new ArgumentException("invalid AndrewsPitchfork parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_andrews_pitchfork_free); } public AndrewsPitchforkOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraAndrewsPitchforkOutput native; bool ok; unsafe { ok = NativeMethods.wickra_andrews_pitchfork_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new AndrewsPitchforkOutput(native.median, native.upper, native.lower) : null; } public void Reset() { NativeMethods.wickra_andrews_pitchfork_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Apo : IDisposable { private readonly WickraHandle _handle; public Apo(int fast, int slow) { ArgumentOutOfRangeException.ThrowIfNegative(fast); ArgumentOutOfRangeException.ThrowIfNegative(slow); var ptr = NativeMethods.wickra_apo_new((nuint)fast, (nuint)slow); if (ptr == nint.Zero) { throw new ArgumentException("invalid Apo parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_apo_free); } public double Update(double @value) { var result = NativeMethods.wickra_apo_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_apo_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_apo_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Aroon : IDisposable { private readonly WickraHandle _handle; public Aroon(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_aroon_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Aroon parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_aroon_free); } public AroonOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraAroonOutput native; bool ok; unsafe { ok = NativeMethods.wickra_aroon_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new AroonOutput(native.up, native.down) : null; } public void Reset() { NativeMethods.wickra_aroon_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AroonOscillator : IDisposable { private readonly WickraHandle _handle; public AroonOscillator(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_aroon_oscillator_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid AroonOscillator parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_aroon_oscillator_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_aroon_oscillator_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_aroon_oscillator_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_aroon_oscillator_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Atr : IDisposable { private readonly WickraHandle _handle; public Atr(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_atr_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Atr parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_atr_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_atr_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_atr_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_atr_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AtrBands : IDisposable { private readonly WickraHandle _handle; public AtrBands(int period, double multiplier) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_atr_bands_new((nuint)period, multiplier); if (ptr == nint.Zero) { throw new ArgumentException("invalid AtrBands parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_atr_bands_free); } public AtrBandsOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraAtrBandsOutput native; bool ok; unsafe { ok = NativeMethods.wickra_atr_bands_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new AtrBandsOutput(native.upper, native.middle, native.lower) : null; } public void Reset() { NativeMethods.wickra_atr_bands_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AtrRatchet : IDisposable { private readonly WickraHandle _handle; public AtrRatchet(int atrPeriod, double startMult, double increment) { ArgumentOutOfRangeException.ThrowIfNegative(atrPeriod); var ptr = NativeMethods.wickra_atr_ratchet_new((nuint)atrPeriod, startMult, increment); if (ptr == nint.Zero) { throw new ArgumentException("invalid AtrRatchet parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_atr_ratchet_free); } public AtrRatchetOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraAtrRatchetOutput native; bool ok; unsafe { ok = NativeMethods.wickra_atr_ratchet_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new AtrRatchetOutput(native.@value, native.direction) : null; } public void Reset() { NativeMethods.wickra_atr_ratchet_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AtrTrailingStop : IDisposable { private readonly WickraHandle _handle; public AtrTrailingStop(int atrPeriod, double multiplier) { ArgumentOutOfRangeException.ThrowIfNegative(atrPeriod); var ptr = NativeMethods.wickra_atr_trailing_stop_new((nuint)atrPeriod, multiplier); if (ptr == nint.Zero) { throw new ArgumentException("invalid AtrTrailingStop parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_atr_trailing_stop_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_atr_trailing_stop_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_atr_trailing_stop_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_atr_trailing_stop_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AutoFib : IDisposable { private readonly WickraHandle _handle; public AutoFib() { var ptr = NativeMethods.wickra_auto_fib_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid AutoFib parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_auto_fib_free); } public AutoFibOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraAutoFibOutput native; bool ok; unsafe { ok = NativeMethods.wickra_auto_fib_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new AutoFibOutput(native.level_0, native.level_236, native.level_382, native.level_500, native.level_618, native.level_786, native.level_1000) : null; } public void Reset() { NativeMethods.wickra_auto_fib_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Autocorrelation : IDisposable { private readonly WickraHandle _handle; public Autocorrelation(int period, int lag) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(lag); var ptr = NativeMethods.wickra_autocorrelation_new((nuint)period, (nuint)lag); if (ptr == nint.Zero) { throw new ArgumentException("invalid Autocorrelation parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_autocorrelation_free); } public double Update(double @value) { var result = NativeMethods.wickra_autocorrelation_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_autocorrelation_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_autocorrelation_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AutocorrelationPeriodogram : IDisposable { private readonly WickraHandle _handle; public AutocorrelationPeriodogram(int minPeriod, int maxPeriod) { ArgumentOutOfRangeException.ThrowIfNegative(minPeriod); ArgumentOutOfRangeException.ThrowIfNegative(maxPeriod); var ptr = NativeMethods.wickra_autocorrelation_periodogram_new((nuint)minPeriod, (nuint)maxPeriod); if (ptr == nint.Zero) { throw new ArgumentException("invalid AutocorrelationPeriodogram parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_autocorrelation_periodogram_free); } public double Update(double @value) { var result = NativeMethods.wickra_autocorrelation_periodogram_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_autocorrelation_periodogram_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_autocorrelation_periodogram_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AverageDailyRange : IDisposable { private readonly WickraHandle _handle; public AverageDailyRange(int period, int utcOffsetMinutes) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_average_daily_range_new((nuint)period, utcOffsetMinutes); if (ptr == nint.Zero) { throw new ArgumentException("invalid AverageDailyRange parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_average_daily_range_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_average_daily_range_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_average_daily_range_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_average_daily_range_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AverageDrawdown : IDisposable { private readonly WickraHandle _handle; public AverageDrawdown(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_average_drawdown_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid AverageDrawdown parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_average_drawdown_free); } public double Update(double @value) { var result = NativeMethods.wickra_average_drawdown_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_average_drawdown_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_average_drawdown_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AvgPrice : IDisposable { private readonly WickraHandle _handle; public AvgPrice() { var ptr = NativeMethods.wickra_avg_price_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid AvgPrice parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_avg_price_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_avg_price_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_avg_price_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_avg_price_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AwesomeOscillator : IDisposable { private readonly WickraHandle _handle; public AwesomeOscillator(int fast, int slow) { ArgumentOutOfRangeException.ThrowIfNegative(fast); ArgumentOutOfRangeException.ThrowIfNegative(slow); var ptr = NativeMethods.wickra_awesome_oscillator_new((nuint)fast, (nuint)slow); if (ptr == nint.Zero) { throw new ArgumentException("invalid AwesomeOscillator parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_awesome_oscillator_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_awesome_oscillator_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_awesome_oscillator_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_awesome_oscillator_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class AwesomeOscillatorHistogram : IDisposable { private readonly WickraHandle _handle; public AwesomeOscillatorHistogram(int fast, int slow, int smaPeriod) { ArgumentOutOfRangeException.ThrowIfNegative(fast); ArgumentOutOfRangeException.ThrowIfNegative(slow); ArgumentOutOfRangeException.ThrowIfNegative(smaPeriod); var ptr = NativeMethods.wickra_awesome_oscillator_histogram_new((nuint)fast, (nuint)slow, (nuint)smaPeriod); if (ptr == nint.Zero) { throw new ArgumentException("invalid AwesomeOscillatorHistogram parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_awesome_oscillator_histogram_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_awesome_oscillator_histogram_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_awesome_oscillator_histogram_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_awesome_oscillator_histogram_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class BalanceOfPower : IDisposable { private readonly WickraHandle _handle; public BalanceOfPower() { var ptr = NativeMethods.wickra_balance_of_power_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid BalanceOfPower parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_balance_of_power_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_balance_of_power_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_balance_of_power_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_balance_of_power_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class BandpassFilter : IDisposable { private readonly WickraHandle _handle; public BandpassFilter(int period, double bandwidth) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_bandpass_filter_new((nuint)period, bandwidth); if (ptr == nint.Zero) { throw new ArgumentException("invalid BandpassFilter parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_bandpass_filter_free); } public double Update(double @value) { var result = NativeMethods.wickra_bandpass_filter_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_bandpass_filter_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_bandpass_filter_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Bat : IDisposable { private readonly WickraHandle _handle; public Bat() { var ptr = NativeMethods.wickra_bat_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Bat parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_bat_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_bat_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_bat_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_bat_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class BeltHold : IDisposable { private readonly WickraHandle _handle; public BeltHold() { var ptr = NativeMethods.wickra_belt_hold_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid BeltHold parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_belt_hold_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_belt_hold_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_belt_hold_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_belt_hold_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Beta : IDisposable { private readonly WickraHandle _handle; public Beta(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_beta_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Beta parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_beta_free); } public double Update(double x, double y) { var result = NativeMethods.wickra_beta_update(_handle.DangerousGetHandle(), x, y); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan x, ReadOnlySpan y) { var n = x.Length; if (y.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* xPtr = x) fixed (double* yPtr = y) fixed (double* outputPtr = output) { NativeMethods.wickra_beta_batch(_handle.DangerousGetHandle(), xPtr, yPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_beta_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class BetaNeutralSpread : IDisposable { private readonly WickraHandle _handle; public BetaNeutralSpread(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_beta_neutral_spread_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid BetaNeutralSpread parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_beta_neutral_spread_free); } public double Update(double x, double y) { var result = NativeMethods.wickra_beta_neutral_spread_update(_handle.DangerousGetHandle(), x, y); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan x, ReadOnlySpan y) { var n = x.Length; if (y.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* xPtr = x) fixed (double* yPtr = y) fixed (double* outputPtr = output) { NativeMethods.wickra_beta_neutral_spread_batch(_handle.DangerousGetHandle(), xPtr, yPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_beta_neutral_spread_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class BetterVolume : IDisposable { private readonly WickraHandle _handle; public BetterVolume(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_better_volume_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid BetterVolume parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_better_volume_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_better_volume_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_better_volume_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_better_volume_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class BipowerVariation : IDisposable { private readonly WickraHandle _handle; public BipowerVariation(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_bipower_variation_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid BipowerVariation parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_bipower_variation_free); } public double Update(double @value) { var result = NativeMethods.wickra_bipower_variation_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_bipower_variation_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_bipower_variation_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class BodySizePct : IDisposable { private readonly WickraHandle _handle; public BodySizePct() { var ptr = NativeMethods.wickra_body_size_pct_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid BodySizePct parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_body_size_pct_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_body_size_pct_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_body_size_pct_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_body_size_pct_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class BollingerBands : IDisposable { private readonly WickraHandle _handle; public BollingerBands(int period, double multiplier) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_bollinger_bands_new((nuint)period, multiplier); if (ptr == nint.Zero) { throw new ArgumentException("invalid BollingerBands parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_bollinger_bands_free); } public BollingerOutput? Update(double @value) { WickraBollingerOutput native; bool ok; unsafe { ok = NativeMethods.wickra_bollinger_bands_update(_handle.DangerousGetHandle(), @value, &native); } GC.KeepAlive(_handle); return ok ? new BollingerOutput(native.upper, native.middle, native.lower, native.stddev) : null; } public void Reset() { NativeMethods.wickra_bollinger_bands_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class BollingerBandwidth : IDisposable { private readonly WickraHandle _handle; public BollingerBandwidth(int period, double multiplier) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_bollinger_bandwidth_new((nuint)period, multiplier); if (ptr == nint.Zero) { throw new ArgumentException("invalid BollingerBandwidth parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_bollinger_bandwidth_free); } public double Update(double @value) { var result = NativeMethods.wickra_bollinger_bandwidth_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_bollinger_bandwidth_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_bollinger_bandwidth_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class BomarBands : IDisposable { private readonly WickraHandle _handle; public BomarBands(int period, double coverage) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_bomar_bands_new((nuint)period, coverage); if (ptr == nint.Zero) { throw new ArgumentException("invalid BomarBands parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_bomar_bands_free); } public BomarBandsOutput? Update(double @value) { WickraBomarBandsOutput native; bool ok; unsafe { ok = NativeMethods.wickra_bomar_bands_update(_handle.DangerousGetHandle(), @value, &native); } GC.KeepAlive(_handle); return ok ? new BomarBandsOutput(native.upper, native.middle, native.lower) : null; } public void Reset() { NativeMethods.wickra_bomar_bands_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class BreadthThrust : IDisposable { private readonly WickraHandle _handle; public BreadthThrust(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_breadth_thrust_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid BreadthThrust parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_breadth_thrust_free); } public double Update(ReadOnlySpan change, ReadOnlySpan volume, ReadOnlySpan newHigh, ReadOnlySpan newLow, ReadOnlySpan aboveMa, ReadOnlySpan onBuySignal, long timestamp) { if (volume.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newHigh.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newLow.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (aboveMa.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (onBuySignal.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* changePtr = change) fixed (double* volumePtr = volume) fixed (bool* newHighPtr = newHigh) fixed (bool* newLowPtr = newLow) fixed (bool* aboveMaPtr = aboveMa) fixed (bool* onBuySignalPtr = onBuySignal) { result = NativeMethods.wickra_breadth_thrust_update(_handle.DangerousGetHandle(), changePtr, volumePtr, newHighPtr, newLowPtr, aboveMaPtr, onBuySignalPtr, (nuint)change.Length, timestamp); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_breadth_thrust_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Breakaway : IDisposable { private readonly WickraHandle _handle; public Breakaway() { var ptr = NativeMethods.wickra_breakaway_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Breakaway parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_breakaway_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_breakaway_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_breakaway_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_breakaway_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class BullishPercentIndex : IDisposable { private readonly WickraHandle _handle; public BullishPercentIndex() { var ptr = NativeMethods.wickra_bullish_percent_index_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid BullishPercentIndex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_bullish_percent_index_free); } public double Update(ReadOnlySpan change, ReadOnlySpan volume, ReadOnlySpan newHigh, ReadOnlySpan newLow, ReadOnlySpan aboveMa, ReadOnlySpan onBuySignal, long timestamp) { if (volume.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newHigh.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newLow.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (aboveMa.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (onBuySignal.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* changePtr = change) fixed (double* volumePtr = volume) fixed (bool* newHighPtr = newHigh) fixed (bool* newLowPtr = newLow) fixed (bool* aboveMaPtr = aboveMa) fixed (bool* onBuySignalPtr = onBuySignal) { result = NativeMethods.wickra_bullish_percent_index_update(_handle.DangerousGetHandle(), changePtr, volumePtr, newHighPtr, newLowPtr, aboveMaPtr, onBuySignalPtr, (nuint)change.Length, timestamp); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_bullish_percent_index_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class BurkeRatio : IDisposable { private readonly WickraHandle _handle; public BurkeRatio(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_burke_ratio_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid BurkeRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_burke_ratio_free); } public double Update(double @value) { var result = NativeMethods.wickra_burke_ratio_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_burke_ratio_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_burke_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Butterfly : IDisposable { private readonly WickraHandle _handle; public Butterfly() { var ptr = NativeMethods.wickra_butterfly_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Butterfly parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_butterfly_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_butterfly_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_butterfly_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_butterfly_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class CalendarSpread : IDisposable { private readonly WickraHandle _handle; public CalendarSpread() { var ptr = NativeMethods.wickra_calendar_spread_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid CalendarSpread parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_calendar_spread_free); } public double Update(double fundingRate, double markPrice, double indexPrice, double futuresPrice, double openInterest, double longSize, double shortSize, double takerBuyVolume, double takerSellVolume, double longLiquidation, double shortLiquidation, long timestamp) { var result = NativeMethods.wickra_calendar_spread_update(_handle.DangerousGetHandle(), fundingRate, markPrice, indexPrice, futuresPrice, openInterest, longSize, shortSize, takerBuyVolume, takerSellVolume, longLiquidation, shortLiquidation, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_calendar_spread_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class CalmarRatio : IDisposable { private readonly WickraHandle _handle; public CalmarRatio(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_calmar_ratio_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid CalmarRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_calmar_ratio_free); } public double Update(double @value) { var result = NativeMethods.wickra_calmar_ratio_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_calmar_ratio_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_calmar_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Camarilla : IDisposable { private readonly WickraHandle _handle; public Camarilla() { var ptr = NativeMethods.wickra_camarilla_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Camarilla parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_camarilla_free); } public CamarillaPivotsOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraCamarillaPivotsOutput native; bool ok; unsafe { ok = NativeMethods.wickra_camarilla_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new CamarillaPivotsOutput(native.pp, native.r1, native.r2, native.r3, native.r4, native.s1, native.s2, native.s3, native.s4) : null; } public void Reset() { NativeMethods.wickra_camarilla_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class CandleVolume : IDisposable { private readonly WickraHandle _handle; public CandleVolume(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_candle_volume_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid CandleVolume parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_candle_volume_free); } public CandleVolumeOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraCandleVolumeOutput native; bool ok; unsafe { ok = NativeMethods.wickra_candle_volume_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new CandleVolumeOutput(native.body, native.width) : null; } public void Reset() { NativeMethods.wickra_candle_volume_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Cci : IDisposable { private readonly WickraHandle _handle; public Cci(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_cci_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Cci parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_cci_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_cci_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_cci_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_cci_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class CenterOfGravity : IDisposable { private readonly WickraHandle _handle; public CenterOfGravity(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_center_of_gravity_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid CenterOfGravity parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_center_of_gravity_free); } public double Update(double @value) { var result = NativeMethods.wickra_center_of_gravity_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_center_of_gravity_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_center_of_gravity_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class CentralPivotRange : IDisposable { private readonly WickraHandle _handle; public CentralPivotRange() { var ptr = NativeMethods.wickra_central_pivot_range_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid CentralPivotRange parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_central_pivot_range_free); } public CentralPivotRangeOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraCentralPivotRangeOutput native; bool ok; unsafe { ok = NativeMethods.wickra_central_pivot_range_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new CentralPivotRangeOutput(native.pivot, native.tc, native.bc) : null; } public void Reset() { NativeMethods.wickra_central_pivot_range_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Cfo : IDisposable { private readonly WickraHandle _handle; public Cfo(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_cfo_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Cfo parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_cfo_free); } public double Update(double @value) { var result = NativeMethods.wickra_cfo_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_cfo_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_cfo_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ChaikinMoneyFlow : IDisposable { private readonly WickraHandle _handle; public ChaikinMoneyFlow(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_chaikin_money_flow_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid ChaikinMoneyFlow parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_chaikin_money_flow_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_chaikin_money_flow_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_chaikin_money_flow_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_chaikin_money_flow_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ChaikinOscillator : IDisposable { private readonly WickraHandle _handle; public ChaikinOscillator(int fast, int slow) { ArgumentOutOfRangeException.ThrowIfNegative(fast); ArgumentOutOfRangeException.ThrowIfNegative(slow); var ptr = NativeMethods.wickra_chaikin_oscillator_new((nuint)fast, (nuint)slow); if (ptr == nint.Zero) { throw new ArgumentException("invalid ChaikinOscillator parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_chaikin_oscillator_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_chaikin_oscillator_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_chaikin_oscillator_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_chaikin_oscillator_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ChaikinVolatility : IDisposable { private readonly WickraHandle _handle; public ChaikinVolatility(int emaPeriod, int rocPeriod) { ArgumentOutOfRangeException.ThrowIfNegative(emaPeriod); ArgumentOutOfRangeException.ThrowIfNegative(rocPeriod); var ptr = NativeMethods.wickra_chaikin_volatility_new((nuint)emaPeriod, (nuint)rocPeriod); if (ptr == nint.Zero) { throw new ArgumentException("invalid ChaikinVolatility parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_chaikin_volatility_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_chaikin_volatility_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_chaikin_volatility_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_chaikin_volatility_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ChandeKrollStop : IDisposable { private readonly WickraHandle _handle; public ChandeKrollStop(int atrPeriod, double atrMultiplier, int stopPeriod) { ArgumentOutOfRangeException.ThrowIfNegative(atrPeriod); ArgumentOutOfRangeException.ThrowIfNegative(stopPeriod); var ptr = NativeMethods.wickra_chande_kroll_stop_new((nuint)atrPeriod, atrMultiplier, (nuint)stopPeriod); if (ptr == nint.Zero) { throw new ArgumentException("invalid ChandeKrollStop parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_chande_kroll_stop_free); } public ChandeKrollStopOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraChandeKrollStopOutput native; bool ok; unsafe { ok = NativeMethods.wickra_chande_kroll_stop_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new ChandeKrollStopOutput(native.stop_long, native.stop_short) : null; } public void Reset() { NativeMethods.wickra_chande_kroll_stop_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ChandelierExit : IDisposable { private readonly WickraHandle _handle; public ChandelierExit(int period, double multiplier) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_chandelier_exit_new((nuint)period, multiplier); if (ptr == nint.Zero) { throw new ArgumentException("invalid ChandelierExit parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_chandelier_exit_free); } public ChandelierExitOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraChandelierExitOutput native; bool ok; unsafe { ok = NativeMethods.wickra_chandelier_exit_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new ChandelierExitOutput(native.long_stop, native.short_stop) : null; } public void Reset() { NativeMethods.wickra_chandelier_exit_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ChoppinessIndex : IDisposable { private readonly WickraHandle _handle; public ChoppinessIndex(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_choppiness_index_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid ChoppinessIndex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_choppiness_index_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_choppiness_index_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_choppiness_index_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_choppiness_index_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ClassicPivots : IDisposable { private readonly WickraHandle _handle; public ClassicPivots() { var ptr = NativeMethods.wickra_classic_pivots_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid ClassicPivots parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_classic_pivots_free); } public ClassicPivotsOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraClassicPivotsOutput native; bool ok; unsafe { ok = NativeMethods.wickra_classic_pivots_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new ClassicPivotsOutput(native.pp, native.r1, native.r2, native.r3, native.s1, native.s2, native.s3) : null; } public void Reset() { NativeMethods.wickra_classic_pivots_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class CloseVsOpen : IDisposable { private readonly WickraHandle _handle; public CloseVsOpen() { var ptr = NativeMethods.wickra_close_vs_open_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid CloseVsOpen parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_close_vs_open_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_close_vs_open_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_close_vs_open_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_close_vs_open_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ClosingMarubozu : IDisposable { private readonly WickraHandle _handle; public ClosingMarubozu() { var ptr = NativeMethods.wickra_closing_marubozu_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid ClosingMarubozu parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_closing_marubozu_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_closing_marubozu_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_closing_marubozu_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_closing_marubozu_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Cmo : IDisposable { private readonly WickraHandle _handle; public Cmo(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_cmo_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Cmo parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_cmo_free); } public double Update(double @value) { var result = NativeMethods.wickra_cmo_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_cmo_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_cmo_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class CoefficientOfVariation : IDisposable { private readonly WickraHandle _handle; public CoefficientOfVariation(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_coefficient_of_variation_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid CoefficientOfVariation parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_coefficient_of_variation_free); } public double Update(double @value) { var result = NativeMethods.wickra_coefficient_of_variation_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_coefficient_of_variation_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_coefficient_of_variation_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Cointegration : IDisposable { private readonly WickraHandle _handle; public Cointegration(int period, int adfLags) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(adfLags); var ptr = NativeMethods.wickra_cointegration_new((nuint)period, (nuint)adfLags); if (ptr == nint.Zero) { throw new ArgumentException("invalid Cointegration parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_cointegration_free); } public CointegrationOutput? Update(double x, double y) { WickraCointegrationOutput native; bool ok; unsafe { ok = NativeMethods.wickra_cointegration_update(_handle.DangerousGetHandle(), x, y, &native); } GC.KeepAlive(_handle); return ok ? new CointegrationOutput(native.hedge_ratio, native.spread, native.adf_stat) : null; } public void Reset() { NativeMethods.wickra_cointegration_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class CommonSenseRatio : IDisposable { private readonly WickraHandle _handle; public CommonSenseRatio(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_common_sense_ratio_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid CommonSenseRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_common_sense_ratio_free); } public double Update(double @value) { var result = NativeMethods.wickra_common_sense_ratio_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_common_sense_ratio_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_common_sense_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class CompositeProfile : IDisposable { private readonly WickraHandle _handle; public CompositeProfile(int period, int bins, double valueAreaPct) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(bins); var ptr = NativeMethods.wickra_composite_profile_new((nuint)period, (nuint)bins, valueAreaPct); if (ptr == nint.Zero) { throw new ArgumentException("invalid CompositeProfile parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_composite_profile_free); } public CompositeProfileOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraCompositeProfileOutput native; bool ok; unsafe { ok = NativeMethods.wickra_composite_profile_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new CompositeProfileOutput(native.poc, native.vah, native.val) : null; } public void Reset() { NativeMethods.wickra_composite_profile_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ConcealingBabySwallow : IDisposable { private readonly WickraHandle _handle; public ConcealingBabySwallow() { var ptr = NativeMethods.wickra_concealing_baby_swallow_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid ConcealingBabySwallow parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_concealing_baby_swallow_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_concealing_baby_swallow_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_concealing_baby_swallow_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_concealing_baby_swallow_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ConditionalValueAtRisk : IDisposable { private readonly WickraHandle _handle; public ConditionalValueAtRisk(int period, double confidence) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_conditional_value_at_risk_new((nuint)period, confidence); if (ptr == nint.Zero) { throw new ArgumentException("invalid ConditionalValueAtRisk parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_conditional_value_at_risk_free); } public double Update(double @value) { var result = NativeMethods.wickra_conditional_value_at_risk_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_conditional_value_at_risk_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_conditional_value_at_risk_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ConnorsRsi : IDisposable { private readonly WickraHandle _handle; public ConnorsRsi(int periodRsi, int periodStreak, int periodRank) { ArgumentOutOfRangeException.ThrowIfNegative(periodRsi); ArgumentOutOfRangeException.ThrowIfNegative(periodStreak); ArgumentOutOfRangeException.ThrowIfNegative(periodRank); var ptr = NativeMethods.wickra_connors_rsi_new((nuint)periodRsi, (nuint)periodStreak, (nuint)periodRank); if (ptr == nint.Zero) { throw new ArgumentException("invalid ConnorsRsi parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_connors_rsi_free); } public double Update(double @value) { var result = NativeMethods.wickra_connors_rsi_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_connors_rsi_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_connors_rsi_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Coppock : IDisposable { private readonly WickraHandle _handle; public Coppock(int rocLongPeriod, int rocShortPeriod, int wmaPeriod) { ArgumentOutOfRangeException.ThrowIfNegative(rocLongPeriod); ArgumentOutOfRangeException.ThrowIfNegative(rocShortPeriod); ArgumentOutOfRangeException.ThrowIfNegative(wmaPeriod); var ptr = NativeMethods.wickra_coppock_new((nuint)rocLongPeriod, (nuint)rocShortPeriod, (nuint)wmaPeriod); if (ptr == nint.Zero) { throw new ArgumentException("invalid Coppock parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_coppock_free); } public double Update(double @value) { var result = NativeMethods.wickra_coppock_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_coppock_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_coppock_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class CorrelationTrendIndicator : IDisposable { private readonly WickraHandle _handle; public CorrelationTrendIndicator(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_correlation_trend_indicator_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid CorrelationTrendIndicator parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_correlation_trend_indicator_free); } public double Update(double @value) { var result = NativeMethods.wickra_correlation_trend_indicator_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_correlation_trend_indicator_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_correlation_trend_indicator_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Counterattack : IDisposable { private readonly WickraHandle _handle; public Counterattack() { var ptr = NativeMethods.wickra_counterattack_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Counterattack parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_counterattack_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_counterattack_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_counterattack_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_counterattack_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Crab : IDisposable { private readonly WickraHandle _handle; public Crab() { var ptr = NativeMethods.wickra_crab_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Crab parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_crab_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_crab_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_crab_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_crab_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class CumulativeVolumeDelta : IDisposable { private readonly WickraHandle _handle; public CumulativeVolumeDelta() { var ptr = NativeMethods.wickra_cumulative_volume_delta_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid CumulativeVolumeDelta parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_cumulative_volume_delta_free); } public double Update(double price, double size, bool isBuy, long timestamp) { var result = NativeMethods.wickra_cumulative_volume_delta_update(_handle.DangerousGetHandle(), price, size, isBuy, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_cumulative_volume_delta_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class CumulativeVolumeIndex : IDisposable { private readonly WickraHandle _handle; public CumulativeVolumeIndex() { var ptr = NativeMethods.wickra_cumulative_volume_index_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid CumulativeVolumeIndex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_cumulative_volume_index_free); } public double Update(ReadOnlySpan change, ReadOnlySpan volume, ReadOnlySpan newHigh, ReadOnlySpan newLow, ReadOnlySpan aboveMa, ReadOnlySpan onBuySignal, long timestamp) { if (volume.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newHigh.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newLow.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (aboveMa.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (onBuySignal.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* changePtr = change) fixed (double* volumePtr = volume) fixed (bool* newHighPtr = newHigh) fixed (bool* newLowPtr = newLow) fixed (bool* aboveMaPtr = aboveMa) fixed (bool* onBuySignalPtr = onBuySignal) { result = NativeMethods.wickra_cumulative_volume_index_update(_handle.DangerousGetHandle(), changePtr, volumePtr, newHighPtr, newLowPtr, aboveMaPtr, onBuySignalPtr, (nuint)change.Length, timestamp); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_cumulative_volume_index_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class CupAndHandle : IDisposable { private readonly WickraHandle _handle; public CupAndHandle() { var ptr = NativeMethods.wickra_cup_and_handle_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid CupAndHandle parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_cup_and_handle_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_cup_and_handle_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_cup_and_handle_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_cup_and_handle_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class CyberneticCycle : IDisposable { private readonly WickraHandle _handle; public CyberneticCycle(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_cybernetic_cycle_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid CyberneticCycle parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_cybernetic_cycle_free); } public double Update(double @value) { var result = NativeMethods.wickra_cybernetic_cycle_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_cybernetic_cycle_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_cybernetic_cycle_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Cypher : IDisposable { private readonly WickraHandle _handle; public Cypher() { var ptr = NativeMethods.wickra_cypher_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Cypher parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_cypher_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_cypher_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_cypher_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_cypher_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class DayOfWeekProfile : IDisposable { private readonly WickraHandle _handle; private readonly int _valuesCapacity; public DayOfWeekProfile(int utcOffsetMinutes) { var ptr = NativeMethods.wickra_day_of_week_profile_new(utcOffsetMinutes); if (ptr == nint.Zero) { throw new ArgumentException("invalid DayOfWeekProfile parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_day_of_week_profile_free); _valuesCapacity = 4096; } public double[]? Update(double open, double high, double low, double close, double volume, long timestamp) { var values = new double[_valuesCapacity]; long length; unsafe { fixed (double* valuesPtr = values) { length = (long)NativeMethods.wickra_day_of_week_profile_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, valuesPtr, (nuint)_valuesCapacity); } } GC.KeepAlive(_handle); if (length < 0) { return null; } if (length < values.Length) { Array.Resize(ref values, (int)length); } return values; } public void Reset() { NativeMethods.wickra_day_of_week_profile_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Decycler : IDisposable { private readonly WickraHandle _handle; public Decycler(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_decycler_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Decycler parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_decycler_free); } public double Update(double @value) { var result = NativeMethods.wickra_decycler_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_decycler_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_decycler_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class DecyclerOscillator : IDisposable { private readonly WickraHandle _handle; public DecyclerOscillator(int fast, int slow) { ArgumentOutOfRangeException.ThrowIfNegative(fast); ArgumentOutOfRangeException.ThrowIfNegative(slow); var ptr = NativeMethods.wickra_decycler_oscillator_new((nuint)fast, (nuint)slow); if (ptr == nint.Zero) { throw new ArgumentException("invalid DecyclerOscillator parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_decycler_oscillator_free); } public double Update(double @value) { var result = NativeMethods.wickra_decycler_oscillator_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_decycler_oscillator_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_decycler_oscillator_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Dema : IDisposable { private readonly WickraHandle _handle; public Dema(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_dema_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Dema parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_dema_free); } public double Update(double @value) { var result = NativeMethods.wickra_dema_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_dema_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_dema_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class DemandIndex : IDisposable { private readonly WickraHandle _handle; public DemandIndex(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_demand_index_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid DemandIndex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_demand_index_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_demand_index_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_demand_index_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_demand_index_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class DemarkPivots : IDisposable { private readonly WickraHandle _handle; public DemarkPivots() { var ptr = NativeMethods.wickra_demark_pivots_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid DemarkPivots parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_demark_pivots_free); } public DemarkPivotsOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraDemarkPivotsOutput native; bool ok; unsafe { ok = NativeMethods.wickra_demark_pivots_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new DemarkPivotsOutput(native.pp, native.r1, native.s1) : null; } public void Reset() { NativeMethods.wickra_demark_pivots_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class DepthSlope : IDisposable { private readonly WickraHandle _handle; public DepthSlope() { var ptr = NativeMethods.wickra_depth_slope_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid DepthSlope parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_depth_slope_free); } public double Update(ReadOnlySpan bidPrice, ReadOnlySpan bidSize, ReadOnlySpan askPrice, ReadOnlySpan askSize) { if (bidSize.Length != bidPrice.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (askSize.Length != askPrice.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* bidPricePtr = bidPrice) fixed (double* bidSizePtr = bidSize) fixed (double* askPricePtr = askPrice) fixed (double* askSizePtr = askSize) { result = NativeMethods.wickra_depth_slope_update(_handle.DangerousGetHandle(), bidPricePtr, bidSizePtr, (nuint)bidPrice.Length, askPricePtr, askSizePtr, (nuint)askPrice.Length); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_depth_slope_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class DerivativeOscillator : IDisposable { private readonly WickraHandle _handle; public DerivativeOscillator(int rsiPeriod, int smooth1, int smooth2, int signalPeriod) { ArgumentOutOfRangeException.ThrowIfNegative(rsiPeriod); ArgumentOutOfRangeException.ThrowIfNegative(smooth1); ArgumentOutOfRangeException.ThrowIfNegative(smooth2); ArgumentOutOfRangeException.ThrowIfNegative(signalPeriod); var ptr = NativeMethods.wickra_derivative_oscillator_new((nuint)rsiPeriod, (nuint)smooth1, (nuint)smooth2, (nuint)signalPeriod); if (ptr == nint.Zero) { throw new ArgumentException("invalid DerivativeOscillator parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_derivative_oscillator_free); } public double Update(double @value) { var result = NativeMethods.wickra_derivative_oscillator_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_derivative_oscillator_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_derivative_oscillator_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class DetrendedStdDev : IDisposable { private readonly WickraHandle _handle; public DetrendedStdDev(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_detrended_std_dev_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid DetrendedStdDev parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_detrended_std_dev_free); } public double Update(double @value) { var result = NativeMethods.wickra_detrended_std_dev_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_detrended_std_dev_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_detrended_std_dev_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class DisparityIndex : IDisposable { private readonly WickraHandle _handle; public DisparityIndex(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_disparity_index_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid DisparityIndex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_disparity_index_free); } public double Update(double @value) { var result = NativeMethods.wickra_disparity_index_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_disparity_index_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_disparity_index_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class DistanceSsd : IDisposable { private readonly WickraHandle _handle; public DistanceSsd(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_distance_ssd_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid DistanceSsd parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_distance_ssd_free); } public double Update(double x, double y) { var result = NativeMethods.wickra_distance_ssd_update(_handle.DangerousGetHandle(), x, y); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan x, ReadOnlySpan y) { var n = x.Length; if (y.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* xPtr = x) fixed (double* yPtr = y) fixed (double* outputPtr = output) { NativeMethods.wickra_distance_ssd_batch(_handle.DangerousGetHandle(), xPtr, yPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_distance_ssd_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Doji : IDisposable { private readonly WickraHandle _handle; public Doji() { var ptr = NativeMethods.wickra_doji_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Doji parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_doji_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_doji_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_doji_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_doji_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class DojiStar : IDisposable { private readonly WickraHandle _handle; public DojiStar() { var ptr = NativeMethods.wickra_doji_star_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid DojiStar parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_doji_star_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_doji_star_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_doji_star_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_doji_star_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class DollarBars : IDisposable { private readonly WickraHandle _handle; public DollarBars(double dollarPerBar) { var ptr = NativeMethods.wickra_dollar_bars_new(dollarPerBar); if (ptr == nint.Zero) { throw new ArgumentException("invalid DollarBars parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_dollar_bars_free); } public DollarBar[] Update(double open, double high, double low, double close, double volume, long timestamp) { const int cap = 64; Span buffer = stackalloc WickraDollarBar[cap]; long count; unsafe { fixed (WickraDollarBar* ptr = buffer) { count = (long)NativeMethods.wickra_dollar_bars_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, ptr, (nuint)cap); } } GC.KeepAlive(_handle); if (count <= 0) { return Array.Empty(); } var result = new DollarBar[count]; for (var i = 0; i < count; i++) { result[i] = new DollarBar(buffer[i].open, buffer[i].high, buffer[i].low, buffer[i].close, buffer[i].volume, buffer[i].dollar); } return result; } public void Reset() { NativeMethods.wickra_dollar_bars_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Donchian : IDisposable { private readonly WickraHandle _handle; public Donchian(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_donchian_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Donchian parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_donchian_free); } public DonchianOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraDonchianOutput native; bool ok; unsafe { ok = NativeMethods.wickra_donchian_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new DonchianOutput(native.upper, native.middle, native.lower) : null; } public void Reset() { NativeMethods.wickra_donchian_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class DonchianStop : IDisposable { private readonly WickraHandle _handle; public DonchianStop(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_donchian_stop_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid DonchianStop parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_donchian_stop_free); } public DonchianStopOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraDonchianStopOutput native; bool ok; unsafe { ok = NativeMethods.wickra_donchian_stop_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new DonchianStopOutput(native.stop_long, native.stop_short) : null; } public void Reset() { NativeMethods.wickra_donchian_stop_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class DoubleBollinger : IDisposable { private readonly WickraHandle _handle; public DoubleBollinger(int period, double kInner, double kOuter) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_double_bollinger_new((nuint)period, kInner, kOuter); if (ptr == nint.Zero) { throw new ArgumentException("invalid DoubleBollinger parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_double_bollinger_free); } public DoubleBollingerOutput? Update(double @value) { WickraDoubleBollingerOutput native; bool ok; unsafe { ok = NativeMethods.wickra_double_bollinger_update(_handle.DangerousGetHandle(), @value, &native); } GC.KeepAlive(_handle); return ok ? new DoubleBollingerOutput(native.upper_outer, native.upper_inner, native.middle, native.lower_inner, native.lower_outer) : null; } public void Reset() { NativeMethods.wickra_double_bollinger_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class DoubleTopBottom : IDisposable { private readonly WickraHandle _handle; public DoubleTopBottom() { var ptr = NativeMethods.wickra_double_top_bottom_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid DoubleTopBottom parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_double_top_bottom_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_double_top_bottom_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_double_top_bottom_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_double_top_bottom_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class DownsideGapThreeMethods : IDisposable { private readonly WickraHandle _handle; public DownsideGapThreeMethods() { var ptr = NativeMethods.wickra_downside_gap_three_methods_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid DownsideGapThreeMethods parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_downside_gap_three_methods_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_downside_gap_three_methods_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_downside_gap_three_methods_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_downside_gap_three_methods_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Dpo : IDisposable { private readonly WickraHandle _handle; public Dpo(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_dpo_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Dpo parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_dpo_free); } public double Update(double @value) { var result = NativeMethods.wickra_dpo_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_dpo_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_dpo_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class DragonflyDoji : IDisposable { private readonly WickraHandle _handle; public DragonflyDoji() { var ptr = NativeMethods.wickra_dragonfly_doji_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid DragonflyDoji parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_dragonfly_doji_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_dragonfly_doji_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_dragonfly_doji_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_dragonfly_doji_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class DrawdownDuration : IDisposable { private readonly WickraHandle _handle; public DrawdownDuration() { var ptr = NativeMethods.wickra_drawdown_duration_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid DrawdownDuration parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_drawdown_duration_free); } public double Update(double @value) { var result = NativeMethods.wickra_drawdown_duration_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_drawdown_duration_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_drawdown_duration_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class DumplingTop : IDisposable { private readonly WickraHandle _handle; public DumplingTop(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_dumpling_top_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid DumplingTop parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_dumpling_top_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_dumpling_top_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_dumpling_top_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_dumpling_top_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Dx : IDisposable { private readonly WickraHandle _handle; public Dx(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_dx_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Dx parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_dx_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_dx_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_dx_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_dx_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class DynamicMomentumIndex : IDisposable { private readonly WickraHandle _handle; public DynamicMomentumIndex(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_dynamic_momentum_index_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid DynamicMomentumIndex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_dynamic_momentum_index_free); } public double Update(double @value) { var result = NativeMethods.wickra_dynamic_momentum_index_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_dynamic_momentum_index_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_dynamic_momentum_index_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class EaseOfMovement : IDisposable { private readonly WickraHandle _handle; public EaseOfMovement(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_ease_of_movement_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid EaseOfMovement parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_ease_of_movement_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_ease_of_movement_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_ease_of_movement_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_ease_of_movement_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class EffectiveSpread : IDisposable { private readonly WickraHandle _handle; public EffectiveSpread() { var ptr = NativeMethods.wickra_effective_spread_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid EffectiveSpread parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_effective_spread_free); } public double Update(double price, double size, bool isBuy, long timestamp, double mid) { var result = NativeMethods.wickra_effective_spread_update(_handle.DangerousGetHandle(), price, size, isBuy, timestamp, mid); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_effective_spread_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class EhlersStochastic : IDisposable { private readonly WickraHandle _handle; public EhlersStochastic(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_ehlers_stochastic_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid EhlersStochastic parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_ehlers_stochastic_free); } public double Update(double @value) { var result = NativeMethods.wickra_ehlers_stochastic_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_ehlers_stochastic_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_ehlers_stochastic_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Ehma : IDisposable { private readonly WickraHandle _handle; public Ehma(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_ehma_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Ehma parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_ehma_free); } public double Update(double @value) { var result = NativeMethods.wickra_ehma_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_ehma_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_ehma_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ElderImpulse : IDisposable { private readonly WickraHandle _handle; public ElderImpulse(int emaPeriod, int macdFast, int macdSlow, int macdSignal) { ArgumentOutOfRangeException.ThrowIfNegative(emaPeriod); ArgumentOutOfRangeException.ThrowIfNegative(macdFast); ArgumentOutOfRangeException.ThrowIfNegative(macdSlow); ArgumentOutOfRangeException.ThrowIfNegative(macdSignal); var ptr = NativeMethods.wickra_elder_impulse_new((nuint)emaPeriod, (nuint)macdFast, (nuint)macdSlow, (nuint)macdSignal); if (ptr == nint.Zero) { throw new ArgumentException("invalid ElderImpulse parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_elder_impulse_free); } public double Update(double @value) { var result = NativeMethods.wickra_elder_impulse_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_elder_impulse_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_elder_impulse_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ElderRay : IDisposable { private readonly WickraHandle _handle; public ElderRay(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_elder_ray_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid ElderRay parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_elder_ray_free); } public ElderRayOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraElderRayOutput native; bool ok; unsafe { ok = NativeMethods.wickra_elder_ray_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new ElderRayOutput(native.bull_power, native.bear_power) : null; } public void Reset() { NativeMethods.wickra_elder_ray_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ElderSafeZone : IDisposable { private readonly WickraHandle _handle; public ElderSafeZone(int period, double coeff) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_elder_safe_zone_new((nuint)period, coeff); if (ptr == nint.Zero) { throw new ArgumentException("invalid ElderSafeZone parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_elder_safe_zone_free); } public ElderSafeZoneOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraElderSafeZoneOutput native; bool ok; unsafe { ok = NativeMethods.wickra_elder_safe_zone_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new ElderSafeZoneOutput(native.@value, native.direction) : null; } public void Reset() { NativeMethods.wickra_elder_safe_zone_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Ema : IDisposable { private readonly WickraHandle _handle; public Ema(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_ema_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Ema parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_ema_free); } public double Update(double @value) { var result = NativeMethods.wickra_ema_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_ema_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_ema_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class EmpiricalModeDecomposition : IDisposable { private readonly WickraHandle _handle; public EmpiricalModeDecomposition(int period, double fraction) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_empirical_mode_decomposition_new((nuint)period, fraction); if (ptr == nint.Zero) { throw new ArgumentException("invalid EmpiricalModeDecomposition parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_empirical_mode_decomposition_free); } public double Update(double @value) { var result = NativeMethods.wickra_empirical_mode_decomposition_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_empirical_mode_decomposition_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_empirical_mode_decomposition_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Engulfing : IDisposable { private readonly WickraHandle _handle; public Engulfing() { var ptr = NativeMethods.wickra_engulfing_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Engulfing parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_engulfing_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_engulfing_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_engulfing_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_engulfing_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Equivolume : IDisposable { private readonly WickraHandle _handle; public Equivolume(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_equivolume_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Equivolume parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_equivolume_free); } public EquivolumeOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraEquivolumeOutput native; bool ok; unsafe { ok = NativeMethods.wickra_equivolume_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new EquivolumeOutput(native.height, native.width) : null; } public void Reset() { NativeMethods.wickra_equivolume_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class EstimatedLeverageRatio : IDisposable { private readonly WickraHandle _handle; public EstimatedLeverageRatio() { var ptr = NativeMethods.wickra_estimated_leverage_ratio_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid EstimatedLeverageRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_estimated_leverage_ratio_free); } public double Update(double fundingRate, double markPrice, double indexPrice, double futuresPrice, double openInterest, double longSize, double shortSize, double takerBuyVolume, double takerSellVolume, double longLiquidation, double shortLiquidation, long timestamp) { var result = NativeMethods.wickra_estimated_leverage_ratio_update(_handle.DangerousGetHandle(), fundingRate, markPrice, indexPrice, futuresPrice, openInterest, longSize, shortSize, takerBuyVolume, takerSellVolume, longLiquidation, shortLiquidation, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_estimated_leverage_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class EvenBetterSinewave : IDisposable { private readonly WickraHandle _handle; public EvenBetterSinewave(int hpPeriod, int ssfLength) { ArgumentOutOfRangeException.ThrowIfNegative(hpPeriod); ArgumentOutOfRangeException.ThrowIfNegative(ssfLength); var ptr = NativeMethods.wickra_even_better_sinewave_new((nuint)hpPeriod, (nuint)ssfLength); if (ptr == nint.Zero) { throw new ArgumentException("invalid EvenBetterSinewave parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_even_better_sinewave_free); } public double Update(double @value) { var result = NativeMethods.wickra_even_better_sinewave_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_even_better_sinewave_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_even_better_sinewave_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class EveningDojiStar : IDisposable { private readonly WickraHandle _handle; public EveningDojiStar() { var ptr = NativeMethods.wickra_evening_doji_star_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid EveningDojiStar parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_evening_doji_star_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_evening_doji_star_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_evening_doji_star_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_evening_doji_star_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Evwma : IDisposable { private readonly WickraHandle _handle; public Evwma(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_evwma_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Evwma parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_evwma_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_evwma_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_evwma_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_evwma_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class EwmaVolatility : IDisposable { private readonly WickraHandle _handle; public EwmaVolatility(double lambda) { var ptr = NativeMethods.wickra_ewma_volatility_new(lambda); if (ptr == nint.Zero) { throw new ArgumentException("invalid EwmaVolatility parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_ewma_volatility_free); } public double Update(double @value) { var result = NativeMethods.wickra_ewma_volatility_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_ewma_volatility_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_ewma_volatility_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Expectancy : IDisposable { private readonly WickraHandle _handle; public Expectancy(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_expectancy_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Expectancy parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_expectancy_free); } public double Update(double @value) { var result = NativeMethods.wickra_expectancy_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_expectancy_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_expectancy_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class FallingThreeMethods : IDisposable { private readonly WickraHandle _handle; public FallingThreeMethods() { var ptr = NativeMethods.wickra_falling_three_methods_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid FallingThreeMethods parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_falling_three_methods_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_falling_three_methods_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_falling_three_methods_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_falling_three_methods_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Fama : IDisposable { private readonly WickraHandle _handle; public Fama(double fastLimit, double slowLimit) { var ptr = NativeMethods.wickra_fama_new(fastLimit, slowLimit); if (ptr == nint.Zero) { throw new ArgumentException("invalid Fama parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_fama_free); } public double Update(double @value) { var result = NativeMethods.wickra_fama_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_fama_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_fama_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class FibArcs : IDisposable { private readonly WickraHandle _handle; public FibArcs() { var ptr = NativeMethods.wickra_fib_arcs_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid FibArcs parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_fib_arcs_free); } public FibArcsOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraFibArcsOutput native; bool ok; unsafe { ok = NativeMethods.wickra_fib_arcs_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new FibArcsOutput(native.arc_382, native.arc_500, native.arc_618) : null; } public void Reset() { NativeMethods.wickra_fib_arcs_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class FibChannel : IDisposable { private readonly WickraHandle _handle; public FibChannel() { var ptr = NativeMethods.wickra_fib_channel_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid FibChannel parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_fib_channel_free); } public FibChannelOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraFibChannelOutput native; bool ok; unsafe { ok = NativeMethods.wickra_fib_channel_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new FibChannelOutput(native.@base, native.level_618, native.level_1000, native.level_1618) : null; } public void Reset() { NativeMethods.wickra_fib_channel_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class FibConfluence : IDisposable { private readonly WickraHandle _handle; public FibConfluence() { var ptr = NativeMethods.wickra_fib_confluence_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid FibConfluence parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_fib_confluence_free); } public FibConfluenceOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraFibConfluenceOutput native; bool ok; unsafe { ok = NativeMethods.wickra_fib_confluence_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new FibConfluenceOutput(native.price, native.strength) : null; } public void Reset() { NativeMethods.wickra_fib_confluence_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class FibExtension : IDisposable { private readonly WickraHandle _handle; public FibExtension() { var ptr = NativeMethods.wickra_fib_extension_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid FibExtension parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_fib_extension_free); } public FibExtensionOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraFibExtensionOutput native; bool ok; unsafe { ok = NativeMethods.wickra_fib_extension_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new FibExtensionOutput(native.level_1272, native.level_1414, native.level_1618, native.level_2000, native.level_2618) : null; } public void Reset() { NativeMethods.wickra_fib_extension_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class FibFan : IDisposable { private readonly WickraHandle _handle; public FibFan() { var ptr = NativeMethods.wickra_fib_fan_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid FibFan parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_fib_fan_free); } public FibFanOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraFibFanOutput native; bool ok; unsafe { ok = NativeMethods.wickra_fib_fan_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new FibFanOutput(native.fan_382, native.fan_500, native.fan_618) : null; } public void Reset() { NativeMethods.wickra_fib_fan_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class FibProjection : IDisposable { private readonly WickraHandle _handle; public FibProjection() { var ptr = NativeMethods.wickra_fib_projection_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid FibProjection parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_fib_projection_free); } public FibProjectionOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraFibProjectionOutput native; bool ok; unsafe { ok = NativeMethods.wickra_fib_projection_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new FibProjectionOutput(native.level_618, native.level_1000, native.level_1618, native.level_2618) : null; } public void Reset() { NativeMethods.wickra_fib_projection_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class FibRetracement : IDisposable { private readonly WickraHandle _handle; public FibRetracement() { var ptr = NativeMethods.wickra_fib_retracement_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid FibRetracement parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_fib_retracement_free); } public FibRetracementOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraFibRetracementOutput native; bool ok; unsafe { ok = NativeMethods.wickra_fib_retracement_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new FibRetracementOutput(native.level_0, native.level_236, native.level_382, native.level_500, native.level_618, native.level_786, native.level_1000) : null; } public void Reset() { NativeMethods.wickra_fib_retracement_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class FibTimeZones : IDisposable { private readonly WickraHandle _handle; public FibTimeZones() { var ptr = NativeMethods.wickra_fib_time_zones_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid FibTimeZones parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_fib_time_zones_free); } public FibTimeZonesOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraFibTimeZonesOutput native; bool ok; unsafe { ok = NativeMethods.wickra_fib_time_zones_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new FibTimeZonesOutput(native.on_zone, native.bars_to_next) : null; } public void Reset() { NativeMethods.wickra_fib_time_zones_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class FibonacciPivots : IDisposable { private readonly WickraHandle _handle; public FibonacciPivots() { var ptr = NativeMethods.wickra_fibonacci_pivots_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid FibonacciPivots parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_fibonacci_pivots_free); } public FibonacciPivotsOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraFibonacciPivotsOutput native; bool ok; unsafe { ok = NativeMethods.wickra_fibonacci_pivots_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new FibonacciPivotsOutput(native.pp, native.r1, native.r2, native.r3, native.s1, native.s2, native.s3) : null; } public void Reset() { NativeMethods.wickra_fibonacci_pivots_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class FisherRsi : IDisposable { private readonly WickraHandle _handle; public FisherRsi(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_fisher_rsi_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid FisherRsi parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_fisher_rsi_free); } public double Update(double @value) { var result = NativeMethods.wickra_fisher_rsi_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_fisher_rsi_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_fisher_rsi_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class FisherTransform : IDisposable { private readonly WickraHandle _handle; public FisherTransform(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_fisher_transform_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid FisherTransform parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_fisher_transform_free); } public double Update(double @value) { var result = NativeMethods.wickra_fisher_transform_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_fisher_transform_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_fisher_transform_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class FlagPennant : IDisposable { private readonly WickraHandle _handle; public FlagPennant() { var ptr = NativeMethods.wickra_flag_pennant_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid FlagPennant parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_flag_pennant_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_flag_pennant_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_flag_pennant_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_flag_pennant_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Footprint : IDisposable { private readonly WickraHandle _handle; public Footprint(double tickSize) { var ptr = NativeMethods.wickra_footprint_new(tickSize); if (ptr == nint.Zero) { throw new ArgumentException("invalid Footprint parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_footprint_free); } public FootprintLevel[] Update(double price, double size, bool isBuy, long timestamp) { const int cap = 64; Span buffer = stackalloc WickraFootprintLevel[cap]; long count; unsafe { fixed (WickraFootprintLevel* ptr = buffer) { count = (long)NativeMethods.wickra_footprint_update(_handle.DangerousGetHandle(), price, size, isBuy, timestamp, ptr, (nuint)cap); } } GC.KeepAlive(_handle); if (count <= 0) { return Array.Empty(); } var result = new FootprintLevel[count]; for (var i = 0; i < count; i++) { result[i] = new FootprintLevel(buffer[i].price, buffer[i].bid_vol, buffer[i].ask_vol); } return result; } public void Reset() { NativeMethods.wickra_footprint_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ForceIndex : IDisposable { private readonly WickraHandle _handle; public ForceIndex(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_force_index_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid ForceIndex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_force_index_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_force_index_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_force_index_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_force_index_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class FractalChaosBands : IDisposable { private readonly WickraHandle _handle; public FractalChaosBands(int k) { ArgumentOutOfRangeException.ThrowIfNegative(k); var ptr = NativeMethods.wickra_fractal_chaos_bands_new((nuint)k); if (ptr == nint.Zero) { throw new ArgumentException("invalid FractalChaosBands parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_fractal_chaos_bands_free); } public FractalChaosBandsOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraFractalChaosBandsOutput native; bool ok; unsafe { ok = NativeMethods.wickra_fractal_chaos_bands_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new FractalChaosBandsOutput(native.upper, native.lower) : null; } public void Reset() { NativeMethods.wickra_fractal_chaos_bands_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Frama : IDisposable { private readonly WickraHandle _handle; public Frama(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_frama_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Frama parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_frama_free); } public double Update(double @value) { var result = NativeMethods.wickra_frama_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_frama_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_frama_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class FryPanBottom : IDisposable { private readonly WickraHandle _handle; public FryPanBottom(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_fry_pan_bottom_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid FryPanBottom parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_fry_pan_bottom_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_fry_pan_bottom_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_fry_pan_bottom_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_fry_pan_bottom_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class FundingBasis : IDisposable { private readonly WickraHandle _handle; public FundingBasis() { var ptr = NativeMethods.wickra_funding_basis_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid FundingBasis parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_funding_basis_free); } public double Update(double fundingRate, double markPrice, double indexPrice, double futuresPrice, double openInterest, double longSize, double shortSize, double takerBuyVolume, double takerSellVolume, double longLiquidation, double shortLiquidation, long timestamp) { var result = NativeMethods.wickra_funding_basis_update(_handle.DangerousGetHandle(), fundingRate, markPrice, indexPrice, futuresPrice, openInterest, longSize, shortSize, takerBuyVolume, takerSellVolume, longLiquidation, shortLiquidation, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_funding_basis_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class FundingImpliedApr : IDisposable { private readonly WickraHandle _handle; public FundingImpliedApr(double intervalsPerYear) { var ptr = NativeMethods.wickra_funding_implied_apr_new(intervalsPerYear); if (ptr == nint.Zero) { throw new ArgumentException("invalid FundingImpliedApr parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_funding_implied_apr_free); } public double Update(double fundingRate, double markPrice, double indexPrice, double futuresPrice, double openInterest, double longSize, double shortSize, double takerBuyVolume, double takerSellVolume, double longLiquidation, double shortLiquidation, long timestamp) { var result = NativeMethods.wickra_funding_implied_apr_update(_handle.DangerousGetHandle(), fundingRate, markPrice, indexPrice, futuresPrice, openInterest, longSize, shortSize, takerBuyVolume, takerSellVolume, longLiquidation, shortLiquidation, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_funding_implied_apr_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class FundingRate : IDisposable { private readonly WickraHandle _handle; public FundingRate() { var ptr = NativeMethods.wickra_funding_rate_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid FundingRate parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_funding_rate_free); } public double Update(double fundingRate, double markPrice, double indexPrice, double futuresPrice, double openInterest, double longSize, double shortSize, double takerBuyVolume, double takerSellVolume, double longLiquidation, double shortLiquidation, long timestamp) { var result = NativeMethods.wickra_funding_rate_update(_handle.DangerousGetHandle(), fundingRate, markPrice, indexPrice, futuresPrice, openInterest, longSize, shortSize, takerBuyVolume, takerSellVolume, longLiquidation, shortLiquidation, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_funding_rate_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class FundingRateMean : IDisposable { private readonly WickraHandle _handle; public FundingRateMean(int window) { ArgumentOutOfRangeException.ThrowIfNegative(window); var ptr = NativeMethods.wickra_funding_rate_mean_new((nuint)window); if (ptr == nint.Zero) { throw new ArgumentException("invalid FundingRateMean parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_funding_rate_mean_free); } public double Update(double fundingRate, double markPrice, double indexPrice, double futuresPrice, double openInterest, double longSize, double shortSize, double takerBuyVolume, double takerSellVolume, double longLiquidation, double shortLiquidation, long timestamp) { var result = NativeMethods.wickra_funding_rate_mean_update(_handle.DangerousGetHandle(), fundingRate, markPrice, indexPrice, futuresPrice, openInterest, longSize, shortSize, takerBuyVolume, takerSellVolume, longLiquidation, shortLiquidation, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_funding_rate_mean_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class FundingRateZScore : IDisposable { private readonly WickraHandle _handle; public FundingRateZScore(int window) { ArgumentOutOfRangeException.ThrowIfNegative(window); var ptr = NativeMethods.wickra_funding_rate_z_score_new((nuint)window); if (ptr == nint.Zero) { throw new ArgumentException("invalid FundingRateZScore parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_funding_rate_z_score_free); } public double Update(double fundingRate, double markPrice, double indexPrice, double futuresPrice, double openInterest, double longSize, double shortSize, double takerBuyVolume, double takerSellVolume, double longLiquidation, double shortLiquidation, long timestamp) { var result = NativeMethods.wickra_funding_rate_z_score_update(_handle.DangerousGetHandle(), fundingRate, markPrice, indexPrice, futuresPrice, openInterest, longSize, shortSize, takerBuyVolume, takerSellVolume, longLiquidation, shortLiquidation, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_funding_rate_z_score_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class GainLossRatio : IDisposable { private readonly WickraHandle _handle; public GainLossRatio(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_gain_loss_ratio_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid GainLossRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_gain_loss_ratio_free); } public double Update(double @value) { var result = NativeMethods.wickra_gain_loss_ratio_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_gain_loss_ratio_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_gain_loss_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class GainToPainRatio : IDisposable { private readonly WickraHandle _handle; public GainToPainRatio(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_gain_to_pain_ratio_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid GainToPainRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_gain_to_pain_ratio_free); } public double Update(double @value) { var result = NativeMethods.wickra_gain_to_pain_ratio_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_gain_to_pain_ratio_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_gain_to_pain_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class GapSideBySideWhite : IDisposable { private readonly WickraHandle _handle; public GapSideBySideWhite() { var ptr = NativeMethods.wickra_gap_side_by_side_white_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid GapSideBySideWhite parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_gap_side_by_side_white_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_gap_side_by_side_white_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_gap_side_by_side_white_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_gap_side_by_side_white_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Garch11 : IDisposable { private readonly WickraHandle _handle; public Garch11(double omega, double alpha, double beta) { var ptr = NativeMethods.wickra_garch11_new(omega, alpha, beta); if (ptr == nint.Zero) { throw new ArgumentException("invalid Garch11 parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_garch11_free); } public double Update(double @value) { var result = NativeMethods.wickra_garch11_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_garch11_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_garch11_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class GarmanKlassVolatility : IDisposable { private readonly WickraHandle _handle; public GarmanKlassVolatility(int period, int tradingPeriods) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(tradingPeriods); var ptr = NativeMethods.wickra_garman_klass_volatility_new((nuint)period, (nuint)tradingPeriods); if (ptr == nint.Zero) { throw new ArgumentException("invalid GarmanKlassVolatility parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_garman_klass_volatility_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_garman_klass_volatility_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_garman_klass_volatility_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_garman_klass_volatility_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Gartley : IDisposable { private readonly WickraHandle _handle; public Gartley() { var ptr = NativeMethods.wickra_gartley_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Gartley parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_gartley_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_gartley_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_gartley_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_gartley_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class GatorOscillator : IDisposable { private readonly WickraHandle _handle; public GatorOscillator(int jawPeriod, int teethPeriod, int lipsPeriod) { ArgumentOutOfRangeException.ThrowIfNegative(jawPeriod); ArgumentOutOfRangeException.ThrowIfNegative(teethPeriod); ArgumentOutOfRangeException.ThrowIfNegative(lipsPeriod); var ptr = NativeMethods.wickra_gator_oscillator_new((nuint)jawPeriod, (nuint)teethPeriod, (nuint)lipsPeriod); if (ptr == nint.Zero) { throw new ArgumentException("invalid GatorOscillator parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_gator_oscillator_free); } public GatorOscillatorOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraGatorOscillatorOutput native; bool ok; unsafe { ok = NativeMethods.wickra_gator_oscillator_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new GatorOscillatorOutput(native.upper, native.lower) : null; } public void Reset() { NativeMethods.wickra_gator_oscillator_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class GeneralizedDema : IDisposable { private readonly WickraHandle _handle; public GeneralizedDema(int period, double v) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_generalized_dema_new((nuint)period, v); if (ptr == nint.Zero) { throw new ArgumentException("invalid GeneralizedDema parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_generalized_dema_free); } public double Update(double @value) { var result = NativeMethods.wickra_generalized_dema_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_generalized_dema_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_generalized_dema_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class GeometricMa : IDisposable { private readonly WickraHandle _handle; public GeometricMa(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_geometric_ma_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid GeometricMa parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_geometric_ma_free); } public double Update(double @value) { var result = NativeMethods.wickra_geometric_ma_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_geometric_ma_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_geometric_ma_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class GoldenPocket : IDisposable { private readonly WickraHandle _handle; public GoldenPocket() { var ptr = NativeMethods.wickra_golden_pocket_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid GoldenPocket parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_golden_pocket_free); } public GoldenPocketOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraGoldenPocketOutput native; bool ok; unsafe { ok = NativeMethods.wickra_golden_pocket_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new GoldenPocketOutput(native.low, native.mid, native.high) : null; } public void Reset() { NativeMethods.wickra_golden_pocket_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class GrangerCausality : IDisposable { private readonly WickraHandle _handle; public GrangerCausality(int period, int lag) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(lag); var ptr = NativeMethods.wickra_granger_causality_new((nuint)period, (nuint)lag); if (ptr == nint.Zero) { throw new ArgumentException("invalid GrangerCausality parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_granger_causality_free); } public double Update(double x, double y) { var result = NativeMethods.wickra_granger_causality_update(_handle.DangerousGetHandle(), x, y); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan x, ReadOnlySpan y) { var n = x.Length; if (y.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* xPtr = x) fixed (double* yPtr = y) fixed (double* outputPtr = output) { NativeMethods.wickra_granger_causality_batch(_handle.DangerousGetHandle(), xPtr, yPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_granger_causality_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class GravestoneDoji : IDisposable { private readonly WickraHandle _handle; public GravestoneDoji() { var ptr = NativeMethods.wickra_gravestone_doji_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid GravestoneDoji parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_gravestone_doji_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_gravestone_doji_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_gravestone_doji_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_gravestone_doji_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Hammer : IDisposable { private readonly WickraHandle _handle; public Hammer() { var ptr = NativeMethods.wickra_hammer_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Hammer parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_hammer_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_hammer_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_hammer_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_hammer_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HangingMan : IDisposable { private readonly WickraHandle _handle; public HangingMan() { var ptr = NativeMethods.wickra_hanging_man_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid HangingMan parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_hanging_man_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_hanging_man_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_hanging_man_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_hanging_man_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Harami : IDisposable { private readonly WickraHandle _handle; public Harami() { var ptr = NativeMethods.wickra_harami_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Harami parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_harami_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_harami_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_harami_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_harami_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HaramiCross : IDisposable { private readonly WickraHandle _handle; public HaramiCross() { var ptr = NativeMethods.wickra_harami_cross_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid HaramiCross parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_harami_cross_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_harami_cross_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_harami_cross_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_harami_cross_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HasbrouckInformationShare : IDisposable { private readonly WickraHandle _handle; public HasbrouckInformationShare(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_hasbrouck_information_share_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid HasbrouckInformationShare parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_hasbrouck_information_share_free); } public double Update(double x, double y) { var result = NativeMethods.wickra_hasbrouck_information_share_update(_handle.DangerousGetHandle(), x, y); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan x, ReadOnlySpan y) { var n = x.Length; if (y.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* xPtr = x) fixed (double* yPtr = y) fixed (double* outputPtr = output) { NativeMethods.wickra_hasbrouck_information_share_batch(_handle.DangerousGetHandle(), xPtr, yPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_hasbrouck_information_share_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HeadAndShoulders : IDisposable { private readonly WickraHandle _handle; public HeadAndShoulders() { var ptr = NativeMethods.wickra_head_and_shoulders_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid HeadAndShoulders parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_head_and_shoulders_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_head_and_shoulders_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_head_and_shoulders_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_head_and_shoulders_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HeikinAshi : IDisposable { private readonly WickraHandle _handle; public HeikinAshi() { var ptr = NativeMethods.wickra_heikin_ashi_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid HeikinAshi parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_heikin_ashi_free); } public HeikinAshiOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraHeikinAshiOutput native; bool ok; unsafe { ok = NativeMethods.wickra_heikin_ashi_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new HeikinAshiOutput(native.open, native.high, native.low, native.close) : null; } public void Reset() { NativeMethods.wickra_heikin_ashi_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HeikinAshiOscillator : IDisposable { private readonly WickraHandle _handle; public HeikinAshiOscillator(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_heikin_ashi_oscillator_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid HeikinAshiOscillator parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_heikin_ashi_oscillator_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_heikin_ashi_oscillator_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_heikin_ashi_oscillator_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_heikin_ashi_oscillator_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HiLoActivator : IDisposable { private readonly WickraHandle _handle; public HiLoActivator(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_hi_lo_activator_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid HiLoActivator parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_hi_lo_activator_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_hi_lo_activator_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_hi_lo_activator_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_hi_lo_activator_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HighLowIndex : IDisposable { private readonly WickraHandle _handle; public HighLowIndex(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_high_low_index_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid HighLowIndex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_high_low_index_free); } public double Update(ReadOnlySpan change, ReadOnlySpan volume, ReadOnlySpan newHigh, ReadOnlySpan newLow, ReadOnlySpan aboveMa, ReadOnlySpan onBuySignal, long timestamp) { if (volume.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newHigh.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newLow.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (aboveMa.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (onBuySignal.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* changePtr = change) fixed (double* volumePtr = volume) fixed (bool* newHighPtr = newHigh) fixed (bool* newLowPtr = newLow) fixed (bool* aboveMaPtr = aboveMa) fixed (bool* onBuySignalPtr = onBuySignal) { result = NativeMethods.wickra_high_low_index_update(_handle.DangerousGetHandle(), changePtr, volumePtr, newHighPtr, newLowPtr, aboveMaPtr, onBuySignalPtr, (nuint)change.Length, timestamp); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_high_low_index_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HighLowRange : IDisposable { private readonly WickraHandle _handle; public HighLowRange() { var ptr = NativeMethods.wickra_high_low_range_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid HighLowRange parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_high_low_range_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_high_low_range_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_high_low_range_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_high_low_range_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HighLowVolumeNodes : IDisposable { private readonly WickraHandle _handle; public HighLowVolumeNodes(int period, int bins) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(bins); var ptr = NativeMethods.wickra_high_low_volume_nodes_new((nuint)period, (nuint)bins); if (ptr == nint.Zero) { throw new ArgumentException("invalid HighLowVolumeNodes parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_high_low_volume_nodes_free); } public HighLowVolumeNodesOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraHighLowVolumeNodesOutput native; bool ok; unsafe { ok = NativeMethods.wickra_high_low_volume_nodes_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new HighLowVolumeNodesOutput(native.hvn, native.lvn) : null; } public void Reset() { NativeMethods.wickra_high_low_volume_nodes_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HighWave : IDisposable { private readonly WickraHandle _handle; public HighWave() { var ptr = NativeMethods.wickra_high_wave_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid HighWave parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_high_wave_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_high_wave_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_high_wave_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_high_wave_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HighpassFilter : IDisposable { private readonly WickraHandle _handle; public HighpassFilter(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_highpass_filter_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid HighpassFilter parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_highpass_filter_free); } public double Update(double @value) { var result = NativeMethods.wickra_highpass_filter_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_highpass_filter_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_highpass_filter_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Hikkake : IDisposable { private readonly WickraHandle _handle; public Hikkake() { var ptr = NativeMethods.wickra_hikkake_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Hikkake parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_hikkake_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_hikkake_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_hikkake_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_hikkake_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HikkakeModified : IDisposable { private readonly WickraHandle _handle; public HikkakeModified() { var ptr = NativeMethods.wickra_hikkake_modified_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid HikkakeModified parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_hikkake_modified_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_hikkake_modified_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_hikkake_modified_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_hikkake_modified_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HilbertDominantCycle : IDisposable { private readonly WickraHandle _handle; public HilbertDominantCycle() { var ptr = NativeMethods.wickra_hilbert_dominant_cycle_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid HilbertDominantCycle parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_hilbert_dominant_cycle_free); } public double Update(double @value) { var result = NativeMethods.wickra_hilbert_dominant_cycle_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_hilbert_dominant_cycle_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_hilbert_dominant_cycle_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HistoricalVolatility : IDisposable { private readonly WickraHandle _handle; public HistoricalVolatility(int period, int tradingPeriods) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(tradingPeriods); var ptr = NativeMethods.wickra_historical_volatility_new((nuint)period, (nuint)tradingPeriods); if (ptr == nint.Zero) { throw new ArgumentException("invalid HistoricalVolatility parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_historical_volatility_free); } public double Update(double @value) { var result = NativeMethods.wickra_historical_volatility_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_historical_volatility_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_historical_volatility_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Hma : IDisposable { private readonly WickraHandle _handle; public Hma(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_hma_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Hma parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_hma_free); } public double Update(double @value) { var result = NativeMethods.wickra_hma_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_hma_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_hma_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HoltWinters : IDisposable { private readonly WickraHandle _handle; public HoltWinters(double alpha, double beta) { var ptr = NativeMethods.wickra_holt_winters_new(alpha, beta); if (ptr == nint.Zero) { throw new ArgumentException("invalid HoltWinters parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_holt_winters_free); } public double Update(double @value) { var result = NativeMethods.wickra_holt_winters_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_holt_winters_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_holt_winters_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HomingPigeon : IDisposable { private readonly WickraHandle _handle; public HomingPigeon() { var ptr = NativeMethods.wickra_homing_pigeon_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid HomingPigeon parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_homing_pigeon_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_homing_pigeon_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_homing_pigeon_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_homing_pigeon_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HtDcPhase : IDisposable { private readonly WickraHandle _handle; public HtDcPhase() { var ptr = NativeMethods.wickra_ht_dc_phase_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid HtDcPhase parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_ht_dc_phase_free); } public double Update(double @value) { var result = NativeMethods.wickra_ht_dc_phase_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_ht_dc_phase_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_ht_dc_phase_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HtPhasor : IDisposable { private readonly WickraHandle _handle; public HtPhasor() { var ptr = NativeMethods.wickra_ht_phasor_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid HtPhasor parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_ht_phasor_free); } public HtPhasorOutput? Update(double @value) { WickraHtPhasorOutput native; bool ok; unsafe { ok = NativeMethods.wickra_ht_phasor_update(_handle.DangerousGetHandle(), @value, &native); } GC.KeepAlive(_handle); return ok ? new HtPhasorOutput(native.inphase, native.quadrature) : null; } public void Reset() { NativeMethods.wickra_ht_phasor_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HtTrendMode : IDisposable { private readonly WickraHandle _handle; public HtTrendMode() { var ptr = NativeMethods.wickra_ht_trend_mode_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid HtTrendMode parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_ht_trend_mode_free); } public double Update(double @value) { var result = NativeMethods.wickra_ht_trend_mode_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_ht_trend_mode_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_ht_trend_mode_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HurstChannel : IDisposable { private readonly WickraHandle _handle; public HurstChannel(int period, double multiplier) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_hurst_channel_new((nuint)period, multiplier); if (ptr == nint.Zero) { throw new ArgumentException("invalid HurstChannel parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_hurst_channel_free); } public HurstChannelOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraHurstChannelOutput native; bool ok; unsafe { ok = NativeMethods.wickra_hurst_channel_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new HurstChannelOutput(native.upper, native.middle, native.lower) : null; } public void Reset() { NativeMethods.wickra_hurst_channel_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class HurstExponent : IDisposable { private readonly WickraHandle _handle; public HurstExponent(int period, int chunks) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(chunks); var ptr = NativeMethods.wickra_hurst_exponent_new((nuint)period, (nuint)chunks); if (ptr == nint.Zero) { throw new ArgumentException("invalid HurstExponent parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_hurst_exponent_free); } public double Update(double @value) { var result = NativeMethods.wickra_hurst_exponent_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_hurst_exponent_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_hurst_exponent_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Ichimoku : IDisposable { private readonly WickraHandle _handle; public Ichimoku(int tenkanPeriod, int kijunPeriod, int senkouBPeriod, int displacement) { ArgumentOutOfRangeException.ThrowIfNegative(tenkanPeriod); ArgumentOutOfRangeException.ThrowIfNegative(kijunPeriod); ArgumentOutOfRangeException.ThrowIfNegative(senkouBPeriod); ArgumentOutOfRangeException.ThrowIfNegative(displacement); var ptr = NativeMethods.wickra_ichimoku_new((nuint)tenkanPeriod, (nuint)kijunPeriod, (nuint)senkouBPeriod, (nuint)displacement); if (ptr == nint.Zero) { throw new ArgumentException("invalid Ichimoku parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_ichimoku_free); } public IchimokuOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraIchimokuOutput native; bool ok; unsafe { ok = NativeMethods.wickra_ichimoku_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new IchimokuOutput(native.tenkan, native.kijun, native.senkou_a, native.senkou_b, native.chikou) : null; } public void Reset() { NativeMethods.wickra_ichimoku_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class IdenticalThreeCrows : IDisposable { private readonly WickraHandle _handle; public IdenticalThreeCrows() { var ptr = NativeMethods.wickra_identical_three_crows_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid IdenticalThreeCrows parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_identical_three_crows_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_identical_three_crows_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_identical_three_crows_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_identical_three_crows_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ImbalanceBars : IDisposable { private readonly WickraHandle _handle; public ImbalanceBars(double threshold) { var ptr = NativeMethods.wickra_imbalance_bars_new(threshold); if (ptr == nint.Zero) { throw new ArgumentException("invalid ImbalanceBars parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_imbalance_bars_free); } public ImbalanceBar[] Update(double open, double high, double low, double close, double volume, long timestamp) { const int cap = 64; Span buffer = stackalloc WickraImbalanceBar[cap]; long count; unsafe { fixed (WickraImbalanceBar* ptr = buffer) { count = (long)NativeMethods.wickra_imbalance_bars_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, ptr, (nuint)cap); } } GC.KeepAlive(_handle); if (count <= 0) { return Array.Empty(); } var result = new ImbalanceBar[count]; for (var i = 0; i < count; i++) { result[i] = new ImbalanceBar(buffer[i].open, buffer[i].high, buffer[i].low, buffer[i].close, buffer[i].imbalance, buffer[i].direction); } return result; } public void Reset() { NativeMethods.wickra_imbalance_bars_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class InNeck : IDisposable { private readonly WickraHandle _handle; public InNeck() { var ptr = NativeMethods.wickra_in_neck_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid InNeck parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_in_neck_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_in_neck_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_in_neck_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_in_neck_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Inertia : IDisposable { private readonly WickraHandle _handle; public Inertia(int rviPeriod, int linregPeriod) { ArgumentOutOfRangeException.ThrowIfNegative(rviPeriod); ArgumentOutOfRangeException.ThrowIfNegative(linregPeriod); var ptr = NativeMethods.wickra_inertia_new((nuint)rviPeriod, (nuint)linregPeriod); if (ptr == nint.Zero) { throw new ArgumentException("invalid Inertia parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_inertia_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_inertia_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_inertia_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_inertia_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class InformationRatio : IDisposable { private readonly WickraHandle _handle; public InformationRatio(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_information_ratio_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid InformationRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_information_ratio_free); } public double Update(double x, double y) { var result = NativeMethods.wickra_information_ratio_update(_handle.DangerousGetHandle(), x, y); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan x, ReadOnlySpan y) { var n = x.Length; if (y.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* xPtr = x) fixed (double* yPtr = y) fixed (double* outputPtr = output) { NativeMethods.wickra_information_ratio_batch(_handle.DangerousGetHandle(), xPtr, yPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_information_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class InitialBalance : IDisposable { private readonly WickraHandle _handle; public InitialBalance(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_initial_balance_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid InitialBalance parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_initial_balance_free); } public InitialBalanceOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraInitialBalanceOutput native; bool ok; unsafe { ok = NativeMethods.wickra_initial_balance_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new InitialBalanceOutput(native.high, native.low) : null; } public void Reset() { NativeMethods.wickra_initial_balance_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class InstantaneousTrendline : IDisposable { private readonly WickraHandle _handle; public InstantaneousTrendline(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_instantaneous_trendline_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid InstantaneousTrendline parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_instantaneous_trendline_free); } public double Update(double @value) { var result = NativeMethods.wickra_instantaneous_trendline_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_instantaneous_trendline_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_instantaneous_trendline_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class IntradayIntensity : IDisposable { private readonly WickraHandle _handle; public IntradayIntensity() { var ptr = NativeMethods.wickra_intraday_intensity_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid IntradayIntensity parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_intraday_intensity_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_intraday_intensity_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_intraday_intensity_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_intraday_intensity_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class IntradayMomentumIndex : IDisposable { private readonly WickraHandle _handle; public IntradayMomentumIndex(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_intraday_momentum_index_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid IntradayMomentumIndex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_intraday_momentum_index_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_intraday_momentum_index_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_intraday_momentum_index_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_intraday_momentum_index_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class IntradayVolatilityProfile : IDisposable { private readonly WickraHandle _handle; private readonly int _valuesCapacity; public IntradayVolatilityProfile(int buckets, int utcOffsetMinutes) { ArgumentOutOfRangeException.ThrowIfNegative(buckets); var ptr = NativeMethods.wickra_intraday_volatility_profile_new((nuint)buckets, utcOffsetMinutes); if (ptr == nint.Zero) { throw new ArgumentException("invalid IntradayVolatilityProfile parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_intraday_volatility_profile_free); _valuesCapacity = buckets; } public double[]? Update(double open, double high, double low, double close, double volume, long timestamp) { var values = new double[_valuesCapacity]; long length; unsafe { fixed (double* valuesPtr = values) { length = (long)NativeMethods.wickra_intraday_volatility_profile_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, valuesPtr, (nuint)_valuesCapacity); } } GC.KeepAlive(_handle); if (length < 0) { return null; } if (length < values.Length) { Array.Resize(ref values, (int)length); } return values; } public void Reset() { NativeMethods.wickra_intraday_volatility_profile_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class InverseFisherTransform : IDisposable { private readonly WickraHandle _handle; public InverseFisherTransform(double scale) { var ptr = NativeMethods.wickra_inverse_fisher_transform_new(scale); if (ptr == nint.Zero) { throw new ArgumentException("invalid InverseFisherTransform parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_inverse_fisher_transform_free); } public double Update(double @value) { var result = NativeMethods.wickra_inverse_fisher_transform_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_inverse_fisher_transform_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_inverse_fisher_transform_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class InvertedHammer : IDisposable { private readonly WickraHandle _handle; public InvertedHammer() { var ptr = NativeMethods.wickra_inverted_hammer_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid InvertedHammer parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_inverted_hammer_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_inverted_hammer_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_inverted_hammer_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_inverted_hammer_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class JarqueBera : IDisposable { private readonly WickraHandle _handle; public JarqueBera(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_jarque_bera_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid JarqueBera parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_jarque_bera_free); } public double Update(double @value) { var result = NativeMethods.wickra_jarque_bera_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_jarque_bera_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_jarque_bera_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Jma : IDisposable { private readonly WickraHandle _handle; public Jma(int period, double phase, uint power) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_jma_new((nuint)period, phase, power); if (ptr == nint.Zero) { throw new ArgumentException("invalid Jma parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_jma_free); } public double Update(double @value) { var result = NativeMethods.wickra_jma_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_jma_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_jma_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class JumpIndicator : IDisposable { private readonly WickraHandle _handle; public JumpIndicator(int period, double threshold) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_jump_indicator_new((nuint)period, threshold); if (ptr == nint.Zero) { throw new ArgumentException("invalid JumpIndicator parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_jump_indicator_free); } public double Update(double @value) { var result = NativeMethods.wickra_jump_indicator_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_jump_indicator_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_jump_indicator_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class KRatio : IDisposable { private readonly WickraHandle _handle; public KRatio(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_k_ratio_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid KRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_k_ratio_free); } public double Update(double @value) { var result = NativeMethods.wickra_k_ratio_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_k_ratio_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_k_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class KagiBars : IDisposable { private readonly WickraHandle _handle; public KagiBars(double reversal) { var ptr = NativeMethods.wickra_kagi_bars_new(reversal); if (ptr == nint.Zero) { throw new ArgumentException("invalid KagiBars parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_kagi_bars_free); } public KagiBar[] Update(double open, double high, double low, double close, double volume, long timestamp) { const int cap = 64; Span buffer = stackalloc WickraKagiBar[cap]; long count; unsafe { fixed (WickraKagiBar* ptr = buffer) { count = (long)NativeMethods.wickra_kagi_bars_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, ptr, (nuint)cap); } } GC.KeepAlive(_handle); if (count <= 0) { return Array.Empty(); } var result = new KagiBar[count]; for (var i = 0; i < count; i++) { result[i] = new KagiBar(buffer[i].start, buffer[i].end, buffer[i].direction); } return result; } public void Reset() { NativeMethods.wickra_kagi_bars_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class KalmanHedgeRatio : IDisposable { private readonly WickraHandle _handle; public KalmanHedgeRatio(double delta, double observationVar) { var ptr = NativeMethods.wickra_kalman_hedge_ratio_new(delta, observationVar); if (ptr == nint.Zero) { throw new ArgumentException("invalid KalmanHedgeRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_kalman_hedge_ratio_free); } public KalmanHedgeRatioOutput? Update(double x, double y) { WickraKalmanHedgeRatioOutput native; bool ok; unsafe { ok = NativeMethods.wickra_kalman_hedge_ratio_update(_handle.DangerousGetHandle(), x, y, &native); } GC.KeepAlive(_handle); return ok ? new KalmanHedgeRatioOutput(native.hedge_ratio, native.intercept, native.spread) : null; } public void Reset() { NativeMethods.wickra_kalman_hedge_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Kama : IDisposable { private readonly WickraHandle _handle; public Kama(int erPeriod, int fast, int slow) { ArgumentOutOfRangeException.ThrowIfNegative(erPeriod); ArgumentOutOfRangeException.ThrowIfNegative(fast); ArgumentOutOfRangeException.ThrowIfNegative(slow); var ptr = NativeMethods.wickra_kama_new((nuint)erPeriod, (nuint)fast, (nuint)slow); if (ptr == nint.Zero) { throw new ArgumentException("invalid Kama parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_kama_free); } public double Update(double @value) { var result = NativeMethods.wickra_kama_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_kama_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_kama_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class KaseDevStop : IDisposable { private readonly WickraHandle _handle; public KaseDevStop(int period, double dev) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_kase_dev_stop_new((nuint)period, dev); if (ptr == nint.Zero) { throw new ArgumentException("invalid KaseDevStop parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_kase_dev_stop_free); } public KaseDevStopOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraKaseDevStopOutput native; bool ok; unsafe { ok = NativeMethods.wickra_kase_dev_stop_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new KaseDevStopOutput(native.@value, native.direction) : null; } public void Reset() { NativeMethods.wickra_kase_dev_stop_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class KasePermissionStochastic : IDisposable { private readonly WickraHandle _handle; public KasePermissionStochastic(int length, int smooth) { ArgumentOutOfRangeException.ThrowIfNegative(length); ArgumentOutOfRangeException.ThrowIfNegative(smooth); var ptr = NativeMethods.wickra_kase_permission_stochastic_new((nuint)length, (nuint)smooth); if (ptr == nint.Zero) { throw new ArgumentException("invalid KasePermissionStochastic parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_kase_permission_stochastic_free); } public KasePermissionStochasticOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraKasePermissionStochasticOutput native; bool ok; unsafe { ok = NativeMethods.wickra_kase_permission_stochastic_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new KasePermissionStochasticOutput(native.fast, native.slow) : null; } public void Reset() { NativeMethods.wickra_kase_permission_stochastic_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class KellyCriterion : IDisposable { private readonly WickraHandle _handle; public KellyCriterion(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_kelly_criterion_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid KellyCriterion parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_kelly_criterion_free); } public double Update(double @value) { var result = NativeMethods.wickra_kelly_criterion_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_kelly_criterion_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_kelly_criterion_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Keltner : IDisposable { private readonly WickraHandle _handle; public Keltner(int emaPeriod, int atrPeriod, double multiplier) { ArgumentOutOfRangeException.ThrowIfNegative(emaPeriod); ArgumentOutOfRangeException.ThrowIfNegative(atrPeriod); var ptr = NativeMethods.wickra_keltner_new((nuint)emaPeriod, (nuint)atrPeriod, multiplier); if (ptr == nint.Zero) { throw new ArgumentException("invalid Keltner parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_keltner_free); } public KeltnerOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraKeltnerOutput native; bool ok; unsafe { ok = NativeMethods.wickra_keltner_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new KeltnerOutput(native.upper, native.middle, native.lower) : null; } public void Reset() { NativeMethods.wickra_keltner_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class KendallTau : IDisposable { private readonly WickraHandle _handle; public KendallTau(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_kendall_tau_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid KendallTau parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_kendall_tau_free); } public double Update(double x, double y) { var result = NativeMethods.wickra_kendall_tau_update(_handle.DangerousGetHandle(), x, y); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan x, ReadOnlySpan y) { var n = x.Length; if (y.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* xPtr = x) fixed (double* yPtr = y) fixed (double* outputPtr = output) { NativeMethods.wickra_kendall_tau_batch(_handle.DangerousGetHandle(), xPtr, yPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_kendall_tau_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Kicking : IDisposable { private readonly WickraHandle _handle; public Kicking() { var ptr = NativeMethods.wickra_kicking_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Kicking parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_kicking_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_kicking_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_kicking_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_kicking_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class KickingByLength : IDisposable { private readonly WickraHandle _handle; public KickingByLength() { var ptr = NativeMethods.wickra_kicking_by_length_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid KickingByLength parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_kicking_by_length_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_kicking_by_length_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_kicking_by_length_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_kicking_by_length_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Kst : IDisposable { private readonly WickraHandle _handle; public Kst(int roc1, int roc2, int roc3, int roc4, int sma1, int sma2, int sma3, int sma4, int signal) { ArgumentOutOfRangeException.ThrowIfNegative(roc1); ArgumentOutOfRangeException.ThrowIfNegative(roc2); ArgumentOutOfRangeException.ThrowIfNegative(roc3); ArgumentOutOfRangeException.ThrowIfNegative(roc4); ArgumentOutOfRangeException.ThrowIfNegative(sma1); ArgumentOutOfRangeException.ThrowIfNegative(sma2); ArgumentOutOfRangeException.ThrowIfNegative(sma3); ArgumentOutOfRangeException.ThrowIfNegative(sma4); ArgumentOutOfRangeException.ThrowIfNegative(signal); var ptr = NativeMethods.wickra_kst_new((nuint)roc1, (nuint)roc2, (nuint)roc3, (nuint)roc4, (nuint)sma1, (nuint)sma2, (nuint)sma3, (nuint)sma4, (nuint)signal); if (ptr == nint.Zero) { throw new ArgumentException("invalid Kst parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_kst_free); } public KstOutput? Update(double @value) { WickraKstOutput native; bool ok; unsafe { ok = NativeMethods.wickra_kst_update(_handle.DangerousGetHandle(), @value, &native); } GC.KeepAlive(_handle); return ok ? new KstOutput(native.kst, native.signal) : null; } public void Reset() { NativeMethods.wickra_kst_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Kurtosis : IDisposable { private readonly WickraHandle _handle; public Kurtosis(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_kurtosis_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Kurtosis parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_kurtosis_free); } public double Update(double @value) { var result = NativeMethods.wickra_kurtosis_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_kurtosis_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_kurtosis_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Kvo : IDisposable { private readonly WickraHandle _handle; public Kvo(int fast, int slow) { ArgumentOutOfRangeException.ThrowIfNegative(fast); ArgumentOutOfRangeException.ThrowIfNegative(slow); var ptr = NativeMethods.wickra_kvo_new((nuint)fast, (nuint)slow); if (ptr == nint.Zero) { throw new ArgumentException("invalid Kvo parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_kvo_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_kvo_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_kvo_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_kvo_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class KylesLambda : IDisposable { private readonly WickraHandle _handle; public KylesLambda(int window) { ArgumentOutOfRangeException.ThrowIfNegative(window); var ptr = NativeMethods.wickra_kyles_lambda_new((nuint)window); if (ptr == nint.Zero) { throw new ArgumentException("invalid KylesLambda parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_kyles_lambda_free); } public double Update(double price, double size, bool isBuy, long timestamp, double mid) { var result = NativeMethods.wickra_kyles_lambda_update(_handle.DangerousGetHandle(), price, size, isBuy, timestamp, mid); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_kyles_lambda_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class LadderBottom : IDisposable { private readonly WickraHandle _handle; public LadderBottom() { var ptr = NativeMethods.wickra_ladder_bottom_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid LadderBottom parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_ladder_bottom_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_ladder_bottom_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_ladder_bottom_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_ladder_bottom_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class LaguerreRsi : IDisposable { private readonly WickraHandle _handle; public LaguerreRsi(double gamma) { var ptr = NativeMethods.wickra_laguerre_rsi_new(gamma); if (ptr == nint.Zero) { throw new ArgumentException("invalid LaguerreRsi parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_laguerre_rsi_free); } public double Update(double @value) { var result = NativeMethods.wickra_laguerre_rsi_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_laguerre_rsi_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_laguerre_rsi_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class LeadLagCrossCorrelation : IDisposable { private readonly WickraHandle _handle; public LeadLagCrossCorrelation(int window, int maxLag) { ArgumentOutOfRangeException.ThrowIfNegative(window); ArgumentOutOfRangeException.ThrowIfNegative(maxLag); var ptr = NativeMethods.wickra_lead_lag_cross_correlation_new((nuint)window, (nuint)maxLag); if (ptr == nint.Zero) { throw new ArgumentException("invalid LeadLagCrossCorrelation parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_lead_lag_cross_correlation_free); } public LeadLagCrossCorrelationOutput? Update(double x, double y) { WickraLeadLagCrossCorrelationOutput native; bool ok; unsafe { ok = NativeMethods.wickra_lead_lag_cross_correlation_update(_handle.DangerousGetHandle(), x, y, &native); } GC.KeepAlive(_handle); return ok ? new LeadLagCrossCorrelationOutput(native.lag, native.correlation) : null; } public void Reset() { NativeMethods.wickra_lead_lag_cross_correlation_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class LinRegAngle : IDisposable { private readonly WickraHandle _handle; public LinRegAngle(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_lin_reg_angle_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid LinRegAngle parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_lin_reg_angle_free); } public double Update(double @value) { var result = NativeMethods.wickra_lin_reg_angle_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_lin_reg_angle_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_lin_reg_angle_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class LinRegChannel : IDisposable { private readonly WickraHandle _handle; public LinRegChannel(int period, double multiplier) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_lin_reg_channel_new((nuint)period, multiplier); if (ptr == nint.Zero) { throw new ArgumentException("invalid LinRegChannel parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_lin_reg_channel_free); } public LinRegChannelOutput? Update(double @value) { WickraLinRegChannelOutput native; bool ok; unsafe { ok = NativeMethods.wickra_lin_reg_channel_update(_handle.DangerousGetHandle(), @value, &native); } GC.KeepAlive(_handle); return ok ? new LinRegChannelOutput(native.upper, native.middle, native.lower) : null; } public void Reset() { NativeMethods.wickra_lin_reg_channel_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class LinRegIntercept : IDisposable { private readonly WickraHandle _handle; public LinRegIntercept(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_lin_reg_intercept_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid LinRegIntercept parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_lin_reg_intercept_free); } public double Update(double @value) { var result = NativeMethods.wickra_lin_reg_intercept_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_lin_reg_intercept_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_lin_reg_intercept_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class LinRegSlope : IDisposable { private readonly WickraHandle _handle; public LinRegSlope(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_lin_reg_slope_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid LinRegSlope parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_lin_reg_slope_free); } public double Update(double @value) { var result = NativeMethods.wickra_lin_reg_slope_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_lin_reg_slope_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_lin_reg_slope_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class LinearRegression : IDisposable { private readonly WickraHandle _handle; public LinearRegression(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_linear_regression_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid LinearRegression parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_linear_regression_free); } public double Update(double @value) { var result = NativeMethods.wickra_linear_regression_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_linear_regression_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_linear_regression_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class LiquidationFeatures : IDisposable { private readonly WickraHandle _handle; public LiquidationFeatures() { var ptr = NativeMethods.wickra_liquidation_features_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid LiquidationFeatures parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_liquidation_features_free); } public LiquidationFeaturesOutput? Update(double fundingRate, double markPrice, double indexPrice, double futuresPrice, double openInterest, double longSize, double shortSize, double takerBuyVolume, double takerSellVolume, double longLiquidation, double shortLiquidation, long timestamp) { WickraLiquidationFeaturesOutput native; bool ok; unsafe { ok = NativeMethods.wickra_liquidation_features_update(_handle.DangerousGetHandle(), fundingRate, markPrice, indexPrice, futuresPrice, openInterest, longSize, shortSize, takerBuyVolume, takerSellVolume, longLiquidation, shortLiquidation, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new LiquidationFeaturesOutput(native.long_, native.short_, native.net, native.total, native.imbalance) : null; } public void Reset() { NativeMethods.wickra_liquidation_features_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class LogReturn : IDisposable { private readonly WickraHandle _handle; public LogReturn(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_log_return_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid LogReturn parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_log_return_free); } public double Update(double @value) { var result = NativeMethods.wickra_log_return_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_log_return_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_log_return_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class LongLeggedDoji : IDisposable { private readonly WickraHandle _handle; public LongLeggedDoji() { var ptr = NativeMethods.wickra_long_legged_doji_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid LongLeggedDoji parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_long_legged_doji_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_long_legged_doji_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_long_legged_doji_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_long_legged_doji_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class LongLine : IDisposable { private readonly WickraHandle _handle; public LongLine() { var ptr = NativeMethods.wickra_long_line_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid LongLine parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_long_line_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_long_line_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_long_line_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_long_line_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class LongShortRatio : IDisposable { private readonly WickraHandle _handle; public LongShortRatio() { var ptr = NativeMethods.wickra_long_short_ratio_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid LongShortRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_long_short_ratio_free); } public double Update(double fundingRate, double markPrice, double indexPrice, double futuresPrice, double openInterest, double longSize, double shortSize, double takerBuyVolume, double takerSellVolume, double longLiquidation, double shortLiquidation, long timestamp) { var result = NativeMethods.wickra_long_short_ratio_update(_handle.DangerousGetHandle(), fundingRate, markPrice, indexPrice, futuresPrice, openInterest, longSize, shortSize, takerBuyVolume, takerSellVolume, longLiquidation, shortLiquidation, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_long_short_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class M2Measure : IDisposable { private readonly WickraHandle _handle; public M2Measure(int period, double riskFree, double benchmarkStddev) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_m2_measure_new((nuint)period, riskFree, benchmarkStddev); if (ptr == nint.Zero) { throw new ArgumentException("invalid M2Measure parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_m2_measure_free); } public double Update(double @value) { var result = NativeMethods.wickra_m2_measure_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_m2_measure_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_m2_measure_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MaEnvelope : IDisposable { private readonly WickraHandle _handle; public MaEnvelope(int period, double percent) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_ma_envelope_new((nuint)period, percent); if (ptr == nint.Zero) { throw new ArgumentException("invalid MaEnvelope parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_ma_envelope_free); } public MaEnvelopeOutput? Update(double @value) { WickraMaEnvelopeOutput native; bool ok; unsafe { ok = NativeMethods.wickra_ma_envelope_update(_handle.DangerousGetHandle(), @value, &native); } GC.KeepAlive(_handle); return ok ? new MaEnvelopeOutput(native.upper, native.middle, native.lower) : null; } public void Reset() { NativeMethods.wickra_ma_envelope_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MacdExt : IDisposable { private readonly WickraHandle _handle; public MacdExt(int fast, byte fastType, int slow, byte slowType, int signal, byte signalType) { ArgumentOutOfRangeException.ThrowIfNegative(fast); ArgumentOutOfRangeException.ThrowIfNegative(slow); ArgumentOutOfRangeException.ThrowIfNegative(signal); var ptr = NativeMethods.wickra_macd_ext_new((nuint)fast, fastType, (nuint)slow, slowType, (nuint)signal, signalType); if (ptr == nint.Zero) { throw new ArgumentException("invalid MacdExt parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_macd_ext_free); } public MacdOutput? Update(double @value) { WickraMacdOutput native; bool ok; unsafe { ok = NativeMethods.wickra_macd_ext_update(_handle.DangerousGetHandle(), @value, &native); } GC.KeepAlive(_handle); return ok ? new MacdOutput(native.macd, native.signal, native.histogram) : null; } public void Reset() { NativeMethods.wickra_macd_ext_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MacdFix : IDisposable { private readonly WickraHandle _handle; public MacdFix(int signal) { ArgumentOutOfRangeException.ThrowIfNegative(signal); var ptr = NativeMethods.wickra_macd_fix_new((nuint)signal); if (ptr == nint.Zero) { throw new ArgumentException("invalid MacdFix parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_macd_fix_free); } public MacdOutput? Update(double @value) { WickraMacdOutput native; bool ok; unsafe { ok = NativeMethods.wickra_macd_fix_update(_handle.DangerousGetHandle(), @value, &native); } GC.KeepAlive(_handle); return ok ? new MacdOutput(native.macd, native.signal, native.histogram) : null; } public void Reset() { NativeMethods.wickra_macd_fix_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MacdHistogram : IDisposable { private readonly WickraHandle _handle; public MacdHistogram(int fast, int slow, int signal) { ArgumentOutOfRangeException.ThrowIfNegative(fast); ArgumentOutOfRangeException.ThrowIfNegative(slow); ArgumentOutOfRangeException.ThrowIfNegative(signal); var ptr = NativeMethods.wickra_macd_histogram_new((nuint)fast, (nuint)slow, (nuint)signal); if (ptr == nint.Zero) { throw new ArgumentException("invalid MacdHistogram parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_macd_histogram_free); } public double Update(double @value) { var result = NativeMethods.wickra_macd_histogram_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_macd_histogram_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_macd_histogram_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MacdIndicator : IDisposable { private readonly WickraHandle _handle; public MacdIndicator(int fast, int slow, int signal) { ArgumentOutOfRangeException.ThrowIfNegative(fast); ArgumentOutOfRangeException.ThrowIfNegative(slow); ArgumentOutOfRangeException.ThrowIfNegative(signal); var ptr = NativeMethods.wickra_macd_indicator_new((nuint)fast, (nuint)slow, (nuint)signal); if (ptr == nint.Zero) { throw new ArgumentException("invalid MacdIndicator parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_macd_indicator_free); } public MacdOutput? Update(double @value) { WickraMacdOutput native; bool ok; unsafe { ok = NativeMethods.wickra_macd_indicator_update(_handle.DangerousGetHandle(), @value, &native); } GC.KeepAlive(_handle); return ok ? new MacdOutput(native.macd, native.signal, native.histogram) : null; } public void Reset() { NativeMethods.wickra_macd_indicator_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Mama : IDisposable { private readonly WickraHandle _handle; public Mama(double fastLimit, double slowLimit) { var ptr = NativeMethods.wickra_mama_new(fastLimit, slowLimit); if (ptr == nint.Zero) { throw new ArgumentException("invalid Mama parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_mama_free); } public MamaOutput? Update(double @value) { WickraMamaOutput native; bool ok; unsafe { ok = NativeMethods.wickra_mama_update(_handle.DangerousGetHandle(), @value, &native); } GC.KeepAlive(_handle); return ok ? new MamaOutput(native.mama, native.fama) : null; } public void Reset() { NativeMethods.wickra_mama_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MarketFacilitationIndex : IDisposable { private readonly WickraHandle _handle; public MarketFacilitationIndex() { var ptr = NativeMethods.wickra_market_facilitation_index_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid MarketFacilitationIndex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_market_facilitation_index_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_market_facilitation_index_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_market_facilitation_index_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_market_facilitation_index_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MartinRatio : IDisposable { private readonly WickraHandle _handle; public MartinRatio(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_martin_ratio_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid MartinRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_martin_ratio_free); } public double Update(double @value) { var result = NativeMethods.wickra_martin_ratio_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_martin_ratio_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_martin_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Marubozu : IDisposable { private readonly WickraHandle _handle; public Marubozu() { var ptr = NativeMethods.wickra_marubozu_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Marubozu parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_marubozu_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_marubozu_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_marubozu_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_marubozu_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MassIndex : IDisposable { private readonly WickraHandle _handle; public MassIndex(int emaPeriod, int sumPeriod) { ArgumentOutOfRangeException.ThrowIfNegative(emaPeriod); ArgumentOutOfRangeException.ThrowIfNegative(sumPeriod); var ptr = NativeMethods.wickra_mass_index_new((nuint)emaPeriod, (nuint)sumPeriod); if (ptr == nint.Zero) { throw new ArgumentException("invalid MassIndex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_mass_index_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_mass_index_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_mass_index_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_mass_index_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MatHold : IDisposable { private readonly WickraHandle _handle; public MatHold() { var ptr = NativeMethods.wickra_mat_hold_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid MatHold parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_mat_hold_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_mat_hold_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_mat_hold_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_mat_hold_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MatchingLow : IDisposable { private readonly WickraHandle _handle; public MatchingLow() { var ptr = NativeMethods.wickra_matching_low_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid MatchingLow parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_matching_low_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_matching_low_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_matching_low_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_matching_low_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MaxDrawdown : IDisposable { private readonly WickraHandle _handle; public MaxDrawdown(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_max_drawdown_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid MaxDrawdown parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_max_drawdown_free); } public double Update(double @value) { var result = NativeMethods.wickra_max_drawdown_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_max_drawdown_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_max_drawdown_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class McClellanOscillator : IDisposable { private readonly WickraHandle _handle; public McClellanOscillator() { var ptr = NativeMethods.wickra_mc_clellan_oscillator_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid McClellanOscillator parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_mc_clellan_oscillator_free); } public double Update(ReadOnlySpan change, ReadOnlySpan volume, ReadOnlySpan newHigh, ReadOnlySpan newLow, ReadOnlySpan aboveMa, ReadOnlySpan onBuySignal, long timestamp) { if (volume.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newHigh.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newLow.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (aboveMa.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (onBuySignal.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* changePtr = change) fixed (double* volumePtr = volume) fixed (bool* newHighPtr = newHigh) fixed (bool* newLowPtr = newLow) fixed (bool* aboveMaPtr = aboveMa) fixed (bool* onBuySignalPtr = onBuySignal) { result = NativeMethods.wickra_mc_clellan_oscillator_update(_handle.DangerousGetHandle(), changePtr, volumePtr, newHighPtr, newLowPtr, aboveMaPtr, onBuySignalPtr, (nuint)change.Length, timestamp); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_mc_clellan_oscillator_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class McClellanSummationIndex : IDisposable { private readonly WickraHandle _handle; public McClellanSummationIndex() { var ptr = NativeMethods.wickra_mc_clellan_summation_index_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid McClellanSummationIndex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_mc_clellan_summation_index_free); } public double Update(ReadOnlySpan change, ReadOnlySpan volume, ReadOnlySpan newHigh, ReadOnlySpan newLow, ReadOnlySpan aboveMa, ReadOnlySpan onBuySignal, long timestamp) { if (volume.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newHigh.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newLow.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (aboveMa.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (onBuySignal.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* changePtr = change) fixed (double* volumePtr = volume) fixed (bool* newHighPtr = newHigh) fixed (bool* newLowPtr = newLow) fixed (bool* aboveMaPtr = aboveMa) fixed (bool* onBuySignalPtr = onBuySignal) { result = NativeMethods.wickra_mc_clellan_summation_index_update(_handle.DangerousGetHandle(), changePtr, volumePtr, newHighPtr, newLowPtr, aboveMaPtr, onBuySignalPtr, (nuint)change.Length, timestamp); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_mc_clellan_summation_index_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class McGinleyDynamic : IDisposable { private readonly WickraHandle _handle; public McGinleyDynamic(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_mc_ginley_dynamic_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid McGinleyDynamic parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_mc_ginley_dynamic_free); } public double Update(double @value) { var result = NativeMethods.wickra_mc_ginley_dynamic_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_mc_ginley_dynamic_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_mc_ginley_dynamic_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MedianAbsoluteDeviation : IDisposable { private readonly WickraHandle _handle; public MedianAbsoluteDeviation(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_median_absolute_deviation_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid MedianAbsoluteDeviation parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_median_absolute_deviation_free); } public double Update(double @value) { var result = NativeMethods.wickra_median_absolute_deviation_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_median_absolute_deviation_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_median_absolute_deviation_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MedianChannel : IDisposable { private readonly WickraHandle _handle; public MedianChannel(int period, double multiplier) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_median_channel_new((nuint)period, multiplier); if (ptr == nint.Zero) { throw new ArgumentException("invalid MedianChannel parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_median_channel_free); } public MedianChannelOutput? Update(double @value) { WickraMedianChannelOutput native; bool ok; unsafe { ok = NativeMethods.wickra_median_channel_update(_handle.DangerousGetHandle(), @value, &native); } GC.KeepAlive(_handle); return ok ? new MedianChannelOutput(native.upper, native.middle, native.lower) : null; } public void Reset() { NativeMethods.wickra_median_channel_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MedianMa : IDisposable { private readonly WickraHandle _handle; public MedianMa(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_median_ma_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid MedianMa parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_median_ma_free); } public double Update(double @value) { var result = NativeMethods.wickra_median_ma_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_median_ma_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_median_ma_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MedianPrice : IDisposable { private readonly WickraHandle _handle; public MedianPrice() { var ptr = NativeMethods.wickra_median_price_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid MedianPrice parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_median_price_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_median_price_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_median_price_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_median_price_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Mfi : IDisposable { private readonly WickraHandle _handle; public Mfi(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_mfi_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Mfi parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_mfi_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_mfi_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_mfi_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_mfi_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Microprice : IDisposable { private readonly WickraHandle _handle; public Microprice() { var ptr = NativeMethods.wickra_microprice_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Microprice parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_microprice_free); } public double Update(ReadOnlySpan bidPrice, ReadOnlySpan bidSize, ReadOnlySpan askPrice, ReadOnlySpan askSize) { if (bidSize.Length != bidPrice.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (askSize.Length != askPrice.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* bidPricePtr = bidPrice) fixed (double* bidSizePtr = bidSize) fixed (double* askPricePtr = askPrice) fixed (double* askSizePtr = askSize) { result = NativeMethods.wickra_microprice_update(_handle.DangerousGetHandle(), bidPricePtr, bidSizePtr, (nuint)bidPrice.Length, askPricePtr, askSizePtr, (nuint)askPrice.Length); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_microprice_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MidPoint : IDisposable { private readonly WickraHandle _handle; public MidPoint(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_mid_point_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid MidPoint parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_mid_point_free); } public double Update(double @value) { var result = NativeMethods.wickra_mid_point_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_mid_point_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_mid_point_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MidPrice : IDisposable { private readonly WickraHandle _handle; public MidPrice(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_mid_price_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid MidPrice parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_mid_price_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_mid_price_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_mid_price_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_mid_price_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MinusDi : IDisposable { private readonly WickraHandle _handle; public MinusDi(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_minus_di_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid MinusDi parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_minus_di_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_minus_di_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_minus_di_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_minus_di_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MinusDm : IDisposable { private readonly WickraHandle _handle; public MinusDm(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_minus_dm_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid MinusDm parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_minus_dm_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_minus_dm_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_minus_dm_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_minus_dm_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ModifiedMaStop : IDisposable { private readonly WickraHandle _handle; public ModifiedMaStop(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_modified_ma_stop_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid ModifiedMaStop parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_modified_ma_stop_free); } public ModifiedMaStopOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraModifiedMaStopOutput native; bool ok; unsafe { ok = NativeMethods.wickra_modified_ma_stop_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new ModifiedMaStopOutput(native.@value, native.direction) : null; } public void Reset() { NativeMethods.wickra_modified_ma_stop_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Mom : IDisposable { private readonly WickraHandle _handle; public Mom(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_mom_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Mom parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_mom_free); } public double Update(double @value) { var result = NativeMethods.wickra_mom_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_mom_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_mom_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MorningDojiStar : IDisposable { private readonly WickraHandle _handle; public MorningDojiStar() { var ptr = NativeMethods.wickra_morning_doji_star_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid MorningDojiStar parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_morning_doji_star_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_morning_doji_star_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_morning_doji_star_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_morning_doji_star_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MorningEveningStar : IDisposable { private readonly WickraHandle _handle; public MorningEveningStar() { var ptr = NativeMethods.wickra_morning_evening_star_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid MorningEveningStar parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_morning_evening_star_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_morning_evening_star_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_morning_evening_star_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_morning_evening_star_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class MurreyMathLines : IDisposable { private readonly WickraHandle _handle; public MurreyMathLines(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_murrey_math_lines_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid MurreyMathLines parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_murrey_math_lines_free); } public MurreyMathLinesOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraMurreyMathLinesOutput native; bool ok; unsafe { ok = NativeMethods.wickra_murrey_math_lines_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new MurreyMathLinesOutput(native.mm8_8, native.mm7_8, native.mm6_8, native.mm5_8, native.mm4_8, native.mm3_8, native.mm2_8, native.mm1_8, native.mm0_8) : null; } public void Reset() { NativeMethods.wickra_murrey_math_lines_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class NakedPoc : IDisposable { private readonly WickraHandle _handle; public NakedPoc(int sessionLen, int bins) { ArgumentOutOfRangeException.ThrowIfNegative(sessionLen); ArgumentOutOfRangeException.ThrowIfNegative(bins); var ptr = NativeMethods.wickra_naked_poc_new((nuint)sessionLen, (nuint)bins); if (ptr == nint.Zero) { throw new ArgumentException("invalid NakedPoc parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_naked_poc_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_naked_poc_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_naked_poc_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_naked_poc_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Natr : IDisposable { private readonly WickraHandle _handle; public Natr(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_natr_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Natr parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_natr_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_natr_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_natr_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_natr_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class NewHighsNewLows : IDisposable { private readonly WickraHandle _handle; public NewHighsNewLows() { var ptr = NativeMethods.wickra_new_highs_new_lows_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid NewHighsNewLows parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_new_highs_new_lows_free); } public double Update(ReadOnlySpan change, ReadOnlySpan volume, ReadOnlySpan newHigh, ReadOnlySpan newLow, ReadOnlySpan aboveMa, ReadOnlySpan onBuySignal, long timestamp) { if (volume.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newHigh.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newLow.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (aboveMa.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (onBuySignal.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* changePtr = change) fixed (double* volumePtr = volume) fixed (bool* newHighPtr = newHigh) fixed (bool* newLowPtr = newLow) fixed (bool* aboveMaPtr = aboveMa) fixed (bool* onBuySignalPtr = onBuySignal) { result = NativeMethods.wickra_new_highs_new_lows_update(_handle.DangerousGetHandle(), changePtr, volumePtr, newHighPtr, newLowPtr, aboveMaPtr, onBuySignalPtr, (nuint)change.Length, timestamp); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_new_highs_new_lows_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class NewPriceLines : IDisposable { private readonly WickraHandle _handle; public NewPriceLines(int count) { ArgumentOutOfRangeException.ThrowIfNegative(count); var ptr = NativeMethods.wickra_new_price_lines_new((nuint)count); if (ptr == nint.Zero) { throw new ArgumentException("invalid NewPriceLines parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_new_price_lines_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_new_price_lines_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_new_price_lines_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_new_price_lines_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Nrtr : IDisposable { private readonly WickraHandle _handle; public Nrtr(double pct) { var ptr = NativeMethods.wickra_nrtr_new(pct); if (ptr == nint.Zero) { throw new ArgumentException("invalid Nrtr parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_nrtr_free); } public NrtrOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraNrtrOutput native; bool ok; unsafe { ok = NativeMethods.wickra_nrtr_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new NrtrOutput(native.@value, native.direction) : null; } public void Reset() { NativeMethods.wickra_nrtr_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Nvi : IDisposable { private readonly WickraHandle _handle; public Nvi() { var ptr = NativeMethods.wickra_nvi_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Nvi parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_nvi_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_nvi_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_nvi_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_nvi_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Obv : IDisposable { private readonly WickraHandle _handle; public Obv() { var ptr = NativeMethods.wickra_obv_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Obv parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_obv_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_obv_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_obv_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_obv_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class OIPriceDivergence : IDisposable { private readonly WickraHandle _handle; public OIPriceDivergence(int window) { ArgumentOutOfRangeException.ThrowIfNegative(window); var ptr = NativeMethods.wickra_oi_price_divergence_new((nuint)window); if (ptr == nint.Zero) { throw new ArgumentException("invalid OIPriceDivergence parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_oi_price_divergence_free); } public double Update(double fundingRate, double markPrice, double indexPrice, double futuresPrice, double openInterest, double longSize, double shortSize, double takerBuyVolume, double takerSellVolume, double longLiquidation, double shortLiquidation, long timestamp) { var result = NativeMethods.wickra_oi_price_divergence_update(_handle.DangerousGetHandle(), fundingRate, markPrice, indexPrice, futuresPrice, openInterest, longSize, shortSize, takerBuyVolume, takerSellVolume, longLiquidation, shortLiquidation, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_oi_price_divergence_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class OiToVolumeRatio : IDisposable { private readonly WickraHandle _handle; public OiToVolumeRatio() { var ptr = NativeMethods.wickra_oi_to_volume_ratio_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid OiToVolumeRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_oi_to_volume_ratio_free); } public double Update(double fundingRate, double markPrice, double indexPrice, double futuresPrice, double openInterest, double longSize, double shortSize, double takerBuyVolume, double takerSellVolume, double longLiquidation, double shortLiquidation, long timestamp) { var result = NativeMethods.wickra_oi_to_volume_ratio_update(_handle.DangerousGetHandle(), fundingRate, markPrice, indexPrice, futuresPrice, openInterest, longSize, shortSize, takerBuyVolume, takerSellVolume, longLiquidation, shortLiquidation, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_oi_to_volume_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class OIWeighted : IDisposable { private readonly WickraHandle _handle; public OIWeighted() { var ptr = NativeMethods.wickra_oi_weighted_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid OIWeighted parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_oi_weighted_free); } public double Update(double fundingRate, double markPrice, double indexPrice, double futuresPrice, double openInterest, double longSize, double shortSize, double takerBuyVolume, double takerSellVolume, double longLiquidation, double shortLiquidation, long timestamp) { var result = NativeMethods.wickra_oi_weighted_update(_handle.DangerousGetHandle(), fundingRate, markPrice, indexPrice, futuresPrice, openInterest, longSize, shortSize, takerBuyVolume, takerSellVolume, longLiquidation, shortLiquidation, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_oi_weighted_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class OmegaRatio : IDisposable { private readonly WickraHandle _handle; public OmegaRatio(int period, double threshold) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_omega_ratio_new((nuint)period, threshold); if (ptr == nint.Zero) { throw new ArgumentException("invalid OmegaRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_omega_ratio_free); } public double Update(double @value) { var result = NativeMethods.wickra_omega_ratio_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_omega_ratio_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_omega_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class OnNeck : IDisposable { private readonly WickraHandle _handle; public OnNeck() { var ptr = NativeMethods.wickra_on_neck_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid OnNeck parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_on_neck_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_on_neck_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_on_neck_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_on_neck_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class OpenInterestDelta : IDisposable { private readonly WickraHandle _handle; public OpenInterestDelta() { var ptr = NativeMethods.wickra_open_interest_delta_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid OpenInterestDelta parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_open_interest_delta_free); } public double Update(double fundingRate, double markPrice, double indexPrice, double futuresPrice, double openInterest, double longSize, double shortSize, double takerBuyVolume, double takerSellVolume, double longLiquidation, double shortLiquidation, long timestamp) { var result = NativeMethods.wickra_open_interest_delta_update(_handle.DangerousGetHandle(), fundingRate, markPrice, indexPrice, futuresPrice, openInterest, longSize, shortSize, takerBuyVolume, takerSellVolume, longLiquidation, shortLiquidation, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_open_interest_delta_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class OpenInterestMomentum : IDisposable { private readonly WickraHandle _handle; public OpenInterestMomentum(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_open_interest_momentum_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid OpenInterestMomentum parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_open_interest_momentum_free); } public double Update(double fundingRate, double markPrice, double indexPrice, double futuresPrice, double openInterest, double longSize, double shortSize, double takerBuyVolume, double takerSellVolume, double longLiquidation, double shortLiquidation, long timestamp) { var result = NativeMethods.wickra_open_interest_momentum_update(_handle.DangerousGetHandle(), fundingRate, markPrice, indexPrice, futuresPrice, openInterest, longSize, shortSize, takerBuyVolume, takerSellVolume, longLiquidation, shortLiquidation, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_open_interest_momentum_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class OpeningMarubozu : IDisposable { private readonly WickraHandle _handle; public OpeningMarubozu() { var ptr = NativeMethods.wickra_opening_marubozu_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid OpeningMarubozu parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_opening_marubozu_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_opening_marubozu_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_opening_marubozu_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_opening_marubozu_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class OpeningRange : IDisposable { private readonly WickraHandle _handle; public OpeningRange(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_opening_range_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid OpeningRange parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_opening_range_free); } public OpeningRangeOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraOpeningRangeOutput native; bool ok; unsafe { ok = NativeMethods.wickra_opening_range_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new OpeningRangeOutput(native.high, native.low, native.breakout_distance) : null; } public void Reset() { NativeMethods.wickra_opening_range_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class OrderBookImbalanceFull : IDisposable { private readonly WickraHandle _handle; public OrderBookImbalanceFull() { var ptr = NativeMethods.wickra_order_book_imbalance_full_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid OrderBookImbalanceFull parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_order_book_imbalance_full_free); } public double Update(ReadOnlySpan bidPrice, ReadOnlySpan bidSize, ReadOnlySpan askPrice, ReadOnlySpan askSize) { if (bidSize.Length != bidPrice.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (askSize.Length != askPrice.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* bidPricePtr = bidPrice) fixed (double* bidSizePtr = bidSize) fixed (double* askPricePtr = askPrice) fixed (double* askSizePtr = askSize) { result = NativeMethods.wickra_order_book_imbalance_full_update(_handle.DangerousGetHandle(), bidPricePtr, bidSizePtr, (nuint)bidPrice.Length, askPricePtr, askSizePtr, (nuint)askPrice.Length); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_order_book_imbalance_full_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class OrderBookImbalanceTop1 : IDisposable { private readonly WickraHandle _handle; public OrderBookImbalanceTop1() { var ptr = NativeMethods.wickra_order_book_imbalance_top1_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid OrderBookImbalanceTop1 parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_order_book_imbalance_top1_free); } public double Update(ReadOnlySpan bidPrice, ReadOnlySpan bidSize, ReadOnlySpan askPrice, ReadOnlySpan askSize) { if (bidSize.Length != bidPrice.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (askSize.Length != askPrice.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* bidPricePtr = bidPrice) fixed (double* bidSizePtr = bidSize) fixed (double* askPricePtr = askPrice) fixed (double* askSizePtr = askSize) { result = NativeMethods.wickra_order_book_imbalance_top1_update(_handle.DangerousGetHandle(), bidPricePtr, bidSizePtr, (nuint)bidPrice.Length, askPricePtr, askSizePtr, (nuint)askPrice.Length); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_order_book_imbalance_top1_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class OrderBookImbalanceTopN : IDisposable { private readonly WickraHandle _handle; public OrderBookImbalanceTopN(int levels) { ArgumentOutOfRangeException.ThrowIfNegative(levels); var ptr = NativeMethods.wickra_order_book_imbalance_top_n_new((nuint)levels); if (ptr == nint.Zero) { throw new ArgumentException("invalid OrderBookImbalanceTopN parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_order_book_imbalance_top_n_free); } public double Update(ReadOnlySpan bidPrice, ReadOnlySpan bidSize, ReadOnlySpan askPrice, ReadOnlySpan askSize) { if (bidSize.Length != bidPrice.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (askSize.Length != askPrice.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* bidPricePtr = bidPrice) fixed (double* bidSizePtr = bidSize) fixed (double* askPricePtr = askPrice) fixed (double* askSizePtr = askSize) { result = NativeMethods.wickra_order_book_imbalance_top_n_update(_handle.DangerousGetHandle(), bidPricePtr, bidSizePtr, (nuint)bidPrice.Length, askPricePtr, askSizePtr, (nuint)askPrice.Length); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_order_book_imbalance_top_n_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class OrderFlowImbalance : IDisposable { private readonly WickraHandle _handle; public OrderFlowImbalance(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_order_flow_imbalance_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid OrderFlowImbalance parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_order_flow_imbalance_free); } public double Update(ReadOnlySpan bidPrice, ReadOnlySpan bidSize, ReadOnlySpan askPrice, ReadOnlySpan askSize) { if (bidSize.Length != bidPrice.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (askSize.Length != askPrice.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* bidPricePtr = bidPrice) fixed (double* bidSizePtr = bidSize) fixed (double* askPricePtr = askPrice) fixed (double* askSizePtr = askSize) { result = NativeMethods.wickra_order_flow_imbalance_update(_handle.DangerousGetHandle(), bidPricePtr, bidSizePtr, (nuint)bidPrice.Length, askPricePtr, askSizePtr, (nuint)askPrice.Length); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_order_flow_imbalance_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class OuHalfLife : IDisposable { private readonly WickraHandle _handle; public OuHalfLife(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_ou_half_life_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid OuHalfLife parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_ou_half_life_free); } public double Update(double x, double y) { var result = NativeMethods.wickra_ou_half_life_update(_handle.DangerousGetHandle(), x, y); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan x, ReadOnlySpan y) { var n = x.Length; if (y.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* xPtr = x) fixed (double* yPtr = y) fixed (double* outputPtr = output) { NativeMethods.wickra_ou_half_life_batch(_handle.DangerousGetHandle(), xPtr, yPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_ou_half_life_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class OvernightGap : IDisposable { private readonly WickraHandle _handle; public OvernightGap(int utcOffsetMinutes) { var ptr = NativeMethods.wickra_overnight_gap_new(utcOffsetMinutes); if (ptr == nint.Zero) { throw new ArgumentException("invalid OvernightGap parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_overnight_gap_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_overnight_gap_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_overnight_gap_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_overnight_gap_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class OvernightIntradayReturn : IDisposable { private readonly WickraHandle _handle; public OvernightIntradayReturn(int utcOffsetMinutes) { var ptr = NativeMethods.wickra_overnight_intraday_return_new(utcOffsetMinutes); if (ptr == nint.Zero) { throw new ArgumentException("invalid OvernightIntradayReturn parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_overnight_intraday_return_free); } public OvernightIntradayReturnOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraOvernightIntradayReturnOutput native; bool ok; unsafe { ok = NativeMethods.wickra_overnight_intraday_return_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new OvernightIntradayReturnOutput(native.overnight, native.intraday) : null; } public void Reset() { NativeMethods.wickra_overnight_intraday_return_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class PainIndex : IDisposable { private readonly WickraHandle _handle; public PainIndex(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_pain_index_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid PainIndex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_pain_index_free); } public double Update(double @value) { var result = NativeMethods.wickra_pain_index_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_pain_index_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_pain_index_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class PairSpreadZScore : IDisposable { private readonly WickraHandle _handle; public PairSpreadZScore(int betaPeriod, int zPeriod) { ArgumentOutOfRangeException.ThrowIfNegative(betaPeriod); ArgumentOutOfRangeException.ThrowIfNegative(zPeriod); var ptr = NativeMethods.wickra_pair_spread_z_score_new((nuint)betaPeriod, (nuint)zPeriod); if (ptr == nint.Zero) { throw new ArgumentException("invalid PairSpreadZScore parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_pair_spread_z_score_free); } public double Update(double x, double y) { var result = NativeMethods.wickra_pair_spread_z_score_update(_handle.DangerousGetHandle(), x, y); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan x, ReadOnlySpan y) { var n = x.Length; if (y.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* xPtr = x) fixed (double* yPtr = y) fixed (double* outputPtr = output) { NativeMethods.wickra_pair_spread_z_score_batch(_handle.DangerousGetHandle(), xPtr, yPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_pair_spread_z_score_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class PairwiseBeta : IDisposable { private readonly WickraHandle _handle; public PairwiseBeta(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_pairwise_beta_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid PairwiseBeta parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_pairwise_beta_free); } public double Update(double x, double y) { var result = NativeMethods.wickra_pairwise_beta_update(_handle.DangerousGetHandle(), x, y); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan x, ReadOnlySpan y) { var n = x.Length; if (y.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* xPtr = x) fixed (double* yPtr = y) fixed (double* outputPtr = output) { NativeMethods.wickra_pairwise_beta_batch(_handle.DangerousGetHandle(), xPtr, yPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_pairwise_beta_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ParkinsonVolatility : IDisposable { private readonly WickraHandle _handle; public ParkinsonVolatility(int period, int tradingPeriods) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(tradingPeriods); var ptr = NativeMethods.wickra_parkinson_volatility_new((nuint)period, (nuint)tradingPeriods); if (ptr == nint.Zero) { throw new ArgumentException("invalid ParkinsonVolatility parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_parkinson_volatility_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_parkinson_volatility_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_parkinson_volatility_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_parkinson_volatility_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class PearsonCorrelation : IDisposable { private readonly WickraHandle _handle; public PearsonCorrelation(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_pearson_correlation_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid PearsonCorrelation parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_pearson_correlation_free); } public double Update(double x, double y) { var result = NativeMethods.wickra_pearson_correlation_update(_handle.DangerousGetHandle(), x, y); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan x, ReadOnlySpan y) { var n = x.Length; if (y.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* xPtr = x) fixed (double* yPtr = y) fixed (double* outputPtr = output) { NativeMethods.wickra_pearson_correlation_batch(_handle.DangerousGetHandle(), xPtr, yPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_pearson_correlation_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class PercentAboveMa : IDisposable { private readonly WickraHandle _handle; public PercentAboveMa() { var ptr = NativeMethods.wickra_percent_above_ma_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid PercentAboveMa parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_percent_above_ma_free); } public double Update(ReadOnlySpan change, ReadOnlySpan volume, ReadOnlySpan newHigh, ReadOnlySpan newLow, ReadOnlySpan aboveMa, ReadOnlySpan onBuySignal, long timestamp) { if (volume.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newHigh.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newLow.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (aboveMa.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (onBuySignal.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* changePtr = change) fixed (double* volumePtr = volume) fixed (bool* newHighPtr = newHigh) fixed (bool* newLowPtr = newLow) fixed (bool* aboveMaPtr = aboveMa) fixed (bool* onBuySignalPtr = onBuySignal) { result = NativeMethods.wickra_percent_above_ma_update(_handle.DangerousGetHandle(), changePtr, volumePtr, newHighPtr, newLowPtr, aboveMaPtr, onBuySignalPtr, (nuint)change.Length, timestamp); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_percent_above_ma_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class PercentB : IDisposable { private readonly WickraHandle _handle; public PercentB(int period, double multiplier) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_percent_b_new((nuint)period, multiplier); if (ptr == nint.Zero) { throw new ArgumentException("invalid PercentB parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_percent_b_free); } public double Update(double @value) { var result = NativeMethods.wickra_percent_b_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_percent_b_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_percent_b_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class PercentageTrailingStop : IDisposable { private readonly WickraHandle _handle; public PercentageTrailingStop(double percent) { var ptr = NativeMethods.wickra_percentage_trailing_stop_new(percent); if (ptr == nint.Zero) { throw new ArgumentException("invalid PercentageTrailingStop parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_percentage_trailing_stop_free); } public double Update(double @value) { var result = NativeMethods.wickra_percentage_trailing_stop_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_percentage_trailing_stop_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_percentage_trailing_stop_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class PerpetualPremiumIndex : IDisposable { private readonly WickraHandle _handle; public PerpetualPremiumIndex() { var ptr = NativeMethods.wickra_perpetual_premium_index_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid PerpetualPremiumIndex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_perpetual_premium_index_free); } public double Update(double fundingRate, double markPrice, double indexPrice, double futuresPrice, double openInterest, double longSize, double shortSize, double takerBuyVolume, double takerSellVolume, double longLiquidation, double shortLiquidation, long timestamp) { var result = NativeMethods.wickra_perpetual_premium_index_update(_handle.DangerousGetHandle(), fundingRate, markPrice, indexPrice, futuresPrice, openInterest, longSize, shortSize, takerBuyVolume, takerSellVolume, longLiquidation, shortLiquidation, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_perpetual_premium_index_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Pgo : IDisposable { private readonly WickraHandle _handle; public Pgo(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_pgo_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Pgo parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_pgo_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_pgo_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_pgo_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_pgo_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class PiercingDarkCloud : IDisposable { private readonly WickraHandle _handle; public PiercingDarkCloud() { var ptr = NativeMethods.wickra_piercing_dark_cloud_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid PiercingDarkCloud parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_piercing_dark_cloud_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_piercing_dark_cloud_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_piercing_dark_cloud_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_piercing_dark_cloud_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Pin : IDisposable { private readonly WickraHandle _handle; public Pin(int window) { ArgumentOutOfRangeException.ThrowIfNegative(window); var ptr = NativeMethods.wickra_pin_new((nuint)window); if (ptr == nint.Zero) { throw new ArgumentException("invalid Pin parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_pin_free); } public double Update(double price, double size, bool isBuy, long timestamp) { var result = NativeMethods.wickra_pin_update(_handle.DangerousGetHandle(), price, size, isBuy, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_pin_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class PivotReversal : IDisposable { private readonly WickraHandle _handle; public PivotReversal(int left, int right) { ArgumentOutOfRangeException.ThrowIfNegative(left); ArgumentOutOfRangeException.ThrowIfNegative(right); var ptr = NativeMethods.wickra_pivot_reversal_new((nuint)left, (nuint)right); if (ptr == nint.Zero) { throw new ArgumentException("invalid PivotReversal parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_pivot_reversal_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_pivot_reversal_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_pivot_reversal_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_pivot_reversal_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class PlusDi : IDisposable { private readonly WickraHandle _handle; public PlusDi(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_plus_di_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid PlusDi parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_plus_di_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_plus_di_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_plus_di_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_plus_di_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class PlusDm : IDisposable { private readonly WickraHandle _handle; public PlusDm(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_plus_dm_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid PlusDm parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_plus_dm_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_plus_dm_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_plus_dm_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_plus_dm_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Pmo : IDisposable { private readonly WickraHandle _handle; public Pmo(int smoothing1, int smoothing2) { ArgumentOutOfRangeException.ThrowIfNegative(smoothing1); ArgumentOutOfRangeException.ThrowIfNegative(smoothing2); var ptr = NativeMethods.wickra_pmo_new((nuint)smoothing1, (nuint)smoothing2); if (ptr == nint.Zero) { throw new ArgumentException("invalid Pmo parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_pmo_free); } public double Update(double @value) { var result = NativeMethods.wickra_pmo_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_pmo_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_pmo_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class PointAndFigureBars : IDisposable { private readonly WickraHandle _handle; public PointAndFigureBars(double boxSize, int reversal) { ArgumentOutOfRangeException.ThrowIfNegative(reversal); var ptr = NativeMethods.wickra_point_and_figure_bars_new(boxSize, (nuint)reversal); if (ptr == nint.Zero) { throw new ArgumentException("invalid PointAndFigureBars parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_point_and_figure_bars_free); } public PnfColumn[] Update(double open, double high, double low, double close, double volume, long timestamp) { const int cap = 64; Span buffer = stackalloc WickraPnfColumn[cap]; long count; unsafe { fixed (WickraPnfColumn* ptr = buffer) { count = (long)NativeMethods.wickra_point_and_figure_bars_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, ptr, (nuint)cap); } } GC.KeepAlive(_handle); if (count <= 0) { return Array.Empty(); } var result = new PnfColumn[count]; for (var i = 0; i < count; i++) { result[i] = new PnfColumn(buffer[i].direction, buffer[i].high, buffer[i].low); } return result; } public void Reset() { NativeMethods.wickra_point_and_figure_bars_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class PolarizedFractalEfficiency : IDisposable { private readonly WickraHandle _handle; public PolarizedFractalEfficiency(int period, int smoothing) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(smoothing); var ptr = NativeMethods.wickra_polarized_fractal_efficiency_new((nuint)period, (nuint)smoothing); if (ptr == nint.Zero) { throw new ArgumentException("invalid PolarizedFractalEfficiency parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_polarized_fractal_efficiency_free); } public double Update(double @value) { var result = NativeMethods.wickra_polarized_fractal_efficiency_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_polarized_fractal_efficiency_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_polarized_fractal_efficiency_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Ppo : IDisposable { private readonly WickraHandle _handle; public Ppo(int fast, int slow) { ArgumentOutOfRangeException.ThrowIfNegative(fast); ArgumentOutOfRangeException.ThrowIfNegative(slow); var ptr = NativeMethods.wickra_ppo_new((nuint)fast, (nuint)slow); if (ptr == nint.Zero) { throw new ArgumentException("invalid Ppo parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_ppo_free); } public double Update(double @value) { var result = NativeMethods.wickra_ppo_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_ppo_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_ppo_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class PpoHistogram : IDisposable { private readonly WickraHandle _handle; public PpoHistogram(int fast, int slow, int signal) { ArgumentOutOfRangeException.ThrowIfNegative(fast); ArgumentOutOfRangeException.ThrowIfNegative(slow); ArgumentOutOfRangeException.ThrowIfNegative(signal); var ptr = NativeMethods.wickra_ppo_histogram_new((nuint)fast, (nuint)slow, (nuint)signal); if (ptr == nint.Zero) { throw new ArgumentException("invalid PpoHistogram parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_ppo_histogram_free); } public double Update(double @value) { var result = NativeMethods.wickra_ppo_histogram_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_ppo_histogram_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_ppo_histogram_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ProfileShape : IDisposable { private readonly WickraHandle _handle; public ProfileShape(int period, int bins) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(bins); var ptr = NativeMethods.wickra_profile_shape_new((nuint)period, (nuint)bins); if (ptr == nint.Zero) { throw new ArgumentException("invalid ProfileShape parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_profile_shape_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_profile_shape_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_profile_shape_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_profile_shape_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ProfitFactor : IDisposable { private readonly WickraHandle _handle; public ProfitFactor(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_profit_factor_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid ProfitFactor parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_profit_factor_free); } public double Update(double @value) { var result = NativeMethods.wickra_profit_factor_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_profit_factor_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_profit_factor_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ProjectionBands : IDisposable { private readonly WickraHandle _handle; public ProjectionBands(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_projection_bands_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid ProjectionBands parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_projection_bands_free); } public ProjectionBandsOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraProjectionBandsOutput native; bool ok; unsafe { ok = NativeMethods.wickra_projection_bands_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new ProjectionBandsOutput(native.upper, native.middle, native.lower) : null; } public void Reset() { NativeMethods.wickra_projection_bands_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ProjectionOscillator : IDisposable { private readonly WickraHandle _handle; public ProjectionOscillator(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_projection_oscillator_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid ProjectionOscillator parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_projection_oscillator_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_projection_oscillator_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_projection_oscillator_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_projection_oscillator_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Psar : IDisposable { private readonly WickraHandle _handle; public Psar(double afStart, double afStep, double afMax) { var ptr = NativeMethods.wickra_psar_new(afStart, afStep, afMax); if (ptr == nint.Zero) { throw new ArgumentException("invalid Psar parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_psar_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_psar_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_psar_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_psar_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Pvi : IDisposable { private readonly WickraHandle _handle; public Pvi() { var ptr = NativeMethods.wickra_pvi_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Pvi parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_pvi_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_pvi_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_pvi_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_pvi_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Qqe : IDisposable { private readonly WickraHandle _handle; public Qqe(int rsiPeriod, int smoothing, double factor) { ArgumentOutOfRangeException.ThrowIfNegative(rsiPeriod); ArgumentOutOfRangeException.ThrowIfNegative(smoothing); var ptr = NativeMethods.wickra_qqe_new((nuint)rsiPeriod, (nuint)smoothing, factor); if (ptr == nint.Zero) { throw new ArgumentException("invalid Qqe parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_qqe_free); } public QqeOutput? Update(double @value) { WickraQqeOutput native; bool ok; unsafe { ok = NativeMethods.wickra_qqe_update(_handle.DangerousGetHandle(), @value, &native); } GC.KeepAlive(_handle); return ok ? new QqeOutput(native.rsi_ma, native.trailing_line) : null; } public void Reset() { NativeMethods.wickra_qqe_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Qstick : IDisposable { private readonly WickraHandle _handle; public Qstick(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_qstick_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Qstick parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_qstick_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_qstick_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_qstick_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_qstick_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class QuartileBands : IDisposable { private readonly WickraHandle _handle; public QuartileBands(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_quartile_bands_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid QuartileBands parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_quartile_bands_free); } public QuartileBandsOutput? Update(double @value) { WickraQuartileBandsOutput native; bool ok; unsafe { ok = NativeMethods.wickra_quartile_bands_update(_handle.DangerousGetHandle(), @value, &native); } GC.KeepAlive(_handle); return ok ? new QuartileBandsOutput(native.upper, native.middle, native.lower) : null; } public void Reset() { NativeMethods.wickra_quartile_bands_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class QuotedSpread : IDisposable { private readonly WickraHandle _handle; public QuotedSpread() { var ptr = NativeMethods.wickra_quoted_spread_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid QuotedSpread parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_quoted_spread_free); } public double Update(ReadOnlySpan bidPrice, ReadOnlySpan bidSize, ReadOnlySpan askPrice, ReadOnlySpan askSize) { if (bidSize.Length != bidPrice.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (askSize.Length != askPrice.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* bidPricePtr = bidPrice) fixed (double* bidSizePtr = bidSize) fixed (double* askPricePtr = askPrice) fixed (double* askSizePtr = askSize) { result = NativeMethods.wickra_quoted_spread_update(_handle.DangerousGetHandle(), bidPricePtr, bidSizePtr, (nuint)bidPrice.Length, askPricePtr, askSizePtr, (nuint)askPrice.Length); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_quoted_spread_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RSquared : IDisposable { private readonly WickraHandle _handle; public RSquared(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_r_squared_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid RSquared parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_r_squared_free); } public double Update(double @value) { var result = NativeMethods.wickra_r_squared_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_r_squared_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_r_squared_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RangeBars : IDisposable { private readonly WickraHandle _handle; public RangeBars(double range) { var ptr = NativeMethods.wickra_range_bars_new(range); if (ptr == nint.Zero) { throw new ArgumentException("invalid RangeBars parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_range_bars_free); } public RangeBar[] Update(double open, double high, double low, double close, double volume, long timestamp) { const int cap = 64; Span buffer = stackalloc WickraRangeBar[cap]; long count; unsafe { fixed (WickraRangeBar* ptr = buffer) { count = (long)NativeMethods.wickra_range_bars_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, ptr, (nuint)cap); } } GC.KeepAlive(_handle); if (count <= 0) { return Array.Empty(); } var result = new RangeBar[count]; for (var i = 0; i < count; i++) { result[i] = new RangeBar(buffer[i].open, buffer[i].close, buffer[i].direction); } return result; } public void Reset() { NativeMethods.wickra_range_bars_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RealizedSpread : IDisposable { private readonly WickraHandle _handle; public RealizedSpread(int horizon) { ArgumentOutOfRangeException.ThrowIfNegative(horizon); var ptr = NativeMethods.wickra_realized_spread_new((nuint)horizon); if (ptr == nint.Zero) { throw new ArgumentException("invalid RealizedSpread parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_realized_spread_free); } public double Update(double price, double size, bool isBuy, long timestamp, double mid) { var result = NativeMethods.wickra_realized_spread_update(_handle.DangerousGetHandle(), price, size, isBuy, timestamp, mid); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_realized_spread_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RealizedVolatility : IDisposable { private readonly WickraHandle _handle; public RealizedVolatility(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_realized_volatility_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid RealizedVolatility parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_realized_volatility_free); } public double Update(double @value) { var result = NativeMethods.wickra_realized_volatility_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_realized_volatility_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_realized_volatility_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RecoveryFactor : IDisposable { private readonly WickraHandle _handle; public RecoveryFactor() { var ptr = NativeMethods.wickra_recovery_factor_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid RecoveryFactor parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_recovery_factor_free); } public double Update(double @value) { var result = NativeMethods.wickra_recovery_factor_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_recovery_factor_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_recovery_factor_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RectangleRange : IDisposable { private readonly WickraHandle _handle; public RectangleRange() { var ptr = NativeMethods.wickra_rectangle_range_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid RectangleRange parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_rectangle_range_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_rectangle_range_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_rectangle_range_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_rectangle_range_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Reflex : IDisposable { private readonly WickraHandle _handle; public Reflex(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_reflex_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Reflex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_reflex_free); } public double Update(double @value) { var result = NativeMethods.wickra_reflex_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_reflex_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_reflex_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RegimeLabel : IDisposable { private readonly WickraHandle _handle; public RegimeLabel(int volPeriod, int lookback) { ArgumentOutOfRangeException.ThrowIfNegative(volPeriod); ArgumentOutOfRangeException.ThrowIfNegative(lookback); var ptr = NativeMethods.wickra_regime_label_new((nuint)volPeriod, (nuint)lookback); if (ptr == nint.Zero) { throw new ArgumentException("invalid RegimeLabel parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_regime_label_free); } public double Update(double @value) { var result = NativeMethods.wickra_regime_label_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_regime_label_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_regime_label_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RelativeStrengthAB : IDisposable { private readonly WickraHandle _handle; public RelativeStrengthAB(int maPeriod, int rsiPeriod) { ArgumentOutOfRangeException.ThrowIfNegative(maPeriod); ArgumentOutOfRangeException.ThrowIfNegative(rsiPeriod); var ptr = NativeMethods.wickra_relative_strength_ab_new((nuint)maPeriod, (nuint)rsiPeriod); if (ptr == nint.Zero) { throw new ArgumentException("invalid RelativeStrengthAB parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_relative_strength_ab_free); } public RelativeStrengthOutput? Update(double x, double y) { WickraRelativeStrengthOutput native; bool ok; unsafe { ok = NativeMethods.wickra_relative_strength_ab_update(_handle.DangerousGetHandle(), x, y, &native); } GC.KeepAlive(_handle); return ok ? new RelativeStrengthOutput(native.ratio, native.ratio_ma, native.ratio_rsi) : null; } public void Reset() { NativeMethods.wickra_relative_strength_ab_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RenkoBars : IDisposable { private readonly WickraHandle _handle; public RenkoBars(double boxSize) { var ptr = NativeMethods.wickra_renko_bars_new(boxSize); if (ptr == nint.Zero) { throw new ArgumentException("invalid RenkoBars parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_renko_bars_free); } public RenkoBrick[] Update(double open, double high, double low, double close, double volume, long timestamp) { const int cap = 64; Span buffer = stackalloc WickraRenkoBrick[cap]; long count; unsafe { fixed (WickraRenkoBrick* ptr = buffer) { count = (long)NativeMethods.wickra_renko_bars_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, ptr, (nuint)cap); } } GC.KeepAlive(_handle); if (count <= 0) { return Array.Empty(); } var result = new RenkoBrick[count]; for (var i = 0; i < count; i++) { result[i] = new RenkoBrick(buffer[i].open, buffer[i].close, buffer[i].direction); } return result; } public void Reset() { NativeMethods.wickra_renko_bars_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RenkoTrailingStop : IDisposable { private readonly WickraHandle _handle; public RenkoTrailingStop(double blockSize) { var ptr = NativeMethods.wickra_renko_trailing_stop_new(blockSize); if (ptr == nint.Zero) { throw new ArgumentException("invalid RenkoTrailingStop parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_renko_trailing_stop_free); } public double Update(double @value) { var result = NativeMethods.wickra_renko_trailing_stop_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_renko_trailing_stop_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_renko_trailing_stop_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RickshawMan : IDisposable { private readonly WickraHandle _handle; public RickshawMan() { var ptr = NativeMethods.wickra_rickshaw_man_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid RickshawMan parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_rickshaw_man_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_rickshaw_man_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_rickshaw_man_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_rickshaw_man_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RisingThreeMethods : IDisposable { private readonly WickraHandle _handle; public RisingThreeMethods() { var ptr = NativeMethods.wickra_rising_three_methods_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid RisingThreeMethods parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_rising_three_methods_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_rising_three_methods_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_rising_three_methods_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_rising_three_methods_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Rmi : IDisposable { private readonly WickraHandle _handle; public Rmi(int period, int momentum) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(momentum); var ptr = NativeMethods.wickra_rmi_new((nuint)period, (nuint)momentum); if (ptr == nint.Zero) { throw new ArgumentException("invalid Rmi parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_rmi_free); } public double Update(double @value) { var result = NativeMethods.wickra_rmi_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_rmi_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_rmi_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Roc : IDisposable { private readonly WickraHandle _handle; public Roc(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_roc_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Roc parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_roc_free); } public double Update(double @value) { var result = NativeMethods.wickra_roc_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_roc_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_roc_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Rocp : IDisposable { private readonly WickraHandle _handle; public Rocp(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_rocp_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Rocp parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_rocp_free); } public double Update(double @value) { var result = NativeMethods.wickra_rocp_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_rocp_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_rocp_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Rocr : IDisposable { private readonly WickraHandle _handle; public Rocr(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_rocr_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Rocr parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_rocr_free); } public double Update(double @value) { var result = NativeMethods.wickra_rocr_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_rocr_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_rocr_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Rocr100 : IDisposable { private readonly WickraHandle _handle; public Rocr100(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_rocr100_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Rocr100 parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_rocr100_free); } public double Update(double @value) { var result = NativeMethods.wickra_rocr100_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_rocr100_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_rocr100_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RogersSatchellVolatility : IDisposable { private readonly WickraHandle _handle; public RogersSatchellVolatility(int period, int tradingPeriods) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(tradingPeriods); var ptr = NativeMethods.wickra_rogers_satchell_volatility_new((nuint)period, (nuint)tradingPeriods); if (ptr == nint.Zero) { throw new ArgumentException("invalid RogersSatchellVolatility parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_rogers_satchell_volatility_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_rogers_satchell_volatility_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_rogers_satchell_volatility_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_rogers_satchell_volatility_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RollMeasure : IDisposable { private readonly WickraHandle _handle; public RollMeasure(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_roll_measure_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid RollMeasure parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_roll_measure_free); } public double Update(double price, double size, bool isBuy, long timestamp) { var result = NativeMethods.wickra_roll_measure_update(_handle.DangerousGetHandle(), price, size, isBuy, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_roll_measure_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RollingCorrelation : IDisposable { private readonly WickraHandle _handle; public RollingCorrelation(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_rolling_correlation_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid RollingCorrelation parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_rolling_correlation_free); } public double Update(double x, double y) { var result = NativeMethods.wickra_rolling_correlation_update(_handle.DangerousGetHandle(), x, y); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan x, ReadOnlySpan y) { var n = x.Length; if (y.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* xPtr = x) fixed (double* yPtr = y) fixed (double* outputPtr = output) { NativeMethods.wickra_rolling_correlation_batch(_handle.DangerousGetHandle(), xPtr, yPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_rolling_correlation_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RollingCovariance : IDisposable { private readonly WickraHandle _handle; public RollingCovariance(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_rolling_covariance_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid RollingCovariance parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_rolling_covariance_free); } public double Update(double x, double y) { var result = NativeMethods.wickra_rolling_covariance_update(_handle.DangerousGetHandle(), x, y); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan x, ReadOnlySpan y) { var n = x.Length; if (y.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* xPtr = x) fixed (double* yPtr = y) fixed (double* outputPtr = output) { NativeMethods.wickra_rolling_covariance_batch(_handle.DangerousGetHandle(), xPtr, yPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_rolling_covariance_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RollingIqr : IDisposable { private readonly WickraHandle _handle; public RollingIqr(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_rolling_iqr_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid RollingIqr parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_rolling_iqr_free); } public double Update(double @value) { var result = NativeMethods.wickra_rolling_iqr_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_rolling_iqr_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_rolling_iqr_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RollingMinMaxScaler : IDisposable { private readonly WickraHandle _handle; public RollingMinMaxScaler(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_rolling_min_max_scaler_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid RollingMinMaxScaler parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_rolling_min_max_scaler_free); } public double Update(double @value) { var result = NativeMethods.wickra_rolling_min_max_scaler_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_rolling_min_max_scaler_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_rolling_min_max_scaler_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RollingPercentileRank : IDisposable { private readonly WickraHandle _handle; public RollingPercentileRank(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_rolling_percentile_rank_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid RollingPercentileRank parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_rolling_percentile_rank_free); } public double Update(double @value) { var result = NativeMethods.wickra_rolling_percentile_rank_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_rolling_percentile_rank_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_rolling_percentile_rank_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RollingQuantile : IDisposable { private readonly WickraHandle _handle; public RollingQuantile(int period, double quantile) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_rolling_quantile_new((nuint)period, quantile); if (ptr == nint.Zero) { throw new ArgumentException("invalid RollingQuantile parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_rolling_quantile_free); } public double Update(double @value) { var result = NativeMethods.wickra_rolling_quantile_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_rolling_quantile_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_rolling_quantile_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RollingVwap : IDisposable { private readonly WickraHandle _handle; public RollingVwap(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_rolling_vwap_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid RollingVwap parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_rolling_vwap_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_rolling_vwap_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_rolling_vwap_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_rolling_vwap_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RoofingFilter : IDisposable { private readonly WickraHandle _handle; public RoofingFilter(int lpPeriod, int hpPeriod) { ArgumentOutOfRangeException.ThrowIfNegative(lpPeriod); ArgumentOutOfRangeException.ThrowIfNegative(hpPeriod); var ptr = NativeMethods.wickra_roofing_filter_new((nuint)lpPeriod, (nuint)hpPeriod); if (ptr == nint.Zero) { throw new ArgumentException("invalid RoofingFilter parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_roofing_filter_free); } public double Update(double @value) { var result = NativeMethods.wickra_roofing_filter_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_roofing_filter_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_roofing_filter_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Rsi : IDisposable { private readonly WickraHandle _handle; public Rsi(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_rsi_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Rsi parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_rsi_free); } public double Update(double @value) { var result = NativeMethods.wickra_rsi_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_rsi_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_rsi_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Rsx : IDisposable { private readonly WickraHandle _handle; public Rsx(int length) { ArgumentOutOfRangeException.ThrowIfNegative(length); var ptr = NativeMethods.wickra_rsx_new((nuint)length); if (ptr == nint.Zero) { throw new ArgumentException("invalid Rsx parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_rsx_free); } public double Update(double @value) { var result = NativeMethods.wickra_rsx_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_rsx_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_rsx_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RunBars : IDisposable { private readonly WickraHandle _handle; public RunBars(int runLength) { ArgumentOutOfRangeException.ThrowIfNegative(runLength); var ptr = NativeMethods.wickra_run_bars_new((nuint)runLength); if (ptr == nint.Zero) { throw new ArgumentException("invalid RunBars parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_run_bars_free); } public RunBar[] Update(double open, double high, double low, double close, double volume, long timestamp) { const int cap = 64; Span buffer = stackalloc WickraRunBar[cap]; long count; unsafe { fixed (WickraRunBar* ptr = buffer) { count = (long)NativeMethods.wickra_run_bars_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, ptr, (nuint)cap); } } GC.KeepAlive(_handle); if (count <= 0) { return Array.Empty(); } var result = new RunBar[count]; for (var i = 0; i < count; i++) { result[i] = new RunBar(buffer[i].open, buffer[i].high, buffer[i].low, buffer[i].close, buffer[i].length, buffer[i].direction); } return result; } public void Reset() { NativeMethods.wickra_run_bars_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Rvi : IDisposable { private readonly WickraHandle _handle; public Rvi(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_rvi_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Rvi parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_rvi_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_rvi_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_rvi_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_rvi_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class RviVolatility : IDisposable { private readonly WickraHandle _handle; public RviVolatility(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_rvi_volatility_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid RviVolatility parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_rvi_volatility_free); } public double Update(double @value) { var result = NativeMethods.wickra_rvi_volatility_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_rvi_volatility_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_rvi_volatility_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Rwi : IDisposable { private readonly WickraHandle _handle; public Rwi(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_rwi_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Rwi parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_rwi_free); } public RwiOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraRwiOutput native; bool ok; unsafe { ok = NativeMethods.wickra_rwi_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new RwiOutput(native.high, native.low) : null; } public void Reset() { NativeMethods.wickra_rwi_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SampleEntropy : IDisposable { private readonly WickraHandle _handle; public SampleEntropy(int period, int m, double rFactor) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(m); var ptr = NativeMethods.wickra_sample_entropy_new((nuint)period, (nuint)m, rFactor); if (ptr == nint.Zero) { throw new ArgumentException("invalid SampleEntropy parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_sample_entropy_free); } public double Update(double @value) { var result = NativeMethods.wickra_sample_entropy_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_sample_entropy_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_sample_entropy_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SarExt : IDisposable { private readonly WickraHandle _handle; public SarExt(double startValue, double offsetOnReverse, double accelInitLong, double accelLong, double accelMaxLong, double accelInitShort, double accelShort, double accelMaxShort) { var ptr = NativeMethods.wickra_sar_ext_new(startValue, offsetOnReverse, accelInitLong, accelLong, accelMaxLong, accelInitShort, accelShort, accelMaxShort); if (ptr == nint.Zero) { throw new ArgumentException("invalid SarExt parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_sar_ext_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_sar_ext_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_sar_ext_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_sar_ext_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SeasonalZScore : IDisposable { private readonly WickraHandle _handle; public SeasonalZScore(int utcOffsetMinutes) { var ptr = NativeMethods.wickra_seasonal_z_score_new(utcOffsetMinutes); if (ptr == nint.Zero) { throw new ArgumentException("invalid SeasonalZScore parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_seasonal_z_score_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_seasonal_z_score_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_seasonal_z_score_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_seasonal_z_score_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SeparatingLines : IDisposable { private readonly WickraHandle _handle; public SeparatingLines() { var ptr = NativeMethods.wickra_separating_lines_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid SeparatingLines parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_separating_lines_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_separating_lines_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_separating_lines_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_separating_lines_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SessionHighLow : IDisposable { private readonly WickraHandle _handle; public SessionHighLow(int utcOffsetMinutes) { var ptr = NativeMethods.wickra_session_high_low_new(utcOffsetMinutes); if (ptr == nint.Zero) { throw new ArgumentException("invalid SessionHighLow parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_session_high_low_free); } public SessionHighLowOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraSessionHighLowOutput native; bool ok; unsafe { ok = NativeMethods.wickra_session_high_low_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new SessionHighLowOutput(native.high, native.low) : null; } public void Reset() { NativeMethods.wickra_session_high_low_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SessionRange : IDisposable { private readonly WickraHandle _handle; public SessionRange(int utcOffsetMinutes) { var ptr = NativeMethods.wickra_session_range_new(utcOffsetMinutes); if (ptr == nint.Zero) { throw new ArgumentException("invalid SessionRange parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_session_range_free); } public SessionRangeOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraSessionRangeOutput native; bool ok; unsafe { ok = NativeMethods.wickra_session_range_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new SessionRangeOutput(native.asia, native.eu, native.us) : null; } public void Reset() { NativeMethods.wickra_session_range_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SessionVwap : IDisposable { private readonly WickraHandle _handle; public SessionVwap(int utcOffsetMinutes) { var ptr = NativeMethods.wickra_session_vwap_new(utcOffsetMinutes); if (ptr == nint.Zero) { throw new ArgumentException("invalid SessionVwap parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_session_vwap_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_session_vwap_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_session_vwap_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_session_vwap_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ShannonEntropy : IDisposable { private readonly WickraHandle _handle; public ShannonEntropy(int period, int bins) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(bins); var ptr = NativeMethods.wickra_shannon_entropy_new((nuint)period, (nuint)bins); if (ptr == nint.Zero) { throw new ArgumentException("invalid ShannonEntropy parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_shannon_entropy_free); } public double Update(double @value) { var result = NativeMethods.wickra_shannon_entropy_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_shannon_entropy_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_shannon_entropy_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Shark : IDisposable { private readonly WickraHandle _handle; public Shark() { var ptr = NativeMethods.wickra_shark_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Shark parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_shark_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_shark_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_shark_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_shark_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SharpeRatio : IDisposable { private readonly WickraHandle _handle; public SharpeRatio(int period, double riskFree) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_sharpe_ratio_new((nuint)period, riskFree); if (ptr == nint.Zero) { throw new ArgumentException("invalid SharpeRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_sharpe_ratio_free); } public double Update(double @value) { var result = NativeMethods.wickra_sharpe_ratio_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_sharpe_ratio_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_sharpe_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ShootingStar : IDisposable { private readonly WickraHandle _handle; public ShootingStar() { var ptr = NativeMethods.wickra_shooting_star_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid ShootingStar parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_shooting_star_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_shooting_star_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_shooting_star_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_shooting_star_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ShortLine : IDisposable { private readonly WickraHandle _handle; public ShortLine() { var ptr = NativeMethods.wickra_short_line_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid ShortLine parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_short_line_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_short_line_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_short_line_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_short_line_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SignedVolume : IDisposable { private readonly WickraHandle _handle; public SignedVolume() { var ptr = NativeMethods.wickra_signed_volume_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid SignedVolume parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_signed_volume_free); } public double Update(double price, double size, bool isBuy, long timestamp) { var result = NativeMethods.wickra_signed_volume_update(_handle.DangerousGetHandle(), price, size, isBuy, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_signed_volume_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SineWave : IDisposable { private readonly WickraHandle _handle; public SineWave() { var ptr = NativeMethods.wickra_sine_wave_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid SineWave parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_sine_wave_free); } public double Update(double @value) { var result = NativeMethods.wickra_sine_wave_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_sine_wave_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_sine_wave_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SineWeightedMa : IDisposable { private readonly WickraHandle _handle; public SineWeightedMa(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_sine_weighted_ma_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid SineWeightedMa parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_sine_weighted_ma_free); } public double Update(double @value) { var result = NativeMethods.wickra_sine_weighted_ma_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_sine_weighted_ma_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_sine_weighted_ma_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SinglePrints : IDisposable { private readonly WickraHandle _handle; public SinglePrints(int period, int bins) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(bins); var ptr = NativeMethods.wickra_single_prints_new((nuint)period, (nuint)bins); if (ptr == nint.Zero) { throw new ArgumentException("invalid SinglePrints parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_single_prints_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_single_prints_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_single_prints_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_single_prints_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Skewness : IDisposable { private readonly WickraHandle _handle; public Skewness(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_skewness_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Skewness parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_skewness_free); } public double Update(double @value) { var result = NativeMethods.wickra_skewness_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_skewness_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_skewness_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Sma : IDisposable { private readonly WickraHandle _handle; public Sma(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_sma_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Sma parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_sma_free); } public double Update(double @value) { var result = NativeMethods.wickra_sma_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_sma_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_sma_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Smi : IDisposable { private readonly WickraHandle _handle; public Smi(int period, int dPeriod, int d2Period) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(dPeriod); ArgumentOutOfRangeException.ThrowIfNegative(d2Period); var ptr = NativeMethods.wickra_smi_new((nuint)period, (nuint)dPeriod, (nuint)d2Period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Smi parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_smi_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_smi_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_smi_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_smi_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Smma : IDisposable { private readonly WickraHandle _handle; public Smma(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_smma_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Smma parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_smma_free); } public double Update(double @value) { var result = NativeMethods.wickra_smma_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_smma_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_smma_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SmoothedHeikinAshi : IDisposable { private readonly WickraHandle _handle; public SmoothedHeikinAshi(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_smoothed_heikin_ashi_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid SmoothedHeikinAshi parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_smoothed_heikin_ashi_free); } public SmoothedHeikinAshiOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraSmoothedHeikinAshiOutput native; bool ok; unsafe { ok = NativeMethods.wickra_smoothed_heikin_ashi_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new SmoothedHeikinAshiOutput(native.open, native.high, native.low, native.close) : null; } public void Reset() { NativeMethods.wickra_smoothed_heikin_ashi_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SortinoRatio : IDisposable { private readonly WickraHandle _handle; public SortinoRatio(int period, double mar) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_sortino_ratio_new((nuint)period, mar); if (ptr == nint.Zero) { throw new ArgumentException("invalid SortinoRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_sortino_ratio_free); } public double Update(double @value) { var result = NativeMethods.wickra_sortino_ratio_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_sortino_ratio_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_sortino_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SpearmanCorrelation : IDisposable { private readonly WickraHandle _handle; public SpearmanCorrelation(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_spearman_correlation_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid SpearmanCorrelation parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_spearman_correlation_free); } public double Update(double x, double y) { var result = NativeMethods.wickra_spearman_correlation_update(_handle.DangerousGetHandle(), x, y); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan x, ReadOnlySpan y) { var n = x.Length; if (y.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* xPtr = x) fixed (double* yPtr = y) fixed (double* outputPtr = output) { NativeMethods.wickra_spearman_correlation_batch(_handle.DangerousGetHandle(), xPtr, yPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_spearman_correlation_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SpinningTop : IDisposable { private readonly WickraHandle _handle; public SpinningTop() { var ptr = NativeMethods.wickra_spinning_top_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid SpinningTop parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_spinning_top_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_spinning_top_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_spinning_top_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_spinning_top_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SpreadAr1Coefficient : IDisposable { private readonly WickraHandle _handle; public SpreadAr1Coefficient(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_spread_ar1_coefficient_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid SpreadAr1Coefficient parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_spread_ar1_coefficient_free); } public double Update(double x, double y) { var result = NativeMethods.wickra_spread_ar1_coefficient_update(_handle.DangerousGetHandle(), x, y); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan x, ReadOnlySpan y) { var n = x.Length; if (y.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* xPtr = x) fixed (double* yPtr = y) fixed (double* outputPtr = output) { NativeMethods.wickra_spread_ar1_coefficient_batch(_handle.DangerousGetHandle(), xPtr, yPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_spread_ar1_coefficient_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SpreadBollingerBands : IDisposable { private readonly WickraHandle _handle; public SpreadBollingerBands(int period, double numStd) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_spread_bollinger_bands_new((nuint)period, numStd); if (ptr == nint.Zero) { throw new ArgumentException("invalid SpreadBollingerBands parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_spread_bollinger_bands_free); } public SpreadBollingerBandsOutput? Update(double x, double y) { WickraSpreadBollingerBandsOutput native; bool ok; unsafe { ok = NativeMethods.wickra_spread_bollinger_bands_update(_handle.DangerousGetHandle(), x, y, &native); } GC.KeepAlive(_handle); return ok ? new SpreadBollingerBandsOutput(native.middle, native.upper, native.lower, native.percent_b) : null; } public void Reset() { NativeMethods.wickra_spread_bollinger_bands_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SpreadHurst : IDisposable { private readonly WickraHandle _handle; public SpreadHurst(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_spread_hurst_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid SpreadHurst parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_spread_hurst_free); } public double Update(double x, double y) { var result = NativeMethods.wickra_spread_hurst_update(_handle.DangerousGetHandle(), x, y); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan x, ReadOnlySpan y) { var n = x.Length; if (y.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* xPtr = x) fixed (double* yPtr = y) fixed (double* outputPtr = output) { NativeMethods.wickra_spread_hurst_batch(_handle.DangerousGetHandle(), xPtr, yPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_spread_hurst_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class StalledPattern : IDisposable { private readonly WickraHandle _handle; public StalledPattern() { var ptr = NativeMethods.wickra_stalled_pattern_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid StalledPattern parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_stalled_pattern_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_stalled_pattern_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_stalled_pattern_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_stalled_pattern_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class StandardError : IDisposable { private readonly WickraHandle _handle; public StandardError(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_standard_error_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid StandardError parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_standard_error_free); } public double Update(double @value) { var result = NativeMethods.wickra_standard_error_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_standard_error_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_standard_error_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class StandardErrorBands : IDisposable { private readonly WickraHandle _handle; public StandardErrorBands(int period, double multiplier) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_standard_error_bands_new((nuint)period, multiplier); if (ptr == nint.Zero) { throw new ArgumentException("invalid StandardErrorBands parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_standard_error_bands_free); } public StandardErrorBandsOutput? Update(double @value) { WickraStandardErrorBandsOutput native; bool ok; unsafe { ok = NativeMethods.wickra_standard_error_bands_update(_handle.DangerousGetHandle(), @value, &native); } GC.KeepAlive(_handle); return ok ? new StandardErrorBandsOutput(native.upper, native.middle, native.lower) : null; } public void Reset() { NativeMethods.wickra_standard_error_bands_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class StarcBands : IDisposable { private readonly WickraHandle _handle; public StarcBands(int smaPeriod, int atrPeriod, double multiplier) { ArgumentOutOfRangeException.ThrowIfNegative(smaPeriod); ArgumentOutOfRangeException.ThrowIfNegative(atrPeriod); var ptr = NativeMethods.wickra_starc_bands_new((nuint)smaPeriod, (nuint)atrPeriod, multiplier); if (ptr == nint.Zero) { throw new ArgumentException("invalid StarcBands parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_starc_bands_free); } public StarcBandsOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraStarcBandsOutput native; bool ok; unsafe { ok = NativeMethods.wickra_starc_bands_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new StarcBandsOutput(native.upper, native.middle, native.lower) : null; } public void Reset() { NativeMethods.wickra_starc_bands_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Stc : IDisposable { private readonly WickraHandle _handle; public Stc(int fast, int slow, int schaffPeriod, double factor) { ArgumentOutOfRangeException.ThrowIfNegative(fast); ArgumentOutOfRangeException.ThrowIfNegative(slow); ArgumentOutOfRangeException.ThrowIfNegative(schaffPeriod); var ptr = NativeMethods.wickra_stc_new((nuint)fast, (nuint)slow, (nuint)schaffPeriod, factor); if (ptr == nint.Zero) { throw new ArgumentException("invalid Stc parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_stc_free); } public double Update(double @value) { var result = NativeMethods.wickra_stc_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_stc_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_stc_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class StdDev : IDisposable { private readonly WickraHandle _handle; public StdDev(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_std_dev_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid StdDev parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_std_dev_free); } public double Update(double @value) { var result = NativeMethods.wickra_std_dev_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_std_dev_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_std_dev_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class StepTrailingStop : IDisposable { private readonly WickraHandle _handle; public StepTrailingStop(double stepSize) { var ptr = NativeMethods.wickra_step_trailing_stop_new(stepSize); if (ptr == nint.Zero) { throw new ArgumentException("invalid StepTrailingStop parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_step_trailing_stop_free); } public double Update(double @value) { var result = NativeMethods.wickra_step_trailing_stop_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_step_trailing_stop_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_step_trailing_stop_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SterlingRatio : IDisposable { private readonly WickraHandle _handle; public SterlingRatio(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_sterling_ratio_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid SterlingRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_sterling_ratio_free); } public double Update(double @value) { var result = NativeMethods.wickra_sterling_ratio_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_sterling_ratio_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_sterling_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class StickSandwich : IDisposable { private readonly WickraHandle _handle; public StickSandwich() { var ptr = NativeMethods.wickra_stick_sandwich_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid StickSandwich parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_stick_sandwich_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_stick_sandwich_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_stick_sandwich_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_stick_sandwich_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class StochRsi : IDisposable { private readonly WickraHandle _handle; public StochRsi(int rsiPeriod, int stochPeriod) { ArgumentOutOfRangeException.ThrowIfNegative(rsiPeriod); ArgumentOutOfRangeException.ThrowIfNegative(stochPeriod); var ptr = NativeMethods.wickra_stoch_rsi_new((nuint)rsiPeriod, (nuint)stochPeriod); if (ptr == nint.Zero) { throw new ArgumentException("invalid StochRsi parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_stoch_rsi_free); } public double Update(double @value) { var result = NativeMethods.wickra_stoch_rsi_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_stoch_rsi_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_stoch_rsi_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Stochastic : IDisposable { private readonly WickraHandle _handle; public Stochastic(int kPeriod, int dPeriod) { ArgumentOutOfRangeException.ThrowIfNegative(kPeriod); ArgumentOutOfRangeException.ThrowIfNegative(dPeriod); var ptr = NativeMethods.wickra_stochastic_new((nuint)kPeriod, (nuint)dPeriod); if (ptr == nint.Zero) { throw new ArgumentException("invalid Stochastic parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_stochastic_free); } public StochasticOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraStochasticOutput native; bool ok; unsafe { ok = NativeMethods.wickra_stochastic_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new StochasticOutput(native.k, native.d) : null; } public void Reset() { NativeMethods.wickra_stochastic_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class StochasticCci : IDisposable { private readonly WickraHandle _handle; public StochasticCci(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_stochastic_cci_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid StochasticCci parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_stochastic_cci_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_stochastic_cci_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_stochastic_cci_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_stochastic_cci_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SuperSmoother : IDisposable { private readonly WickraHandle _handle; public SuperSmoother(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_super_smoother_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid SuperSmoother parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_super_smoother_free); } public double Update(double @value) { var result = NativeMethods.wickra_super_smoother_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_super_smoother_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_super_smoother_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class SuperTrend : IDisposable { private readonly WickraHandle _handle; public SuperTrend(int atrPeriod, double multiplier) { ArgumentOutOfRangeException.ThrowIfNegative(atrPeriod); var ptr = NativeMethods.wickra_super_trend_new((nuint)atrPeriod, multiplier); if (ptr == nint.Zero) { throw new ArgumentException("invalid SuperTrend parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_super_trend_free); } public SuperTrendOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraSuperTrendOutput native; bool ok; unsafe { ok = NativeMethods.wickra_super_trend_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new SuperTrendOutput(native.@value, native.direction) : null; } public void Reset() { NativeMethods.wickra_super_trend_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class T3 : IDisposable { private readonly WickraHandle _handle; public T3(int period, double v) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_t3_new((nuint)period, v); if (ptr == nint.Zero) { throw new ArgumentException("invalid T3 parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_t3_free); } public double Update(double @value) { var result = NativeMethods.wickra_t3_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_t3_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_t3_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TailRatio : IDisposable { private readonly WickraHandle _handle; public TailRatio(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_tail_ratio_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid TailRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_tail_ratio_free); } public double Update(double @value) { var result = NativeMethods.wickra_tail_ratio_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_tail_ratio_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_tail_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TakerBuySellRatio : IDisposable { private readonly WickraHandle _handle; public TakerBuySellRatio() { var ptr = NativeMethods.wickra_taker_buy_sell_ratio_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid TakerBuySellRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_taker_buy_sell_ratio_free); } public double Update(double fundingRate, double markPrice, double indexPrice, double futuresPrice, double openInterest, double longSize, double shortSize, double takerBuyVolume, double takerSellVolume, double longLiquidation, double shortLiquidation, long timestamp) { var result = NativeMethods.wickra_taker_buy_sell_ratio_update(_handle.DangerousGetHandle(), fundingRate, markPrice, indexPrice, futuresPrice, openInterest, longSize, shortSize, takerBuyVolume, takerSellVolume, longLiquidation, shortLiquidation, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_taker_buy_sell_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Takuri : IDisposable { private readonly WickraHandle _handle; public Takuri() { var ptr = NativeMethods.wickra_takuri_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Takuri parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_takuri_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_takuri_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_takuri_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_takuri_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TasukiGap : IDisposable { private readonly WickraHandle _handle; public TasukiGap() { var ptr = NativeMethods.wickra_tasuki_gap_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid TasukiGap parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_tasuki_gap_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_tasuki_gap_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_tasuki_gap_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_tasuki_gap_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TdCamouflage : IDisposable { private readonly WickraHandle _handle; public TdCamouflage() { var ptr = NativeMethods.wickra_td_camouflage_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid TdCamouflage parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_td_camouflage_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_td_camouflage_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_td_camouflage_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_td_camouflage_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TdClop : IDisposable { private readonly WickraHandle _handle; public TdClop() { var ptr = NativeMethods.wickra_td_clop_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid TdClop parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_td_clop_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_td_clop_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_td_clop_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_td_clop_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TdClopwin : IDisposable { private readonly WickraHandle _handle; public TdClopwin() { var ptr = NativeMethods.wickra_td_clopwin_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid TdClopwin parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_td_clopwin_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_td_clopwin_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_td_clopwin_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_td_clopwin_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TdCombo : IDisposable { private readonly WickraHandle _handle; public TdCombo(int setupLookback, int setupTarget, int countdownLookback, int countdownTarget) { ArgumentOutOfRangeException.ThrowIfNegative(setupLookback); ArgumentOutOfRangeException.ThrowIfNegative(setupTarget); ArgumentOutOfRangeException.ThrowIfNegative(countdownLookback); ArgumentOutOfRangeException.ThrowIfNegative(countdownTarget); var ptr = NativeMethods.wickra_td_combo_new((nuint)setupLookback, (nuint)setupTarget, (nuint)countdownLookback, (nuint)countdownTarget); if (ptr == nint.Zero) { throw new ArgumentException("invalid TdCombo parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_td_combo_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_td_combo_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_td_combo_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_td_combo_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TdCountdown : IDisposable { private readonly WickraHandle _handle; public TdCountdown(int setupLookback, int setupTarget, int countdownLookback, int countdownTarget) { ArgumentOutOfRangeException.ThrowIfNegative(setupLookback); ArgumentOutOfRangeException.ThrowIfNegative(setupTarget); ArgumentOutOfRangeException.ThrowIfNegative(countdownLookback); ArgumentOutOfRangeException.ThrowIfNegative(countdownTarget); var ptr = NativeMethods.wickra_td_countdown_new((nuint)setupLookback, (nuint)setupTarget, (nuint)countdownLookback, (nuint)countdownTarget); if (ptr == nint.Zero) { throw new ArgumentException("invalid TdCountdown parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_td_countdown_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_td_countdown_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_td_countdown_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_td_countdown_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TdDWave : IDisposable { private readonly WickraHandle _handle; public TdDWave(int strength) { ArgumentOutOfRangeException.ThrowIfNegative(strength); var ptr = NativeMethods.wickra_td_d_wave_new((nuint)strength); if (ptr == nint.Zero) { throw new ArgumentException("invalid TdDWave parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_td_d_wave_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_td_d_wave_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_td_d_wave_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_td_d_wave_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TdDeMarker : IDisposable { private readonly WickraHandle _handle; public TdDeMarker(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_td_de_marker_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid TdDeMarker parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_td_de_marker_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_td_de_marker_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_td_de_marker_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_td_de_marker_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TdDifferential : IDisposable { private readonly WickraHandle _handle; public TdDifferential() { var ptr = NativeMethods.wickra_td_differential_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid TdDifferential parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_td_differential_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_td_differential_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_td_differential_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_td_differential_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TdLines : IDisposable { private readonly WickraHandle _handle; public TdLines(int lookback, int target) { ArgumentOutOfRangeException.ThrowIfNegative(lookback); ArgumentOutOfRangeException.ThrowIfNegative(target); var ptr = NativeMethods.wickra_td_lines_new((nuint)lookback, (nuint)target); if (ptr == nint.Zero) { throw new ArgumentException("invalid TdLines parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_td_lines_free); } public TdLinesOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraTdLinesOutput native; bool ok; unsafe { ok = NativeMethods.wickra_td_lines_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new TdLinesOutput(native.resistance, native.support) : null; } public void Reset() { NativeMethods.wickra_td_lines_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TdMovingAverage : IDisposable { private readonly WickraHandle _handle; public TdMovingAverage(int periodSt1, int periodSt2) { ArgumentOutOfRangeException.ThrowIfNegative(periodSt1); ArgumentOutOfRangeException.ThrowIfNegative(periodSt2); var ptr = NativeMethods.wickra_td_moving_average_new((nuint)periodSt1, (nuint)periodSt2); if (ptr == nint.Zero) { throw new ArgumentException("invalid TdMovingAverage parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_td_moving_average_free); } public TdMovingAverageOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraTdMovingAverageOutput native; bool ok; unsafe { ok = NativeMethods.wickra_td_moving_average_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new TdMovingAverageOutput(native.st1, native.st2) : null; } public void Reset() { NativeMethods.wickra_td_moving_average_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TdOpen : IDisposable { private readonly WickraHandle _handle; public TdOpen() { var ptr = NativeMethods.wickra_td_open_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid TdOpen parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_td_open_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_td_open_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_td_open_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_td_open_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TdPressure : IDisposable { private readonly WickraHandle _handle; public TdPressure(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_td_pressure_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid TdPressure parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_td_pressure_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_td_pressure_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_td_pressure_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_td_pressure_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TdPropulsion : IDisposable { private readonly WickraHandle _handle; public TdPropulsion() { var ptr = NativeMethods.wickra_td_propulsion_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid TdPropulsion parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_td_propulsion_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_td_propulsion_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_td_propulsion_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_td_propulsion_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TdRangeProjection : IDisposable { private readonly WickraHandle _handle; public TdRangeProjection() { var ptr = NativeMethods.wickra_td_range_projection_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid TdRangeProjection parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_td_range_projection_free); } public TdRangeProjectionOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraTdRangeProjectionOutput native; bool ok; unsafe { ok = NativeMethods.wickra_td_range_projection_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new TdRangeProjectionOutput(native.high, native.low) : null; } public void Reset() { NativeMethods.wickra_td_range_projection_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TdRei : IDisposable { private readonly WickraHandle _handle; public TdRei(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_td_rei_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid TdRei parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_td_rei_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_td_rei_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_td_rei_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_td_rei_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TdRiskLevel : IDisposable { private readonly WickraHandle _handle; public TdRiskLevel(int lookback, int target) { ArgumentOutOfRangeException.ThrowIfNegative(lookback); ArgumentOutOfRangeException.ThrowIfNegative(target); var ptr = NativeMethods.wickra_td_risk_level_new((nuint)lookback, (nuint)target); if (ptr == nint.Zero) { throw new ArgumentException("invalid TdRiskLevel parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_td_risk_level_free); } public TdRiskLevelOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraTdRiskLevelOutput native; bool ok; unsafe { ok = NativeMethods.wickra_td_risk_level_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new TdRiskLevelOutput(native.buy_risk, native.sell_risk) : null; } public void Reset() { NativeMethods.wickra_td_risk_level_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TdSequential : IDisposable { private readonly WickraHandle _handle; public TdSequential(int setupLookback, int setupTarget, int countdownLookback, int countdownTarget) { ArgumentOutOfRangeException.ThrowIfNegative(setupLookback); ArgumentOutOfRangeException.ThrowIfNegative(setupTarget); ArgumentOutOfRangeException.ThrowIfNegative(countdownLookback); ArgumentOutOfRangeException.ThrowIfNegative(countdownTarget); var ptr = NativeMethods.wickra_td_sequential_new((nuint)setupLookback, (nuint)setupTarget, (nuint)countdownLookback, (nuint)countdownTarget); if (ptr == nint.Zero) { throw new ArgumentException("invalid TdSequential parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_td_sequential_free); } public TdSequentialOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraTdSequentialOutput native; bool ok; unsafe { ok = NativeMethods.wickra_td_sequential_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new TdSequentialOutput(native.setup, native.countdown, native.direction) : null; } public void Reset() { NativeMethods.wickra_td_sequential_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TdSetup : IDisposable { private readonly WickraHandle _handle; public TdSetup(int lookback, int target) { ArgumentOutOfRangeException.ThrowIfNegative(lookback); ArgumentOutOfRangeException.ThrowIfNegative(target); var ptr = NativeMethods.wickra_td_setup_new((nuint)lookback, (nuint)target); if (ptr == nint.Zero) { throw new ArgumentException("invalid TdSetup parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_td_setup_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_td_setup_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_td_setup_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_td_setup_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TdTrap : IDisposable { private readonly WickraHandle _handle; public TdTrap() { var ptr = NativeMethods.wickra_td_trap_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid TdTrap parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_td_trap_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_td_trap_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_td_trap_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_td_trap_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Tema : IDisposable { private readonly WickraHandle _handle; public Tema(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_tema_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Tema parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_tema_free); } public double Update(double @value) { var result = NativeMethods.wickra_tema_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_tema_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_tema_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TermStructureBasis : IDisposable { private readonly WickraHandle _handle; public TermStructureBasis() { var ptr = NativeMethods.wickra_term_structure_basis_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid TermStructureBasis parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_term_structure_basis_free); } public double Update(double fundingRate, double markPrice, double indexPrice, double futuresPrice, double openInterest, double longSize, double shortSize, double takerBuyVolume, double takerSellVolume, double longLiquidation, double shortLiquidation, long timestamp) { var result = NativeMethods.wickra_term_structure_basis_update(_handle.DangerousGetHandle(), fundingRate, markPrice, indexPrice, futuresPrice, openInterest, longSize, shortSize, takerBuyVolume, takerSellVolume, longLiquidation, shortLiquidation, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_term_structure_basis_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ThreeDrives : IDisposable { private readonly WickraHandle _handle; public ThreeDrives() { var ptr = NativeMethods.wickra_three_drives_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid ThreeDrives parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_three_drives_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_three_drives_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_three_drives_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_three_drives_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ThreeInside : IDisposable { private readonly WickraHandle _handle; public ThreeInside() { var ptr = NativeMethods.wickra_three_inside_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid ThreeInside parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_three_inside_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_three_inside_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_three_inside_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_three_inside_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ThreeLineBreak : IDisposable { private readonly WickraHandle _handle; public ThreeLineBreak(int lines) { ArgumentOutOfRangeException.ThrowIfNegative(lines); var ptr = NativeMethods.wickra_three_line_break_new((nuint)lines); if (ptr == nint.Zero) { throw new ArgumentException("invalid ThreeLineBreak parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_three_line_break_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_three_line_break_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_three_line_break_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_three_line_break_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ThreeLineBreakBars : IDisposable { private readonly WickraHandle _handle; public ThreeLineBreakBars(int lines) { ArgumentOutOfRangeException.ThrowIfNegative(lines); var ptr = NativeMethods.wickra_three_line_break_bars_new((nuint)lines); if (ptr == nint.Zero) { throw new ArgumentException("invalid ThreeLineBreakBars parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_three_line_break_bars_free); } public LineBreakBar[] Update(double open, double high, double low, double close, double volume, long timestamp) { const int cap = 64; Span buffer = stackalloc WickraLineBreakBar[cap]; long count; unsafe { fixed (WickraLineBreakBar* ptr = buffer) { count = (long)NativeMethods.wickra_three_line_break_bars_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, ptr, (nuint)cap); } } GC.KeepAlive(_handle); if (count <= 0) { return Array.Empty(); } var result = new LineBreakBar[count]; for (var i = 0; i < count; i++) { result[i] = new LineBreakBar(buffer[i].open, buffer[i].close, buffer[i].direction); } return result; } public void Reset() { NativeMethods.wickra_three_line_break_bars_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ThreeLineStrike : IDisposable { private readonly WickraHandle _handle; public ThreeLineStrike() { var ptr = NativeMethods.wickra_three_line_strike_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid ThreeLineStrike parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_three_line_strike_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_three_line_strike_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_three_line_strike_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_three_line_strike_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ThreeOutside : IDisposable { private readonly WickraHandle _handle; public ThreeOutside() { var ptr = NativeMethods.wickra_three_outside_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid ThreeOutside parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_three_outside_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_three_outside_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_three_outside_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_three_outside_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ThreeSoldiersOrCrows : IDisposable { private readonly WickraHandle _handle; public ThreeSoldiersOrCrows() { var ptr = NativeMethods.wickra_three_soldiers_or_crows_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid ThreeSoldiersOrCrows parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_three_soldiers_or_crows_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_three_soldiers_or_crows_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_three_soldiers_or_crows_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_three_soldiers_or_crows_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ThreeStarsInSouth : IDisposable { private readonly WickraHandle _handle; public ThreeStarsInSouth() { var ptr = NativeMethods.wickra_three_stars_in_south_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid ThreeStarsInSouth parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_three_stars_in_south_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_three_stars_in_south_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_three_stars_in_south_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_three_stars_in_south_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Thrusting : IDisposable { private readonly WickraHandle _handle; public Thrusting() { var ptr = NativeMethods.wickra_thrusting_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Thrusting parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_thrusting_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_thrusting_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_thrusting_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_thrusting_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TickBars : IDisposable { private readonly WickraHandle _handle; public TickBars(int ticks) { ArgumentOutOfRangeException.ThrowIfNegative(ticks); var ptr = NativeMethods.wickra_tick_bars_new((nuint)ticks); if (ptr == nint.Zero) { throw new ArgumentException("invalid TickBars parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_tick_bars_free); } public TickBar[] Update(double open, double high, double low, double close, double volume, long timestamp) { const int cap = 64; Span buffer = stackalloc WickraTickBar[cap]; long count; unsafe { fixed (WickraTickBar* ptr = buffer) { count = (long)NativeMethods.wickra_tick_bars_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, ptr, (nuint)cap); } } GC.KeepAlive(_handle); if (count <= 0) { return Array.Empty(); } var result = new TickBar[count]; for (var i = 0; i < count; i++) { result[i] = new TickBar(buffer[i].open, buffer[i].high, buffer[i].low, buffer[i].close, buffer[i].volume); } return result; } public void Reset() { NativeMethods.wickra_tick_bars_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TickIndex : IDisposable { private readonly WickraHandle _handle; public TickIndex() { var ptr = NativeMethods.wickra_tick_index_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid TickIndex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_tick_index_free); } public double Update(ReadOnlySpan change, ReadOnlySpan volume, ReadOnlySpan newHigh, ReadOnlySpan newLow, ReadOnlySpan aboveMa, ReadOnlySpan onBuySignal, long timestamp) { if (volume.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newHigh.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newLow.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (aboveMa.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (onBuySignal.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* changePtr = change) fixed (double* volumePtr = volume) fixed (bool* newHighPtr = newHigh) fixed (bool* newLowPtr = newLow) fixed (bool* aboveMaPtr = aboveMa) fixed (bool* onBuySignalPtr = onBuySignal) { result = NativeMethods.wickra_tick_index_update(_handle.DangerousGetHandle(), changePtr, volumePtr, newHighPtr, newLowPtr, aboveMaPtr, onBuySignalPtr, (nuint)change.Length, timestamp); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_tick_index_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Tii : IDisposable { private readonly WickraHandle _handle; public Tii(int smaPeriod, int devPeriod) { ArgumentOutOfRangeException.ThrowIfNegative(smaPeriod); ArgumentOutOfRangeException.ThrowIfNegative(devPeriod); var ptr = NativeMethods.wickra_tii_new((nuint)smaPeriod, (nuint)devPeriod); if (ptr == nint.Zero) { throw new ArgumentException("invalid Tii parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_tii_free); } public double Update(double @value) { var result = NativeMethods.wickra_tii_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_tii_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_tii_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TimeBasedStop : IDisposable { private readonly WickraHandle _handle; public TimeBasedStop(int maxBars) { ArgumentOutOfRangeException.ThrowIfNegative(maxBars); var ptr = NativeMethods.wickra_time_based_stop_new((nuint)maxBars); if (ptr == nint.Zero) { throw new ArgumentException("invalid TimeBasedStop parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_time_based_stop_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_time_based_stop_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_time_based_stop_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_time_based_stop_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TimeOfDayReturnProfile : IDisposable { private readonly WickraHandle _handle; private readonly int _valuesCapacity; public TimeOfDayReturnProfile(int buckets, int utcOffsetMinutes) { ArgumentOutOfRangeException.ThrowIfNegative(buckets); var ptr = NativeMethods.wickra_time_of_day_return_profile_new((nuint)buckets, utcOffsetMinutes); if (ptr == nint.Zero) { throw new ArgumentException("invalid TimeOfDayReturnProfile parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_time_of_day_return_profile_free); _valuesCapacity = buckets; } public double[]? Update(double open, double high, double low, double close, double volume, long timestamp) { var values = new double[_valuesCapacity]; long length; unsafe { fixed (double* valuesPtr = values) { length = (long)NativeMethods.wickra_time_of_day_return_profile_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, valuesPtr, (nuint)_valuesCapacity); } } GC.KeepAlive(_handle); if (length < 0) { return null; } if (length < values.Length) { Array.Resize(ref values, (int)length); } return values; } public void Reset() { NativeMethods.wickra_time_of_day_return_profile_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TowerTopBottom : IDisposable { private readonly WickraHandle _handle; public TowerTopBottom() { var ptr = NativeMethods.wickra_tower_top_bottom_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid TowerTopBottom parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_tower_top_bottom_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_tower_top_bottom_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_tower_top_bottom_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_tower_top_bottom_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TpoProfile : IDisposable { private readonly WickraHandle _handle; private readonly int _valuesCapacity; public TpoProfile(int period, int binCount) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(binCount); var ptr = NativeMethods.wickra_tpo_profile_new((nuint)period, (nuint)binCount); if (ptr == nint.Zero) { throw new ArgumentException("invalid TpoProfile parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_tpo_profile_free); _valuesCapacity = binCount; } public TpoProfileOutputScalars? Update(double open, double high, double low, double close, double volume, long timestamp) { var values = new double[_valuesCapacity]; WickraTpoProfileOutputScalars scalars; long length; unsafe { fixed (double* valuesPtr = values) { length = (long)NativeMethods.wickra_tpo_profile_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &scalars, valuesPtr, (nuint)_valuesCapacity); } } GC.KeepAlive(_handle); if (length < 0) { return null; } if (length < values.Length) { Array.Resize(ref values, (int)length); } return new TpoProfileOutputScalars(scalars.price_low, scalars.price_high, values); } public void Reset() { NativeMethods.wickra_tpo_profile_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TradeImbalance : IDisposable { private readonly WickraHandle _handle; public TradeImbalance(int window) { ArgumentOutOfRangeException.ThrowIfNegative(window); var ptr = NativeMethods.wickra_trade_imbalance_new((nuint)window); if (ptr == nint.Zero) { throw new ArgumentException("invalid TradeImbalance parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_trade_imbalance_free); } public double Update(double price, double size, bool isBuy, long timestamp) { var result = NativeMethods.wickra_trade_imbalance_update(_handle.DangerousGetHandle(), price, size, isBuy, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_trade_imbalance_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TradeSignAutocorrelation : IDisposable { private readonly WickraHandle _handle; public TradeSignAutocorrelation(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_trade_sign_autocorrelation_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid TradeSignAutocorrelation parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_trade_sign_autocorrelation_free); } public double Update(double price, double size, bool isBuy, long timestamp) { var result = NativeMethods.wickra_trade_sign_autocorrelation_update(_handle.DangerousGetHandle(), price, size, isBuy, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_trade_sign_autocorrelation_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TradeVolumeIndex : IDisposable { private readonly WickraHandle _handle; public TradeVolumeIndex(double minTick) { var ptr = NativeMethods.wickra_trade_volume_index_new(minTick); if (ptr == nint.Zero) { throw new ArgumentException("invalid TradeVolumeIndex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_trade_volume_index_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_trade_volume_index_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_trade_volume_index_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_trade_volume_index_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TrendLabel : IDisposable { private readonly WickraHandle _handle; public TrendLabel(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_trend_label_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid TrendLabel parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_trend_label_free); } public double Update(double @value) { var result = NativeMethods.wickra_trend_label_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_trend_label_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_trend_label_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TrendStrengthIndex : IDisposable { private readonly WickraHandle _handle; public TrendStrengthIndex(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_trend_strength_index_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid TrendStrengthIndex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_trend_strength_index_free); } public double Update(double @value) { var result = NativeMethods.wickra_trend_strength_index_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_trend_strength_index_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_trend_strength_index_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Trendflex : IDisposable { private readonly WickraHandle _handle; public Trendflex(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_trendflex_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Trendflex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_trendflex_free); } public double Update(double @value) { var result = NativeMethods.wickra_trendflex_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_trendflex_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_trendflex_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TreynorRatio : IDisposable { private readonly WickraHandle _handle; public TreynorRatio(int period, double riskFree) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_treynor_ratio_new((nuint)period, riskFree); if (ptr == nint.Zero) { throw new ArgumentException("invalid TreynorRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_treynor_ratio_free); } public double Update(double x, double y) { var result = NativeMethods.wickra_treynor_ratio_update(_handle.DangerousGetHandle(), x, y); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan x, ReadOnlySpan y) { var n = x.Length; if (y.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* xPtr = x) fixed (double* yPtr = y) fixed (double* outputPtr = output) { NativeMethods.wickra_treynor_ratio_batch(_handle.DangerousGetHandle(), xPtr, yPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_treynor_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Triangle : IDisposable { private readonly WickraHandle _handle; public Triangle() { var ptr = NativeMethods.wickra_triangle_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Triangle parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_triangle_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_triangle_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_triangle_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_triangle_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Trima : IDisposable { private readonly WickraHandle _handle; public Trima(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_trima_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Trima parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_trima_free); } public double Update(double @value) { var result = NativeMethods.wickra_trima_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_trima_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_trima_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Trin : IDisposable { private readonly WickraHandle _handle; public Trin() { var ptr = NativeMethods.wickra_trin_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Trin parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_trin_free); } public double Update(ReadOnlySpan change, ReadOnlySpan volume, ReadOnlySpan newHigh, ReadOnlySpan newLow, ReadOnlySpan aboveMa, ReadOnlySpan onBuySignal, long timestamp) { if (volume.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newHigh.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newLow.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (aboveMa.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (onBuySignal.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* changePtr = change) fixed (double* volumePtr = volume) fixed (bool* newHighPtr = newHigh) fixed (bool* newLowPtr = newLow) fixed (bool* aboveMaPtr = aboveMa) fixed (bool* onBuySignalPtr = onBuySignal) { result = NativeMethods.wickra_trin_update(_handle.DangerousGetHandle(), changePtr, volumePtr, newHighPtr, newLowPtr, aboveMaPtr, onBuySignalPtr, (nuint)change.Length, timestamp); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_trin_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TripleTopBottom : IDisposable { private readonly WickraHandle _handle; public TripleTopBottom() { var ptr = NativeMethods.wickra_triple_top_bottom_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid TripleTopBottom parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_triple_top_bottom_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_triple_top_bottom_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_triple_top_bottom_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_triple_top_bottom_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Tristar : IDisposable { private readonly WickraHandle _handle; public Tristar() { var ptr = NativeMethods.wickra_tristar_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Tristar parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_tristar_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_tristar_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_tristar_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_tristar_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Trix : IDisposable { private readonly WickraHandle _handle; public Trix(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_trix_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Trix parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_trix_free); } public double Update(double @value) { var result = NativeMethods.wickra_trix_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_trix_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_trix_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TrueRange : IDisposable { private readonly WickraHandle _handle; public TrueRange() { var ptr = NativeMethods.wickra_true_range_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid TrueRange parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_true_range_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_true_range_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_true_range_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_true_range_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Tsf : IDisposable { private readonly WickraHandle _handle; public Tsf(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_tsf_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Tsf parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_tsf_free); } public double Update(double @value) { var result = NativeMethods.wickra_tsf_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_tsf_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_tsf_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TsfOscillator : IDisposable { private readonly WickraHandle _handle; public TsfOscillator(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_tsf_oscillator_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid TsfOscillator parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_tsf_oscillator_free); } public double Update(double @value) { var result = NativeMethods.wickra_tsf_oscillator_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_tsf_oscillator_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_tsf_oscillator_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Tsi : IDisposable { private readonly WickraHandle _handle; public Tsi(int @long, int @short) { ArgumentOutOfRangeException.ThrowIfNegative(@long); ArgumentOutOfRangeException.ThrowIfNegative(@short); var ptr = NativeMethods.wickra_tsi_new((nuint)@long, (nuint)@short); if (ptr == nint.Zero) { throw new ArgumentException("invalid Tsi parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_tsi_free); } public double Update(double @value) { var result = NativeMethods.wickra_tsi_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_tsi_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_tsi_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Tsv : IDisposable { private readonly WickraHandle _handle; public Tsv(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_tsv_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Tsv parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_tsv_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_tsv_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_tsv_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_tsv_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TtmSqueeze : IDisposable { private readonly WickraHandle _handle; public TtmSqueeze(int period, double bbMult, double kcMult) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_ttm_squeeze_new((nuint)period, bbMult, kcMult); if (ptr == nint.Zero) { throw new ArgumentException("invalid TtmSqueeze parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_ttm_squeeze_free); } public TtmSqueezeOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraTtmSqueezeOutput native; bool ok; unsafe { ok = NativeMethods.wickra_ttm_squeeze_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new TtmSqueezeOutput(native.squeeze, native.momentum) : null; } public void Reset() { NativeMethods.wickra_ttm_squeeze_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TtmTrend : IDisposable { private readonly WickraHandle _handle; public TtmTrend(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_ttm_trend_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid TtmTrend parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_ttm_trend_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_ttm_trend_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_ttm_trend_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_ttm_trend_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TurnOfMonth : IDisposable { private readonly WickraHandle _handle; public TurnOfMonth(uint nFirst, uint nLast, int utcOffsetMinutes) { var ptr = NativeMethods.wickra_turn_of_month_new(nFirst, nLast, utcOffsetMinutes); if (ptr == nint.Zero) { throw new ArgumentException("invalid TurnOfMonth parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_turn_of_month_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_turn_of_month_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_turn_of_month_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_turn_of_month_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Tweezer : IDisposable { private readonly WickraHandle _handle; public Tweezer() { var ptr = NativeMethods.wickra_tweezer_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Tweezer parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_tweezer_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_tweezer_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_tweezer_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_tweezer_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TwiggsMoneyFlow : IDisposable { private readonly WickraHandle _handle; public TwiggsMoneyFlow(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_twiggs_money_flow_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid TwiggsMoneyFlow parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_twiggs_money_flow_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_twiggs_money_flow_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_twiggs_money_flow_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_twiggs_money_flow_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TwoCrows : IDisposable { private readonly WickraHandle _handle; public TwoCrows() { var ptr = NativeMethods.wickra_two_crows_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid TwoCrows parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_two_crows_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_two_crows_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_two_crows_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_two_crows_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class TypicalPrice : IDisposable { private readonly WickraHandle _handle; public TypicalPrice() { var ptr = NativeMethods.wickra_typical_price_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid TypicalPrice parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_typical_price_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_typical_price_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_typical_price_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_typical_price_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class UlcerIndex : IDisposable { private readonly WickraHandle _handle; public UlcerIndex(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_ulcer_index_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid UlcerIndex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_ulcer_index_free); } public double Update(double @value) { var result = NativeMethods.wickra_ulcer_index_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_ulcer_index_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_ulcer_index_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class UltimateOscillator : IDisposable { private readonly WickraHandle _handle; public UltimateOscillator(int @short, int mid, int @long) { ArgumentOutOfRangeException.ThrowIfNegative(@short); ArgumentOutOfRangeException.ThrowIfNegative(mid); ArgumentOutOfRangeException.ThrowIfNegative(@long); var ptr = NativeMethods.wickra_ultimate_oscillator_new((nuint)@short, (nuint)mid, (nuint)@long); if (ptr == nint.Zero) { throw new ArgumentException("invalid UltimateOscillator parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_ultimate_oscillator_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_ultimate_oscillator_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_ultimate_oscillator_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_ultimate_oscillator_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class UniqueThreeRiver : IDisposable { private readonly WickraHandle _handle; public UniqueThreeRiver() { var ptr = NativeMethods.wickra_unique_three_river_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid UniqueThreeRiver parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_unique_three_river_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_unique_three_river_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_unique_three_river_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_unique_three_river_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class UniversalOscillator : IDisposable { private readonly WickraHandle _handle; public UniversalOscillator(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_universal_oscillator_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid UniversalOscillator parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_universal_oscillator_free); } public double Update(double @value) { var result = NativeMethods.wickra_universal_oscillator_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_universal_oscillator_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_universal_oscillator_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class UpDownVolumeRatio : IDisposable { private readonly WickraHandle _handle; public UpDownVolumeRatio() { var ptr = NativeMethods.wickra_up_down_volume_ratio_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid UpDownVolumeRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_up_down_volume_ratio_free); } public double Update(ReadOnlySpan change, ReadOnlySpan volume, ReadOnlySpan newHigh, ReadOnlySpan newLow, ReadOnlySpan aboveMa, ReadOnlySpan onBuySignal, long timestamp) { if (volume.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newHigh.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (newLow.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (aboveMa.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } if (onBuySignal.Length != change.Length) { throw new ArgumentException("input spans in the same group must have equal length"); } double result; unsafe { fixed (double* changePtr = change) fixed (double* volumePtr = volume) fixed (bool* newHighPtr = newHigh) fixed (bool* newLowPtr = newLow) fixed (bool* aboveMaPtr = aboveMa) fixed (bool* onBuySignalPtr = onBuySignal) { result = NativeMethods.wickra_up_down_volume_ratio_update(_handle.DangerousGetHandle(), changePtr, volumePtr, newHighPtr, newLowPtr, aboveMaPtr, onBuySignalPtr, (nuint)change.Length, timestamp); } } GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_up_down_volume_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class UpsideGapThreeMethods : IDisposable { private readonly WickraHandle _handle; public UpsideGapThreeMethods() { var ptr = NativeMethods.wickra_upside_gap_three_methods_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid UpsideGapThreeMethods parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_upside_gap_three_methods_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_upside_gap_three_methods_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_upside_gap_three_methods_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_upside_gap_three_methods_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class UpsideGapTwoCrows : IDisposable { private readonly WickraHandle _handle; public UpsideGapTwoCrows() { var ptr = NativeMethods.wickra_upside_gap_two_crows_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid UpsideGapTwoCrows parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_upside_gap_two_crows_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_upside_gap_two_crows_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_upside_gap_two_crows_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_upside_gap_two_crows_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class UpsidePotentialRatio : IDisposable { private readonly WickraHandle _handle; public UpsidePotentialRatio(int period, double mar) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_upside_potential_ratio_new((nuint)period, mar); if (ptr == nint.Zero) { throw new ArgumentException("invalid UpsidePotentialRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_upside_potential_ratio_free); } public double Update(double @value) { var result = NativeMethods.wickra_upside_potential_ratio_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_upside_potential_ratio_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_upside_potential_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ValueArea : IDisposable { private readonly WickraHandle _handle; public ValueArea(int period, int binCount, double valueAreaPct) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(binCount); var ptr = NativeMethods.wickra_value_area_new((nuint)period, (nuint)binCount, valueAreaPct); if (ptr == nint.Zero) { throw new ArgumentException("invalid ValueArea parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_value_area_free); } public ValueAreaOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraValueAreaOutput native; bool ok; unsafe { ok = NativeMethods.wickra_value_area_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new ValueAreaOutput(native.poc, native.vah, native.val) : null; } public void Reset() { NativeMethods.wickra_value_area_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ValueAtRisk : IDisposable { private readonly WickraHandle _handle; public ValueAtRisk(int period, double confidence) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_value_at_risk_new((nuint)period, confidence); if (ptr == nint.Zero) { throw new ArgumentException("invalid ValueAtRisk parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_value_at_risk_free); } public double Update(double @value) { var result = NativeMethods.wickra_value_at_risk_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_value_at_risk_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_value_at_risk_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Variance : IDisposable { private readonly WickraHandle _handle; public Variance(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_variance_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Variance parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_variance_free); } public double Update(double @value) { var result = NativeMethods.wickra_variance_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_variance_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_variance_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class VarianceRatio : IDisposable { private readonly WickraHandle _handle; public VarianceRatio(int period, int q) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(q); var ptr = NativeMethods.wickra_variance_ratio_new((nuint)period, (nuint)q); if (ptr == nint.Zero) { throw new ArgumentException("invalid VarianceRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_variance_ratio_free); } public double Update(double x, double y) { var result = NativeMethods.wickra_variance_ratio_update(_handle.DangerousGetHandle(), x, y); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan x, ReadOnlySpan y) { var n = x.Length; if (y.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* xPtr = x) fixed (double* yPtr = y) fixed (double* outputPtr = output) { NativeMethods.wickra_variance_ratio_batch(_handle.DangerousGetHandle(), xPtr, yPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_variance_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class VerticalHorizontalFilter : IDisposable { private readonly WickraHandle _handle; public VerticalHorizontalFilter(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_vertical_horizontal_filter_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid VerticalHorizontalFilter parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_vertical_horizontal_filter_free); } public double Update(double @value) { var result = NativeMethods.wickra_vertical_horizontal_filter_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_vertical_horizontal_filter_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_vertical_horizontal_filter_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Vidya : IDisposable { private readonly WickraHandle _handle; public Vidya(int period, int cmoPeriod) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(cmoPeriod); var ptr = NativeMethods.wickra_vidya_new((nuint)period, (nuint)cmoPeriod); if (ptr == nint.Zero) { throw new ArgumentException("invalid Vidya parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_vidya_free); } public double Update(double @value) { var result = NativeMethods.wickra_vidya_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_vidya_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_vidya_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class VolatilityCone : IDisposable { private readonly WickraHandle _handle; public VolatilityCone(int window, int lookback) { ArgumentOutOfRangeException.ThrowIfNegative(window); ArgumentOutOfRangeException.ThrowIfNegative(lookback); var ptr = NativeMethods.wickra_volatility_cone_new((nuint)window, (nuint)lookback); if (ptr == nint.Zero) { throw new ArgumentException("invalid VolatilityCone parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_volatility_cone_free); } public VolatilityConeOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraVolatilityConeOutput native; bool ok; unsafe { ok = NativeMethods.wickra_volatility_cone_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new VolatilityConeOutput(native.current, native.min, native.median, native.max, native.percentile) : null; } public void Reset() { NativeMethods.wickra_volatility_cone_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class VolatilityOfVolatility : IDisposable { private readonly WickraHandle _handle; public VolatilityOfVolatility(int volWindow, int vovWindow) { ArgumentOutOfRangeException.ThrowIfNegative(volWindow); ArgumentOutOfRangeException.ThrowIfNegative(vovWindow); var ptr = NativeMethods.wickra_volatility_of_volatility_new((nuint)volWindow, (nuint)vovWindow); if (ptr == nint.Zero) { throw new ArgumentException("invalid VolatilityOfVolatility parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_volatility_of_volatility_free); } public double Update(double @value) { var result = NativeMethods.wickra_volatility_of_volatility_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_volatility_of_volatility_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_volatility_of_volatility_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class VolatilityRatio : IDisposable { private readonly WickraHandle _handle; public VolatilityRatio(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_volatility_ratio_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid VolatilityRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_volatility_ratio_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_volatility_ratio_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_volatility_ratio_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_volatility_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class VoltyStop : IDisposable { private readonly WickraHandle _handle; public VoltyStop(int atrPeriod, double multiplier) { ArgumentOutOfRangeException.ThrowIfNegative(atrPeriod); var ptr = NativeMethods.wickra_volty_stop_new((nuint)atrPeriod, multiplier); if (ptr == nint.Zero) { throw new ArgumentException("invalid VoltyStop parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_volty_stop_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_volty_stop_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_volty_stop_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_volty_stop_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class VolumeBars : IDisposable { private readonly WickraHandle _handle; public VolumeBars(double volumePerBar) { var ptr = NativeMethods.wickra_volume_bars_new(volumePerBar); if (ptr == nint.Zero) { throw new ArgumentException("invalid VolumeBars parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_volume_bars_free); } public VolumeBar[] Update(double open, double high, double low, double close, double volume, long timestamp) { const int cap = 64; Span buffer = stackalloc WickraVolumeBar[cap]; long count; unsafe { fixed (WickraVolumeBar* ptr = buffer) { count = (long)NativeMethods.wickra_volume_bars_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, ptr, (nuint)cap); } } GC.KeepAlive(_handle); if (count <= 0) { return Array.Empty(); } var result = new VolumeBar[count]; for (var i = 0; i < count; i++) { result[i] = new VolumeBar(buffer[i].open, buffer[i].high, buffer[i].low, buffer[i].close, buffer[i].volume); } return result; } public void Reset() { NativeMethods.wickra_volume_bars_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class VolumeByTimeProfile : IDisposable { private readonly WickraHandle _handle; private readonly int _valuesCapacity; public VolumeByTimeProfile(int buckets, int utcOffsetMinutes) { ArgumentOutOfRangeException.ThrowIfNegative(buckets); var ptr = NativeMethods.wickra_volume_by_time_profile_new((nuint)buckets, utcOffsetMinutes); if (ptr == nint.Zero) { throw new ArgumentException("invalid VolumeByTimeProfile parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_volume_by_time_profile_free); _valuesCapacity = buckets; } public double[]? Update(double open, double high, double low, double close, double volume, long timestamp) { var values = new double[_valuesCapacity]; long length; unsafe { fixed (double* valuesPtr = values) { length = (long)NativeMethods.wickra_volume_by_time_profile_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, valuesPtr, (nuint)_valuesCapacity); } } GC.KeepAlive(_handle); if (length < 0) { return null; } if (length < values.Length) { Array.Resize(ref values, (int)length); } return values; } public void Reset() { NativeMethods.wickra_volume_by_time_profile_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class VolumeOscillator : IDisposable { private readonly WickraHandle _handle; public VolumeOscillator(int fast, int slow) { ArgumentOutOfRangeException.ThrowIfNegative(fast); ArgumentOutOfRangeException.ThrowIfNegative(slow); var ptr = NativeMethods.wickra_volume_oscillator_new((nuint)fast, (nuint)slow); if (ptr == nint.Zero) { throw new ArgumentException("invalid VolumeOscillator parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_volume_oscillator_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_volume_oscillator_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_volume_oscillator_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_volume_oscillator_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class VolumePriceTrend : IDisposable { private readonly WickraHandle _handle; public VolumePriceTrend() { var ptr = NativeMethods.wickra_volume_price_trend_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid VolumePriceTrend parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_volume_price_trend_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_volume_price_trend_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_volume_price_trend_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_volume_price_trend_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class VolumeProfile : IDisposable { private readonly WickraHandle _handle; private readonly int _valuesCapacity; public VolumeProfile(int period, int binCount) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(binCount); var ptr = NativeMethods.wickra_volume_profile_new((nuint)period, (nuint)binCount); if (ptr == nint.Zero) { throw new ArgumentException("invalid VolumeProfile parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_volume_profile_free); _valuesCapacity = binCount; } public VolumeProfileOutputScalars? Update(double open, double high, double low, double close, double volume, long timestamp) { var values = new double[_valuesCapacity]; WickraVolumeProfileOutputScalars scalars; long length; unsafe { fixed (double* valuesPtr = values) { length = (long)NativeMethods.wickra_volume_profile_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &scalars, valuesPtr, (nuint)_valuesCapacity); } } GC.KeepAlive(_handle); if (length < 0) { return null; } if (length < values.Length) { Array.Resize(ref values, (int)length); } return new VolumeProfileOutputScalars(scalars.price_low, scalars.price_high, values); } public void Reset() { NativeMethods.wickra_volume_profile_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class VolumeRsi : IDisposable { private readonly WickraHandle _handle; public VolumeRsi(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_volume_rsi_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid VolumeRsi parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_volume_rsi_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_volume_rsi_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_volume_rsi_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_volume_rsi_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class VolumeWeightedMacd : IDisposable { private readonly WickraHandle _handle; public VolumeWeightedMacd(int fast, int slow, int signal) { ArgumentOutOfRangeException.ThrowIfNegative(fast); ArgumentOutOfRangeException.ThrowIfNegative(slow); ArgumentOutOfRangeException.ThrowIfNegative(signal); var ptr = NativeMethods.wickra_volume_weighted_macd_new((nuint)fast, (nuint)slow, (nuint)signal); if (ptr == nint.Zero) { throw new ArgumentException("invalid VolumeWeightedMacd parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_volume_weighted_macd_free); } public VolumeWeightedMacdOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraVolumeWeightedMacdOutput native; bool ok; unsafe { ok = NativeMethods.wickra_volume_weighted_macd_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new VolumeWeightedMacdOutput(native.macd, native.signal, native.histogram) : null; } public void Reset() { NativeMethods.wickra_volume_weighted_macd_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class VolumeWeightedSr : IDisposable { private readonly WickraHandle _handle; public VolumeWeightedSr(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_volume_weighted_sr_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid VolumeWeightedSr parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_volume_weighted_sr_free); } public VolumeWeightedSrOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraVolumeWeightedSrOutput native; bool ok; unsafe { ok = NativeMethods.wickra_volume_weighted_sr_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new VolumeWeightedSrOutput(native.support, native.resistance) : null; } public void Reset() { NativeMethods.wickra_volume_weighted_sr_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Vortex : IDisposable { private readonly WickraHandle _handle; public Vortex(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_vortex_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Vortex parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_vortex_free); } public VortexOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraVortexOutput native; bool ok; unsafe { ok = NativeMethods.wickra_vortex_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new VortexOutput(native.plus, native.minus) : null; } public void Reset() { NativeMethods.wickra_vortex_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Vpin : IDisposable { private readonly WickraHandle _handle; public Vpin(double bucketVolume, int numBuckets) { ArgumentOutOfRangeException.ThrowIfNegative(numBuckets); var ptr = NativeMethods.wickra_vpin_new(bucketVolume, (nuint)numBuckets); if (ptr == nint.Zero) { throw new ArgumentException("invalid Vpin parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_vpin_free); } public double Update(double price, double size, bool isBuy, long timestamp) { var result = NativeMethods.wickra_vpin_update(_handle.DangerousGetHandle(), price, size, isBuy, timestamp); GC.KeepAlive(_handle); return result; } public void Reset() { NativeMethods.wickra_vpin_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Vwap : IDisposable { private readonly WickraHandle _handle; public Vwap() { var ptr = NativeMethods.wickra_vwap_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Vwap parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_vwap_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_vwap_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_vwap_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_vwap_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class VwapStdDevBands : IDisposable { private readonly WickraHandle _handle; public VwapStdDevBands(double multiplier) { var ptr = NativeMethods.wickra_vwap_std_dev_bands_new(multiplier); if (ptr == nint.Zero) { throw new ArgumentException("invalid VwapStdDevBands parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_vwap_std_dev_bands_free); } public VwapStdDevBandsOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraVwapStdDevBandsOutput native; bool ok; unsafe { ok = NativeMethods.wickra_vwap_std_dev_bands_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new VwapStdDevBandsOutput(native.upper, native.middle, native.lower, native.stddev) : null; } public void Reset() { NativeMethods.wickra_vwap_std_dev_bands_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Vwma : IDisposable { private readonly WickraHandle _handle; public Vwma(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_vwma_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Vwma parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_vwma_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_vwma_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_vwma_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_vwma_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Vzo : IDisposable { private readonly WickraHandle _handle; public Vzo(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_vzo_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Vzo parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_vzo_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_vzo_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_vzo_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_vzo_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Wad : IDisposable { private readonly WickraHandle _handle; public Wad() { var ptr = NativeMethods.wickra_wad_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Wad parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_wad_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_wad_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_wad_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_wad_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class WavePm : IDisposable { private readonly WickraHandle _handle; public WavePm(int length, int smoothing) { ArgumentOutOfRangeException.ThrowIfNegative(length); ArgumentOutOfRangeException.ThrowIfNegative(smoothing); var ptr = NativeMethods.wickra_wave_pm_new((nuint)length, (nuint)smoothing); if (ptr == nint.Zero) { throw new ArgumentException("invalid WavePm parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_wave_pm_free); } public double Update(double @value) { var result = NativeMethods.wickra_wave_pm_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_wave_pm_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_wave_pm_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class WaveTrend : IDisposable { private readonly WickraHandle _handle; public WaveTrend(int channelPeriod, int averagePeriod, int signalPeriod) { ArgumentOutOfRangeException.ThrowIfNegative(channelPeriod); ArgumentOutOfRangeException.ThrowIfNegative(averagePeriod); ArgumentOutOfRangeException.ThrowIfNegative(signalPeriod); var ptr = NativeMethods.wickra_wave_trend_new((nuint)channelPeriod, (nuint)averagePeriod, (nuint)signalPeriod); if (ptr == nint.Zero) { throw new ArgumentException("invalid WaveTrend parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_wave_trend_free); } public WaveTrendOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraWaveTrendOutput native; bool ok; unsafe { ok = NativeMethods.wickra_wave_trend_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new WaveTrendOutput(native.wt1, native.wt2) : null; } public void Reset() { NativeMethods.wickra_wave_trend_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Wedge : IDisposable { private readonly WickraHandle _handle; public Wedge() { var ptr = NativeMethods.wickra_wedge_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid Wedge parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_wedge_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_wedge_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_wedge_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_wedge_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class WeightedClose : IDisposable { private readonly WickraHandle _handle; public WeightedClose() { var ptr = NativeMethods.wickra_weighted_close_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid WeightedClose parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_weighted_close_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_weighted_close_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_weighted_close_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_weighted_close_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class WickRatio : IDisposable { private readonly WickraHandle _handle; public WickRatio() { var ptr = NativeMethods.wickra_wick_ratio_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid WickRatio parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_wick_ratio_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_wick_ratio_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_wick_ratio_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_wick_ratio_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class WilliamsFractals : IDisposable { private readonly WickraHandle _handle; public WilliamsFractals() { var ptr = NativeMethods.wickra_williams_fractals_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid WilliamsFractals parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_williams_fractals_free); } public WilliamsFractalsOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraWilliamsFractalsOutput native; bool ok; unsafe { ok = NativeMethods.wickra_williams_fractals_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new WilliamsFractalsOutput(native.up, native.down) : null; } public void Reset() { NativeMethods.wickra_williams_fractals_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class WilliamsR : IDisposable { private readonly WickraHandle _handle; public WilliamsR(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_williams_r_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid WilliamsR parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_williams_r_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_williams_r_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_williams_r_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_williams_r_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class WinRate : IDisposable { private readonly WickraHandle _handle; public WinRate(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_win_rate_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid WinRate parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_win_rate_free); } public double Update(double @value) { var result = NativeMethods.wickra_win_rate_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_win_rate_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_win_rate_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Wma : IDisposable { private readonly WickraHandle _handle; public Wma(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_wma_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Wma parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_wma_free); } public double Update(double @value) { var result = NativeMethods.wickra_wma_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_wma_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_wma_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class WoodiePivots : IDisposable { private readonly WickraHandle _handle; public WoodiePivots() { var ptr = NativeMethods.wickra_woodie_pivots_new(); if (ptr == nint.Zero) { throw new ArgumentException("invalid WoodiePivots parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_woodie_pivots_free); } public WoodiePivotsOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraWoodiePivotsOutput native; bool ok; unsafe { ok = NativeMethods.wickra_woodie_pivots_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new WoodiePivotsOutput(native.pp, native.r1, native.r2, native.s1, native.s2) : null; } public void Reset() { NativeMethods.wickra_woodie_pivots_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class YangZhangVolatility : IDisposable { private readonly WickraHandle _handle; public YangZhangVolatility(int period, int tradingPeriods) { ArgumentOutOfRangeException.ThrowIfNegative(period); ArgumentOutOfRangeException.ThrowIfNegative(tradingPeriods); var ptr = NativeMethods.wickra_yang_zhang_volatility_new((nuint)period, (nuint)tradingPeriods); if (ptr == nint.Zero) { throw new ArgumentException("invalid YangZhangVolatility parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_yang_zhang_volatility_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_yang_zhang_volatility_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_yang_zhang_volatility_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_yang_zhang_volatility_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class YoyoExit : IDisposable { private readonly WickraHandle _handle; public YoyoExit(int atrPeriod, double multiplier) { ArgumentOutOfRangeException.ThrowIfNegative(atrPeriod); var ptr = NativeMethods.wickra_yoyo_exit_new((nuint)atrPeriod, multiplier); if (ptr == nint.Zero) { throw new ArgumentException("invalid YoyoExit parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_yoyo_exit_free); } public double Update(double open, double high, double low, double close, double volume, long timestamp) { var result = NativeMethods.wickra_yoyo_exit_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan open, ReadOnlySpan high, ReadOnlySpan low, ReadOnlySpan close, ReadOnlySpan volume, ReadOnlySpan timestamp) { var n = open.Length; if (high.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (low.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (close.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (volume.Length != n) { throw new ArgumentException("all input spans must have the same length"); } if (timestamp.Length != n) { throw new ArgumentException("all input spans must have the same length"); } var output = new double[n]; unsafe { fixed (double* openPtr = open) fixed (double* highPtr = high) fixed (double* lowPtr = low) fixed (double* closePtr = close) fixed (double* volumePtr = volume) fixed (long* timestampPtr = timestamp) fixed (double* outputPtr = output) { NativeMethods.wickra_yoyo_exit_batch(_handle.DangerousGetHandle(), openPtr, highPtr, lowPtr, closePtr, volumePtr, timestampPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_yoyo_exit_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ZScore : IDisposable { private readonly WickraHandle _handle; public ZScore(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_z_score_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid ZScore parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_z_score_free); } public double Update(double @value) { var result = NativeMethods.wickra_z_score_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_z_score_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_z_score_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ZeroLagMacd : IDisposable { private readonly WickraHandle _handle; public ZeroLagMacd(int fast, int slow, int signal) { ArgumentOutOfRangeException.ThrowIfNegative(fast); ArgumentOutOfRangeException.ThrowIfNegative(slow); ArgumentOutOfRangeException.ThrowIfNegative(signal); var ptr = NativeMethods.wickra_zero_lag_macd_new((nuint)fast, (nuint)slow, (nuint)signal); if (ptr == nint.Zero) { throw new ArgumentException("invalid ZeroLagMacd parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_zero_lag_macd_free); } public ZeroLagMacdOutput? Update(double @value) { WickraZeroLagMacdOutput native; bool ok; unsafe { ok = NativeMethods.wickra_zero_lag_macd_update(_handle.DangerousGetHandle(), @value, &native); } GC.KeepAlive(_handle); return ok ? new ZeroLagMacdOutput(native.macd, native.signal, native.histogram) : null; } public void Reset() { NativeMethods.wickra_zero_lag_macd_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class ZigZag : IDisposable { private readonly WickraHandle _handle; public ZigZag(double threshold) { var ptr = NativeMethods.wickra_zig_zag_new(threshold); if (ptr == nint.Zero) { throw new ArgumentException("invalid ZigZag parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_zig_zag_free); } public ZigZagOutput? Update(double open, double high, double low, double close, double volume, long timestamp) { WickraZigZagOutput native; bool ok; unsafe { ok = NativeMethods.wickra_zig_zag_update(_handle.DangerousGetHandle(), open, high, low, close, volume, timestamp, &native); } GC.KeepAlive(_handle); return ok ? new ZigZagOutput(native.swing, native.direction) : null; } public void Reset() { NativeMethods.wickra_zig_zag_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); } public sealed class Zlema : IDisposable { private readonly WickraHandle _handle; public Zlema(int period) { ArgumentOutOfRangeException.ThrowIfNegative(period); var ptr = NativeMethods.wickra_zlema_new((nuint)period); if (ptr == nint.Zero) { throw new ArgumentException("invalid Zlema parameters"); } _handle = new WickraHandle(ptr, NativeMethods.wickra_zlema_free); } public double Update(double @value) { var result = NativeMethods.wickra_zlema_update(_handle.DangerousGetHandle(), @value); GC.KeepAlive(_handle); return result; } public double[] Batch(ReadOnlySpan input) { var n = input.Length; var output = new double[n]; unsafe { fixed (double* inputPtr = input) fixed (double* outputPtr = output) { NativeMethods.wickra_zlema_batch(_handle.DangerousGetHandle(), inputPtr, outputPtr, (nuint)n); } } GC.KeepAlive(_handle); return output; } public void Reset() { NativeMethods.wickra_zlema_reset(_handle.DangerousGetHandle()); GC.KeepAlive(_handle); } public void Dispose() => _handle.Dispose(); }