C#
Verified against the Rust reference. Every one of Wickra's 514 indicators is replayed through all 10 languages and checked bit-for-bit against the Rust core's golden fixtures in CI — the math here is provably identical to every other binding (how).
The C# binding is the first language shim on the C ABI hub. It ships on NuGet as Wickra with the native library prebuilt for every supported platform; there is nothing to compile.
dotnet add package Wickra- Distribution: NuGet (
Wickra), native libraries bundled per RID (win/linux/osx × x64/arm64). - Built on: the C ABI hub via
[LibraryImport]source-generated P/Invoke, generated fromwickra.h. - Memory model: opaque handles wrapped in a
SafeHandle;usingfor deterministic cleanup, with a finalizer as the safety net.
The class shape
Every indicator is an IDisposable class with Update / Batch / WarmupPeriod / IsReady / Reset. Prefer using so the native handle is freed deterministically.
using Wickra;
using var sma = new Sma(14); // throws ArgumentException on invalid params
int w = sma.WarmupPeriod(); // updates until ready: 14
double v = sma.Update(42.0); // NaN while warming up
bool ready = sma.IsReady(); // false until warmed up
sma.Reset();
// freed at the end of the using scopeThe alt-chart bar builders (RenkoBars, KagiBars, …) have no WarmupPeriod / IsReady — a candle can complete 0..n bars, so they have no warmup.
Streaming
using var rsi = new Rsi(14);
foreach (var price in feed)
{
var v = rsi.Update(price);
if (double.IsFinite(v) && v > 70.0)
{
Console.WriteLine($"overbought {v:F2}");
}
}Batch (one call over a whole series)
using var ema = new Ema(20);
double[] values = ema.Batch(prices); // NaN at warmup positionsMulti-output indicators
Indicators with several outputs return a nullable record struct — null while warming up:
using var macd = new MacdIndicator(12, 26, 9);
foreach (var price in feed)
{
if (macd.Update(price) is { } m)
{
Console.WriteLine($"macd={m.Macd:F4} signal={m.Signal:F4} hist={m.Histogram:F4}");
}
}Candle-input indicators take OHLCV plus a timestamp, e.g. atr.Update(open, high, low, close, volume, timestamp).