Quickstart: Go
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).
A five-minute tour of the Wickra Go binding — a cgo shim on the C ABI hub. By the end you will have streamed an RSI, run a batch SMA, and read a multi-output MACD, all as idiomatic Go.
Install
go get github.com/wickra-lib/wickra-go/v2The binding uses cgo, so a C compiler is required. The prebuilt Wickra C ABI libraries are committed in the module per platform under lib/<goos>_<goarch>/, so go get builds with no manual library build or staging. On Linux and macOS the library path is baked in via rpath; on Windows the bundled wickra.dll must be discoverable at run time (next to the executable or on PATH).
The type shape
Every indicator is a type over an opaque native handle, with the same operations as the C ABI underneath:
import wickra "github.com/wickra-lib/wickra-go/v2"
sma, err := wickra.NewSma(14) // err is ErrInvalidParams on invalid params
if err != nil {
panic(err)
}
defer sma.Close() // frees the handle (a finalizer is a backstop)
w := sma.WarmupPeriod() // updates until ready: 14
v := sma.Update(42.0) // NaN while warming up
ready := sma.IsReady() // false until warmed up
sma.Reset() // back to a fresh stateThe alt-chart bar builders (RenkoBars, KagiBars, …) have no WarmupPeriod / IsReady — a candle can complete 0..n bars, so they have no warmup.
Update never revisits the history behind the tick. Prefer defer x.Close() for prompt cleanup; a runtime.SetFinalizer also frees the handle, so a missed Close never leaks permanently.
Streaming and batch side by side
package main
import (
"fmt"
"math"
wickra "github.com/wickra-lib/wickra-go/v2"
)
func main() {
// 1. Streaming: feed Wilder's textbook example into RSI(14).
rsi, _ := wickra.NewRsi(14)
defer rsi.Close()
prices := []float64{
44.34, 44.09, 44.15, 43.61, 44.33, 44.83, 45.10, 45.42,
45.84, 46.08, 45.89, 46.03, 45.61, 46.28, 46.28, 46.00,
}
for i, p := range prices {
r := rsi.Update(p)
if !math.IsNaN(r) { // NaN during the 15-bar warmup
fmt.Printf("tick %2d rsi=%.4f\n", i+1, r)
}
}
// 2. Batch: one SMA(3) call over five prices writes NaN at warmup.
sma, _ := wickra.NewSma(3)
defer sma.Close()
out := sma.Batch([]float64{1, 2, 3, 4, 5})
// out -> { NaN, NaN, 2.0, 3.0, 4.0 }
_ = out
}The first RSI value lands on tick 15. Batch output is bit-for-bit identical to feeding the same inputs through Update one at a time.
The opt-in fast batch
Every single-output Batch has a BatchInto(dst, ...) form that writes into a slice you reuse (destination first, as copy does), and a BatchFast / BatchFastInto twin; MACD, MacdFix and Bollinger Bands have a record-slice BatchFast:
out := make([]float64, len(prices))
sma, _ := wickra.NewSma(20)
defer sma.Close()
sma.BatchInto(out, prices) // exact, no allocation
ema, _ := wickra.NewEma(20)
defer ema.Close()
fast := ema.BatchFast(prices) // or ema.BatchFastInto(out, prices)The fast batch runs a SIMD kernel where the indicator has one (moving averages, RSI, ATR, MACD and MACDFIX, Bollinger Bands, the Chaikin oscillator, skewness, Pearson correlation and more). The kernel reassociates the arithmetic, so each value agrees with the exact batch to within a few units in the last place rather than bit for bit; NaN placement and length are identical, and the result is the same on every platform. Where an indicator has no kernel, the fast batch is the exact batch. Keep the exact batch wherever you compare against streaming bit for bit; reach for the fast one when throughput is the point. See Streaming vs Batch.
Multi-output indicators
Indicators with several outputs (MACD, Bollinger, ADX, …) return a value plus a bool — false while warming up, true once a value is ready:
macd, _ := wickra.NewMacdIndicator(12, 26, 9)
defer macd.Close()
for _, price := range feed {
if m, ok := macd.Update(price); ok {
fmt.Printf("macd=%.4f signal=%.4f hist=%.4f\n", m.Macd, m.Signal, m.Histogram)
}
}Candle-input indicators (ATR, ADX, OBV, …) take the OHLCV fields plus a timestamp, e.g. atr.Update(open, high, low, close, volume, timestamp).
A deeper example
examples/go/backtest runs a basket of indicators over an OHLCV series; the examples/go/ directory also has a multi-indicator streaming demo, multi-timeframe resampling, a goroutine fan-out, three strategy examples, and Binance fetch/live examples. Build and stage the C ABI once, then run any of them:
cargo build -p wickra-c --release
cp target/release/libwickra.so bindings/go/lib/ # .dylib on macOS, wickra.dll on Windows
cd examples/go && go run ./streamingSee also
- Quickstart: C — the C ABI hub the Go binding links against.
- Streaming vs Batch — the
batch == repeated updatecontract that holds across every binding. - Indicators overview — the full catalogue.
- Source: https://github.com/wickra-lib/wickra