feat: show review fields in symbol archive trade table
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
"""档案交易:复盘字段优先(开仓类型、持仓时长、开平仓时间)。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import tempfile
|
||||
import unittest
|
||||
from datetime import datetime, timedelta
|
||||
from pathlib import Path
|
||||
|
||||
from hub_symbol_archive_lib import init_db, load_symbol_trades, upsert_trades_cache
|
||||
from hub_trades_lib import _normalize_archive_trade_row, effective_entry_type, effective_hold_minutes
|
||||
|
||||
|
||||
class TestHubTradesReviewFields(unittest.TestCase):
|
||||
def test_effective_entry_type_prefers_reviewed(self):
|
||||
d = {
|
||||
"entry_reason": "突破回踩",
|
||||
"reviewed_entry_reason": "趋势回调",
|
||||
"monitor_type": "下单监控",
|
||||
}
|
||||
self.assertEqual(effective_entry_type(d), "趋势回调")
|
||||
|
||||
def test_effective_hold_minutes_prefers_reviewed(self):
|
||||
d = {
|
||||
"hold_minutes": 30,
|
||||
"reviewed_hold_minutes": 95,
|
||||
"opened_at_ms": 1_700_000_000_000,
|
||||
"closed_at_ms": 1_700_001_800_000,
|
||||
}
|
||||
self.assertEqual(effective_hold_minutes(d), 95)
|
||||
|
||||
def test_normalize_archive_trade_row_review_fields(self):
|
||||
closed = (datetime.now() - timedelta(days=2)).strftime("%Y-%m-%d %H:%M:%S")
|
||||
opened = (datetime.now() - timedelta(days=2, hours=2)).strftime("%Y-%m-%d %H:%M:%S")
|
||||
row = _normalize_archive_trade_row(
|
||||
{
|
||||
"id": 9,
|
||||
"symbol": "ONDO/USDT",
|
||||
"direction": "short",
|
||||
"result": "止损",
|
||||
"reviewed_result": "手动平仓",
|
||||
"pnl_amount": -2.5,
|
||||
"reviewed_pnl_amount": -2.58,
|
||||
"opened_at": opened,
|
||||
"reviewed_opened_at": "2026-06-07 14:30:00",
|
||||
"closed_at": closed,
|
||||
"reviewed_closed_at": "2026-06-08 08:44:21",
|
||||
"opened_at_ms": 1_700_000_000_000,
|
||||
"closed_at_ms": 1_700_007_200_000,
|
||||
"entry_reason": "突破回踩",
|
||||
"reviewed_entry_reason": "趋势回调",
|
||||
"hold_minutes": 30,
|
||||
"reviewed_hold_minutes": 1080,
|
||||
"monitor_type": "趋势回调",
|
||||
"reviewed_at": closed,
|
||||
},
|
||||
exchange_key="gate",
|
||||
)
|
||||
self.assertIsNotNone(row)
|
||||
assert row is not None
|
||||
self.assertEqual(row["entry_type"], "趋势回调")
|
||||
self.assertEqual(row["hold_minutes"], 1080)
|
||||
self.assertEqual(row["opened_at"], "2026-06-07 14:30:00")
|
||||
self.assertEqual(row["closed_at"], "2026-06-08 08:44:21")
|
||||
self.assertTrue(row["reviewed"])
|
||||
|
||||
def test_archive_cache_enriches_review_display_fields(self):
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
db = Path(td) / "archive.db"
|
||||
init_db(db)
|
||||
upsert_trades_cache(
|
||||
"gate",
|
||||
[
|
||||
{
|
||||
"id": 3,
|
||||
"symbol": "ONDO/USDT",
|
||||
"direction": "short",
|
||||
"result": "手动平仓",
|
||||
"pnl_amount": -2.58,
|
||||
"opened_at": "2026-06-07 14:30:00",
|
||||
"closed_at": "2026-06-08 08:44:21",
|
||||
"opened_at_ms": 1_781_000_000_000,
|
||||
"closed_at_ms": 1_781_065_000_000,
|
||||
"entry_type": "趋势回调",
|
||||
"hold_minutes": 1080,
|
||||
"hold_minutes_text": "18小时0分钟",
|
||||
"reviewed": True,
|
||||
}
|
||||
],
|
||||
db_path=db,
|
||||
)
|
||||
rows = load_symbol_trades("gate", "ONDO/USDT", db_path=db)
|
||||
self.assertEqual(len(rows), 1)
|
||||
self.assertEqual(rows[0]["entry_type"], "趋势回调")
|
||||
self.assertEqual(rows[0]["hold_minutes"], 1080)
|
||||
self.assertTrue(rows[0]["opened_at"].startswith("2026-06-07"))
|
||||
self.assertTrue(rows[0]["closed_at"].startswith("2026-06-08"))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
Reference in New Issue
Block a user