test_search_eth_nextgen_micro_portfolio.py 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. import importlib.util
  2. import sys
  3. from pathlib import Path
  4. from types import SimpleNamespace
  5. import pytest
  6. def load_module():
  7. path = Path(__file__).resolve().parents[1] / "scripts" / "search_eth_nextgen_micro_portfolio.py"
  8. spec = importlib.util.spec_from_file_location("search_eth_nextgen_micro_portfolio", path)
  9. assert spec is not None
  10. module = importlib.util.module_from_spec(spec)
  11. assert spec.loader is not None
  12. sys.modules[spec.name] = module
  13. spec.loader.exec_module(module)
  14. return module
  15. def test_trade_returns_apply_selected_cost_model():
  16. module = load_module()
  17. result = SimpleNamespace(
  18. trades=[
  19. {
  20. "return_pct": 1.0,
  21. "cost_weight": 0.5,
  22. "exit_time": "2026-04-30 12:00",
  23. }
  24. ]
  25. )
  26. maker = module.nextgen_trade_returns(result, 1.0, 0.0021)
  27. taker = module.nextgen_trade_returns(result, 1.0, 0.0030)
  28. assert maker[0].value == pytest.approx(0.01 - 0.0021 * 0.5)
  29. assert taker[0].value == pytest.approx(0.01 - 0.0030 * 0.5)
  30. def test_monthly_stability_groups_by_name_and_cost_model():
  31. module = load_module()
  32. pandas = pytest.importorskip("pandas")
  33. frame = pandas.DataFrame(
  34. [
  35. {"cost_model": "maker_taker", "name": "a", "return": 0.02},
  36. {"cost_model": "maker_taker", "name": "a", "return": -0.01},
  37. {"cost_model": "taker_taker", "name": "a", "return": -0.03},
  38. ]
  39. )
  40. stability = module.monthly_stability(frame).sort_values(["cost_model", "name"]).reset_index(drop=True)
  41. assert stability.loc[0, "cost_model"] == "maker_taker"
  42. assert stability.loc[0, "months"] == 2
  43. assert stability.loc[0, "positive_month_rate"] == pytest.approx(0.5)
  44. assert stability.loc[1, "cost_model"] == "taker_taker"
  45. assert stability.loc[1, "positive_month_rate"] == pytest.approx(0.0)
  46. def test_robust_survivors_requires_positive_returns_and_calmar_per_cost_model():
  47. module = load_module()
  48. pandas = pytest.importorskip("pandas")
  49. rows = []
  50. for cost_model, ret_3m in (("maker_taker", 0.04), ("taker_taker", -0.01)):
  51. for horizon, total_return in (("full", 0.30), ("3y", 0.20), ("1y", 0.10), ("6m", 0.08), ("3m", ret_3m)):
  52. rows.append(
  53. {
  54. "cost_model": cost_model,
  55. "name": "candidate",
  56. "horizon": horizon,
  57. "net_total_return": total_return,
  58. "net_calmar": 0.50,
  59. }
  60. )
  61. survivors = module.robust_survivors(pandas.DataFrame(rows))
  62. assert survivors["cost_model"].tolist() == ["maker_taker"]