Files
crypto_monitor/tests/test_trend_dca_enrich_fills.py
T
dekun d56d9050aa fix(trend): use money RR, track DCA fills, snapshot before close
Align running-plan header and DCA table with risk-budget RR, record actual fill prices after each leg, and save pre-close snapshots on stop/TP/handoff across hub and exchanges.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-07 17:34:50 +08:00

68 lines
2.3 KiB
Python

"""趋势回调运行中计划:实际成交价重算补仓表与金额盈亏比。"""
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 calc_trend_plan_money_metrics # noqa: E402
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)
if __name__ == "__main__":
unittest.main()