"""趋势回调运行中计划:实际成交价重算补仓表与金额盈亏比。""" from __future__ import annotations import json import sys import unittest from pathlib import Path ROOT = Path(__file__).resolve().parents[1] sys.path.insert(0, str(ROOT)) from strategy_snapshot_lib import attach_trend_dca_levels # noqa: E402 from strategy_trend_lib import ( # noqa: E402 calc_trend_plan_money_metrics, trend_leg_display_price, ) class TestTrendDcaEnrichFills(unittest.TestCase): def _base_plan(self, **overrides): plan = { "direction": "long", "stop_loss": 0.329, "take_profit": 0.476, "first_order_amount": 115, "snapshot_available_usdt": 97.98, "risk_percent": 5, "contract_size": 1.0, "grid_prices_json": json.dumps([0.3465, 0.343, 0.3395, 0.336, 0.3325]), "leg_amounts_json": json.dumps([23, 23, 23, 23, 23]), "dca_legs": 5, "first_order_done": 1, "legs_done": 0, "avg_entry_price": 0.3537, "order_amount_open": 115, "target_order_amount": 230, "leg_fill_prices_json": json.dumps([0.3537]), } plan.update(overrides) return plan def test_header_money_rr_not_price_rr(self): plan = self._base_plan() metrics = calc_trend_plan_money_metrics(plan) self.assertAlmostEqual(metrics["risk_amount_u"], 4.899, places=2) self.assertIsNotNone(metrics["money_rr"]) self.assertLess(metrics["money_rr"], 4.0) def test_done_dca_uses_actual_fill_price(self): plan = self._base_plan( legs_done=1, avg_entry_price=0.3512, order_amount_open=138, leg_fill_prices_json=json.dumps([0.3537, 0.3458]), ) enriched = attach_trend_dca_levels(plan) levels = enriched["dca_levels"] self.assertEqual(len(levels), 6) dca1 = levels[1] self.assertEqual(dca1["status"], "done") self.assertAlmostEqual(dca1["price"], 0.3458, places=4) self.assertIsNotNone(dca1["avg_entry"]) self.assertIsNotNone(dca1["rr"]) dca2 = levels[2] self.assertEqual(dca2["status"], "pending") self.assertAlmostEqual(dca2["price"], 0.343, places=4) def test_missing_dca_fills_use_grid_trigger_not_inferred_price(self): """缺补仓成交价时:触发价用计划网格,末档均价对齐头部,禁止反推离谱成交价。""" plan = self._base_plan( legs_done=2, avg_entry_price=0.3507, order_amount_open=161, leg_fill_prices_json=json.dumps([0.3436]), grid_prices_json=json.dumps([0.343, 0.343, 0.3395, 0.336, 0.3325]), ) enriched = attach_trend_dca_levels(plan) levels = enriched["dca_levels"] dca1 = levels[1] dca2 = levels[2] self.assertEqual(dca1["status"], "done") self.assertAlmostEqual(dca1["price"], 0.343, places=4) self.assertEqual(dca2["status"], "done") self.assertAlmostEqual(dca2["price"], 0.343, places=4) self.assertAlmostEqual(dca2["avg_entry"], 0.3507, places=4) self.assertLess(dca2["price"], 0.36) def test_display_price_never_infers_from_target_avg(self): """四所共用:缺记录时只用网格,不因均价反推离谱触发价。""" plan = self._base_plan( legs_done=2, avg_entry_price=0.3507, leg_fill_prices_json=json.dumps([0.3436]), grid_prices_json=json.dumps([0.343, 0.343, 0.3395, 0.336, 0.3325]), ) self.assertAlmostEqual(trend_leg_display_price(plan, 2), 0.343, places=4) self.assertLess(trend_leg_display_price(plan, 2), 0.36) if __name__ == "__main__": unittest.main()