08082eb88f
Unify display on trend_leg_display_price: use recorded fills or grid triggers only; last done row avg comes from live entry, never back-solve trigger prices. Co-authored-by: Cursor <cursoragent@cursor.com>
93 lines
2.8 KiB
Python
93 lines
2.8 KiB
Python
"""四所趋势 enrich:实例与中控 monitor 字段一致。"""
|
|
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_trend_register import ( # noqa: E402
|
|
enrich_trend_plan,
|
|
enrich_trend_plan_for_hub,
|
|
)
|
|
|
|
|
|
class _FakeModule:
|
|
@staticmethod
|
|
def normalize_exchange_symbol(sym):
|
|
return sym
|
|
|
|
@staticmethod
|
|
def ensure_markets_loaded():
|
|
return None
|
|
|
|
@staticmethod
|
|
def get_live_position_exchange_metrics(ex_sym, direction, order_leverage=None):
|
|
return {
|
|
"entry_price": 0.3507,
|
|
"mark_price": 0.3431,
|
|
"unrealized_pnl": -1.23,
|
|
}
|
|
|
|
@staticmethod
|
|
def get_contract_size(_ex_sym):
|
|
return 1.0
|
|
|
|
|
|
class TestTrendHubEnrichUnified(unittest.TestCase):
|
|
def _cfg(self):
|
|
return {
|
|
"app_module": _FakeModule(),
|
|
"breakeven_offset_pct": 0.3,
|
|
"row_to_dict": lambda row: dict(row) if not isinstance(row, dict) else row,
|
|
}
|
|
|
|
def _plan_row(self):
|
|
return {
|
|
"id": 4,
|
|
"symbol": "ONDO/USDT:USDT",
|
|
"exchange_symbol": "ONDO/USDT:USDT",
|
|
"direction": "long",
|
|
"stop_loss": 0.329,
|
|
"take_profit": 0.476,
|
|
"add_upper": 0.35,
|
|
"first_order_amount": 115,
|
|
"snapshot_available_usdt": 97.98,
|
|
"risk_percent": 5,
|
|
"contract_size": 1.0,
|
|
"grid_prices_json": json.dumps([0.343, 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": 2,
|
|
"avg_entry_price": 0.3434,
|
|
"order_amount_open": 161,
|
|
"leg_fill_prices_json": json.dumps([0.3436]),
|
|
"leverage": 10,
|
|
"plan_margin_capital": 8.17,
|
|
}
|
|
|
|
def test_hub_and_page_share_live_avg_and_dca_levels(self):
|
|
cfg = self._cfg()
|
|
row = self._plan_row()
|
|
page = enrich_trend_plan(cfg, row)
|
|
hub = enrich_trend_plan_for_hub(cfg, row)
|
|
self.assertAlmostEqual(page["avg_entry_price"], 0.3507, places=4)
|
|
self.assertAlmostEqual(hub["avg_entry_price"], 0.3507, places=4)
|
|
self.assertIn("dca_levels", page)
|
|
self.assertIn("dca_levels", hub)
|
|
last_done = hub["dca_levels"][2]
|
|
self.assertEqual(last_done["status"], "done")
|
|
self.assertAlmostEqual(last_done["price"], 0.343, places=4)
|
|
self.assertAlmostEqual(last_done["avg_entry"], 0.3507, places=4)
|
|
self.assertLess(last_done["price"], 0.36)
|
|
self.assertEqual(hub.get("monitor_source"), "趋势回调计划")
|
|
self.assertEqual(hub.get("add_count"), 2)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|