移植 A_Share_DP 引擎;本地缓存与 60s tip;月线由日线 UTC 聚合;不碰主站 analyze/缠论叠层。 Co-authored-by: Cursor <cursoragent@cursor.com>
67 lines
2.6 KiB
Python
67 lines
2.6 KiB
Python
"""Decision engine MTF gate tests (ported semantics)."""
|
|
|
|
from crypto_wyckoff.domain_models import (
|
|
DecisionSignal,
|
|
EngineResult,
|
|
WyckoffCycle,
|
|
WyckoffEvent,
|
|
WyckoffPhase,
|
|
)
|
|
from crypto_wyckoff.decision import DecisionEngine
|
|
|
|
|
|
def _er(name, payload, score=70, confidence=70):
|
|
return EngineResult(name=name, score=score, confidence=confidence, payload=payload)
|
|
|
|
|
|
def test_monthly_distribution_daily_spring_is_watch():
|
|
eng = DecisionEngine()
|
|
monthly = _er("Cycle", {"cycle": WyckoffCycle.DISTRIBUTION.value, "trend_score": 40}, score=40)
|
|
weekly_c = _er("Cycle", {"cycle": WyckoffCycle.ACCUMULATION.value, "trend_score": 70}, score=70)
|
|
weekly_p = _er(
|
|
"Phase",
|
|
{"phase": WyckoffPhase.B.value, "cycle": WyckoffCycle.ACCUMULATION.value, "structure_score": 65},
|
|
score=65,
|
|
)
|
|
weekly_e = _er("Event", {"current_event": WyckoffEvent.ST.value, "recent_events": ["SC", "AR", "ST"]}, score=60)
|
|
daily_e = _er(
|
|
"Event",
|
|
{"current_event": WyckoffEvent.SPRING.value, "recent_events": ["SC", "AR", "ST", "Spring"], "entry_score": 92},
|
|
score=92,
|
|
confidence=92,
|
|
)
|
|
daily_s = _er("Signal", {"signal_label": "Spring", "current_event": "Spring"}, confidence=92, score=92)
|
|
out = eng.run(monthly, weekly_c, weekly_p, weekly_e, daily_e, daily_s)
|
|
assert out.payload["decision_signal"] == DecisionSignal.WATCH.value
|
|
assert out.payload["d_event"] == WyckoffEvent.SPRING.value
|
|
|
|
|
|
def test_bull_alignment_can_strong_buy():
|
|
eng = DecisionEngine()
|
|
monthly = _er("Cycle", {"cycle": WyckoffCycle.MARKUP.value, "trend_score": 90}, score=90, confidence=90)
|
|
weekly_c = _er("Cycle", {"cycle": WyckoffCycle.ACCUMULATION.value, "trend_score": 85}, score=85, confidence=85)
|
|
weekly_p = _er(
|
|
"Phase",
|
|
{"phase": WyckoffPhase.D.value, "cycle": WyckoffCycle.ACCUMULATION.value, "structure_score": 88},
|
|
score=88,
|
|
confidence=88,
|
|
)
|
|
weekly_e = _er("Event", {"current_event": WyckoffEvent.SOS.value, "recent_events": ["SOS"]}, score=85, confidence=85)
|
|
daily_e = _er(
|
|
"Event",
|
|
{
|
|
"current_event": WyckoffEvent.SPRING.value,
|
|
"recent_events": ["SC", "AR", "ST", "Spring", "Test"],
|
|
"active_events": ["SC", "AR", "ST", "Spring"],
|
|
"entry_score": 92,
|
|
},
|
|
score=92,
|
|
confidence=92,
|
|
)
|
|
daily_s = _er("Signal", {"signal_label": "Spring"}, confidence=92, score=92)
|
|
out = eng.run(monthly, weekly_c, weekly_p, weekly_e, daily_e, daily_s)
|
|
assert out.payload["decision_signal"] in (
|
|
DecisionSignal.STRONG_BUY.value,
|
|
DecisionSignal.BUY.value,
|
|
)
|