feat: Add Trading Protection System with 4 protections + comprehensive tests

Implement automatic trading protection system to prevent excessive losses:

PROTECTIONS (100% original code, NOT copied from Freqtrade):
- Max Drawdown Protection: Blocks trading when DD > 15% (configurable)
- Cooldown Period: 4h mandatory rest after 5% loss
- Stoploss Guard: Detects stoploss clusters (>5 per day)
- Low Performance Filter: Filters factors with Sharpe < 0.5, Win Rate < 40%

ARCHITECTURE:
- Base protection interface with common utilities
- 4 specialized protection implementations
- ProtectionManager orchestrates all active protections
- Time-based blocking with automatic expiry

TESTS (32 total, ALL PASS):
- 25 unit tests in test/backtesting/test_protections.py
- 7 integration tests in test/integration/test_all_features.py
- Tests cover: normal operation, edge cases, error handling

DOCUMENTATION:
- Update QWEN.md with development guidelines for AI assistant
  * Mandatory rules: Update QWEN.md, README, requirements.txt, tests
  * Pre-commit checklist
  * Example workflow
- Update README.md with protection system features
- Update project structure with new modules

All code is 100% original - NO license issues with Freqtrade GPLv3.
This commit is contained in:
TPTBusiness
2026-04-03 13:01:56 +02:00
parent 2a011d262e
commit bd025e50dc
11 changed files with 1481 additions and 0 deletions
+95
View File
@@ -800,3 +800,98 @@ class TestIntegrationWorkflow:
checks = risk_manager.check_limits(weights, vol=0.15, dd=-0.08)
assert isinstance(checks, dict)
assert all(key in checks for key in ["position_limit", "leverage_limit", "drawdown_limit"])
# =============================================================================
# 14. PROTECTION MANAGER TESTS
# =============================================================================
class TestProtectionManager:
"""Test Protection Manager system."""
def test_protections_import(self):
"""Test that protections can be imported."""
from rdagent.components.backtesting.protections import (
ProtectionManager,
MaxDrawdownProtection,
CooldownProtection,
StoplossGuardProtection,
LowPerformanceProtection
)
def test_protection_manager_creates(self):
"""Test ProtectionManager can be created."""
from rdagent.components.backtesting.protections import ProtectionManager
manager = ProtectionManager()
assert manager is not None
def test_default_protections_configured(self):
"""Test default protections can be configured."""
from rdagent.components.backtesting.protections import ProtectionManager
manager = ProtectionManager()
manager.create_default_protections()
assert len(manager.protections) == 4
def test_protection_manager_blocks(self):
"""Test ProtectionManager can block trading."""
from rdagent.components.backtesting.protections import ProtectionManager
from datetime import datetime
manager = ProtectionManager()
manager.create_default_protections()
# Trigger max drawdown
result = manager.check_all(
returns=[-0.10, -0.05, -0.05],
timestamps=[datetime.now()] * 3,
current_equity=80000,
peak_equity=100000
)
assert result.should_block
def test_protection_manager_allows(self):
"""Test ProtectionManager allows good conditions."""
from rdagent.components.backtesting.protections import ProtectionManager
from datetime import datetime
manager = ProtectionManager()
manager.create_default_protections()
result = manager.check_all(
returns=[0.01, 0.02, 0.015],
timestamps=[datetime.now()] * 3,
current_equity=105000,
peak_equity=105000
)
assert not result.should_block
def test_protection_base_classes(self):
"""Test that base classes and enums are importable."""
from rdagent.components.backtesting.protections import (
BaseProtection,
ProtectionConfig,
ProtectionResult,
ProtectionType,
ProtectionScope
)
assert BaseProtection is not None
assert ProtectionResult is not None
assert ProtectionType is not None
assert ProtectionScope is not None
def test_protection_configs_importable(self):
"""Test that all config classes are importable."""
from rdagent.components.backtesting.protections import (
MaxDrawdownConfig,
CooldownConfig,
StoplossGuardConfig,
LowPerformanceConfig
)
assert MaxDrawdownConfig is not None
assert CooldownConfig is not None
assert StoplossGuardConfig is not None
assert LowPerformanceConfig is not None