Local changes: Updated model training, removed debug instrumentation, and configuration improvements
This commit is contained in:
79
src/strategies/technical/moving_avg_strategy.py
Normal file
79
src/strategies/technical/moving_avg_strategy.py
Normal file
@@ -0,0 +1,79 @@
|
||||
"""Moving Average Crossover strategy."""
|
||||
|
||||
import pandas as pd
|
||||
from decimal import Decimal
|
||||
from typing import Optional, Dict, Any
|
||||
from src.strategies.base import BaseStrategy, StrategySignal, SignalType
|
||||
from src.data.indicators import get_indicators
|
||||
|
||||
class MovingAverageStrategy(BaseStrategy):
|
||||
"""Moving average crossover strategy."""
|
||||
|
||||
def __init__(self, name: str, parameters: Optional[Dict[str, Any]] = None, timeframes: Optional[list] = None):
|
||||
"""Initialize moving average strategy.
|
||||
|
||||
Parameters:
|
||||
fast_period: Fast MA period (default 10)
|
||||
slow_period: Slow MA period (default 30)
|
||||
ma_type: MA type - 'sma' or 'ema' (default 'ema')
|
||||
"""
|
||||
super().__init__(name, parameters, timeframes)
|
||||
self.fast_period = self.parameters.get('fast_period', 10)
|
||||
self.slow_period = self.parameters.get('slow_period', 30)
|
||||
self.ma_type = self.parameters.get('ma_type', 'ema')
|
||||
self.indicators = get_indicators()
|
||||
self._price_history = []
|
||||
|
||||
async def on_tick(self, symbol: str, price: Decimal, timeframe: str, data: Dict[str, Any]) -> Optional[StrategySignal]:
|
||||
"""Generate signal based on MA crossover."""
|
||||
|
||||
|
||||
# Add price to history
|
||||
self._price_history.append(float(price))
|
||||
if len(self._price_history) < self.slow_period + 1:
|
||||
return None
|
||||
|
||||
# Calculate MAs
|
||||
prices = pd.Series(self._price_history[-self.slow_period-1:])
|
||||
|
||||
if self.ma_type == 'sma':
|
||||
fast_ma = self.indicators.sma(prices, self.fast_period)
|
||||
slow_ma = self.indicators.sma(prices, self.slow_period)
|
||||
else:
|
||||
fast_ma = self.indicators.ema(prices, self.fast_period)
|
||||
slow_ma = self.indicators.ema(prices, self.slow_period)
|
||||
|
||||
if len(fast_ma) < 2 or len(slow_ma) < 2:
|
||||
return None
|
||||
|
||||
# Check for crossover
|
||||
fast_current = fast_ma.iloc[-1]
|
||||
fast_prev = fast_ma.iloc[-2]
|
||||
slow_current = slow_ma.iloc[-1]
|
||||
slow_prev = slow_ma.iloc[-2]
|
||||
|
||||
# Bullish crossover
|
||||
if fast_prev <= slow_prev and fast_current > slow_current:
|
||||
return StrategySignal(
|
||||
signal_type=SignalType.BUY,
|
||||
symbol=symbol,
|
||||
strength=min(1.0, (fast_current - slow_current) / slow_current),
|
||||
price=price,
|
||||
metadata={'fast_ma': float(fast_current), 'slow_ma': float(slow_current)}
|
||||
)
|
||||
# Bearish crossover
|
||||
elif fast_prev >= slow_prev and fast_current < slow_current:
|
||||
return StrategySignal(
|
||||
signal_type=SignalType.SELL,
|
||||
symbol=symbol,
|
||||
strength=min(1.0, (slow_current - fast_current) / slow_current),
|
||||
price=price,
|
||||
metadata={'fast_ma': float(fast_current), 'slow_ma': float(slow_current)}
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
def on_signal(self, signal: StrategySignal) -> Optional[StrategySignal]:
|
||||
"""Process signal."""
|
||||
return signal if self.should_execute(signal) else None
|
||||
|
||||
Reference in New Issue
Block a user