mirror of
https://github.com/xavierchuan/FX-ML-Trading-Engine.git
synced 2026-08-18 03:18:06 +00:00
Add files via upload
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Append a metrics row using TCA summary + KPI overrides.
|
||||
|
||||
Example:
|
||||
python scripts/update_metrics_from_tca.py \
|
||||
--tca QuantTrader/results/execution/tca_summary.json \
|
||||
--run-id 20251112_parallel_demo_live \
|
||||
--status pass --latency-avg 28 --latency-p95 45 \
|
||||
--total-pnl 27.3 --max-exposure 500000 --max-drawdown 0.02 \
|
||||
--rolling-sharpe 1.5 --live-drawdown 0.03 \
|
||||
--live-latency-p95 45 --slippage-bps 1.2
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import csv
|
||||
import json
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def parse_args() -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(description="Append metrics row from TCA summary.")
|
||||
parser.add_argument("--tca", required=True, help="Path to tca_summary.json")
|
||||
parser.add_argument("--metrics", default="results/risk/metrics.csv", help="Metrics CSV path")
|
||||
parser.add_argument("--run-id", required=True)
|
||||
parser.add_argument("--status", default="pass")
|
||||
parser.add_argument("--latency-avg", type=float, required=True)
|
||||
parser.add_argument("--latency-p95", type=float, required=True)
|
||||
parser.add_argument("--total-pnl", type=float, required=True)
|
||||
parser.add_argument("--max-exposure", type=float, required=True)
|
||||
parser.add_argument("--max-drawdown", type=float, required=True)
|
||||
parser.add_argument("--rolling-sharpe", type=float, required=True)
|
||||
parser.add_argument("--live-drawdown", type=float, required=True)
|
||||
parser.add_argument("--live-latency-p95", type=float, required=True)
|
||||
parser.add_argument("--slippage-bps", type=float, required=True)
|
||||
parser.add_argument("--rejects", type=int, default=0)
|
||||
parser.add_argument("--kills", type=int, default=0)
|
||||
parser.add_argument("--max-gross-notional", type=float, default=0.0)
|
||||
return parser.parse_args()
|
||||
|
||||
|
||||
def main() -> None:
|
||||
args = parse_args()
|
||||
tca_path = Path(args.tca)
|
||||
if not tca_path.exists():
|
||||
raise SystemExit(f"TCA summary not found: {tca_path}")
|
||||
with tca_path.open("r", encoding="utf-8") as f:
|
||||
tca = json.load(f)
|
||||
|
||||
timestamp = datetime.now(timezone.utc).isoformat()
|
||||
row = {
|
||||
"timestamp": timestamp,
|
||||
"run_id": args.run_id,
|
||||
"rejects": args.rejects,
|
||||
"kills": args.kills,
|
||||
"status": args.status,
|
||||
"latency_ms_avg": args.latency_avg,
|
||||
"latency_ms_p95": args.latency_p95,
|
||||
"total_pnl": args.total_pnl,
|
||||
"max_gross_notional": args.max_gross_notional or args.max_exposure,
|
||||
"max_symbol_exposure": args.max_exposure,
|
||||
"max_drawdown_pct": args.max_drawdown,
|
||||
"rolling_sharpe_30d": args.rolling_sharpe,
|
||||
"live_drawdown_pct": args.live_drawdown,
|
||||
"live_latency_ms_p95": args.live_latency_p95,
|
||||
"slippage_bps": args.slippage_bps,
|
||||
"paper_trade_count": tca.get("paper_trade_count"),
|
||||
"paper_total_pnl": tca.get("paper_total_pnl"),
|
||||
"live_trade_count": tca.get("live_trade_count"),
|
||||
"live_total_pnl": tca.get("live_total_pnl"),
|
||||
"pnl_diff_mean": tca.get("pnl_diff_mean"),
|
||||
"pnl_diff_std": tca.get("pnl_diff_std"),
|
||||
}
|
||||
|
||||
metrics_path = Path(args.metrics)
|
||||
metrics_path.parent.mkdir(parents=True, exist_ok=True)
|
||||
write_header = not metrics_path.exists()
|
||||
with metrics_path.open("a", newline="", encoding="utf-8") as f:
|
||||
writer = csv.DictWriter(f, fieldnames=row.keys())
|
||||
if write_header:
|
||||
writer.writeheader()
|
||||
writer.writerow(row)
|
||||
print(f"Appended metrics row for run={args.run_id}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user