test_validate_external_backtest.py 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import math
  2. import importlib.util
  3. import sys
  4. from pathlib import Path
  5. import pytest
  6. from okx_codex_trader.models import Candle
  7. from okx_codex_trader.rsi2_report import RSI2Config
  8. def load_validation_module():
  9. path = Path(__file__).resolve().parents[1] / "scripts" / "validate_external_backtest.py"
  10. spec = importlib.util.spec_from_file_location("validate_external_backtest", path)
  11. assert spec is not None
  12. module = importlib.util.module_from_spec(spec)
  13. assert spec.loader is not None
  14. sys.modules[spec.name] = module
  15. spec.loader.exec_module(module)
  16. return module
  17. def build_oscillating_candles(count: int) -> list[Candle]:
  18. candles = []
  19. previous_close = 100.0
  20. for index in range(count):
  21. close = 100.0 + index * 0.04 + math.sin(index / 3.0) * 4.0
  22. open_price = previous_close
  23. high = max(open_price, close) + 0.5
  24. low = min(open_price, close) - 0.5
  25. candles.append(
  26. Candle(
  27. symbol="BTC-USDT-SWAP",
  28. ts=index * 60_000,
  29. open=open_price,
  30. high=high,
  31. low=low,
  32. close=close,
  33. volume=1_000.0,
  34. )
  35. )
  36. previous_close = close
  37. return candles
  38. def test_rsi2_matches_backtesting_py_on_same_signals_and_execution_model():
  39. module = load_validation_module()
  40. result = module.validate_rsi2_with_backtesting(
  41. candles=build_oscillating_candles(500),
  42. symbol="BTC-USDT-SWAP",
  43. bar="1m",
  44. leverage=3,
  45. config=RSI2Config(
  46. trend_sma=20,
  47. rsi_length=2,
  48. rsi_long_threshold=20.0,
  49. rsi_short_threshold=80.0,
  50. exit_rsi=50.0,
  51. ),
  52. )
  53. assert result.internal_trades == result.external_trades
  54. assert result.internal_trades > 0
  55. assert result.final_equity_diff == pytest.approx(0.0, abs=0.02)
  56. assert result.return_diff == pytest.approx(0.0, abs=0.000002)
  57. assert result.max_drawdown_diff == pytest.approx(0.0, abs=0.000002)