feat(cfo): add Chande Forecast Oscillator
100 * (close - LinReg(close, period)) / close. Positive when close overshoots the linear forecast, negative when it undershoots. Holds the previous value if the close is zero (percentage form undefined). Single param period (default 14). Touchpoints: cfo.rs + mod.rs + lib.rs re-export, PyCfo + __init__.py + test_new_indicators SCALAR + test_known_values linear reference, CfoNode + index.d.ts/index.js + indicators.test.js factory + reference, WasmCfo via scalar macro, scalar-fuzz target, README + CHANGELOG.
This commit is contained in:
@@ -76,6 +76,12 @@ def test_awesome_oscillator_histogram_flat_series_converges_to_zero():
|
||||
np.testing.assert_allclose(out[6:], 0.0, atol=1e-12)
|
||||
|
||||
|
||||
def test_cfo_perfect_linear_series_yields_zero():
|
||||
# LinReg of a perfectly linear series fits exactly, so CFO = 0 after warmup.
|
||||
out = ta.CFO(5).batch(np.arange(1.0, 21.0, dtype=np.float64) * 2.0)
|
||||
np.testing.assert_allclose(out[4:], 0.0, atol=1e-9)
|
||||
|
||||
|
||||
def test_apo_constant_series_converges_to_zero():
|
||||
# Both EMAs reproduce a constant exactly, so APO = 0 after warmup.
|
||||
out = ta.APO(3, 5).batch(np.full(30, 42.0, dtype=np.float64))
|
||||
|
||||
@@ -52,6 +52,7 @@ SCALAR = [
|
||||
(ta.StochRSI, (14, 14)),
|
||||
(ta.PPO, (12, 26)),
|
||||
(ta.APO, (12, 26)),
|
||||
(ta.CFO, (14,)),
|
||||
(ta.DPO, (20,)),
|
||||
(ta.Coppock, (14, 11, 10)),
|
||||
(ta.StdDev, (20,)),
|
||||
|
||||
Reference in New Issue
Block a user