Compute technicals
Canonical formulas (no hand-waving)
| Indicator | Definition |
|---|---|
| SMA(n) | Simple moving average of close over n bars |
| EMA(n) | Exponential moving average with α = 2/(n+1) |
| RSI(14) — Wilder | RS = avg_gain_14 / avg_loss_14 (Wilder smoothing, not simple average); RSI = 100 - 100/(1+RS) |
| MACD | EMA(12) − EMA(26); signal = EMA(9) of MACD |
| Bollinger(20, 2) | SMA(20) ± 2 × stddev(20) |
The Wilder smoothing distinction matters — many tutorials use a simple average and get RSI values off by a few points. The first 14 bars use the simple average to seed; from bar 15 onward, each step is (prev * 13 + new) / 14.
Steps
- Validate inputs — frame must have
Close. For volume-based indicators,Volumetoo. - Compute in-place on a copy — never mutate the caller's frame.
- Append columns named exactly per canonical lib conventions (e.g.
RSI_14,SMA_50,SMA_200,MACD,MACD_signal). - NaN for warmup periods — don't forward-fill the first 13 RSI values.
- Test against a known fixture — at least one indicator should match a published value (e.g. RSI of a flat series = 50; RSI of monotonically increasing close → 100).
Failure modes to avoid
- Using simple average instead of Wilder smoothing for RSI.
- Forward-filling warmup NaN — gives the screen false signals at the start of the window.
- Computing RSI on intraday bars but labeling it as daily.
- Adding pandas-ta / ta-lib as a dep for indicators you can write in 15 lines and test.