feat: show review fields in symbol archive trade table
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user