Files
crypto_trader/tests/unit/autopilot/test_strategy_groups.py

162 lines
6.4 KiB
Python

"""Tests for strategy grouping module."""
import pytest
from src.autopilot.strategy_groups import (
StrategyGroup,
STRATEGY_TO_GROUP,
GROUP_TO_STRATEGIES,
get_strategy_group,
get_strategies_in_group,
get_all_groups,
get_best_strategy_in_group,
convert_strategy_to_group_label,
)
class TestStrategyGroupMappings:
"""Tests for strategy group mappings."""
def test_all_strategies_have_group(self):
"""Verify all registered strategies are mapped to a group."""
# These are the strategies registered in src/strategies/__init__.py
expected_strategies = [
"rsi", "macd", "moving_average", "confirmed", "divergence",
"bollinger_mean_reversion", "dca", "grid", "momentum",
"consensus", "pairs_trading", "volatility_breakout",
"sentiment", "market_making"
]
for strategy in expected_strategies:
group = get_strategy_group(strategy)
assert group is not None, f"Strategy '{strategy}' is not mapped to any group"
def test_get_strategy_group_case_insensitive(self):
"""Test that strategy lookup is case-insensitive."""
assert get_strategy_group("RSI") == get_strategy_group("rsi")
assert get_strategy_group("MACD") == get_strategy_group("macd")
assert get_strategy_group("Moving_Average") == get_strategy_group("moving_average")
def test_get_strategy_group_unknown(self):
"""Test that unknown strategies return None."""
assert get_strategy_group("nonexistent_strategy") is None
assert get_strategy_group("") is None
def test_group_to_strategies_reverse_mapping(self):
"""Verify GROUP_TO_STRATEGIES is the reverse of STRATEGY_TO_GROUP."""
for strategy, group in STRATEGY_TO_GROUP.items():
assert strategy in GROUP_TO_STRATEGIES[group]
def test_all_groups_have_strategies(self):
"""Verify all groups have at least one strategy."""
for group in StrategyGroup:
strategies = get_strategies_in_group(group)
assert len(strategies) > 0, f"Group '{group}' has no strategies"
class TestGetAllGroups:
"""Tests for get_all_groups function."""
def test_returns_all_groups(self):
"""Verify all groups are returned."""
groups = get_all_groups()
assert len(groups) == 5
assert StrategyGroup.TREND_FOLLOWING in groups
assert StrategyGroup.MEAN_REVERSION in groups
assert StrategyGroup.MOMENTUM in groups
assert StrategyGroup.MARKET_MAKING in groups
assert StrategyGroup.SENTIMENT_BASED in groups
class TestGetStrategiesInGroup:
"""Tests for get_strategies_in_group function."""
def test_trend_following_strategies(self):
"""Test trend following group contains expected strategies."""
strategies = get_strategies_in_group(StrategyGroup.TREND_FOLLOWING)
assert "moving_average" in strategies
assert "macd" in strategies
assert "confirmed" in strategies
def test_mean_reversion_strategies(self):
"""Test mean reversion group contains expected strategies."""
strategies = get_strategies_in_group(StrategyGroup.MEAN_REVERSION)
assert "rsi" in strategies
assert "bollinger_mean_reversion" in strategies
assert "grid" in strategies
def test_momentum_strategies(self):
"""Test momentum group contains expected strategies."""
strategies = get_strategies_in_group(StrategyGroup.MOMENTUM)
assert "momentum" in strategies
assert "volatility_breakout" in strategies
class TestGetBestStrategyInGroup:
"""Tests for get_best_strategy_in_group function."""
def test_trend_following_high_adx(self):
"""Test trend following selection with high ADX."""
features = {"adx": 35.0, "rsi": 50.0, "atr_percent": 2.0, "volume_ratio": 1.0}
strategy, confidence = get_best_strategy_in_group(
StrategyGroup.TREND_FOLLOWING, features
)
assert strategy == "confirmed"
assert confidence > 0.5
def test_mean_reversion_extreme_rsi(self):
"""Test mean reversion selection with extreme RSI."""
features = {"adx": 15.0, "rsi": 25.0, "atr_percent": 1.5, "volume_ratio": 1.0}
strategy, confidence = get_best_strategy_in_group(
StrategyGroup.MEAN_REVERSION, features
)
assert strategy == "rsi"
assert confidence > 0.5
def test_momentum_high_volume(self):
"""Test momentum selection with high volume."""
features = {"adx": 25.0, "rsi": 55.0, "atr_percent": 3.0, "volume_ratio": 2.0}
strategy, confidence = get_best_strategy_in_group(
StrategyGroup.MOMENTUM, features
)
assert strategy == "volatility_breakout"
assert confidence > 0.5
def test_respects_available_strategies(self):
"""Test that only available strategies are selected."""
features = {"adx": 35.0, "rsi": 50.0}
# Only MACD available from trend following
strategy, confidence = get_best_strategy_in_group(
StrategyGroup.TREND_FOLLOWING,
features,
available_strategies=["macd"]
)
assert strategy == "macd"
def test_fallback_when_no_strategies_available(self):
"""Test fallback when no strategies in group are available."""
features = {"adx": 25.0, "rsi": 50.0}
strategy, confidence = get_best_strategy_in_group(
StrategyGroup.TREND_FOLLOWING,
features,
available_strategies=["some_other_strategy"]
)
# Should return safe default
assert strategy == "rsi"
assert confidence == 0.5
class TestConvertStrategyToGroupLabel:
"""Tests for convert_strategy_to_group_label function."""
def test_converts_known_strategies(self):
"""Test conversion of known strategies."""
assert convert_strategy_to_group_label("rsi") == "mean_reversion"
assert convert_strategy_to_group_label("macd") == "trend_following"
assert convert_strategy_to_group_label("momentum") == "momentum"
assert convert_strategy_to_group_label("dca") == "market_making"
assert convert_strategy_to_group_label("sentiment") == "sentiment_based"
def test_unknown_strategy_returns_original(self):
"""Test that unknown strategies return original name."""
assert convert_strategy_to_group_label("unknown") == "unknown"