| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- import math
- import importlib.util
- import sys
- from pathlib import Path
- import pytest
- from okx_codex_trader.models import Candle
- from okx_codex_trader.rsi2_report import RSI2Config
- def load_validation_module():
- path = Path(__file__).resolve().parents[1] / "scripts" / "validate_external_backtest.py"
- spec = importlib.util.spec_from_file_location("validate_external_backtest", path)
- assert spec is not None
- module = importlib.util.module_from_spec(spec)
- assert spec.loader is not None
- sys.modules[spec.name] = module
- spec.loader.exec_module(module)
- return module
- def build_oscillating_candles(count: int) -> list[Candle]:
- candles = []
- previous_close = 100.0
- for index in range(count):
- close = 100.0 + index * 0.04 + math.sin(index / 3.0) * 4.0
- open_price = previous_close
- high = max(open_price, close) + 0.5
- low = min(open_price, close) - 0.5
- candles.append(
- Candle(
- symbol="BTC-USDT-SWAP",
- ts=index * 60_000,
- open=open_price,
- high=high,
- low=low,
- close=close,
- volume=1_000.0,
- )
- )
- previous_close = close
- return candles
- def test_rsi2_matches_backtesting_py_on_same_signals_and_execution_model():
- module = load_validation_module()
- result = module.validate_rsi2_with_backtesting(
- candles=build_oscillating_candles(500),
- symbol="BTC-USDT-SWAP",
- bar="1m",
- leverage=3,
- config=RSI2Config(
- trend_sma=20,
- rsi_length=2,
- rsi_long_threshold=20.0,
- rsi_short_threshold=80.0,
- exit_rsi=50.0,
- ),
- )
- assert result.internal_trades == result.external_trades
- assert result.internal_trades > 0
- assert result.final_equity_diff == pytest.approx(0.0, abs=0.02)
- assert result.return_diff == pytest.approx(0.0, abs=0.000002)
- assert result.max_drawdown_diff == pytest.approx(0.0, abs=0.000002)
|