Vasily.onl 235098c045 Add strategy management system with multiple trading strategies
- Introduced a new strategies module containing the StrategyManager class to orchestrate multiple trading strategies.
- Implemented StrategyBase and StrategySignal as foundational components for strategy development.
- Added DefaultStrategy for meta-trend analysis and BBRSStrategy for Bollinger Bands + RSI trading.
- Enhanced documentation to provide clear usage examples and configuration guidelines for the new system.
- Established a modular architecture to support future strategy additions and improvements.
2025-05-23 16:41:08 +08:00

162 lines
5.6 KiB
Python

"""
Base classes for the strategy management system.
This module contains the fundamental building blocks for all trading strategies:
- StrategySignal: Represents trading signals with confidence and metadata
- StrategyBase: Abstract base class that all strategies must inherit from
"""
from abc import ABC, abstractmethod
from typing import Dict, Optional
class StrategySignal:
"""
Represents a trading signal from a strategy.
A signal encapsulates the strategy's recommendation along with confidence
level, optional price target, and additional metadata.
Attributes:
signal_type (str): Type of signal - "ENTRY", "EXIT", or "HOLD"
confidence (float): Confidence level from 0.0 to 1.0
price (Optional[float]): Optional specific price for the signal
metadata (Dict): Additional signal data and context
Example:
# Entry signal with high confidence
signal = StrategySignal("ENTRY", confidence=0.8)
# Exit signal with stop loss price
signal = StrategySignal("EXIT", confidence=1.0, price=50000,
metadata={"type": "STOP_LOSS"})
"""
def __init__(self, signal_type: str, confidence: float = 1.0,
price: Optional[float] = None, metadata: Optional[Dict] = None):
"""
Initialize a strategy signal.
Args:
signal_type: Type of signal ("ENTRY", "EXIT", "HOLD")
confidence: Confidence level (0.0 to 1.0)
price: Optional specific price for the signal
metadata: Additional signal data and context
"""
self.signal_type = signal_type
self.confidence = max(0.0, min(1.0, confidence)) # Clamp to [0,1]
self.price = price
self.metadata = metadata or {}
def __repr__(self) -> str:
"""String representation of the signal."""
return (f"StrategySignal(type={self.signal_type}, "
f"confidence={self.confidence:.2f}, "
f"price={self.price}, metadata={self.metadata})")
class StrategyBase(ABC):
"""
Abstract base class for all trading strategies.
This class defines the interface that all strategies must implement:
- initialize(): Setup strategy with backtester data
- get_entry_signal(): Generate entry signals
- get_exit_signal(): Generate exit signals
- get_confidence(): Optional confidence calculation
Attributes:
name (str): Strategy name
weight (float): Strategy weight for combination
params (Dict): Strategy parameters
initialized (bool): Whether strategy has been initialized
Example:
class MyStrategy(StrategyBase):
def initialize(self, backtester):
# Setup strategy indicators
self.initialized = True
def get_entry_signal(self, backtester, df_index):
# Return StrategySignal based on analysis
if should_enter:
return StrategySignal("ENTRY", confidence=0.7)
return StrategySignal("HOLD", confidence=0.0)
"""
def __init__(self, name: str, weight: float = 1.0, params: Optional[Dict] = None):
"""
Initialize the strategy base.
Args:
name: Strategy name/identifier
weight: Strategy weight for combination (default: 1.0)
params: Strategy-specific parameters
"""
self.name = name
self.weight = weight
self.params = params or {}
self.initialized = False
@abstractmethod
def initialize(self, backtester) -> None:
"""
Initialize strategy with backtester data.
This method is called once before backtesting begins.
Strategies should setup indicators, validate data, and
set self.initialized = True when complete.
Args:
backtester: Backtest instance with data and configuration
"""
pass
@abstractmethod
def get_entry_signal(self, backtester, df_index: int) -> StrategySignal:
"""
Generate entry signal for the given data index.
Args:
backtester: Backtest instance with current state
df_index: Current index in the dataframe
Returns:
StrategySignal: Entry signal with confidence level
"""
pass
@abstractmethod
def get_exit_signal(self, backtester, df_index: int) -> StrategySignal:
"""
Generate exit signal for the given data index.
Args:
backtester: Backtest instance with current state
df_index: Current index in the dataframe
Returns:
StrategySignal: Exit signal with confidence level
"""
pass
def get_confidence(self, backtester, df_index: int) -> float:
"""
Get strategy confidence for the current market state.
Default implementation returns 1.0. Strategies can override
this to provide dynamic confidence based on market conditions.
Args:
backtester: Backtest instance with current state
df_index: Current index in the dataframe
Returns:
float: Confidence level (0.0 to 1.0)
"""
return 1.0
def __repr__(self) -> str:
"""String representation of the strategy."""
return (f"{self.__class__.__name__}(name={self.name}, "
f"weight={self.weight}, initialized={self.initialized})")