Pre-refactor: commit before converting indicators to self-contained files

This commit is contained in:
DiTus
2026-03-01 19:37:07 +01:00
parent e457ce3e20
commit fdab0a3faa
22 changed files with 96 additions and 2726 deletions

View File

@ -1,68 +0,0 @@
"""
Base Strategy Interface
All strategies must inherit from this class.
"""
from abc import ABC, abstractmethod
from dataclasses import dataclass
from typing import Dict, Any, List, Optional
from enum import Enum
class SignalType(Enum):
OPEN_LONG = "open_long"
OPEN_SHORT = "open_short"
CLOSE_LONG = "close_long"
CLOSE_SHORT = "close_short"
HOLD = "hold"
@dataclass
class StrategySignal:
type: SignalType
confidence: float
reasoning: str
class BaseStrategy(ABC):
def __init__(self, config: Optional[Dict[str, Any]] = None):
self.config = config or {}
@property
@abstractmethod
def name(self) -> str:
"""Unique identifier for the strategy"""
pass
@property
@abstractmethod
def required_indicators(self) -> List[str]:
"""List of indicator names required by this strategy (e.g. ['ma44'])"""
pass
@property
@abstractmethod
def display_name(self) -> str:
"""User-friendly name for display in UI (e.g. 'MA44 Crossover')"""
pass
@property
@abstractmethod
def description(self) -> str:
"""Detailed description of how the strategy works"""
pass
@abstractmethod
def analyze(
self,
candle: Dict[str, Any],
indicators: Dict[str, float],
current_position: Optional[Dict[str, Any]] = None
) -> StrategySignal:
"""
Analyze market data and return a trading signal.
Args:
candle: Dictionary containing 'close', 'open', 'high', 'low', 'volume', 'time'
indicators: Dictionary of pre-computed indicator values
current_position: Details about current open position (if any)
{'type': 'long'/'short', 'entry_price': float, 'size': float}
"""
pass

View File

@ -1,77 +0,0 @@
"""
Moving Average Strategy
Configurable trend following strategy.
- Long when Price > MA(period)
- Short when Price < MA(period)
"""
from typing import Dict, Any, List, Optional
from .base import BaseStrategy, StrategySignal, SignalType
class MAStrategy(BaseStrategy):
"""
Configurable Moving Average Strategy.
Config:
- period: int - MA period (default: 44)
"""
DEFAULT_PERIOD = 44
@property
def name(self) -> str:
return "ma_trend"
@property
def required_indicators(self) -> List[str]:
# Dynamic based on config
period = self.config.get('period', self.DEFAULT_PERIOD)
return [f"ma{period}"]
@property
def display_name(self) -> str:
return "MA Strategy"
@property
def description(self) -> str:
return "Configurable Moving Average strategy. Parameters: period (5-500, default: 44). Goes long when price > MA(period), short when price < MA(period). Optional multi-timeframe trend filter available."
def analyze(
self,
candle: Dict[str, Any],
indicators: Dict[str, float],
current_position: Optional[Dict[str, Any]] = None
) -> StrategySignal:
period = self.config.get('period', self.DEFAULT_PERIOD)
ma_key = f"ma{period}"
price = candle['close']
ma_value = indicators.get(ma_key)
if ma_value is None:
return StrategySignal(SignalType.HOLD, 0.0, f"MA{period} not available")
# Current position state
is_long = current_position and current_position.get('type') == 'long'
is_short = current_position and current_position.get('type') == 'short'
# Logic: Price > MA -> Bullish
if price > ma_value:
if is_long:
return StrategySignal(SignalType.HOLD, 1.0, f"Price {price:.2f} > MA{period} {ma_value:.2f}. Stay Long.")
elif is_short:
return StrategySignal(SignalType.CLOSE_SHORT, 1.0, f"Price {price:.2f} crossed above MA{period} {ma_value:.2f}. Close Short.")
else:
return StrategySignal(SignalType.OPEN_LONG, 1.0, f"Price {price:.2f} > MA{period} {ma_value:.2f}. Open Long.")
# Logic: Price < MA -> Bearish
elif price < ma_value:
if is_short:
return StrategySignal(SignalType.HOLD, 1.0, f"Price {price:.2f} < MA{period} {ma_value:.2f}. Stay Short.")
elif is_long:
return StrategySignal(SignalType.CLOSE_LONG, 1.0, f"Price {price:.2f} crossed below MA{period} {ma_value:.2f}. Close Long.")
else:
return StrategySignal(SignalType.OPEN_SHORT, 1.0, f"Price {price:.2f} < MA{period} {ma_value:.2f}. Open Short.")
return StrategySignal(SignalType.HOLD, 0.0, f"Price == MA{period}")