Add win/loss metrics to archive stats with symbol filter sync.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -11,12 +11,15 @@ from zoneinfo import ZoneInfo
|
||||
|
||||
from hub_symbol_archive_lib import (
|
||||
CHART_DISPLAY_TZ,
|
||||
_compute_period_stats,
|
||||
_fill_missing_bars,
|
||||
init_db,
|
||||
list_daily_trades,
|
||||
load_symbol_trades,
|
||||
ms_to_wall_clock_str,
|
||||
parse_wall_clock_ms,
|
||||
resolve_archive_chart,
|
||||
trading_day_bounds_ms,
|
||||
upsert_bars_5m,
|
||||
upsert_trade_overlay,
|
||||
list_symbol_rows,
|
||||
@@ -271,3 +274,71 @@ def test_upsert_forces_sync_exchange_key():
|
||||
assert len(rows) == 1
|
||||
assert rows[0]["exchange_key"] == "gate_bot"
|
||||
assert "account_exchange_key" not in rows[0]
|
||||
|
||||
|
||||
def test_compute_period_stats_win_loss_metrics():
|
||||
rows = [
|
||||
{"exchange_key": "binance", "pnl_amount": 10.0, "behavior_tag": ""},
|
||||
{"exchange_key": "binance", "pnl_amount": 4.0, "behavior_tag": ""},
|
||||
{"exchange_key": "okx", "pnl_amount": -3.0, "behavior_tag": "sick"},
|
||||
{"exchange_key": "okx", "pnl_amount": -6.0, "behavior_tag": ""},
|
||||
]
|
||||
st = _compute_period_stats(rows)
|
||||
assert st["open_count"] == 4
|
||||
assert st["win_count"] == 2
|
||||
assert st["loss_count"] == 2
|
||||
assert st["avg_win"] == 7.0
|
||||
assert st["avg_loss"] == -4.5
|
||||
assert st["max_win"] == 10.0
|
||||
assert st["max_loss"] == -6.0
|
||||
assert st["sick_count"] == 1
|
||||
assert st["pnl_total"] == 5.0
|
||||
assert st["pnl_ex_sick"] == 8.0
|
||||
assert st["by_exchange"]["binance"]["win_count"] == 2
|
||||
|
||||
|
||||
def test_list_daily_trades_search_filters_stats():
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
db = Path(td) / "archive.db"
|
||||
init_db(db)
|
||||
day = "2023-11-15"
|
||||
start_ms, _ = trading_day_bounds_ms(day)
|
||||
btc_close = start_ms + 3_600_000
|
||||
eth_close = start_ms + 7_200_000
|
||||
upsert_trades_cache(
|
||||
"gate",
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"symbol": "BTC/USDT",
|
||||
"result": "止盈",
|
||||
"pnl_amount": 5.0,
|
||||
"opened_at_ms": start_ms,
|
||||
"closed_at_ms": btc_close,
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"symbol": "ETH/USDT",
|
||||
"result": "止损",
|
||||
"pnl_amount": -2.0,
|
||||
"opened_at_ms": btc_close,
|
||||
"closed_at_ms": eth_close,
|
||||
},
|
||||
],
|
||||
db_path=db,
|
||||
)
|
||||
payload = list_daily_trades(
|
||||
period="range",
|
||||
date_from=day,
|
||||
date_to=day,
|
||||
search="btc",
|
||||
db_path=db,
|
||||
)
|
||||
assert len(payload["trades"]) == 1
|
||||
assert payload["trades"][0]["symbol"] == "BTC/USDT"
|
||||
st = payload["stats"]
|
||||
assert st["open_count"] == 1
|
||||
assert st["win_count"] == 1
|
||||
assert st["loss_count"] == 0
|
||||
assert st["max_win"] == 5.0
|
||||
assert st["pnl_total"] == 5.0
|
||||
|
||||
Reference in New Issue
Block a user