Skip to content

Fix CCI, DPO, Ehlers Fisher, Connors RSI and STC to match their definitions - #537

Merged
cinar merged 6 commits into
masterfrom
fix-talib-bugs
Nov 12, 2026
Merged

cinar merged 6 commits into
masterfrom
fix-talib-bugs

Conversation

@cinar

@cinar cinar commented Nov 12, 2026

Copy link
Copy Markdown
Owner

Fixes five indicators that differed from their published definitions, as found by the TA-Lib comparison in #536. Each now matches TA-Lib 0.8.3 on both reference datasets, and its skip: entry in internal/talibcompat is removed.

Commit Issue Change First value
CCI Fixes #521 Mean deviation measures every typical price in the window against the current SMA, not each bar's own SMA bar 38 → 19
DPO Fixes #522 Close[t−k] − SMA[t] instead of Close[t] − SMA[t−k] bar 30 → 19
Ehlers Fisher Fixes #523 Drops the extra * 0.5; Value1 is set to ±0.999 once it passes ±0.99 unchanged
Connors RSI Fixes #524 Ranks the ROC against the 100 preceding values, not 99 bar 100 → 101
STC Fixes #525 Exponential smoothing with factor 0.5 after each stochastic pass, instead of SMA(3) bar 71 → 67

Review notes

  • STC API change. The Stochastic and Apo fields are replaced by FastEma and SlowEma. NewStcWithPeriod keeps its signature; DPeriod now sets the smoothing factor 2 / (DPeriod + 1), so the default 3 gives Schaff's 0.5.
  • STC MACD seeding. STC seeds the fast EMA on the slow EMA's first bar, as TA-Lib does. Macd and Apo start the fast EMA earlier (documented in Document smaller TA-Lib differences: EMA seeding, McGinley start, RVI name, VWAP window #535). Without this, STC still differed by about 1.5 points after 200 bars, because the stochastic magnifies small MACD differences. The doc comment notes the difference.
  • Expected values come from TA-Lib. cci.csv, dpo.csv, ehlers_fisher.csv, connors_rsi.csv and the new stc.csv are regenerated from TA-Lib using each file's own inputs, rounded the way helper.RoundDigit rounds. The CCI example strategy's expected actions are regenerated from TA-Lib CCI.
  • Ehlers Fisher hand-computed values. The previous values came from a Python reference with the same extra * 0.5. They are replaced with TA-Lib FISHER output, and a new test covers the clamp in both directions.
  • DPO precision. The test compares at 4 digits, since one bar is exactly −4.195 and 2-digit rounding depends on floating-point error.
  • STC tests. Adds the first STC test that checks values (against TA-Lib STC), plus a flat-input test.
  • Adds the missing copyright header to trend/dpo_test.go.

Testing

fmt, vet, gosec, staticcheck, revive, go test -race over all packages, and gomarkdoc all pass. Coverage of the changed files is unchanged from before.

🤖 Generated with Claude Code

cinar and others added 6 commits November 11, 2026 21:32
The mean deviation compared each typical price with its own bar's SMA
and then averaged with a second SMA. Lambert's definition, and TA-Lib
CCI, compare every typical price in the window with the current SMA.
The idle period drops from 2*Period-2 to Period-1. The expected values
in cci.csv and cci_strategy.csv are regenerated from TA-Lib CCI.

Fixes #521.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DPO computed Price[t] - SMA[t-k]. The definition, and TA-Lib DPO, use
Price[t-k] - SMA[t]. The idle period drops from Period-1+k to
max(Period-1, k). The expected values in dpo.csv are regenerated from
TA-Lib DPO and compared at 4 digits, since 2-digit rounding hits exact
ties with this data.

Fixes #522.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The transform multiplied the log term by an extra 0.5, and clamped
Value1 at 0.999 instead of setting it to 0.999 once it passes 0.99.
Both now follow Ehlers' article and TA-Lib FISHER. The expected values,
including the hand-computed ones, are regenerated from TA-Lib FISHER,
and a new test covers the clamp.

Fixes #523.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
helper.PercentRank(period) ranks against period-1 preceding values, so
Connors RSI ranked against 99. Connors' definition, and TA-Lib CRSI,
use 100. The first value moves from bar 100 to bar 101. The expected
values in connors_rsi.csv are regenerated from TA-Lib CRSI.

Fixes #524.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
STC smoothed each stochastic pass with an SMA(3) %D. Schaff's
definition, and TA-Lib STC, smooth each pass exponentially with a
factor of 0.5, which DPeriod now sets as 2/(DPeriod+1). The MACD's fast
EMA is also seeded on the slow EMA's first bar, as in TA-Lib, since the
stochastic magnifies seeding differences for hundreds of bars.

API: the Stochastic and Apo fields are replaced by FastEma and SlowEma.
The idle period moves from 71 to 67 bars with the defaults. Adds a
value test against TA-Lib STC (stc.csv) and a flat-input test.

Fixes #525.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@cinar
cinar merged commit 5c05d1e into master Nov 12, 2026
5 checks passed
@cinar
cinar deleted the fix-talib-bugs branch November 12, 2026 05:33
@codecov-commenter

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 91.81%. Comparing base (582c563) to head (c7f2b5d).
⚠️ Report is 1 commits behind head on master.

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #537   +/-   ##
=======================================
  Coverage   91.80%   91.81%           
=======================================
  Files         240      240           
  Lines        7835     7843    +8     
=======================================
+ Hits         7193     7201    +8     
- Misses        549      550    +1     
+ Partials       93       92    -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@github-actions github-actions Bot locked and limited conversation to collaborators Nov 12, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

2 participants