test_build_eth_nextgen_micro_signal_intent.py 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. import pandas as pd
  2. import pytest
  3. from okx_codex_trader import eth_nextgen_micro as module
  4. def test_latest_active_engine_uses_shifted_prior_day_regime(monkeypatch):
  5. index = pd.date_range("2026-01-01", periods=32, freq="D", tz="UTC")
  6. existing = pd.DataFrame({"cost_model": ["maker_taker"], "name": ["equal-2-c0003"], "date": [index[0].strftime("%Y-%m-%d")]})
  7. nextgen = pd.Series([100.0] * 31 + [80.0], index=index)
  8. micro = pd.Series([100.0] * 31 + [120.0], index=index)
  9. monkeypatch.setattr(module.pd, "read_csv", lambda _: existing)
  10. monkeypatch.setattr(module.portfolio, "load_nextgen", lambda _, __: (nextgen, []))
  11. monkeypatch.setattr(module.portfolio, "load_micro_candidates", lambda _, __: {module.MICRO_NAME: (micro, [])})
  12. state = module.latest_active_engine()
  13. assert state["active_engine"] == "nextgen"
  14. def test_latest_active_engine_switches_on_prior_completed_day(monkeypatch):
  15. index = pd.date_range("2026-01-01", periods=33, freq="D", tz="UTC")
  16. existing = pd.DataFrame({"cost_model": ["maker_taker"], "name": ["equal-2-c0003"], "date": [index[0].strftime("%Y-%m-%d")]})
  17. nextgen = pd.Series([100.0] * 31 + [80.0, 80.0], index=index)
  18. micro = pd.Series([100.0] * 31 + [120.0, 120.0], index=index)
  19. monkeypatch.setattr(module.pd, "read_csv", lambda _: existing)
  20. monkeypatch.setattr(module.portfolio, "load_nextgen", lambda _, __: (nextgen, []))
  21. monkeypatch.setattr(module.portfolio, "load_micro_candidates", lambda _, __: {module.MICRO_NAME: (micro, [])})
  22. state = module.latest_active_engine()
  23. assert state["active_engine"] == "micro"
  24. def test_payload_is_readonly(monkeypatch):
  25. monkeypatch.setattr(module, "latest_active_engine", lambda: {"active_engine": "nextgen", "decision_date": "2026-01-01"})
  26. monkeypatch.setattr(
  27. module.nextgen_intent,
  28. "build_payload",
  29. lambda: {"decision": {"signal": "no_signal"}, "data": {"decision_candle_ts": 1000}, "legs": []},
  30. )
  31. monkeypatch.setattr(module, "micro_signal", lambda: {"signal": "short"})
  32. payload = module.build_payload()
  33. assert payload["submitted_orders"] == 0
  34. assert payload["private_key_required"] is False
  35. assert payload["risk_limits"]["no_order_submission"] is True
  36. assert payload["risk_limits"]["blocked_for_live_trading"] is True
  37. assert payload["decision"]["selected_signal"] == "no_signal"
  38. assert payload["execution_intent"]["entry_signal"] == "no_signal"
  39. assert payload["execution_intent"]["entry_unit"] == 0.0
  40. assert payload["execution_intent"]["target_position_known"] is False
  41. def test_payload_records_nextgen_entry_unit(monkeypatch):
  42. monkeypatch.setattr(module, "latest_active_engine", lambda: {"active_engine": "nextgen", "decision_date": "2026-01-01"})
  43. monkeypatch.setattr(
  44. module.nextgen_intent,
  45. "build_payload",
  46. lambda: {"decision": {"signal": "long", "active_suggested_weight": 0.5}, "data": {"decision_candle_ts": 1000}, "legs": []},
  47. )
  48. monkeypatch.setattr(module, "micro_signal", lambda: {"signal": "no_signal"})
  49. payload = module.build_payload()
  50. assert payload["decision"]["selected_signal"] == "long"
  51. assert payload["execution_intent"]["entry_signal"] == "long"
  52. assert payload["execution_intent"]["entry_unit"] == 0.5
  53. assert payload["execution_intent"]["target_position"] is None