feat: show ops-map summaries as detailed period tables
Replace paragraph text with day-hit stats (days/days_hit/pct) so leverage and move charts list each hour with counts. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -61,5 +61,29 @@ def test_aggregate_leverage_buckets():
|
||||
assert b14["n"] == 2
|
||||
assert b14["mean"] == 150
|
||||
assert b14["label"] == "14:00"
|
||||
assert b14["days"] == 1
|
||||
assert b14["days_hit"] == 1
|
||||
assert b14["pct_days_hit"] == 1.0
|
||||
empty = next(b for b in buckets if b["bucket_start_min"] == 0)
|
||||
assert empty["n"] == 0
|
||||
assert empty["days"] == 0
|
||||
assert empty["days_hit"] == 0
|
||||
|
||||
|
||||
def test_aggregate_leverage_days_hit():
|
||||
from datetime import datetime
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
sh = ZoneInfo("Asia/Shanghai")
|
||||
ts1 = int(datetime(2026, 7, 30, 11, 10, tzinfo=sh).timestamp() * 1000)
|
||||
ts2 = int(datetime(2026, 7, 31, 11, 20, tzinfo=sh).timestamp() * 1000)
|
||||
rows = [
|
||||
{"ts_ms": ts1, "side": "C", "leverage": 120}, # day1 hit
|
||||
{"ts_ms": ts2, "side": "C", "leverage": 80}, # day2 miss
|
||||
]
|
||||
buckets = aggregate_leverage(rows, bucket_minutes=60, min_leverage=100, side="C")
|
||||
b11 = next(b for b in buckets if b["bucket_start_min"] == 11 * 60)
|
||||
assert b11["days"] == 2
|
||||
assert b11["days_hit"] == 1
|
||||
assert b11["pct_days_hit"] == 0.5
|
||||
assert b11["n"] == 2
|
||||
|
||||
@@ -1,32 +1,54 @@
|
||||
"""对齐前端 opsSummary 规则的轻量逻辑测试(Python 镜像)。"""
|
||||
"""对齐前端 opsSummary 表规则的轻量逻辑测试。"""
|
||||
|
||||
|
||||
MIN_N = 3
|
||||
TOP_K = 5
|
||||
|
||||
|
||||
def leverage_summary_week(buckets, min_leverage=100):
|
||||
def leverage_rows(buckets, min_leverage=100):
|
||||
active = [b for b in buckets if b["n"] > 0]
|
||||
ranked = sorted(
|
||||
[b for b in active if b["n"] >= MIN_N and b.get("pct_ge_min") is not None],
|
||||
key=lambda b: (b["pct_ge_min"], b["n"], b.get("mean") or 0),
|
||||
reverse=True,
|
||||
)[:TOP_K]
|
||||
return ranked
|
||||
|
||||
def hit_rate(b):
|
||||
if b.get("pct_days_hit") is not None:
|
||||
return b["pct_days_hit"]
|
||||
return b.get("pct_ge_min")
|
||||
|
||||
def test_week_ranks_by_pct_ge_min():
|
||||
buckets = [
|
||||
{"label": "09:00", "n": 10, "mean": 110, "pct_ge_min": 0.5},
|
||||
{"label": "14:00", "n": 10, "mean": 105, "pct_ge_min": 0.8},
|
||||
{"label": "21:00", "n": 2, "mean": 200, "pct_ge_min": 1.0}, # n 不足
|
||||
def days(b):
|
||||
return b["days"] if "days" in b else (1 if b["n"] > 0 else 0)
|
||||
|
||||
def days_hit(b):
|
||||
if "days_hit" in b:
|
||||
return b["days_hit"]
|
||||
return 1 if (b.get("mean") or 0) >= min_leverage and b["n"] > 0 else 0
|
||||
|
||||
rows = [
|
||||
{
|
||||
"label": b["label"],
|
||||
"days": days(b),
|
||||
"days_hit": days_hit(b),
|
||||
"pct": hit_rate(b),
|
||||
"mean": b.get("mean"),
|
||||
"n": b["n"],
|
||||
}
|
||||
for b in active
|
||||
]
|
||||
ranked = leverage_summary_week(buckets)
|
||||
assert [b["label"] for b in ranked] == ["14:00", "09:00"]
|
||||
rows.sort(
|
||||
key=lambda r: (r["pct"] if r["pct"] is not None else -1, r["days_hit"], r["mean"] or 0),
|
||||
reverse=True,
|
||||
)
|
||||
return rows
|
||||
|
||||
|
||||
def test_week_table_uses_days_hit():
|
||||
buckets = [
|
||||
{"label": "09:00", "n": 10, "mean": 110, "pct_ge_min": 0.9, "days": 5, "days_hit": 2, "pct_days_hit": 0.4},
|
||||
{"label": "14:00", "n": 10, "mean": 105, "pct_ge_min": 0.5, "days": 5, "days_hit": 4, "pct_days_hit": 0.8},
|
||||
{"label": "21:00", "n": 2, "mean": 200, "pct_ge_min": 1.0, "days": 1, "days_hit": 1, "pct_days_hit": 1.0},
|
||||
]
|
||||
rows = leverage_rows(buckets)
|
||||
assert [r["label"] for r in rows] == ["21:00", "14:00", "09:00"]
|
||||
assert rows[1]["days"] == 5 and rows[1]["days_hit"] == 4
|
||||
|
||||
|
||||
def test_day_keeps_small_n():
|
||||
active = [b for b in [
|
||||
{"label": "09:00", "n": 1, "mean": 118, "pct_ge_min": 1.0},
|
||||
] if b["n"] > 0]
|
||||
assert len(active) == 1
|
||||
rows = leverage_rows(
|
||||
[{"label": "09:00", "n": 1, "mean": 118, "pct_ge_min": 1.0, "days": 1, "days_hit": 1, "pct_days_hit": 1.0}]
|
||||
)
|
||||
assert len(rows) == 1
|
||||
assert rows[0]["days"] == 1 and rows[0]["days_hit"] == 1
|
||||
|
||||
Reference in New Issue
Block a user