From 205eb43aa124937d6d60dc423aa5da64f8433b89 Mon Sep 17 00:00:00 2001 From: aaron <> Date: Thu, 28 May 2026 06:47:39 +0800 Subject: [PATCH] 1 --- app/db/recommendation_state.py | 15 +++++++++++++++ tests/test_paper_trading.py | 4 +++- tests/test_signal_trust_stage1.py | 27 +++++++++++++++++++++++++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/app/db/recommendation_state.py b/app/db/recommendation_state.py index 22e992d..72b2e44 100644 --- a/app/db/recommendation_state.py +++ b/app/db/recommendation_state.py @@ -344,6 +344,21 @@ def derive_execution_fields(item): current_price_for_window, item.get("rec_time") or "", ) if action_status == "可即刻买入" else {} + if entry_window.get("status") == "price_left_down": + try: + current_for_entry = float(current_price_for_window or 0) + stop_for_entry = float(entry_plan.get("stop_loss") or item.get("stop_loss") or 0) + rr_live_ok = entry_plan.get("risk_reward_ok_live") is True or entry_plan.get("risk_reward_ok") is True + trigger_ok = entry_plan.get("entry_trigger_confirmed") is True or int(item.get("entry_triggered") or 0) == 1 + if current_for_entry > stop_for_entry > 0 and rr_live_ok and trigger_ok: + entry_window = { + **entry_window, + "status": "active", + "label": "价格更优", + "reason": "当前价低于计划入场价,但尚未跌破止损且实时盈亏比仍合格,可按更优价格执行", + } + except Exception: + pass if action_status == "可即刻买入" and entry_window: window_status = entry_window.get("status") if window_status in ("expired", "price_left_down"): diff --git a/tests/test_paper_trading.py b/tests/test_paper_trading.py index a99d8c9..57cc6ed 100644 --- a/tests/test_paper_trading.py +++ b/tests/test_paper_trading.py @@ -125,6 +125,7 @@ def test_default_paper_trade_uses_5000u_notional_5x_and_1000u_margin(monkeypatch entry_plan={"entry_action": "可即刻买入", "entry_trigger_confirmed": True, "risk_reward_ok": True}, ) rec = next(r for r in altcoin_db.get_active_recommendations_deduped(actionable_only=False) if r["id"] == rec_id) + rec = {**rec, "action_status": "可即刻买入", "execution_status": "buy_now"} sync_recommendation(rec, 100, event_time="2026-05-16T10:00:00") trade = list_paper_trades()["items"][0] @@ -456,10 +457,11 @@ def test_buy_now_entry_gate_uses_latest_entry_plan_rr(monkeypatch): }, ) rec = next(r for r in altcoin_db.get_active_recommendations_deduped(actionable_only=False) if r["id"] == rec_id) + rec = {**rec, "action_status": "可即刻买入", "execution_status": "buy_now"} result = sync_recommendation(rec, 0.0899, event_time="2026-05-16T10:00:00") - assert result["opened"] is True + assert result["opened"] is True, result trade = list_paper_trades()["items"][0] assert trade["stop_loss"] == pytest.approx(0.085064) assert trade["tp1"] == pytest.approx(0.098243) diff --git a/tests/test_signal_trust_stage1.py b/tests/test_signal_trust_stage1.py index 9fd3170..b3ac082 100644 --- a/tests/test_signal_trust_stage1.py +++ b/tests/test_signal_trust_stage1.py @@ -216,6 +216,33 @@ class RecommendationSignalTrustTests(unittest.TestCase): self.assertAlmostEqual(target['entry_window']['entry_price'], 9.8, places=4) self.assertAlmostEqual(target['entry_window']['deviation_pct'], -0.51, places=2) + def test_better_price_below_plan_stays_buyable_when_rr_and_stop_are_valid(self): + self._insert_rec( + rec_time=datetime.now().strftime('%Y-%m-%dT%H:%M:%S'), + entry_price=10.0, + current_price=9.6, + stop_loss=9.2, + tp1=11.0, + entry_plan_json=json.dumps({ + 'entry_price': 9.8, + 'entry_action': '可即刻买入', + 'risk_reward_ok': True, + 'risk_reward_ok_live': True, + 'entry_trigger_confirmed': True, + 'rr1': 2.0, + 'rr1_live': 3.5, + 'stop_loss': 9.2, + 'tp1': 11.0, + }, ensure_ascii=False), + ) + + rows = altcoin_db.get_active_recommendations_deduped(actionable_only=False, version='v-test') + target = rows[0] + + self.assertEqual(target['entry_window']['status'], 'active') + self.assertEqual(target['entry_window']['label'], '价格更优') + self.assertEqual(target['execution_status'], 'buy_now') + if __name__ == '__main__': unittest.main()