feat: show FIP path-smoothness in ticker technicals
Display-only Da/Gurun/Warachka information discreteness on the ticker indicator panel. Shared compute with the backtest harness; not wired into gate or rank.
This commit is contained in:
@@ -8,6 +8,7 @@ from app.services.indicator_service import (
|
||||
compute_atr,
|
||||
compute_ema,
|
||||
compute_ema_cross,
|
||||
compute_fip_id,
|
||||
compute_pivot_points,
|
||||
compute_rsi,
|
||||
compute_volume_profile,
|
||||
@@ -262,3 +263,31 @@ class TestComputeEMACross:
|
||||
closes = _rising_closes(30)
|
||||
with pytest.raises(ValidationError, match="EMA Cross requires"):
|
||||
compute_ema_cross(closes, short_period=20, long_period=50)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# FIP ID (display / research context — not a gate)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class TestComputeFipId:
|
||||
def test_steady_climber_is_continuous(self):
|
||||
# Many small up days → low (negative) ID for a positive-return path.
|
||||
closes = [100.0 * (1.002 ** i) for i in range(280)]
|
||||
result = compute_fip_id(closes)
|
||||
assert result["fip_id"] < 0
|
||||
assert result["path"] == "continuous"
|
||||
assert result["display_only"] is True
|
||||
assert 0 <= result["score"] <= 100
|
||||
|
||||
def test_jump_then_flat_is_more_discrete_than_steady(self):
|
||||
steady = [100.0 * (1.002 ** i) for i in range(280)]
|
||||
jumpy = [100.0] * 252
|
||||
jumpy.append(100.0 * 1.5)
|
||||
jumpy.extend([100.0 * 1.5] * 40)
|
||||
id_steady = compute_fip_id(steady)["fip_id"]
|
||||
id_jumpy = compute_fip_id(jumpy)["fip_id"]
|
||||
assert id_jumpy > id_steady
|
||||
|
||||
def test_insufficient_data_raises(self):
|
||||
with pytest.raises(ValidationError, match="FIP ID requires"):
|
||||
compute_fip_id(_rising_closes(50))
|
||||
|
||||
Reference in New Issue
Block a user