new strategies

This commit is contained in:
2025-10-25 21:51:25 +02:00
parent 76a858a7df
commit 541a71d2a6
6 changed files with 291 additions and 52 deletions

View File

@ -7,29 +7,23 @@ class MaCrossStrategy(BaseStrategy):
A strategy based on a fast Simple Moving Average (SMA) crossing
a slow SMA.
"""
def calculate_signals(self, df: pd.DataFrame) -> pd.DataFrame:
# Support multiple naming conventions: some configs use 'fast'/'slow'
# while others use 'short_ma'/'long_ma'. Normalize here so both work.
fast_ma_period = self.params.get('short_ma') or self.params.get('fast') or 0
slow_ma_period = self.params.get('long_ma') or self.params.get('slow') or 0
# If parameters are missing, return a neutral signal frame.
if not fast_ma_period or not slow_ma_period:
logging.warning(f"Missing MA period parameters (fast={fast_ma_period}, slow={slow_ma_period}).")
df['signal'] = 0
return df
def __init__(self, strategy_name: str, params: dict, log_level: str):
super().__init__(strategy_name, params)
self.fast_ma_period = self.params.get('short_ma') or self.params.get('fast') or 0
self.slow_ma_period = self.params.get('long_ma') or self.params.get('slow') or 0
if len(df) < slow_ma_period:
logging.warning(f"Not enough data for MA periods {fast_ma_period}/{slow_ma_period}. Need {slow_ma_period}, have {len(df)}.")
def calculate_signals(self, df: pd.DataFrame) -> pd.DataFrame:
if not self.fast_ma_period or not self.slow_ma_period or len(df) < self.slow_ma_period:
logging.warning(f"Not enough data for MA periods.")
df['signal'] = 0
return df
df['fast_sma'] = df['close'].rolling(window=fast_ma_period).mean()
df['slow_sma'] = df['close'].rolling(window=slow_ma_period).mean()
df['fast_sma'] = df['close'].rolling(window=self.fast_ma_period).mean()
df['slow_sma'] = df['close'].rolling(window=self.slow_ma_period).mean()
# Signal is 1 for Golden Cross (fast > slow), -1 for Death Cross
df['signal'] = 0
df.loc[df['fast_sma'] > df['slow_sma'], 'signal'] = 1
df.loc[df['fast_sma'] < df['slow_sma'], 'signal'] = -1
return df