feat: show review fields in symbol archive trade table

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
dekun
2026-06-08 12:20:29 +08:00
parent 1dcf62bb08
commit 4918699276
5 changed files with 338 additions and 11 deletions
+47 -1
View File
@@ -15,6 +15,7 @@ from hub_ohlcv_lib import (
aggregate_ohlcv_bars,
normalize_chart_timeframe,
)
from hub_trades_lib import effective_entry_type, effective_hold_minutes, format_hold_minutes
ARCHIVE_TIMEFRAMES = frozenset({"5m", "15m", "1h", "4h"})
ARCHIVE_DEFAULT_TIMEFRAME = "15m"
@@ -226,6 +227,51 @@ def upsert_trades_cache(
return n
def _enrich_trade_display_fields(out: dict[str, Any]) -> dict[str, Any]:
"""缓存行补齐复盘优先的展示字段(兼容旧同步数据)。"""
opened_ms = out.get("opened_at_ms") or _parse_dt_ms(out.get("opened_at"))
closed_ms = out.get("closed_at_ms") or _parse_dt_ms(out.get("closed_at"))
if opened_ms:
out["opened_at_ms"] = int(opened_ms)
if closed_ms:
out["closed_at_ms"] = int(closed_ms)
if not out.get("opened_at") and opened_ms:
out["opened_at"] = datetime.fromtimestamp(int(opened_ms) / 1000).strftime(
"%Y-%m-%d %H:%M:%S"
)
if not out.get("closed_at") and closed_ms:
out["closed_at"] = datetime.fromtimestamp(int(closed_ms) / 1000).strftime(
"%Y-%m-%d %H:%M:%S"
)
entry_type = (out.get("entry_type") or effective_entry_type(out) or "").strip()
if entry_type:
out["entry_type"] = entry_type
out["entry_reason"] = entry_type
hold_m = out.get("hold_minutes")
if hold_m in (None, ""):
hold_m = effective_hold_minutes(
out,
opened_ms=out.get("opened_at_ms"),
closed_ms=out.get("closed_at_ms"),
)
try:
hold_m = max(0, int(hold_m or 0))
except (TypeError, ValueError):
hold_m = 0
out["hold_minutes"] = hold_m
out["hold_minutes_text"] = out.get("hold_minutes_text") or format_hold_minutes(hold_m)
if "reviewed" not in out:
out["reviewed"] = bool(
out.get("reviewed_at")
or out.get("reviewed_result")
or out.get("reviewed_opened_at")
or out.get("reviewed_closed_at")
or out.get("reviewed_entry_reason")
or out.get("reviewed_hold_minutes")
)
return out
def _trade_row_to_dict(row: sqlite3.Row, overlay: dict | None = None) -> dict[str, Any]:
d = dict(row)
payload = {}
@@ -240,7 +286,7 @@ def _trade_row_to_dict(row: sqlite3.Row, overlay: dict | None = None) -> dict[st
out["behavior_tag"] = ov.get("behavior_tag") or ""
out["note"] = ov.get("note") or ""
out["trade_id"] = out.get("trade_id") or out.get("id")
return out
return _enrich_trade_display_fields(out)
def load_overlays(