From 9629d3090b9476cead8a3811f55db08e19361e50 Mon Sep 17 00:00:00 2001 From: "Vasily.onl" Date: Fri, 23 May 2025 17:06:35 +0800 Subject: [PATCH] Enhance README and documentation for Cycles framework - Expanded the README.md to provide a comprehensive overview of the Cycles framework, including features, quick start instructions, and configuration examples. - Updated strategies documentation to detail the architecture, available strategies, and their configurations, emphasizing the new multi-timeframe capabilities. - Added a new timeframe system documentation to explain the strategy-controlled timeframe management and automatic data resampling. - Improved the strategy manager documentation to clarify its role in orchestrating multiple strategies and combining signals effectively. - Adjusted configuration examples to reflect recent changes in strategy parameters and usage. --- README.md | 178 +++++++++++++- configs/config_bbrs.json | 2 +- docs/strategies.md | 459 +++++++++++++++++++++++++++++------ docs/strategy_manager.md | 512 ++++++++++++++++++++++----------------- docs/timeframe_system.md | 488 +++++++++++++++++++++++++++++++++++++ 5 files changed, 1335 insertions(+), 304 deletions(-) create mode 100644 docs/timeframe_system.md diff --git a/README.md b/README.md index 63767a6..3528dc1 100644 --- a/README.md +++ b/README.md @@ -1 +1,177 @@ -# Cycles +# Cycles - Advanced Trading Strategy Backtesting Framework + +A sophisticated Python framework for backtesting cryptocurrency trading strategies with multi-timeframe analysis, strategy combination, and advanced signal processing. + +## Features + +- **Multi-Strategy Architecture**: Combine multiple trading strategies with configurable weights and rules +- **Multi-Timeframe Analysis**: Strategies can operate on different timeframes (1min, 5min, 15min, 1h, etc.) +- **Advanced Strategies**: + - **Default Strategy**: Meta-trend analysis using multiple Supertrend indicators + - **BBRS Strategy**: Bollinger Bands + RSI with market regime detection +- **Flexible Signal Combination**: Weighted consensus, majority voting, any/all combinations +- **Precise Stop-Loss**: 1-minute precision for accurate risk management +- **Comprehensive Backtesting**: Detailed performance metrics and trade analysis +- **Data Visualization**: Interactive charts and performance plots + +## Quick Start + +### Prerequisites + +- Python 3.8+ +- [uv](https://github.com/astral-sh/uv) package manager (recommended) + +### Installation + +```bash +# Clone the repository +git clone +cd Cycles + +# Install dependencies with uv +uv sync + +# Or install with pip +pip install -r requirements.txt +``` + +### Running Backtests + +Use the `uv run` command to execute backtests with different configurations: + +```bash +# Run default strategy on 5-minute timeframe +uv run .\main.py .\configs\config_default_5min.json + +# Run default strategy on 15-minute timeframe +uv run .\main.py .\configs\config_default.json + +# Run BBRS strategy with market regime detection +uv run .\main.py .\configs\config_bbrs.json + +# Run combined strategies +uv run .\main.py .\configs\config_combined.json +``` + +### Configuration Examples + +#### Default Strategy (5-minute timeframe) +```bash +uv run .\main.py .\configs\config_default_5min.json +``` + +#### BBRS Strategy with Multi-timeframe Analysis +```bash +uv run .\main.py .\configs\config_bbrs_multi_timeframe.json +``` + +#### Combined Strategies with Weighted Consensus +```bash +uv run .\main.py .\configs\config_combined.json +``` + +## Configuration + +Strategies are configured using JSON files in the `configs/` directory: + +```json +{ + "start_date": "2024-01-01", + "stop_date": "2024-01-31", + "initial_usd": 10000, + "timeframes": ["15min"], + "stop_loss_pcts": [0.03, 0.05], + "strategies": [ + { + "name": "default", + "weight": 1.0, + "params": { + "timeframe": "15min" + } + } + ], + "combination_rules": { + "entry": "any", + "exit": "any", + "min_confidence": 0.5 + } +} +``` + +### Available Strategies + +1. **Default Strategy**: Meta-trend analysis using Supertrend indicators +2. **BBRS Strategy**: Bollinger Bands + RSI with market regime detection + +### Combination Rules + +- **Entry**: `any`, `all`, `majority`, `weighted_consensus` +- **Exit**: `any`, `all`, `priority` (prioritizes stop-loss signals) + +## Project Structure + +``` +Cycles/ +├── configs/ # Configuration files +├── cycles/ # Core framework +│ ├── strategies/ # Strategy implementation +│ │ ├── base.py # Base strategy classes +│ │ ├── default_strategy.py +│ │ ├── bbrs_strategy.py +│ │ └── manager.py # Strategy manager +│ ├── Analysis/ # Technical analysis +│ ├── utils/ # Utilities +│ └── charts.py # Visualization +├── docs/ # Documentation +├── data/ # Market data +├── results/ # Backtest results +└── main.py # Main entry point +``` + +## Documentation + +Detailed documentation is available in the `docs/` directory: + +- **[Strategy Manager](./docs/strategy_manager.md)** - Multi-strategy orchestration and signal combination +- **[Strategies](./docs/strategies.md)** - Individual strategy implementations and usage +- **[Timeframe System](./docs/timeframe_system.md)** - Advanced timeframe management and multi-timeframe strategies +- **[Analysis](./docs/analysis.md)** - Technical analysis components +- **[Storage Utils](./docs/utils_storage.md)** - Data storage and retrieval +- **[System Utils](./docs/utils_system.md)** - System utilities + +## Examples + +### Single Strategy Backtest +```bash +# Test default strategy on different timeframes +uv run .\main.py .\configs\config_default.json # 15min +uv run .\main.py .\configs\config_default_5min.json # 5min +``` + +### Multi-Strategy Backtest +```bash +# Combine multiple strategies with different weights +uv run .\main.py .\configs\config_combined.json +``` + +### Custom Configuration +Create your own configuration file and run: +```bash +uv run .\main.py .\configs\your_config.json +``` + +## Output + +Backtests generate: +- **CSV Results**: Detailed performance metrics per timeframe/strategy +- **Trade Log**: Individual trade records with entry/exit details +- **Performance Charts**: Visual analysis of strategy performance (in debug mode) +- **Log Files**: Detailed execution logs + +## License + +[Add your license information here] + +## Contributing + +[Add contributing guidelines here] diff --git a/configs/config_bbrs.json b/configs/config_bbrs.json index 4540854..6184216 100644 --- a/configs/config_bbrs.json +++ b/configs/config_bbrs.json @@ -2,7 +2,7 @@ "start_date": "2025-03-01", "stop_date": "2025-03-15", "initial_usd": 10000, - "timeframes": ["15min"], + "timeframes": ["1min"], "stop_loss_pcts": [0.05], "strategies": [ { diff --git a/docs/strategies.md b/docs/strategies.md index dd38938..34cf309 100644 --- a/docs/strategies.md +++ b/docs/strategies.md @@ -1,98 +1,405 @@ -# Trading Strategies (`cycles/Analysis/strategies.py`) +# Strategies Documentation -This document outlines the trading strategies implemented within the `Strategy` class. These strategies utilize technical indicators calculated by other classes in the `Analysis` module. +## Overview -## Class: `Strategy` +The Cycles framework implements advanced trading strategies with sophisticated timeframe management, signal processing, and multi-strategy combination capabilities. Each strategy can operate on its preferred timeframes while maintaining precise execution control. -Manages and executes different trading strategies. +## Architecture -### `__init__(self, config: dict = None, logging = None)` +### Strategy System Components -- **Description**: Initializes the Strategy class. -- **Parameters**: - - `config` (dict, optional): Configuration dictionary containing parameters for various indicators and strategy settings. Must be provided if strategies requiring config are used. - - `logging` (logging.Logger, optional): Logger object for outputting messages. Defaults to `None`. +1. **StrategyBase**: Abstract base class with timeframe management +2. **Individual Strategies**: DefaultStrategy, BBRSStrategy implementations +3. **StrategyManager**: Multi-strategy orchestration and signal combination +4. **Timeframe System**: Automatic data resampling and signal mapping -### `run(self, data: pd.DataFrame, strategy_name: str) -> pd.DataFrame` +### New Timeframe Management -- **Description**: Executes a specified trading strategy on the input data. -- **Parameters**: - - `data` (pd.DataFrame): Input DataFrame containing at least price data (e.g., 'close', 'volume'). Specific strategies might require other columns or will calculate them. - - `strategy_name` (str): The name of the strategy to run. Supported names include: - - `"MarketRegimeStrategy"` - - `"CryptoTradingStrategy"` - - `"no_strategy"` (or any other unrecognized name will default to this) -- **Returns**: `pd.DataFrame` - A DataFrame containing the original data augmented with indicator values, and `BuySignal` and `SellSignal` (boolean) columns specific to the executed strategy. The structure of the DataFrame (e.g., daily, 15-minute) depends on the strategy. +Each strategy now controls its own timeframe requirements: -### `no_strategy(self, data: pd.DataFrame) -> pd.DataFrame` +```python +class MyStrategy(StrategyBase): + def get_timeframes(self): + return ["15min", "1h"] # Strategy specifies needed timeframes + + def initialize(self, backtester): + # Framework automatically resamples data + self._resample_data(backtester.original_df) + + # Access resampled data + data_15m = self.get_data_for_timeframe("15min") + data_1h = self.get_data_for_timeframe("1h") +``` -- **Description**: A default strategy that generates no trading signals. It can serve as a baseline or placeholder. -- **Parameters**: - - `data` (pd.DataFrame): Input data DataFrame. -- **Returns**: `pd.DataFrame` - The input DataFrame with `BuySignal` and `SellSignal` columns added, both containing all `False` values. +## Available Strategies ---- +### 1. Default Strategy (Meta-Trend Analysis) -## Implemented Strategies +**Purpose**: Meta-trend analysis using multiple Supertrend indicators -### 1. `MarketRegimeStrategy` +**Timeframe Behavior**: +- **Configurable Primary Timeframe**: Set via `params["timeframe"]` (default: "15min") +- **1-Minute Precision**: Always includes 1min data for precise stop-loss execution +- **Example Timeframes**: `["15min", "1min"]` or `["5min", "1min"]` -- **Description**: An adaptive strategy that combines Bollinger Bands and RSI, adjusting its parameters based on detected market regimes (trending vs. sideways). It operates on daily aggregated data (aggregation is performed internally). -- **Core Logic**: - - Calculates Bollinger Bands (using `BollingerBands` class) with adaptive standard deviation multipliers based on `MarketRegime` (derived from `BBWidth`). - - Calculates RSI (using `RSI` class). - - **Trending Market (Breakout Mode)**: - - Buy: Price < Lower Band ∧ RSI < 50 ∧ Volume Spike. - - Sell: Price > Upper Band ∧ RSI > 50 ∧ Volume Spike. - - **Sideways Market (Mean Reversion)**: - - Buy: Price ≤ Lower Band ∧ RSI ≤ 40. - - Sell: Price ≥ Upper Band ∧ RSI ≥ 60. - - **Squeeze Confirmation** (if `config["SqueezeStrategy"]` is `True`): - - Requires additional confirmation from RSI Bollinger Bands (calculated by `rsi_bollinger_confirmation` helper method). - - Sideways markets also check for volume contraction. -- **Key Configuration Parameters (from `config` dict)**: - - `bb_period`, `bb_width` - - `trending['bb_std_dev_multiplier']`, `trending['rsi_threshold']` - - `sideways['bb_std_dev_multiplier']`, `sideways['rsi_threshold']` - - `rsi_period` - - `SqueezeStrategy` (boolean) -- **Output DataFrame Columns (Daily)**: Includes input columns plus `SMA`, `UpperBand`, `LowerBand`, `BBWidth`, `MarketRegime`, `RSI`, `BuySignal`, `SellSignal`. +**Configuration**: +```json +{ + "name": "default", + "weight": 1.0, + "params": { + "timeframe": "15min", // Configurable: "5min", "15min", "1h", etc. + "stop_loss_pct": 0.03 // Stop loss percentage + } +} +``` -#### `rsi_bollinger_confirmation(self, rsi: pd.Series, window: int = 14, std_mult: float = 1.5) -> tuple` +**Algorithm**: +1. Calculate 3 Supertrend indicators with different parameters on primary timeframe +2. Determine meta-trend: all three must agree for directional signal +3. **Entry**: Meta-trend changes from != 1 to == 1 (all trends align upward) +4. **Exit**: Meta-trend changes to -1 (trend reversal) or stop-loss triggered +5. **Stop-Loss**: 1-minute precision using percentage-based threshold -- **Description** (Helper for `MarketRegimeStrategy`): Calculates Bollinger Bands on RSI values for signal confirmation. -- **Parameters**: - - `rsi` (pd.Series): Series containing RSI values. - - `window` (int, optional): The period for the moving average. Defaults to 14. - - `std_mult` (float, optional): Standard deviation multiplier for bands. Defaults to 1.5. -- **Returns**: `tuple` - (oversold_condition, overbought_condition) as pandas Series (boolean). +**Strengths**: +- Robust trend following with multiple confirmations +- Configurable for different market timeframes +- Precise risk management +- Low false signals in trending markets -### 2. `CryptoTradingStrategy` +**Best Use Cases**: +- Medium to long-term trend following +- Markets with clear directional movements +- Risk-conscious trading with defined exits -- **Description**: A multi-timeframe strategy primarily designed for volatile assets like cryptocurrencies. It aggregates input data into 15-minute and 1-hour intervals for analysis. -- **Core Logic**: - - Aggregates data to 15-minute (`data_15m`) and 1-hour (`data_1h`) resolutions using `aggregate_to_minutes` and `aggregate_to_hourly` from `data_utils.py`. - - Calculates 15-minute Bollinger Bands (20-period, 2 std dev) and 15-minute EMA-smoothed RSI (14-period) using `BollingerBands.calculate_custom_bands` and `RSI.calculate_custom_rsi`. - - Calculates 1-hour Bollinger Bands (50-period, 1.8 std dev) using `BollingerBands.calculate_custom_bands`. - - **Signal Generation (on 15m timeframe)**: - - Buy Signal: Price ≤ Lower 15m Band ∧ Price ≤ Lower 1h Band ∧ RSI_15m < 35 ∧ Volume Confirmation. - - Sell Signal: Price ≥ Upper 15m Band ∧ Price ≥ Upper 1h Band ∧ RSI_15m > 65 ∧ Volume Confirmation. - - **Volume Confirmation**: Current 15m volume > 1.5 × 20-period MA of 15m volume. - - **Risk Management**: Calculates `StopLoss` and `TakeProfit` levels based on a simplified ATR (standard deviation of 15m close prices over the last 4 periods). - - Buy: SL = Price - 2 * ATR; TP = Price + 4 * ATR - - Sell: SL = Price + 2 * ATR; TP = Price - 4 * ATR -- **Key Configuration Parameters**: While this strategy uses fixed parameters for its core indicator calculations, the `config` object passed to the `Strategy` class might be used by helper functions or for future extensions (though not heavily used by the current `CryptoTradingStrategy` logic itself for primary indicator settings). -- **Output DataFrame Columns (15-minute)**: Includes resampled 15m OHLCV, plus `UpperBand_15m`, `SMA_15m`, `LowerBand_15m`, `RSI_15m`, `VolumeMA_15m`, `UpperBand_1h` (forward-filled), `LowerBand_1h` (forward-filled), `BuySignal`, `SellSignal`, `StopLoss`, `TakeProfit`. +### 2. BBRS Strategy (Bollinger Bands + RSI) ---- +**Purpose**: Market regime-adaptive strategy combining Bollinger Bands and RSI -## General Strategy Concepts (from previous high-level notes) +**Timeframe Behavior**: +- **1-Minute Input**: Strategy receives 1-minute data +- **Internal Resampling**: Underlying Strategy class handles resampling to 15min/1h +- **No Double-Resampling**: Avoids conflicts with existing resampling logic +- **Signal Mapping**: Results mapped back to 1-minute resolution -While the specific implementations above have their own detailed logic, some general concepts that often inspire trading strategies include: +**Configuration**: +```json +{ + "name": "bbrs", + "weight": 1.0, + "params": { + "bb_width": 0.05, // Bollinger Band width threshold + "bb_period": 20, // Bollinger Band period + "rsi_period": 14, // RSI calculation period + "trending_rsi_threshold": [30, 70], // RSI thresholds for trending market + "trending_bb_multiplier": 2.5, // BB multiplier for trending market + "sideways_rsi_threshold": [40, 60], // RSI thresholds for sideways market + "sideways_bb_multiplier": 1.8, // BB multiplier for sideways market + "strategy_name": "MarketRegimeStrategy", // Implementation variant + "SqueezeStrategy": true, // Enable squeeze detection + "stop_loss_pct": 0.05 // Stop loss percentage + } +} +``` -- **Adaptive Parameters**: Adjusting indicator settings (like Bollinger Band width or RSI thresholds) based on market conditions (e.g., trending vs. sideways). -- **Multi-Timeframe Analysis**: Confirming signals on one timeframe with trends or levels on another (e.g., 15-minute signals confirmed by 1-hour context). -- **Volume Confirmation**: Using volume spikes or contractions to validate price-based signals. -- **Volatility-Adjusted Risk Management**: Using measures like ATR (Average True Range) to set stop-loss and take-profit levels, or to size positions dynamically. +**Algorithm**: -These concepts are partially reflected in the implemented strategies, particularly in `MarketRegimeStrategy` (adaptive parameters) and `CryptoTradingStrategy` (multi-timeframe, volume confirmation, ATR-based risk levels). +**MarketRegimeStrategy** (Primary Implementation): +1. **Market Regime Detection**: Determines if market is trending or sideways +2. **Adaptive Parameters**: Adjusts BB/RSI thresholds based on market regime +3. **Trending Market Entry**: Price < Lower Band ∧ RSI < 50 ∧ Volume Spike +4. **Sideways Market Entry**: Price ≤ Lower Band ∧ RSI ≤ 40 +5. **Exit Conditions**: Opposite band touch, RSI reversal, or stop-loss +6. **Volume Confirmation**: Requires 1.5× average volume for trending signals + +**CryptoTradingStrategy** (Alternative Implementation): +1. **Multi-Timeframe Analysis**: Combines 15-minute and 1-hour Bollinger Bands +2. **Entry**: Price ≤ both 15m & 1h lower bands + RSI < 35 + Volume surge +3. **Exit**: 2:1 risk-reward ratio with ATR-based stops +4. **Adaptive Volatility**: Uses ATR for dynamic stop-loss/take-profit + +**Strengths**: +- Adapts to different market regimes +- Multiple timeframe confirmation (internal) +- Volume analysis for signal quality +- Sophisticated entry/exit conditions + +**Best Use Cases**: +- Volatile cryptocurrency markets +- Markets with alternating trending/sideways periods +- Short to medium-term trading + +## Strategy Combination + +### Multi-Strategy Architecture + +The StrategyManager allows combining multiple strategies with configurable rules: + +```json +{ + "strategies": [ + { + "name": "default", + "weight": 0.6, + "params": {"timeframe": "15min"} + }, + { + "name": "bbrs", + "weight": 0.4, + "params": {"strategy_name": "MarketRegimeStrategy"} + } + ], + "combination_rules": { + "entry": "weighted_consensus", + "exit": "any", + "min_confidence": 0.6 + } +} +``` + +### Signal Combination Methods + +**Entry Combinations**: +- **`any`**: Enter if ANY strategy signals entry +- **`all`**: Enter only if ALL strategies signal entry +- **`majority`**: Enter if majority of strategies signal entry +- **`weighted_consensus`**: Enter based on weighted confidence average + +**Exit Combinations**: +- **`any`**: Exit if ANY strategy signals exit (recommended for risk management) +- **`all`**: Exit only if ALL strategies agree +- **`priority`**: Prioritized exit (STOP_LOSS > SELL_SIGNAL > others) + +## Performance Characteristics + +### Default Strategy Performance + +**Strengths**: +- **Trend Accuracy**: High accuracy in strong trending markets +- **Risk Management**: Defined stop-losses with 1-minute precision +- **Low Noise**: Multiple Supertrend confirmation reduces false signals +- **Adaptable**: Works across different timeframes + +**Weaknesses**: +- **Sideways Markets**: May generate false signals in ranging markets +- **Lag**: Multiple confirmations can delay entry/exit signals +- **Whipsaws**: Vulnerable to rapid trend reversals + +**Optimal Conditions**: +- Clear trending markets +- Medium to low volatility trending +- Sufficient data history for Supertrend calculation + +### BBRS Strategy Performance + +**Strengths**: +- **Market Adaptation**: Automatically adjusts to market regime +- **Volume Confirmation**: Reduces false signals with volume analysis +- **Multi-Timeframe**: Internal analysis across multiple timeframes +- **Volatility Handling**: Designed for cryptocurrency volatility + +**Weaknesses**: +- **Complexity**: More parameters to optimize +- **Market Noise**: Can be sensitive to short-term noise +- **Volume Dependency**: Requires reliable volume data + +**Optimal Conditions**: +- High-volume cryptocurrency markets +- Markets with clear regime shifts +- Sufficient data for regime detection + +## Usage Examples + +### Single Strategy Backtests + +```bash +# Default strategy on 15-minute timeframe +uv run .\main.py .\configs\config_default.json + +# Default strategy on 5-minute timeframe +uv run .\main.py .\configs\config_default_5min.json + +# BBRS strategy with market regime detection +uv run .\main.py .\configs\config_bbrs.json +``` + +### Multi-Strategy Backtests + +```bash +# Combined strategies with weighted consensus +uv run .\main.py .\configs\config_combined.json +``` + +### Custom Configurations + +**Aggressive Default Strategy**: +```json +{ + "name": "default", + "params": { + "timeframe": "5min", // Faster signals + "stop_loss_pct": 0.02 // Tighter stop-loss + } +} +``` + +**Conservative BBRS Strategy**: +```json +{ + "name": "bbrs", + "params": { + "bb_width": 0.03, // Tighter BB width + "stop_loss_pct": 0.07, // Wider stop-loss + "SqueezeStrategy": false // Disable squeeze for simplicity + } +} +``` + +## Development Guidelines + +### Creating New Strategies + +1. **Inherit from StrategyBase**: +```python +from cycles.strategies.base import StrategyBase, StrategySignal + +class NewStrategy(StrategyBase): + def __init__(self, weight=1.0, params=None): + super().__init__("new_strategy", weight, params) +``` + +2. **Specify Timeframes**: +```python +def get_timeframes(self): + return ["1h"] # Specify required timeframes +``` + +3. **Implement Core Methods**: +```python +def initialize(self, backtester): + self._resample_data(backtester.original_df) + # Calculate indicators... + self.initialized = True + +def get_entry_signal(self, backtester, df_index): + # Entry logic... + return StrategySignal("ENTRY", confidence=0.8) + +def get_exit_signal(self, backtester, df_index): + # Exit logic... + return StrategySignal("EXIT", confidence=1.0) +``` + +4. **Register Strategy**: +```python +# In StrategyManager._load_strategies() +elif name == "new_strategy": + strategies.append(NewStrategy(weight, params)) +``` + +### Timeframe Best Practices + +1. **Minimize Timeframe Requirements**: +```python +def get_timeframes(self): + return ["15min"] # Only what's needed +``` + +2. **Include 1min for Stop-Loss**: +```python +def get_timeframes(self): + primary_tf = self.params.get("timeframe", "15min") + timeframes = [primary_tf] + if "1min" not in timeframes: + timeframes.append("1min") + return timeframes +``` + +3. **Handle Multi-Timeframe Synchronization**: +```python +def get_entry_signal(self, backtester, df_index): + # Get current timestamp from primary timeframe + primary_data = self.get_primary_timeframe_data() + current_time = primary_data.index[df_index] + + # Map to other timeframes + hourly_data = self.get_data_for_timeframe("1h") + h1_idx = hourly_data.index.get_indexer([current_time], method='ffill')[0] +``` + +## Testing and Validation + +### Strategy Testing Workflow + +1. **Individual Strategy Testing**: + - Test each strategy independently + - Validate on different timeframes + - Check edge cases and data sufficiency + +2. **Multi-Strategy Testing**: + - Test strategy combinations + - Validate combination rules + - Monitor for signal conflicts + +3. **Timeframe Validation**: + - Ensure consistent behavior across timeframes + - Validate data alignment + - Check memory usage with large datasets + +### Performance Monitoring + +```python +# Get strategy summary +summary = strategy_manager.get_strategy_summary() +print(f"Strategies: {[s['name'] for s in summary['strategies']]}") +print(f"Timeframes: {summary['all_timeframes']}") + +# Monitor individual strategy performance +for strategy in strategy_manager.strategies: + print(f"{strategy.name}: {strategy.get_timeframes()}") +``` + +## Advanced Topics + +### Multi-Timeframe Strategy Development + +For strategies requiring multiple timeframes: + +```python +class MultiTimeframeStrategy(StrategyBase): + def get_timeframes(self): + return ["5min", "15min", "1h"] + + def get_entry_signal(self, backtester, df_index): + # Analyze multiple timeframes + data_5m = self.get_data_for_timeframe("5min") + data_15m = self.get_data_for_timeframe("15min") + data_1h = self.get_data_for_timeframe("1h") + + # Synchronize across timeframes + current_time = data_5m.index[df_index] + idx_15m = data_15m.index.get_indexer([current_time], method='ffill')[0] + idx_1h = data_1h.index.get_indexer([current_time], method='ffill')[0] + + # Multi-timeframe logic + short_signal = self._analyze_5min(data_5m, df_index) + medium_signal = self._analyze_15min(data_15m, idx_15m) + long_signal = self._analyze_1h(data_1h, idx_1h) + + # Combine signals with appropriate confidence + if short_signal and medium_signal and long_signal: + return StrategySignal("ENTRY", confidence=0.9) + elif short_signal and medium_signal: + return StrategySignal("ENTRY", confidence=0.7) + else: + return StrategySignal("HOLD", confidence=0.0) +``` + +### Strategy Optimization + +1. **Parameter Optimization**: Systematic testing of strategy parameters +2. **Timeframe Optimization**: Finding optimal timeframes for each strategy +3. **Combination Optimization**: Optimizing weights and combination rules +4. **Market Regime Adaptation**: Adapting strategies to different market conditions + +For detailed timeframe system documentation, see [Timeframe System](./timeframe_system.md). diff --git a/docs/strategy_manager.md b/docs/strategy_manager.md index 4aca4c3..8a326d8 100644 --- a/docs/strategy_manager.md +++ b/docs/strategy_manager.md @@ -1,83 +1,180 @@ -# TCP Cycles Strategy Management System +# Strategy Manager Documentation -The Strategy Manager system provides a flexible framework for implementing, combining, and managing multiple trading strategies within the TCP Cycles project. +## Overview -## 🏗️ Architecture +The Strategy Manager is a sophisticated orchestration system that enables the combination of multiple trading strategies with configurable signal aggregation rules. It supports multi-timeframe analysis, weighted consensus voting, and flexible signal combination methods. -### Module Structure -``` -cycles/ -├── strategies/ # Strategy management module -│ ├── __init__.py # Module exports and version info -│ ├── base.py # Base classes (StrategyBase, StrategySignal) -│ ├── default_strategy.py # Meta-trend strategy implementation -│ ├── bbrs_strategy.py # Bollinger Bands + RSI strategy -│ └── manager.py # StrategyManager and orchestration -├── Analysis/ # Technical analysis tools -├── utils/ # Utility functions -├── backtest.py # Backtesting engine -└── charts.py # Charting and visualization -``` +## Architecture ### Core Components -1. **`StrategyBase`**: Abstract base class that all strategies inherit from -2. **`StrategySignal`**: Represents trading signals with confidence levels and metadata -3. **`DefaultStrategy`**: Implementation of the meta-trend strategy using Supertrend indicators -4. **`BBRSStrategy`**: Implementation of the Bollinger Bands + RSI strategy with market regime detection -5. **`StrategyManager`**: Orchestrates multiple strategies and combines their signals +1. **StrategyBase**: Abstract base class defining the strategy interface +2. **StrategySignal**: Encapsulates trading signals with confidence levels +3. **StrategyManager**: Orchestrates multiple strategies and combines signals +4. **Strategy Implementations**: DefaultStrategy, BBRSStrategy, etc. -### Signal Types -- **`"ENTRY"`**: Strategy suggests entering a position -- **`"EXIT"`**: Strategy suggests exiting a position -- **`"HOLD"`**: Strategy suggests no action +### New Timeframe System -## 📋 Configuration +The framework now supports strategy-level timeframe management: -### Single Strategy Configuration +- **Strategy-Controlled Timeframes**: Each strategy specifies its required timeframes +- **Automatic Data Resampling**: Framework automatically resamples 1-minute data to strategy needs +- **Multi-Timeframe Support**: Strategies can use multiple timeframes simultaneously +- **Precision Stop-Loss**: All strategies maintain 1-minute data for precise execution -**Default Strategy Only:** +```python +class MyStrategy(StrategyBase): + def get_timeframes(self): + return ["15min", "1h"] # Strategy needs both timeframes + + def initialize(self, backtester): + # Access resampled data + data_15m = self.get_data_for_timeframe("15min") + data_1h = self.get_data_for_timeframe("1h") + # Setup indicators... +``` + +## Strategy Interface + +### StrategyBase Class + +All strategies must inherit from `StrategyBase` and implement: + +```python +from cycles.strategies.base import StrategyBase, StrategySignal + +class MyStrategy(StrategyBase): + def get_timeframes(self) -> List[str]: + """Specify required timeframes""" + return ["15min"] + + def initialize(self, backtester) -> None: + """Setup strategy with data""" + self._resample_data(backtester.original_df) + # Calculate indicators... + self.initialized = True + + def get_entry_signal(self, backtester, df_index: int) -> StrategySignal: + """Generate entry signals""" + if condition_met: + return StrategySignal("ENTRY", confidence=0.8) + return StrategySignal("HOLD", confidence=0.0) + + def get_exit_signal(self, backtester, df_index: int) -> StrategySignal: + """Generate exit signals""" + if exit_condition: + return StrategySignal("EXIT", confidence=1.0, + metadata={"type": "SELL_SIGNAL"}) + return StrategySignal("HOLD", confidence=0.0) +``` + +### StrategySignal Class + +Encapsulates trading signals with metadata: + +```python +# Entry signal with high confidence +entry_signal = StrategySignal("ENTRY", confidence=0.9) + +# Exit signal with specific price +exit_signal = StrategySignal("EXIT", confidence=1.0, price=50000, + metadata={"type": "STOP_LOSS"}) + +# Hold signal +hold_signal = StrategySignal("HOLD", confidence=0.0) +``` + +## Available Strategies + +### 1. Default Strategy + +Meta-trend analysis using multiple Supertrend indicators. + +**Features:** +- Uses 3 Supertrend indicators with different parameters +- Configurable timeframe (default: 15min) +- Entry when all trends align upward +- Exit on trend reversal or stop-loss + +**Configuration:** ```json { - "start_date": "2025-03-01", - "stop_date": "2025-03-15", - "initial_usd": 10000, - "timeframes": ["15min"], - "stop_loss_pcts": [0.03, 0.05], - "strategies": [ - { - "name": "default", - "weight": 1.0, - "params": {} - } - ], - "combination_rules": { - "entry": "any", - "exit": "any", - "min_confidence": 0.5 + "name": "default", + "weight": 1.0, + "params": { + "timeframe": "15min", + "stop_loss_pct": 0.03 } } ``` -**BBRS Strategy Only:** +**Timeframes:** +- Primary: Configurable (default 15min) +- Stop-loss: Always includes 1min for precision + +### 2. BBRS Strategy + +Bollinger Bands + RSI with market regime detection. + +**Features:** +- Market regime detection (trending vs sideways) +- Adaptive parameters based on market conditions +- Volume analysis and confirmation +- Multi-timeframe internal analysis (1min → 15min/1h) + +**Configuration:** ```json { - "strategies": [ - { - "name": "bbrs", - "weight": 1.0, - "params": { - "bb_width": 0.05, - "bb_period": 20, - "rsi_period": 14, - "strategy_name": "MarketRegimeStrategy" - } - } - ] + "name": "bbrs", + "weight": 1.0, + "params": { + "bb_width": 0.05, + "bb_period": 20, + "rsi_period": 14, + "strategy_name": "MarketRegimeStrategy", + "stop_loss_pct": 0.05 + } } ``` -### Multiple Strategy Configuration +**Timeframes:** +- Input: 1min (Strategy class handles internal resampling) +- Internal: 15min, 1h (handled by underlying Strategy class) +- Output: Mapped back to 1min for backtesting + +## Signal Combination + +### Entry Signal Combination + +```python +combination_rules = { + "entry": "weighted_consensus", # or "any", "all", "majority" + "min_confidence": 0.6 +} +``` + +**Methods:** +- **`any`**: Enter if ANY strategy signals entry +- **`all`**: Enter only if ALL strategies signal entry +- **`majority`**: Enter if majority of strategies signal entry +- **`weighted_consensus`**: Enter based on weighted average confidence + +### Exit Signal Combination + +```python +combination_rules = { + "exit": "priority" # or "any", "all" +} +``` + +**Methods:** +- **`any`**: Exit if ANY strategy signals exit (recommended for risk management) +- **`all`**: Exit only if ALL strategies agree +- **`priority`**: Prioritized exit (STOP_LOSS > SELL_SIGNAL > others) + +## Configuration + +### Basic Strategy Manager Setup ```json { @@ -85,11 +182,14 @@ cycles/ { "name": "default", "weight": 0.6, - "params": {} + "params": { + "timeframe": "15min", + "stop_loss_pct": 0.03 + } }, { - "name": "bbrs", - "weight": 0.4, + "name": "bbrs", + "weight": 0.4, "params": { "bb_width": 0.05, "strategy_name": "MarketRegimeStrategy" @@ -99,229 +199,189 @@ cycles/ "combination_rules": { "entry": "weighted_consensus", "exit": "any", - "min_confidence": 0.6 + "min_confidence": 0.5 } } ``` -## 🔧 Combination Rules +### Timeframe Examples -### Entry Signal Combination Methods - -- **`"any"`**: Enter if ANY strategy signals entry above min_confidence -- **`"all"`**: Enter only if ALL strategies signal entry above min_confidence -- **`"majority"`**: Enter if more than 50% of strategies signal entry -- **`"weighted_consensus"`**: Enter based on weighted average confidence - -### Exit Signal Combination Methods - -- **`"any"`**: Exit if ANY strategy signals exit (recommended for risk management) -- **`"all"`**: Exit only if ALL strategies agree on exit -- **`"priority"`**: Exit based on priority: STOP_LOSS > SELL_SIGNAL > others - -### Parameters - -- **`min_confidence`**: Minimum confidence threshold (0.0 to 1.0) -- **`weight`**: Strategy weight for weighted calculations - -## 🚀 Usage Examples - -### Running with Default Strategy -```bash -python main.py config_default.json +**Single Timeframe Strategy:** +```json +{ + "name": "default", + "params": { + "timeframe": "5min" # Strategy works on 5-minute data + } +} ``` -### Running with BBRS Strategy -```bash -python main.py config_bbrs.json +**Multi-Timeframe Strategy (Future Enhancement):** +```json +{ + "name": "multi_tf_strategy", + "params": { + "timeframes": ["5min", "15min", "1h"], # Multiple timeframes + "primary_timeframe": "15min" + } +} ``` -### Running with Combined Strategies -```bash -python main.py config_combined.json -``` +## Usage Examples -### Running without Config (Interactive) -```bash -python main.py -``` +### Create Strategy Manager -### Programmatic Usage ```python from cycles.strategies import create_strategy_manager -# Create strategy manager from config config = { "strategies": [ - {"name": "default", "weight": 0.7, "params": {}}, - {"name": "bbrs", "weight": 0.3, "params": {"bb_width": 0.05}} + {"name": "default", "weight": 1.0, "params": {"timeframe": "15min"}} ], "combination_rules": { - "entry": "weighted_consensus", - "exit": "any", - "min_confidence": 0.6 + "entry": "any", + "exit": "any" } } strategy_manager = create_strategy_manager(config) ``` -## ⚙️ Strategy Parameters - -### Default Strategy Parameters -- **`stop_loss_pct`**: Stop loss percentage (default: 0.03) - -### BBRS Strategy Parameters -- **`bb_width`**: Bollinger Band width (default: 0.05) -- **`bb_period`**: Bollinger Band period (default: 20) -- **`rsi_period`**: RSI period (default: 14) -- **`trending_rsi_threshold`**: RSI thresholds for trending market [low, high] -- **`trending_bb_multiplier`**: BB multiplier for trending market -- **`sideways_rsi_threshold`**: RSI thresholds for sideways market [low, high] -- **`sideways_bb_multiplier`**: BB multiplier for sideways market -- **`strategy_name`**: Strategy implementation name -- **`SqueezeStrategy`**: Enable squeeze strategy (boolean) -- **`stop_loss_pct`**: Stop loss percentage (default: 0.05) - -## 🔌 Adding New Strategies - -### 1. Create Strategy Class - -Create a new file in `cycles/strategies/` (e.g., `my_strategy.py`): +### Initialize and Use ```python -from .base import StrategyBase, StrategySignal +# Initialize with backtester +strategy_manager.initialize(backtester) -class MyStrategy(StrategyBase): - def __init__(self, weight=1.0, params=None): - super().__init__("my_strategy", weight, params) +# Get signals during backtesting +entry_signal = strategy_manager.get_entry_signal(backtester, df_index) +exit_signal, exit_price = strategy_manager.get_exit_signal(backtester, df_index) + +# Get strategy summary +summary = strategy_manager.get_strategy_summary() +print(f"Loaded strategies: {[s['name'] for s in summary['strategies']]}") +print(f"All timeframes: {summary['all_timeframes']}") +``` + +## Extending the System + +### Adding New Strategies + +1. **Create Strategy Class:** +```python +class NewStrategy(StrategyBase): + def get_timeframes(self): + return ["1h"] # Specify required timeframes def initialize(self, backtester): - # Initialize your strategy indicators + self._resample_data(backtester.original_df) + # Setup indicators... self.initialized = True def get_entry_signal(self, backtester, df_index): # Implement entry logic - if entry_condition: - return StrategySignal("ENTRY", confidence=0.8) - return StrategySignal("HOLD", confidence=0.0) + pass def get_exit_signal(self, backtester, df_index): # Implement exit logic - if exit_condition: - return StrategySignal("EXIT", confidence=1.0, - metadata={"type": "MY_EXIT"}) - return StrategySignal("HOLD", confidence=0.0) + pass ``` -### 2. Register Strategy +2. **Register in StrategyManager:** +```python +# In StrategyManager._load_strategies() +elif name == "new_strategy": + strategies.append(NewStrategy(weight, params)) +``` -Update `cycles/strategies/manager.py` in the `_load_strategies` method: +### Multi-Timeframe Strategy Development + +For strategies requiring multiple timeframes: ```python -elif name == "my_strategy": - from .my_strategy import MyStrategy - strategies.append(MyStrategy(weight, params)) +class MultiTimeframeStrategy(StrategyBase): + def get_timeframes(self): + return ["5min", "15min", "1h"] + + def initialize(self, backtester): + self._resample_data(backtester.original_df) + + # Access different timeframes + data_5m = self.get_data_for_timeframe("5min") + data_15m = self.get_data_for_timeframe("15min") + data_1h = self.get_data_for_timeframe("1h") + + # Calculate indicators on each timeframe + # ... + + def _calculate_signal_confidence(self, backtester, df_index): + # Analyze multiple timeframes for confidence + primary_signal = self._get_primary_signal(df_index) + confirmation = self._get_timeframe_confirmation(df_index) + + return primary_signal * confirmation ``` -### 3. Export Strategy +## Performance Considerations -Update `cycles/strategies/__init__.py`: +### Timeframe Management -```python -from .my_strategy import MyStrategy +- **Efficient Resampling**: Each strategy resamples data once during initialization +- **Memory Usage**: Only required timeframes are kept in memory +- **Signal Mapping**: Efficient mapping between timeframes using pandas reindex -__all__ = [ - # ... existing exports ... - 'MyStrategy' -] -``` +### Strategy Combination -## 📊 Performance Features +- **Lazy Evaluation**: Signals calculated only when needed +- **Error Handling**: Individual strategy failures don't crash the system +- **Logging**: Comprehensive logging for debugging and monitoring -### Strategy Analysis -- Individual strategy performance tracking -- Combined strategy performance metrics -- Signal quality analysis -- Confidence level monitoring +## Best Practices -### Plotting Support -- Automatic chart generation for BBRS strategies -- Meta-trend visualization for default strategy -- Combined signal overlays -- Performance comparison charts +1. **Strategy Design:** + - Specify minimal required timeframes + - Include 1min for stop-loss precision + - Use confidence levels effectively -## 🔄 Backward Compatibility +2. **Signal Combination:** + - Use `any` for exits (risk management) + - Use `weighted_consensus` for entries + - Set appropriate minimum confidence levels -The system maintains full backward compatibility: -- ✅ Existing code using single strategies works unchanged -- ✅ Legacy strategy functions are preserved in main.py -- ✅ Default behavior matches original implementation -- ✅ Gradual migration path available +3. **Error Handling:** + - Implement robust initialization checks + - Handle missing data gracefully + - Log strategy-specific warnings -## 📚 Best Practices +4. **Testing:** + - Test strategies individually before combining + - Validate timeframe requirements + - Monitor memory usage with large datasets -### 1. **Risk Management** -- Use `"any"` exit rule for faster risk exits -- Set appropriate stop loss percentages per strategy -- Monitor combined drawdown vs individual strategies +## Troubleshooting -### 2. **Signal Quality** -- Set appropriate `min_confidence` based on strategy reliability -- Test individual strategies thoroughly before combining -- Monitor signal frequency and quality +### Common Issues -### 3. **Weight Distribution** -- Balance strategy weights based on historical performance -- Consider strategy correlation when setting weights -- Regularly rebalance based on changing market conditions +1. **Timeframe Mismatches:** + - Ensure strategy specifies correct timeframes + - Check data availability for all timeframes -### 4. **Testing & Validation** -- Backtest individual strategies first -- Test combinations on historical data -- Validate on out-of-sample data +2. **Signal Conflicts:** + - Review combination rules + - Adjust confidence thresholds + - Monitor strategy weights -### 5. **Monitoring** -- Log strategy initialization and errors -- Track individual vs combined performance -- Monitor signal generation frequency +3. **Performance Issues:** + - Minimize timeframe requirements + - Optimize indicator calculations + - Use efficient pandas operations -## 🔍 Troubleshooting +### Debugging Tips -### Strategy Not Found Error -``` -ValueError: Unknown strategy: my_strategy -``` -**Solution**: Ensure strategy is registered in `manager.py` `_load_strategies` method - -### No Signals Generated -**Possible Causes**: -- Strategy initialization failed -- Data insufficient for strategy requirements -- `min_confidence` threshold too high - -**Solution**: Check logs, verify data, adjust confidence threshold - -### Poor Combined Performance -**Analysis Steps**: -1. Review individual strategy performance -2. Check strategy correlation and overlap -3. Adjust weights and combination rules -4. Consider market regime compatibility - -### Import Errors -``` -ImportError: cannot import name 'StrategyManager' -``` -**Solution**: Use correct import path: `from cycles.strategies import StrategyManager` - -## 📞 Support - -For issues, feature requests, or contributions: -1. Check existing documentation and examples -2. Review troubleshooting section -3. Examine configuration files for proper syntax -4. Ensure all dependencies are installed +- Enable detailed logging: `logging.basicConfig(level=logging.DEBUG)` +- Use strategy summary: `manager.get_strategy_summary()` +- Test individual strategies before combining +- Monitor signal confidence levels --- diff --git a/docs/timeframe_system.md b/docs/timeframe_system.md new file mode 100644 index 0000000..a099e16 --- /dev/null +++ b/docs/timeframe_system.md @@ -0,0 +1,488 @@ +# Timeframe System Documentation + +## Overview + +The Cycles framework features a sophisticated timeframe management system that allows strategies to operate on their preferred timeframes while maintaining precise execution control. This system supports both single-timeframe and multi-timeframe strategies with automatic data resampling and intelligent signal mapping. + +## Architecture + +### Core Concepts + +1. **Strategy-Controlled Timeframes**: Each strategy specifies its required timeframes +2. **Automatic Resampling**: Framework resamples 1-minute data to strategy needs +3. **Precision Execution**: All strategies maintain 1-minute data for accurate stop-loss execution +4. **Signal Mapping**: Intelligent mapping between different timeframe resolutions + +### Data Flow + +``` +Original 1min Data + ↓ +Strategy.get_timeframes() → ["15min", "1h"] + ↓ +Automatic Resampling + ↓ +Strategy Logic (15min + 1h analysis) + ↓ +Signal Generation + ↓ +Map to Working Timeframe + ↓ +Backtesting Engine +``` + +## Strategy Timeframe Interface + +### StrategyBase Methods + +All strategies inherit timeframe capabilities from `StrategyBase`: + +```python +class MyStrategy(StrategyBase): + def get_timeframes(self) -> List[str]: + """Specify required timeframes for this strategy""" + return ["15min", "1h"] # Strategy needs both timeframes + + def initialize(self, backtester) -> None: + # Automatic resampling happens here + self._resample_data(backtester.original_df) + + # Access resampled data + data_15m = self.get_data_for_timeframe("15min") + data_1h = self.get_data_for_timeframe("1h") + + # Calculate indicators on each timeframe + self.indicators_15m = self._calculate_indicators(data_15m) + self.indicators_1h = self._calculate_indicators(data_1h) + + self.initialized = True +``` + +### Data Access Methods + +```python +# Get data for specific timeframe +data_15m = strategy.get_data_for_timeframe("15min") + +# Get primary timeframe data (first in list) +primary_data = strategy.get_primary_timeframe_data() + +# Check available timeframes +timeframes = strategy.get_timeframes() +``` + +## Supported Timeframes + +### Standard Timeframes + +- **`"1min"`**: 1-minute bars (original resolution) +- **`"5min"`**: 5-minute bars +- **`"15min"`**: 15-minute bars +- **`"30min"`**: 30-minute bars +- **`"1h"`**: 1-hour bars +- **`"4h"`**: 4-hour bars +- **`"1d"`**: Daily bars + +### Custom Timeframes + +Any pandas-compatible frequency string is supported: +- **`"2min"`**: 2-minute bars +- **`"10min"`**: 10-minute bars +- **`"2h"`**: 2-hour bars +- **`"12h"`**: 12-hour bars + +## Strategy Examples + +### Single Timeframe Strategy + +```python +class SingleTimeframeStrategy(StrategyBase): + def get_timeframes(self): + return ["15min"] # Only needs 15-minute data + + def initialize(self, backtester): + self._resample_data(backtester.original_df) + + # Work with 15-minute data + data = self.get_primary_timeframe_data() + self.indicators = self._calculate_indicators(data) + self.initialized = True + + def get_entry_signal(self, backtester, df_index): + # df_index refers to 15-minute data + if self.indicators['signal'][df_index]: + return StrategySignal("ENTRY", confidence=0.8) + return StrategySignal("HOLD", confidence=0.0) +``` + +### Multi-Timeframe Strategy + +```python +class MultiTimeframeStrategy(StrategyBase): + def get_timeframes(self): + return ["15min", "1h", "4h"] # Multiple timeframes + + def initialize(self, backtester): + self._resample_data(backtester.original_df) + + # Access different timeframes + self.data_15m = self.get_data_for_timeframe("15min") + self.data_1h = self.get_data_for_timeframe("1h") + self.data_4h = self.get_data_for_timeframe("4h") + + # Calculate indicators on each timeframe + self.trend_4h = self._calculate_trend(self.data_4h) + self.momentum_1h = self._calculate_momentum(self.data_1h) + self.entry_signals_15m = self._calculate_entries(self.data_15m) + + self.initialized = True + + def get_entry_signal(self, backtester, df_index): + # Primary timeframe is 15min (first in list) + # Map df_index to other timeframes for confirmation + + # Get current 15min timestamp + current_time = self.data_15m.index[df_index] + + # Find corresponding indices in other timeframes + h1_idx = self.data_1h.index.get_indexer([current_time], method='ffill')[0] + h4_idx = self.data_4h.index.get_indexer([current_time], method='ffill')[0] + + # Multi-timeframe confirmation + trend_ok = self.trend_4h[h4_idx] > 0 + momentum_ok = self.momentum_1h[h1_idx] > 0.5 + entry_signal = self.entry_signals_15m[df_index] + + if trend_ok and momentum_ok and entry_signal: + confidence = 0.9 # High confidence with all timeframes aligned + return StrategySignal("ENTRY", confidence=confidence) + + return StrategySignal("HOLD", confidence=0.0) +``` + +### Configurable Timeframe Strategy + +```python +class ConfigurableStrategy(StrategyBase): + def get_timeframes(self): + # Strategy timeframe configurable via parameters + primary_tf = self.params.get("timeframe", "15min") + return [primary_tf, "1min"] # Primary + 1min for stop-loss + + def initialize(self, backtester): + self._resample_data(backtester.original_df) + + primary_tf = self.get_timeframes()[0] + self.data = self.get_data_for_timeframe(primary_tf) + + # Indicator parameters can also be timeframe-dependent + if primary_tf == "5min": + self.ma_period = 20 + elif primary_tf == "15min": + self.ma_period = 14 + else: + self.ma_period = 10 + + self.indicators = self._calculate_indicators(self.data) + self.initialized = True +``` + +## Built-in Strategy Timeframe Behavior + +### Default Strategy + +**Timeframes**: Configurable primary + 1min for stop-loss + +```python +# Configuration +{ + "name": "default", + "params": { + "timeframe": "5min" # Configurable timeframe + } +} + +# Resulting timeframes: ["5min", "1min"] +``` + +**Features**: +- Supertrend analysis on configured timeframe +- 1-minute precision for stop-loss execution +- Optimized for 15-minute default, but works on any timeframe + +### BBRS Strategy + +**Timeframes**: 1min input (internal resampling) + +```python +# Configuration +{ + "name": "bbrs", + "params": { + "strategy_name": "MarketRegimeStrategy" + } +} + +# Resulting timeframes: ["1min"] +``` + +**Features**: +- Uses 1-minute data as input +- Internal resampling to 15min/1h by Strategy class +- Signals mapped back to 1-minute resolution +- No double-resampling issues + +## Advanced Features + +### Timeframe Synchronization + +When working with multiple timeframes, synchronization is crucial: + +```python +def _get_synchronized_signals(self, df_index, primary_timeframe="15min"): + """Get signals synchronized across timeframes""" + + # Get timestamp from primary timeframe + primary_data = self.get_data_for_timeframe(primary_timeframe) + current_time = primary_data.index[df_index] + + signals = {} + for tf in self.get_timeframes(): + if tf == primary_timeframe: + signals[tf] = df_index + else: + # Find corresponding index in other timeframe + tf_data = self.get_data_for_timeframe(tf) + tf_idx = tf_data.index.get_indexer([current_time], method='ffill')[0] + signals[tf] = tf_idx + + return signals +``` + +### Dynamic Timeframe Selection + +Strategies can adapt timeframes based on market conditions: + +```python +class AdaptiveStrategy(StrategyBase): + def get_timeframes(self): + # Fixed set of timeframes strategy might need + return ["5min", "15min", "1h"] + + def _select_active_timeframe(self, market_volatility): + """Select timeframe based on market conditions""" + if market_volatility > 0.8: + return "5min" # High volatility -> shorter timeframe + elif market_volatility > 0.4: + return "15min" # Medium volatility -> medium timeframe + else: + return "1h" # Low volatility -> longer timeframe + + def get_entry_signal(self, backtester, df_index): + # Calculate market volatility + volatility = self._calculate_volatility(df_index) + + # Select appropriate timeframe + active_tf = self._select_active_timeframe(volatility) + + # Generate signal on selected timeframe + return self._generate_signal_for_timeframe(active_tf, df_index) +``` + +## Configuration Examples + +### Single Timeframe Configuration + +```json +{ + "strategies": [ + { + "name": "default", + "weight": 1.0, + "params": { + "timeframe": "15min", + "stop_loss_pct": 0.03 + } + } + ] +} +``` + +### Multi-Timeframe Configuration + +```json +{ + "strategies": [ + { + "name": "multi_timeframe_strategy", + "weight": 1.0, + "params": { + "primary_timeframe": "15min", + "confirmation_timeframes": ["1h", "4h"], + "signal_timeframe": "5min" + } + } + ] +} +``` + +### Mixed Strategy Configuration + +```json +{ + "strategies": [ + { + "name": "default", + "weight": 0.6, + "params": { + "timeframe": "15min" + } + }, + { + "name": "bbrs", + "weight": 0.4, + "params": { + "strategy_name": "MarketRegimeStrategy" + } + } + ] +} +``` + +## Performance Considerations + +### Memory Usage + +- Only required timeframes are resampled and stored +- Original 1-minute data shared across all strategies +- Efficient pandas resampling with minimal memory overhead + +### Processing Speed + +- Resampling happens once during initialization +- No repeated resampling during backtesting +- Vectorized operations on pre-computed timeframes + +### Data Alignment + +- All timeframes aligned to original 1-minute timestamps +- Forward-fill resampling ensures data availability +- Intelligent handling of missing data points + +## Best Practices + +### 1. Minimize Timeframe Requirements + +```python +# Good - minimal timeframes +def get_timeframes(self): + return ["15min"] + +# Less optimal - unnecessary timeframes +def get_timeframes(self): + return ["1min", "5min", "15min", "1h", "4h", "1d"] +``` + +### 2. Use Appropriate Timeframes for Strategy Logic + +```python +# Good - timeframe matches strategy logic +class TrendStrategy(StrategyBase): + def get_timeframes(self): + return ["1h"] # Trend analysis works well on hourly data + +class ScalpingStrategy(StrategyBase): + def get_timeframes(self): + return ["1min", "5min"] # Scalping needs fine-grained data +``` + +### 3. Include 1min for Stop-Loss Precision + +```python +def get_timeframes(self): + primary_tf = self.params.get("timeframe", "15min") + timeframes = [primary_tf] + + # Always include 1min for precise stop-loss + if "1min" not in timeframes: + timeframes.append("1min") + + return timeframes +``` + +### 4. Handle Timeframe Edge Cases + +```python +def get_entry_signal(self, backtester, df_index): + # Check bounds for all timeframes + if df_index >= len(self.get_primary_timeframe_data()): + return StrategySignal("HOLD", confidence=0.0) + + # Robust timeframe indexing + try: + signal = self._calculate_signal(df_index) + return signal + except IndexError: + return StrategySignal("HOLD", confidence=0.0) +``` + +## Troubleshooting + +### Common Issues + +1. **Index Out of Bounds** + ```python + # Problem: Different timeframes have different lengths + # Solution: Always check bounds + if df_index < len(self.data_1h): + signal = self.data_1h[df_index] + ``` + +2. **Timeframe Misalignment** + ```python + # Problem: Assuming same index across timeframes + # Solution: Use timestamp-based alignment + current_time = primary_data.index[df_index] + h1_idx = hourly_data.index.get_indexer([current_time], method='ffill')[0] + ``` + +3. **Memory Issues with Large Datasets** + ```python + # Solution: Only include necessary timeframes + def get_timeframes(self): + # Return minimal set + return ["15min"] # Not ["1min", "5min", "15min", "1h"] + ``` + +### Debugging Tips + +```python +# Log timeframe information +def initialize(self, backtester): + self._resample_data(backtester.original_df) + + for tf in self.get_timeframes(): + data = self.get_data_for_timeframe(tf) + print(f"Timeframe {tf}: {len(data)} bars, " + f"from {data.index[0]} to {data.index[-1]}") + + self.initialized = True +``` + +## Future Enhancements + +### Planned Features + +1. **Dynamic Timeframe Switching**: Strategies adapt timeframes based on market conditions +2. **Timeframe Confidence Weighting**: Different confidence levels per timeframe +3. **Cross-Timeframe Signal Validation**: Automatic signal confirmation across timeframes +4. **Optimized Memory Management**: Lazy loading and caching for large datasets + +### Extension Points + +The timeframe system is designed for easy extension: + +- Custom resampling methods +- Alternative timeframe synchronization strategies +- Market-specific timeframe preferences +- Real-time timeframe adaptation \ No newline at end of file