docs(wiki): add Cookbook, TA-Lib migration table and FAQ
Three content gaps in the wiki: there was no migration story for users porting from TA-Lib, no strategy cookbook, and no FAQ. Add all three as self-contained pages and link them from Home.md's "Wiki contents". * docs/wiki/TA-Lib-Migration.md — full one-to-one mapping table from every common talib.X(...) call to the equivalent Wickra expression, plus a "what Wickra has that TA-Lib does not" / "what TA-Lib has that Wickra does not (yet)" delta. * docs/wiki/Cookbook.md — seven concrete strategy recipes (RSI mean reversion, MACD histogram crossover, Bollinger breakout, ADX-gated trend, multi-timeframe confirmation, SuperTrend trailing stop, Chain<EMA, RSI>) with Rust or Python snippets. * docs/wiki/FAQ.md — common questions on warmup, NaN handling, thread safety, installation, performance and comparing Wickra to TA-Lib / pandas-ta / talipp / finta. Also extend the [Unreleased] CHANGELOG entry that records the examples/<lang>/ restructure with the wiki additions; Home.md gains three new bullets under "Wiki contents".
This commit is contained in:
@@ -66,6 +66,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
- The indicator benchmarks (`crates/wickra/benches/indicators.rs`) now run
|
||||
against the checked-in real BTCUSDT 1-minute dataset instead of a synthetic
|
||||
price series.
|
||||
- Every language's examples now live under a uniform `examples/<lang>/`
|
||||
tree: Rust moved into a new `examples/rust/` workspace member crate
|
||||
(`wickra-examples`, run via `cargo run -p wickra-examples --bin <name>`),
|
||||
Node into `examples/node/` with its own `package.json` linking `wickra` via
|
||||
`file:../../bindings/node`, and the WASM browser demo into
|
||||
`examples/wasm/`. The bundled BTCUSDT datasets move alongside them at
|
||||
`examples/data/`. Six new examples close the cross-language parity matrix:
|
||||
streaming demos for Python and Rust; multi-timeframe and parallel-assets
|
||||
demos for both Rust and Node.
|
||||
|
||||
### Fixed
|
||||
- `Timeframe::floor` no longer overflows for timestamps near `i64::MIN`.
|
||||
|
||||
@@ -0,0 +1,185 @@
|
||||
# Cookbook
|
||||
|
||||
Practical strategy recipes built on Wickra's streaming indicators. Each
|
||||
recipe is a small, runnable snippet you can drop into a backtest loop or a
|
||||
live trading bot. Both paths share the same indicator state, so the same
|
||||
recipe works in either mode — see [Streaming vs Batch](Streaming-vs-Batch.md).
|
||||
|
||||
## 1. RSI mean reversion
|
||||
|
||||
Enter when RSI crosses out of an extreme; flatten when it returns to
|
||||
neutral.
|
||||
|
||||
```python
|
||||
import wickra as ta
|
||||
|
||||
rsi = ta.RSI(14)
|
||||
position = 0 # 0 flat, +1 long, −1 short
|
||||
for price in price_feed:
|
||||
v = rsi.update(price)
|
||||
if v is None:
|
||||
continue
|
||||
if position == 0 and v < 30:
|
||||
position = 1
|
||||
print(f"BUY at {price:.2f}")
|
||||
elif position == 1 and v > 50:
|
||||
position = 0
|
||||
print(f"EXIT long at {price:.2f}")
|
||||
elif position == 0 and v > 70:
|
||||
position = -1
|
||||
print(f"SHORT at {price:.2f}")
|
||||
elif position == -1 and v < 50:
|
||||
position = 0
|
||||
print(f"COVER short at {price:.2f}")
|
||||
```
|
||||
|
||||
## 2. MACD histogram crossover
|
||||
|
||||
Trade in the direction of a MACD-histogram sign change. Zero-crossings of
|
||||
the histogram (`MACD − signal`) are the canonical trigger and lead the
|
||||
slower MACD-vs-signal line cross.
|
||||
|
||||
```rust
|
||||
use wickra::{Indicator, MacdIndicator};
|
||||
|
||||
let mut macd = MacdIndicator::classic(); // (12, 26, 9)
|
||||
let mut last_hist: Option<f64> = None;
|
||||
for &price in &prices {
|
||||
if let Some(v) = macd.update(price) {
|
||||
if let Some(prev) = last_hist {
|
||||
if prev <= 0.0 && v.histogram > 0.0 {
|
||||
println!("BUY: MACD histogram turned positive at {price:.2}");
|
||||
} else if prev >= 0.0 && v.histogram < 0.0 {
|
||||
println!("SELL: MACD histogram turned negative at {price:.2}");
|
||||
}
|
||||
}
|
||||
last_hist = Some(v.histogram);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 3. Bollinger band breakout
|
||||
|
||||
Trade in the direction of a band-piercing close, taking the bands as a
|
||||
dynamic support / resistance.
|
||||
|
||||
```python
|
||||
import wickra as ta
|
||||
|
||||
bb = ta.BollingerBands(20, 2.0)
|
||||
for price in price_feed:
|
||||
out = bb.update(price)
|
||||
if out is None:
|
||||
continue
|
||||
upper, _middle, lower, _stddev = out
|
||||
if price > upper:
|
||||
print(f"BREAKOUT (long): {price:.2f} > upper {upper:.2f}")
|
||||
elif price < lower:
|
||||
print(f"BREAKOUT (short): {price:.2f} < lower {lower:.2f}")
|
||||
```
|
||||
|
||||
## 4. ADX-gated trend filter
|
||||
|
||||
Take EMA-crossover signals only when ADX confirms a trend is in place.
|
||||
This is a textbook way to silence whipsaws in a ranging market.
|
||||
|
||||
```python
|
||||
import wickra as ta
|
||||
|
||||
ema_fast = ta.EMA(20)
|
||||
ema_slow = ta.EMA(50)
|
||||
adx = ta.ADX(14)
|
||||
|
||||
for high, low, close in candle_feed:
|
||||
f = ema_fast.update(close)
|
||||
s = ema_slow.update(close)
|
||||
a = adx.update(high, low, close) # (plus_di, minus_di, adx) or None
|
||||
if f is None or s is None or a is None:
|
||||
continue
|
||||
_, _, adx_v = a
|
||||
if adx_v < 25:
|
||||
continue # ranging market — skip
|
||||
if f > s:
|
||||
print(f"LONG: EMA20 > EMA50, ADX={adx_v:.1f}")
|
||||
elif f < s:
|
||||
print(f"SHORT: EMA20 < EMA50, ADX={adx_v:.1f}")
|
||||
```
|
||||
|
||||
## 5. Multi-timeframe confirmation
|
||||
|
||||
Only take a 1-minute entry when the 1-hour trend agrees. With Wickra you
|
||||
keep one streaming indicator per timeframe and feed each only the candles
|
||||
that belong to it. `wickra-data`'s [`Resampler`](Data-Layer.md) rolls one
|
||||
candle stream up into a coarser one; the canonical example is
|
||||
`examples/rust/src/bin/multi_timeframe.rs`.
|
||||
|
||||
```rust
|
||||
use wickra::{Indicator, Rsi};
|
||||
|
||||
let mut rsi_1m = Rsi::new(14)?;
|
||||
let mut rsi_1h = Rsi::new(14)?;
|
||||
|
||||
for candle in one_min_candles {
|
||||
let fast = rsi_1m.update(candle.close);
|
||||
|
||||
if candle.is_hour_close {
|
||||
let slow = rsi_1h.update(candle.close);
|
||||
if let (Some(f), Some(s)) = (fast, slow) {
|
||||
if f > 70.0 && s > 50.0 {
|
||||
println!("strong overbought (1m {f:.1} / 1h {s:.1})");
|
||||
} else if f < 30.0 && s < 50.0 {
|
||||
println!("strong oversold (1m {f:.1} / 1h {s:.1})");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 6. SuperTrend trailing stop
|
||||
|
||||
`SuperTrend` is a single-line ATR-banded trailing stop with explicit flip
|
||||
logic — drop it into a long-only loop to manage exits:
|
||||
|
||||
```python
|
||||
import wickra as ta
|
||||
|
||||
st = ta.SuperTrend(10, 3.0)
|
||||
position = 0 # 0 flat, +1 long
|
||||
for high, low, close in candle_feed:
|
||||
out = st.update(high, low, close)
|
||||
if out is None:
|
||||
continue
|
||||
value, direction = out
|
||||
if direction > 0 and position == 0:
|
||||
position = 1
|
||||
print(f"BUY at {close:.2f}, stop={value:.2f}")
|
||||
elif direction < 0 and position == 1:
|
||||
position = 0
|
||||
print(f"EXIT at {close:.2f} (SuperTrend flipped)")
|
||||
```
|
||||
|
||||
## 7. Chained indicators
|
||||
|
||||
When you want an indicator computed *over the output of another*, use the
|
||||
Rust `Chain` combinator. The chain itself implements `Indicator`, so you
|
||||
can nest, stack, and feed it into anything that takes an indicator.
|
||||
|
||||
```rust
|
||||
use wickra::{BatchExt, Chain, Ema, Rsi};
|
||||
|
||||
// RSI(7) of EMA(14)-smoothed closes.
|
||||
let mut chain = Chain::new(Ema::new(14)?, Rsi::new(7)?);
|
||||
let out: Vec<Option<f64>> = chain.batch(&prices);
|
||||
```
|
||||
|
||||
See [Indicator Chaining](Indicator-Chaining.md) for the chained-warmup rule
|
||||
and three-stage examples.
|
||||
|
||||
## See also
|
||||
|
||||
- [Indicators Overview](Indicators-Overview.md) — pick the right indicator
|
||||
for the question you are asking.
|
||||
- [Streaming vs Batch](Streaming-vs-Batch.md) — why these recipes work
|
||||
bit-identically in both modes.
|
||||
- [Data Layer](Data-Layer.md) — `Resampler` and the bundled BTCUSDT
|
||||
datasets for live multi-timeframe work.
|
||||
@@ -0,0 +1,123 @@
|
||||
# FAQ
|
||||
|
||||
Frequently asked questions about Wickra. If yours is not here, check the
|
||||
[issue tracker](https://github.com/kingchenc/wickra/issues) or open a new
|
||||
issue.
|
||||
|
||||
## Will batch and streaming produce the same result?
|
||||
|
||||
Yes — bit-identical, by construction. `batch(prices)` is a one-line wrapper
|
||||
that calls `update(p)` for every `p` in the input. The same unit test —
|
||||
`batch_equals_streaming` — pins this for every indicator. See
|
||||
[Streaming vs Batch](Streaming-vs-Batch.md) for the full contract.
|
||||
|
||||
## What does `warmup_period()` mean?
|
||||
|
||||
It's the number of inputs an indicator needs before it emits its first
|
||||
non-`None` value. For RSI(14) that's 15 (14 diffs plus the seed); for
|
||||
SMA(20) it's 20; for MACD(12, 26, 9) it's 34 (`slow + signal − 1`). After
|
||||
warmup the indicator never goes back to `None`. The complete table lives
|
||||
at [Warmup Periods](Warmup-Periods.md).
|
||||
|
||||
## Why am I getting `None` / `NaN` for the first N values?
|
||||
|
||||
That's the warmup. Use `is_ready()` (or the corresponding `isReady()` in
|
||||
Node, `is_ready()` in Python) to gate your code on "do I have a real
|
||||
value yet?" rather than counting inputs yourself:
|
||||
|
||||
```python
|
||||
import wickra as ta
|
||||
rsi = ta.RSI(14)
|
||||
for price in feed:
|
||||
rsi.update(price)
|
||||
if rsi.is_ready():
|
||||
...
|
||||
```
|
||||
|
||||
## Which indicator should I use for X?
|
||||
|
||||
A short cheat-sheet (full version at the bottom of
|
||||
[Indicators Overview](Indicators-Overview.md)):
|
||||
|
||||
- **trend direction** → MA family (`SMA`, `EMA`, `HMA`, `T3`, `KAMA`)
|
||||
- **trend strength** → `ADX`, `ChoppinessIndex`, `VerticalHorizontalFilter`
|
||||
- **overbought / oversold** → `RSI`, `Stochastic`, `Williams %R`, `MFI`
|
||||
- **volatility** → `ATR`, `TrueRange`, `ChaikinVolatility`, `StdDev`
|
||||
- **breakout level** → `Donchian`, `BollingerBands`
|
||||
- **trailing stop** → `PSAR`, `SuperTrend`, `ChandelierExit`,
|
||||
`AtrTrailingStop`
|
||||
- **volume confirmation** → `OBV`, `ChaikinMoneyFlow`, `VWAP`
|
||||
|
||||
## Is a single indicator instance thread-safe?
|
||||
|
||||
No. `update` mutates state, so a single instance must not be shared across
|
||||
threads. Each thread should own its own indicator. For multi-asset
|
||||
parallelism, the Rust crate provides `BatchExt::batch_parallel`, which
|
||||
fans out over many series each with its own fresh instance behind the
|
||||
default `parallel` feature (rayon). Node's `worker_threads` gives the
|
||||
same shape from JavaScript — see `examples/node/parallel_assets.js`.
|
||||
|
||||
## Does Wickra need a system compiler to install?
|
||||
|
||||
No. Every published wheel (PyPI), npm package, and crate ships pre-built
|
||||
artefacts. `pip install wickra` and `npm install wickra` are
|
||||
no-prerequisite installs on Linux, macOS, and Windows x64 / arm64. The
|
||||
only time you need a toolchain is when you are building Wickra from
|
||||
source.
|
||||
|
||||
## How do I handle non-finite inputs (NaN / Inf)?
|
||||
|
||||
The scalar indicators (`SMA`, `EMA`, `WMA`, `RSI`, `ROC`, …) return the
|
||||
most recent valid value when fed a non-finite input, leaving their state
|
||||
untouched. That lets a missing price in your feed pass through without
|
||||
poisoning the rest of the series. `ATR` and the volume-aware indicators
|
||||
reject non-finite volume at the `Candle::new` boundary, so an aggregator
|
||||
that overflows surfaces an error instead of producing a corrupted candle
|
||||
(see [Data Layer](Data-Layer.md)).
|
||||
|
||||
## How fast is Wickra?
|
||||
|
||||
The streaming path is O(1) per `update` — the per-tick cost does not grow
|
||||
with how much history you have already seen. The README has a benchmark
|
||||
table comparing Wickra against `finta` and `talipp`; the gap is roughly
|
||||
10–30× on batch workloads and ~17× per tick on a streaming RSI seeded
|
||||
with 2 000 historical bars.
|
||||
|
||||
## How do I add a custom indicator?
|
||||
|
||||
Implement the `Indicator` trait in
|
||||
`crates/wickra-core/src/indicators/<your_name>.rs`, wire it through the
|
||||
bindings, and add reference-value plus `batch == streaming` equivalence
|
||||
tests. The complete how-to and the project's standards are in
|
||||
[CONTRIBUTING.md](https://github.com/kingchenc/wickra/blob/main/CONTRIBUTING.md).
|
||||
|
||||
## Where do I get historical OHLCV data to test with?
|
||||
|
||||
The repo ships seven real BTCUSDT datasets at
|
||||
`examples/data/btcusdt-{1m,5m,15m,1h,12h,1d,1month}.csv` (50 000 / 10 000 /
|
||||
10 000 / 10 000 / 5 000 / 3 200 / 105 candles respectively). Refresh them
|
||||
with the latest market history via
|
||||
`cargo run -p wickra-examples --bin fetch_btcusdt`. See
|
||||
[Data Layer](Data-Layer.md) for the full story.
|
||||
|
||||
## How is Wickra different from TA-Lib / pandas-ta / talipp?
|
||||
|
||||
* TA-Lib and pandas-ta are batch-only — every new tick triggers a full
|
||||
recomputation. Wickra updates in O(1). The numerical results are the
|
||||
same; the speed gap shows up in live trading and large backtests.
|
||||
* talipp is streaming-first like Wickra but Python-only and slower per
|
||||
update.
|
||||
* `finta` is batch-only and pure-Python.
|
||||
* `ta-lib-python` and TA-Lib both require C build tooling on Windows;
|
||||
Wickra ships pre-built native wheels.
|
||||
|
||||
See the [TA-Lib Migration](TA-Lib-Migration.md) guide for a direct
|
||||
function-by-function mapping.
|
||||
|
||||
## See also
|
||||
|
||||
- [Home](Home.md) — wiki index.
|
||||
- [Streaming vs Batch](Streaming-vs-Batch.md) — the central design idea.
|
||||
- [TA-Lib Migration](TA-Lib-Migration.md) — function-by-function mapping
|
||||
table.
|
||||
- [Cookbook](Cookbook.md) — practical strategy recipes.
|
||||
@@ -62,6 +62,14 @@ Release notes and tagged builds:
|
||||
- [Indicator Chaining](Indicator-Chaining.md) — `Chain::new(first, second)`
|
||||
and `.then(third)`, with a worked EMA(14) → RSI(7) example and the rule
|
||||
for stacked warmups.
|
||||
- [Cookbook](Cookbook.md) — copy-paste strategy recipes built on streaming
|
||||
indicators (RSI mean reversion, MACD crossover, Bollinger breakout,
|
||||
ADX-gated trend, multi-timeframe, SuperTrend trailing stop).
|
||||
- [TA-Lib Migration](TA-Lib-Migration.md) — function-by-function mapping
|
||||
table from TA-Lib's `talib.X(...)` calls to the equivalent Wickra
|
||||
expressions.
|
||||
- [FAQ](FAQ.md) — quick answers to the most common questions about
|
||||
warmup, NaN handling, thread safety, and the streaming-vs-batch contract.
|
||||
|
||||
### Indicator reference
|
||||
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
# Migrating from TA-Lib
|
||||
|
||||
A quick lookup table for users porting code from TA-Lib (the C library, or
|
||||
its Python binding `talib`) to Wickra. Replace `talib.X(...)` with the
|
||||
matching Wickra expression and the rest of your code keeps working.
|
||||
|
||||
## Argument-order conventions
|
||||
|
||||
The two libraries take the same numeric arguments but differ in shape:
|
||||
|
||||
- **TA-Lib (Python)** is functional and pass-by-array. `talib.RSI(close, n)`
|
||||
is a *recompute-everything* call: it walks the entire `close` series each
|
||||
time, even when you only want the latest value.
|
||||
- **Wickra** is a state machine. `wickra.RSI(n)` returns an *instance*; you
|
||||
call `.batch(close)` for the full series or `.update(price)` one price at
|
||||
a time. The same instance, fed one price per minute, drives a live
|
||||
trading bot — see [Streaming vs Batch](Streaming-vs-Batch.md).
|
||||
|
||||
Multi-output indicators (MACD, Bollinger Bands, Stochastic, ADX, Aroon,
|
||||
Keltner, Donchian, SuperTrend, …) return a tuple from `update` and a 2-D
|
||||
NumPy array (one column per output) from `batch`.
|
||||
|
||||
## Mapping table
|
||||
|
||||
| TA-Lib | Wickra (Python) |
|
||||
|-----------------------------------------------------|--------------------------------------------------------------------------------------------------|
|
||||
| `talib.SMA(close, n)` | `wickra.SMA(n).batch(close)` |
|
||||
| `talib.EMA(close, n)` | `wickra.EMA(n).batch(close)` |
|
||||
| `talib.WMA(close, n)` | `wickra.WMA(n).batch(close)` |
|
||||
| `talib.DEMA(close, n)` | `wickra.DEMA(n).batch(close)` |
|
||||
| `talib.TEMA(close, n)` | `wickra.TEMA(n).batch(close)` |
|
||||
| `talib.KAMA(close, n)` | `wickra.KAMA(n).batch(close)` |
|
||||
| `talib.T3(close, n, vfactor)` | `wickra.T3(n, vfactor).batch(close)` |
|
||||
| `talib.RSI(close, n)` | `wickra.RSI(n).batch(close)` |
|
||||
| `talib.STOCH(high, low, close, k, smooth, d)` | `wickra.Stochastic(k_period, d_period).batch(high, low, close)` → shape `(n, 2)` |
|
||||
| `talib.STOCHRSI(close, n, k, d)` | `wickra.StochRSI(rsi_period, stoch_period).batch(close)` |
|
||||
| `talib.CCI(high, low, close, n)` | `wickra.CCI(n).batch(high, low, close)` |
|
||||
| `talib.WILLR(high, low, close, n)` | `wickra.WilliamsR(n).batch(high, low, close)` |
|
||||
| `talib.MFI(high, low, close, volume, n)` | `wickra.MFI(n).batch(high, low, close, volume)` |
|
||||
| `talib.ROC(close, n)` | `wickra.ROC(n).batch(close)` |
|
||||
| `talib.MOM(close, n)` | `wickra.MOM(n).batch(close)` |
|
||||
| `talib.CMO(close, n)` | `wickra.CMO(n).batch(close)` |
|
||||
| `talib.MACD(close, fast, slow, signal)` | `wickra.MACD(fast, slow, signal).batch(close)` → shape `(n, 3)` |
|
||||
| `talib.PPO(close, fast, slow)` | `wickra.PPO(fast, slow).batch(close)` |
|
||||
| `talib.APO(close, fast, slow)` | `wickra.PPO(fast, slow).batch(close)` *(PPO is APO scaled to percent)* |
|
||||
| `talib.TRIX(close, n)` | `wickra.TRIX(n).batch(close)` |
|
||||
| `talib.ADX(high, low, close, n)` | `wickra.ADX(n).batch(high, low, close)` → shape `(n, 3)` (`+DI`, `−DI`, `ADX`) |
|
||||
| `talib.AROON(high, low, n)` | `wickra.Aroon(n).batch(high, low, close)` → shape `(n, 2)` |
|
||||
| `talib.AROONOSC(high, low, n)` | `wickra.AroonOscillator(n).batch(high, low, close)` |
|
||||
| `talib.BBANDS(close, n, dev_up, dev_dn)` | `wickra.BollingerBands(n, multiplier).batch(close)` → shape `(n, 4)` (`upper`, `middle`, `lower`, `stddev`) |
|
||||
| `talib.ATR(high, low, close, n)` | `wickra.ATR(n).batch(high, low, close)` |
|
||||
| `talib.NATR(high, low, close, n)` | `wickra.NATR(n).batch(high, low, close)` |
|
||||
| `talib.STDDEV(close, n)` | `wickra.StdDev(n).batch(close)` |
|
||||
| `talib.TRANGE(high, low, close)` | `wickra.TrueRange().batch(high, low, close)` |
|
||||
| `talib.OBV(close, volume)` | `wickra.OBV().batch(close, volume)` |
|
||||
| `talib.AD(high, low, close, volume)` | `wickra.ADL().batch(high, low, close, volume)` |
|
||||
| `talib.ADOSC(high, low, close, volume, fast, slow)` | `wickra.ChaikinOscillator(fast, slow).batch(high, low, close, volume)` |
|
||||
| `talib.SAR(high, low, accel, max)` | `wickra.PSAR(accel_start, accel_step, accel_max).batch(high, low, close)` |
|
||||
| `talib.LINEARREG(close, n)` | `wickra.LinearRegression(n).batch(close)` |
|
||||
| `talib.LINEARREG_SLOPE(close, n)` | `wickra.LinRegSlope(n).batch(close)` |
|
||||
| `talib.LINEARREG_ANGLE(close, n)` | `wickra.LinRegAngle(n).batch(close)` |
|
||||
| `talib.TYPPRICE(high, low, close)` | `wickra.TypicalPrice().batch(high, low, close)` |
|
||||
| `talib.MEDPRICE(high, low)` | `wickra.MedianPrice().batch(high, low, close)` |
|
||||
| `talib.WCLPRICE(high, low, close)` | `wickra.WeightedClose().batch(high, low, close)` |
|
||||
| `talib.ULTOSC(high, low, close, p1, p2, p3)` | `wickra.UltimateOscillator(p1, p2, p3).batch(high, low, close)` |
|
||||
|
||||
## What Wickra has that TA-Lib does not
|
||||
|
||||
- **Trailing stops** — `SuperTrend`, `ChandelierExit`, `ChandeKrollStop`,
|
||||
`AtrTrailingStop` (TA-Lib only has `SAR`).
|
||||
- **Volume oscillators** — `ChaikinMoneyFlow`, `ForceIndex`,
|
||||
`EaseOfMovement`, `VolumePriceTrend`, plus the windowed `RollingVwap`.
|
||||
- **Other modern indicators** — `Choppiness Index`, `Vertical Horizontal
|
||||
Filter`, `Coppock`, `PMO`, `Z-Score`, `Mass Index`, `Vortex`, `TSI`,
|
||||
`Smma`, `Trima`, `Zlema`, `Vwma`, `BollingerBandwidth`, `%B`.
|
||||
|
||||
## What TA-Lib has that Wickra does not (yet)
|
||||
|
||||
- Pattern recognition (`CDL*` candlestick patterns).
|
||||
- Hilbert-transform-based indicators (`HT_DCPERIOD`, `HT_TRENDLINE`, …).
|
||||
- A few trivial transforms (`AVGPRICE`, `MIDPOINT`, `MIDPRICE`).
|
||||
|
||||
If you need one of these,
|
||||
[open an issue](https://github.com/kingchenc/wickra/issues) — most are
|
||||
short additions on top of the existing engine.
|
||||
|
||||
## See also
|
||||
|
||||
- [Indicators Overview](Indicators-Overview.md) — every Wickra indicator,
|
||||
organised by family.
|
||||
- [Quickstart: Python](Quickstart-Python.md) — concrete Python usage.
|
||||
- [Streaming vs Batch](Streaming-vs-Batch.md) — why Wickra is fast at
|
||||
per-tick updates while TA-Lib re-computes the whole series.
|
||||
Reference in New Issue
Block a user