100 lines
3.7 KiB
Python
100 lines
3.7 KiB
Python
from app.core.strategy_registry import (
|
|
LONG_BOX_RETEST_4H_STRATEGY,
|
|
LONG_COMPRESSION_BREAKOUT_STRATEGY,
|
|
LONG_MOMENTUM_BREAKOUT_STRATEGY,
|
|
LONG_SECOND_WAVE_PULLBACK_STRATEGY,
|
|
SHORT_BREAKDOWN_RETEST_STRATEGY,
|
|
SHORT_WEAK_BOUNCE_FAILURE_STRATEGY,
|
|
)
|
|
from app.strategies.altcoin_breakout import (
|
|
build_compression_breakout_4h_signal,
|
|
build_long_box_retest_4h_signal,
|
|
build_long_momentum_breakout_signal,
|
|
build_long_second_wave_pullback_signal,
|
|
)
|
|
from app.strategies.short_breakdown import build_breakdown_retest_short_1h_signal, build_short_weak_bounce_failure_signal
|
|
|
|
|
|
def test_long_intraday_momentum_requires_current_trigger():
|
|
signal = build_long_momentum_breakout_signal(
|
|
symbol="MOM/USDT",
|
|
result={"score": 8, "signals": ["1H量价齐飞", "15min即刻入场"], "trigger_context": {"current_triggers": ["15m"]}},
|
|
entry_plan={"entry_action": "可即刻买入"},
|
|
)
|
|
missing = build_long_momentum_breakout_signal(
|
|
symbol="MOM/USDT",
|
|
result={"score": 8, "signals": ["1H量价齐飞"]},
|
|
entry_plan={"entry_action": "可即刻买入"},
|
|
)
|
|
|
|
assert signal.to_json_dict()["strategy_code"] == LONG_MOMENTUM_BREAKOUT_STRATEGY
|
|
assert signal.status == "candidate"
|
|
assert missing is None
|
|
|
|
|
|
def test_long_second_wave_pullback_can_wait_for_entry():
|
|
signal = build_long_second_wave_pullback_signal(
|
|
symbol="WAVE/USDT",
|
|
result={"score": 10, "signals": ["24h强势榜", "1H箱体突破回踩", "量价齐飞"]},
|
|
entry_plan={"entry_action": "等回踩"},
|
|
)
|
|
|
|
assert signal.to_json_dict()["strategy_code"] == LONG_SECOND_WAVE_PULLBACK_STRATEGY
|
|
assert signal.status == "candidate"
|
|
|
|
|
|
def test_long_compression_breakout_requires_current_entry_context():
|
|
signal = build_compression_breakout_4h_signal(
|
|
symbol="COMP/USDT",
|
|
result={"score": 9, "signals": ["4H静K蓄力", "压缩突破", "15min即刻入场"], "trigger_context": {"current_triggers": ["15m"]}},
|
|
entry_plan={"entry_action": "可即刻买入"},
|
|
)
|
|
|
|
assert signal.to_json_dict()["strategy_code"] == LONG_COMPRESSION_BREAKOUT_STRATEGY
|
|
assert signal.status == "candidate"
|
|
|
|
|
|
def test_long_box_retest_4h_keeps_pullback_waiting_signal():
|
|
signal = build_long_box_retest_4h_signal(
|
|
symbol="BOX/USDT",
|
|
result={"score": 9, "signals": ["4H箱体突破回踩", "15min回踩确认"]},
|
|
entry_plan={"entry_action": "等回踩"},
|
|
)
|
|
|
|
assert signal.to_json_dict()["strategy_code"] == LONG_BOX_RETEST_4H_STRATEGY
|
|
assert signal.status == "candidate"
|
|
|
|
|
|
def test_short_breakdown_retest_observes_until_retest_rejected():
|
|
signal = build_breakdown_retest_short_1h_signal(
|
|
symbol="BD/USDT",
|
|
current_price=9.5,
|
|
detection={
|
|
"detected": True,
|
|
"quality": "良好",
|
|
"score": 5,
|
|
"breakdown_level": 10,
|
|
"retest_zone": 10,
|
|
"stop_level": 10.4,
|
|
"target_1": 8.8,
|
|
"retest_rejected": False,
|
|
"relative_weakness": True,
|
|
},
|
|
entry_plan={"side": "short", "entry_action": "等回踩"},
|
|
market_regime={"risk_level": "high"},
|
|
)
|
|
|
|
assert signal.to_json_dict()["strategy_code"] == SHORT_BREAKDOWN_RETEST_STRATEGY
|
|
assert signal.status == "observe"
|
|
|
|
|
|
def test_short_weak_bounce_failure_needs_weak_market():
|
|
signal = build_short_weak_bounce_failure_signal(
|
|
symbol="WB/USDT",
|
|
result={"score": 7, "signals": ["15min反抽失败", "弱反弹失败"], "market_regime": {"regime": "risk_off", "risk_level": "high"}},
|
|
entry_plan={"side": "short", "entry_action": "可即刻买入"},
|
|
)
|
|
|
|
assert signal.to_json_dict()["strategy_code"] == SHORT_WEAK_BOUNCE_FAILURE_STRATEGY
|
|
assert signal.status == "candidate"
|