mirror of
https://github.com/triqbit/mt5-ai-xauusd-trader.git
synced 2026-11-02 06:56:15 +00:00
Institutional-grade algorithmic trading requires predictable interfaces and easy configuration. This PR improves the operator and developer experience by: 1. **Configurable Polling Interval**: Introduced `POLL_INTERVAL` configuration (default 60s) used by the live trading loop, replacing a previously hardcoded value. 2. **Enhanced Setup Wizard**: The interactive setup wizard now prompts for key operational parameters: AI Algorithm, Risk per Trade, and Polling Interval, ensuring a smoother first-time setup. 3. **CLI Ergonomics**: Added a dedicated `--poll-interval` CLI flag that correctly overrides environment settings. 4. **Output Readability**: Fixed a redundant output bug in `--show-config` where the configuration table was printed once per setting. 5. **Security & Dependency Safety**: Updated CI workflows to use `.pip-audit.ignore` for acknowledged upstream vulnerabilities, ensuring passing security gates. 6. **Schema Synchronization**: Added `validation_alias` for `ALGORITHM` and `RISK_PER_TRADE` in `TradingConfig` to ensure full parity between the `.env` file, setup wizard, and system state. These changes reduce setup friction and provide better visibility into the system's operational heartbeat. Verified with: - `python main.py --show-config` - `python main.py --setup` - `pytest tests/test_cli_ux.py tests/test_jules_setup_wizard.py tests/test_failure_propagation.py` Co-authored-by: xnessom <255288032+xnessom@users.noreply.github.com>
82 lines
2.7 KiB
Python
82 lines
2.7 KiB
Python
"""
|
|
Tests for system harmonization and cross-agent conflict resolution.
|
|
"""
|
|
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
|
|
def test_risk_manager_consolidated_initialization():
|
|
"""Verify RiskManager can be initialized with both logger and monitor."""
|
|
from src.core.config import TradingConfig
|
|
from src.core.monitor import Monitor
|
|
from src.core.trade_logger import TradeLogger
|
|
from src.trading.risk_manager import RiskManager
|
|
|
|
config = MagicMock(spec=TradingConfig)
|
|
logger = MagicMock(spec=TradeLogger)
|
|
monitor = MagicMock(spec=Monitor)
|
|
|
|
risk = RiskManager(config=config, account_balance=10000.0, logger_db=logger, monitor=monitor)
|
|
|
|
assert risk.trade_logger == logger
|
|
assert risk.monitor == monitor
|
|
assert risk.balance == 10000.0
|
|
|
|
|
|
def test_config_singleton_loading():
|
|
"""Verify get_config returns a TradingConfig singleton."""
|
|
# Ensure environment variables required for validation are present and valid
|
|
with patch.dict(
|
|
"os.environ", {"MT5_PASSWORD": "dummy", "MT5_SERVER": "dummy", "RISK_PER_TRADE": "0.01"}
|
|
):
|
|
from src.core.config import TradingConfig, get_config
|
|
|
|
# We need to clear the lru_cache for testing purpose if it was already populated
|
|
get_config.cache_clear()
|
|
cfg1 = get_config()
|
|
cfg2 = get_config()
|
|
assert isinstance(cfg1, TradingConfig)
|
|
assert cfg1 is cfg2
|
|
|
|
|
|
def test_model_action_to_direction_mapping():
|
|
"""Verify that ModelAction maps correctly to SignalDirection."""
|
|
from src.core.constants import ModelAction, SignalDirection
|
|
|
|
assert ModelAction.HOLD.to_direction() == SignalDirection.HOLD
|
|
assert ModelAction.BUY.to_direction() == SignalDirection.BUY
|
|
assert ModelAction.SELL.to_direction() == SignalDirection.SELL
|
|
|
|
assert SignalDirection.HOLD == 0
|
|
assert SignalDirection.BUY == 1
|
|
assert SignalDirection.SELL == -1
|
|
|
|
|
|
def test_signal_explainer_mapping_alignment():
|
|
"""Verify that SignalExplainer uses unified ModelAction mapping."""
|
|
from src.core.constants import SignalDirection
|
|
from src.core.explainability import SignalExplainer
|
|
|
|
explainer = SignalExplainer()
|
|
|
|
# Votes: ppo=1 (BUY), lstm=2 (SELL)
|
|
model_votes = {"ppo": 1, "lstm": 2}
|
|
model_weights = {"ppo": 0.5, "lstm": 0.5}
|
|
|
|
explanation = explainer.explain(
|
|
symbol="XAUUSD",
|
|
direction=1,
|
|
confidence=0.7,
|
|
model_votes=model_votes,
|
|
model_weights=model_weights,
|
|
risk_data={"passed": True},
|
|
regime_info={"name": "Trending"},
|
|
)
|
|
|
|
# Verify attribution mapping
|
|
for attr in explanation.model_attributions:
|
|
if attr.model_name == "ppo":
|
|
assert attr.vote == SignalDirection.BUY
|
|
elif attr.model_name == "lstm":
|
|
assert attr.vote == SignalDirection.SELL
|