test_research_metrics.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import pandas as pd
  2. from okx_codex_trader.research_metrics import equity_metrics, horizon_rows, trade_stats, worst_month
  3. def test_equity_metrics_calculates_return_drawdown_and_calmar() -> None:
  4. frame = pd.DataFrame(
  5. [
  6. {"ts": pd.Timestamp("2025-01-01", tz="UTC"), "equity": 100.0},
  7. {"ts": pd.Timestamp("2025-07-01", tz="UTC"), "equity": 80.0},
  8. {"ts": pd.Timestamp("2026-01-01", tz="UTC"), "equity": 120.0},
  9. ]
  10. )
  11. metrics = equity_metrics(frame, int(frame["ts"].iloc[0].timestamp() * 1000), int(frame["ts"].iloc[-1].timestamp() * 1000))
  12. assert round(metrics["net_total_return"], 6) == 0.2
  13. assert round(metrics["net_max_drawdown"], 6) == 0.2
  14. assert metrics["net_annualized_return"] > 0.19
  15. assert metrics["net_calmar"] > 0.9
  16. def test_horizon_rows_uses_cutoff_equity_when_history_exists() -> None:
  17. frame = pd.DataFrame(
  18. [
  19. {"ts": pd.Timestamp("2025-01-01", tz="UTC"), "equity": 100.0},
  20. {"ts": pd.Timestamp("2026-01-01", tz="UTC"), "equity": 150.0},
  21. {"ts": pd.Timestamp("2026-02-01", tz="UTC"), "equity": 120.0},
  22. ]
  23. )
  24. last_ts = int(pd.Timestamp("2026-02-01", tz="UTC").timestamp() * 1000)
  25. rows = horizon_rows(frame, last_ts, horizons=(("30d", pd.DateOffset(days=30)),))
  26. assert rows[0]["horizon"] == "30d"
  27. assert rows[0]["horizon_start"] == "2026-01-02 00:00"
  28. assert rows[0]["net_total_return"] < 0.0
  29. def test_trade_stats_and_worst_month() -> None:
  30. stats = trade_stats([{"return_pct": 2.0}, {"return_pct": -1.0}, {"return_pct": 4.0}])
  31. frame = pd.DataFrame(
  32. [
  33. {"ts": pd.Timestamp("2026-01-01", tz="UTC"), "equity": 100.0},
  34. {"ts": pd.Timestamp("2026-01-31", tz="UTC"), "equity": 120.0},
  35. {"ts": pd.Timestamp("2026-02-28", tz="UTC"), "equity": 90.0},
  36. ]
  37. )
  38. assert stats == {"avg_return_pct": 5.0 / 3.0, "payoff_ratio": 3.0, "profit_factor": 6.0}
  39. assert worst_month(frame) == ("2026-02", -0.25)