57 lines
2.2 KiB
Python
57 lines
2.2 KiB
Python
import os
|
|
import sys
|
|
|
|
PROJECT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
|
if PROJECT_DIR not in sys.path:
|
|
sys.path.insert(0, PROJECT_DIR)
|
|
|
|
from app.services import price_tracker
|
|
|
|
|
|
def test_watch_only_recommendation_only_updates_observation_pnl(monkeypatch):
|
|
rec = {
|
|
"id": 1,
|
|
"symbol": "QNT/USDT",
|
|
"entry_price": 100.0,
|
|
"stop_loss": 95.0,
|
|
"tp1": 110.0,
|
|
"tp2": 120.0,
|
|
"entry_plan": {},
|
|
"entry_triggered": 0,
|
|
"display_bucket": "watch_pool",
|
|
"execution_status": "observe",
|
|
"action_status": "观察",
|
|
}
|
|
calls = {"tracking": 0, "state_transition": 0}
|
|
|
|
monkeypatch.setattr(price_tracker, "get_active_recommendations", lambda actionable_only=False: [rec])
|
|
monkeypatch.setattr(price_tracker.exchange, "fetch_ticker", lambda symbol: {"last": 102.0})
|
|
monkeypatch.setattr(price_tracker, "update_latest_price_cache", lambda *args, **kwargs: None)
|
|
def fake_update_tracking(rec_id, current_price):
|
|
calls["tracking"] += 1
|
|
return {"status": "active", "pnl_pct": 2.0}
|
|
monkeypatch.setattr(price_tracker, "update_recommendation_tracking", fake_update_tracking)
|
|
monkeypatch.setattr(price_tracker, "analyze_tracking_signals", lambda symbol, rec, current_price: {
|
|
"action_status": "持有",
|
|
"sell_signals": [],
|
|
"buy_signals": [],
|
|
"exhaustion": {"severity": "low"},
|
|
"pnl_pct": 0.0,
|
|
})
|
|
def fake_state_transition(*args, **kwargs):
|
|
calls["state_transition"] += 1
|
|
return {"action_status": "观察", "push_required": False}
|
|
monkeypatch.setattr(price_tracker, "apply_recommendation_state_transition", fake_state_transition)
|
|
monkeypatch.setattr(price_tracker, "expire_old_recommendations", lambda: None)
|
|
monkeypatch.setattr(price_tracker, "get_stats", lambda: {"active_count": 1})
|
|
|
|
output = price_tracker.track_prices()
|
|
|
|
assert output["tracked_count"] == 0
|
|
assert output["observed_count"] == 1
|
|
assert output["results"][0]["status"] == "observed_watch_only"
|
|
assert output["results"][0]["current_price"] == 102.0
|
|
assert output["results"][0]["pnl_pct"] == 2.0
|
|
assert calls["tracking"] == 1
|
|
assert calls["state_transition"] == 0
|