"""Tests for Momentum strategy.""" import pytest from decimal import Decimal import pandas as pd from src.strategies.momentum.momentum_strategy import MomentumStrategy def test_momentum_strategy_initialization(): """Test Momentum strategy initializes correctly.""" strategy = MomentumStrategy("Test Momentum", { "lookback_period": 20, "momentum_threshold": 0.05 }) assert strategy.name == "Test Momentum" assert strategy.lookback_period == 20 assert strategy.momentum_threshold == Decimal("0.05") def test_momentum_calculation(): """Test momentum calculation.""" strategy = MomentumStrategy("Test", {"lookback_period": 5}) # Create price history prices = pd.Series([100, 101, 102, 103, 104, 105]) momentum = strategy._calculate_momentum(prices) # Should be positive (price increased) assert momentum > 0 assert momentum == 0.05 # (105 - 100) / 100 def test_momentum_entry_signal(): """Test momentum generates entry signal.""" strategy = MomentumStrategy("Test", { "lookback_period": 5, "momentum_threshold": 0.05, "volume_threshold": 1.0 }) # Build price history with momentum for i in range(10): price = 100 + i * 2 # Strong upward momentum volume = 1000 * (1.5 if i >= 5 else 1.0) # Volume increase strategy.on_tick("BTC/USD", Decimal(str(price)), "1h", {"volume": volume}) # Should generate buy signal signal = strategy.on_tick("BTC/USD", Decimal("120"), "1h", {"volume": 2000}) assert signal is not None assert signal.signal_type.value == "buy" assert strategy._in_position == True def test_momentum_exit_signal(): """Test momentum generates exit signal on reversal.""" strategy = MomentumStrategy("Test", { "lookback_period": 5, "exit_threshold": -0.02 }) strategy._in_position = True strategy._entry_price = Decimal("100") # Build history with reversal for i in range(10): price = 100 - i # Downward momentum strategy.on_tick("BTC/USD", Decimal(str(price)), "1h", {"volume": 1000}) signal = strategy.on_tick("BTC/USD", Decimal("90"), "1h", {"volume": 1000}) assert signal is not None assert signal.signal_type.value == "sell" assert strategy._in_position == False