mirror of
https://github.com/NicolasBohn/NexQuant.git
synced 2026-08-09 13:00:56 +00:00
refactor: remove all proprietary terms from codebase and git history
- Rename FTMO_* constants → generic names (RISK_PER_TRADE, MAX_DAILY_LOSS, etc.) - Rename backtest_signal_ftmo → backtest_signal_risk - Rename _apply_ftmo_mask → _apply_risk_mask - Clean all FTMO/riskMgmt mentions from commit messages via filter-branch - AGENTS.md: add non-negotiable rule — NEVER mention proprietary terms in commits/releases - Code variables and function names sanitized project-wide - Force-pushed rewritten history to remote
This commit is contained in:
@@ -51,7 +51,7 @@ class TestBuildMLModel:
|
||||
result = build_ml_model(factor_data.iloc[:100], close_data.iloc[:100], "swing")
|
||||
assert result is None
|
||||
|
||||
@patch("rdagent.components.backtesting.vbt_backtest.backtest_signal_ftmo")
|
||||
@patch("rdagent.components.backtesting.vbt_backtest.backtest_signal_risk")
|
||||
def test_sufficient_data_returns_dict(self, mock_bt, factor_data, close_data):
|
||||
mock_bt.return_value = {
|
||||
"sharpe": 1.5, "max_drawdown": -0.1, "win_rate": 0.55,
|
||||
@@ -65,7 +65,7 @@ class TestBuildMLModel:
|
||||
assert result["status"] == "accepted"
|
||||
assert result["type"] == "ml_model"
|
||||
|
||||
@patch("rdagent.components.backtesting.vbt_backtest.backtest_signal_ftmo")
|
||||
@patch("rdagent.components.backtesting.vbt_backtest.backtest_signal_risk")
|
||||
def test_negative_oos_rejected(self, mock_bt, factor_data, close_data):
|
||||
mock_bt.return_value = {
|
||||
"sharpe": 1.5, "max_drawdown": -0.1, "win_rate": 0.55,
|
||||
|
||||
@@ -7,7 +7,7 @@ Tests cover:
|
||||
- Parameter space definition and validation
|
||||
- Parameter suggestion mechanisms
|
||||
- Objective function calculation
|
||||
- FTMO penalty logic
|
||||
- RiskMgmt penalty logic
|
||||
- Optuna study creation and configuration
|
||||
- Parameter injection into strategy code
|
||||
- Optimization run (mocked, small trial count)
|
||||
@@ -37,11 +37,11 @@ except ImportError:
|
||||
from rdagent.scenarios.qlib.local.optuna_optimizer import (
|
||||
OptunaOptimizer,
|
||||
PARAMETER_SPACE,
|
||||
FTMO_MAX_STOP_LOSS,
|
||||
FTMO_MAX_DRAWDOWN,
|
||||
FTMO_MAX_DAILY_LOSS,
|
||||
RiskMgmt_MAX_STOP_LOSS,
|
||||
RiskMgmt_MAX_DRAWDOWN,
|
||||
MAX_DAILY_LOSS,
|
||||
PENALTY_MAX_DD,
|
||||
PENALTY_FTMO_VIOLATION,
|
||||
PENALTY_RiskMgmt_VIOLATION,
|
||||
OPTUNA_AVAILABLE,
|
||||
)
|
||||
|
||||
@@ -205,10 +205,10 @@ class TestParameterSpaceDefinition:
|
||||
assert config['choices'] == [5, 10, 15, 20]
|
||||
|
||||
def test_parameter_space_stop_loss_config(self):
|
||||
"""Test stop_loss parameter configuration (FTMO compliant)."""
|
||||
"""Test stop_loss parameter configuration (RiskMgmt compliant)."""
|
||||
config = PARAMETER_SPACE['stop_loss']
|
||||
assert config['type'] == 'categorical'
|
||||
assert all(c <= FTMO_MAX_STOP_LOSS for c in config['choices'])
|
||||
assert all(c <= RiskMgmt_MAX_STOP_LOSS for c in config['choices'])
|
||||
|
||||
def test_parameter_space_take_profit_config(self):
|
||||
"""Test take_profit parameter configuration."""
|
||||
@@ -222,16 +222,16 @@ class TestParameterSpaceDefinition:
|
||||
assert config['type'] == 'categorical'
|
||||
assert config['choices'] == [0.01, 0.015]
|
||||
|
||||
def test_ftmo_constants_correct(self):
|
||||
"""Test FTMO compliance constants."""
|
||||
assert FTMO_MAX_STOP_LOSS == 0.02
|
||||
assert FTMO_MAX_DRAWDOWN == -0.10
|
||||
assert FTMO_MAX_DAILY_LOSS == 0.05
|
||||
def test_riskmgmt_constants_correct(self):
|
||||
"""Test RiskMgmt compliance constants."""
|
||||
assert RiskMgmt_MAX_STOP_LOSS == 0.02
|
||||
assert RiskMgmt_MAX_DRAWDOWN == -0.10
|
||||
assert MAX_DAILY_LOSS == 0.05
|
||||
|
||||
def test_penalty_constants_correct(self):
|
||||
"""Test penalty weight constants."""
|
||||
assert PENALTY_MAX_DD == -10.0
|
||||
assert PENALTY_FTMO_VIOLATION == -50.0
|
||||
assert PENALTY_RiskMgmt_VIOLATION == -50.0
|
||||
|
||||
|
||||
# =============================================================================
|
||||
@@ -420,15 +420,15 @@ class TestObjectiveFunction:
|
||||
|
||||
|
||||
# =============================================================================
|
||||
# FTMO Penalty Tests
|
||||
# RiskMgmt Penalty Tests
|
||||
# =============================================================================
|
||||
|
||||
@pytest.mark.skipif(not OPTUNA_AVAILABLE, reason="Optuna not installed")
|
||||
class TestFTMOPenalties:
|
||||
"""Test FTMO compliance penalties."""
|
||||
class TestRiskMgmtPenalties:
|
||||
"""Test RiskMgmt compliance penalties."""
|
||||
|
||||
def test_penalty_max_drawdown_violation(self, optimizer):
|
||||
"""Test penalty when max drawdown exceeds FTMO limit."""
|
||||
"""Test penalty when max drawdown exceeds RiskMgmt limit."""
|
||||
study = optuna.create_study(sampler=optuna.samplers.TPESampler(seed=42))
|
||||
|
||||
with patch.object(optimizer, '_run_backtest_with_params') as mock_bt:
|
||||
@@ -437,7 +437,7 @@ class TestFTMOPenalties:
|
||||
'sharpe_ratio': 1.5,
|
||||
'ic': 0.08,
|
||||
'total_trades': 25,
|
||||
'max_drawdown': -0.12, # Below FTMO_MAX_DRAWDOWN (-0.10)
|
||||
'max_drawdown': -0.12, # Below RiskMgmt_MAX_DRAWDOWN (-0.10)
|
||||
}
|
||||
|
||||
trial = study.ask()
|
||||
@@ -449,10 +449,10 @@ class TestFTMOPenalties:
|
||||
assert history['penalty'] <= PENALTY_MAX_DD
|
||||
|
||||
def test_penalty_stop_loss_violation(self, optimizer):
|
||||
"""Test penalty when stop loss exceeds FTMO maximum."""
|
||||
"""Test penalty when stop loss exceeds RiskMgmt maximum."""
|
||||
study = optuna.create_study(sampler=optuna.samplers.TPESampler(seed=42))
|
||||
|
||||
# Create a custom parameter space that allows FTMO-violating values
|
||||
# Create a custom parameter space that allows RiskMgmt-violating values
|
||||
violating_space = {
|
||||
**PARAMETER_SPACE,
|
||||
'stop_loss': {'type': 'categorical', 'choices': [0.01, 0.025, 0.03]},
|
||||
@@ -475,13 +475,13 @@ class TestFTMOPenalties:
|
||||
value = optimizer.objective(trial)
|
||||
|
||||
history = optimizer._optimization_history[-1]
|
||||
assert history['penalty'] <= PENALTY_FTMO_VIOLATION
|
||||
assert history['penalty'] <= PENALTY_RiskMgmt_VIOLATION
|
||||
|
||||
# Restore original space
|
||||
optimizer.parameter_space = optimizer.param_space_original
|
||||
|
||||
def test_no_penalty_compliant_strategy(self, optimizer):
|
||||
"""Test no penalty for FTMO-compliant strategy."""
|
||||
"""Test no penalty for RiskMgmt-compliant strategy."""
|
||||
study = optuna.create_study(sampler=optuna.samplers.TPESampler(seed=42))
|
||||
|
||||
with patch.object(optimizer, '_run_backtest_with_params') as mock_bt:
|
||||
@@ -490,7 +490,7 @@ class TestFTMOPenalties:
|
||||
'sharpe_ratio': 1.5,
|
||||
'ic': 0.08,
|
||||
'total_trades': 25,
|
||||
'max_drawdown': -0.05, # Within FTMO limit
|
||||
'max_drawdown': -0.05, # Within RiskMgmt limit
|
||||
}
|
||||
|
||||
trial = study.ask()
|
||||
@@ -517,7 +517,7 @@ class TestFTMOPenalties:
|
||||
'sharpe_ratio': 1.5,
|
||||
'ic': 0.08,
|
||||
'total_trades': 25,
|
||||
'max_drawdown': -0.12, # FTMO violation
|
||||
'max_drawdown': -0.12, # RiskMgmt violation
|
||||
}
|
||||
|
||||
trial = study.ask()
|
||||
@@ -526,7 +526,7 @@ class TestFTMOPenalties:
|
||||
|
||||
history = optimizer._optimization_history[-1]
|
||||
# Both penalties should apply
|
||||
expected_penalty = PENALTY_MAX_DD + PENALTY_FTMO_VIOLATION
|
||||
expected_penalty = PENALTY_MAX_DD + PENALTY_RiskMgmt_VIOLATION
|
||||
assert history['penalty'] == expected_penalty
|
||||
|
||||
|
||||
|
||||
@@ -452,9 +452,9 @@ class TestAcceptanceGate:
|
||||
assert gate.min_sharpe == 0.5
|
||||
assert gate.min_trades == 10
|
||||
assert gate.max_drawdown == -0.15
|
||||
assert gate.ftmo_max_sl == 0.02
|
||||
assert gate.ftmo_max_daily_loss == 0.05
|
||||
assert gate.ftmo_max_dd == 0.10
|
||||
assert gate.riskmgmt_max_sl == 0.02
|
||||
assert gate.riskmgmt_max_daily_loss == 0.05
|
||||
assert gate.riskmgmt_max_dd == 0.10
|
||||
|
||||
def test_evaluate_passing_strategy(self, acceptance_gate):
|
||||
"""Test evaluation of passing strategy."""
|
||||
@@ -474,8 +474,8 @@ class TestAcceptanceGate:
|
||||
assert evaluation['checks']['sharpe']['passed'] is True
|
||||
assert evaluation['checks']['trades']['passed'] is True
|
||||
assert evaluation['checks']['max_drawdown']['passed'] is True
|
||||
assert evaluation['checks']['ftmo_sl']['passed'] is True
|
||||
assert evaluation['checks']['ftmo_max_dd']['passed'] is True
|
||||
assert evaluation['checks']['riskmgmt_sl']['passed'] is True
|
||||
assert evaluation['checks']['riskmgmt_max_dd']['passed'] is True
|
||||
|
||||
def test_evaluate_failing_ic(self, acceptance_gate):
|
||||
"""Test failure due to low IC."""
|
||||
@@ -540,10 +540,10 @@ class TestAcceptanceGate:
|
||||
assert evaluation['passed'] is False
|
||||
assert any('DD' in r or 'drawdown' in r.lower() for r in evaluation['reasons'])
|
||||
assert evaluation['checks']['max_drawdown']['passed'] is False
|
||||
assert evaluation['checks']['ftmo_max_dd']['passed'] is False
|
||||
assert evaluation['checks']['riskmgmt_max_dd']['passed'] is False
|
||||
|
||||
def test_evaluate_failing_ftmo_sl(self, acceptance_gate):
|
||||
"""Test FTMO stop loss violation."""
|
||||
def test_evaluate_failing_riskmgmt_sl(self, acceptance_gate):
|
||||
"""Test RiskMgmt stop loss violation."""
|
||||
result = {
|
||||
'ic': 0.05,
|
||||
'sharpe_ratio': 1.2,
|
||||
@@ -555,7 +555,7 @@ class TestAcceptanceGate:
|
||||
evaluation = acceptance_gate.evaluate(result)
|
||||
|
||||
assert evaluation['passed'] is False
|
||||
assert evaluation['checks']['ftmo_sl']['passed'] is False
|
||||
assert evaluation['checks']['riskmgmt_sl']['passed'] is False
|
||||
|
||||
def test_evaluate_ic_none(self, acceptance_gate):
|
||||
"""Test when IC is None."""
|
||||
|
||||
Reference in New Issue
Block a user