2025-05-28 22:37:53 +08:00

15 KiB
Raw Blame History

MetaTrend Strategy Documentation

Overview

The MetaTrend Strategy is a sophisticated trend-following algorithm that uses multiple Supertrend indicators to detect and confirm market trends. By combining signals from multiple Supertrend configurations, it creates a "meta-trend" that provides more reliable trend detection with reduced false signals.

Strategy Concept

Core Philosophy

  • Trend Confirmation: Multiple Supertrend indicators must agree before generating signals
  • False Signal Reduction: Requires consensus among indicators to filter noise
  • Adaptive Sensitivity: Different Supertrend configurations capture various trend timeframes
  • Risk Management: Built-in trend reversal detection for exit signals

Key Features

  • Multi-Supertrend Analysis: Uses 3+ Supertrend indicators with different parameters
  • Consensus-Based Signals: Requires minimum agreement threshold for signal generation
  • Incremental Processing: O(1) memory and processing time per data point
  • Configurable Parameters: Flexible configuration for different market conditions

Algorithm Details

Mathematical Foundation

The strategy uses multiple Supertrend indicators, each calculated as:

Basic Upper Band = (High + Low) / 2 + Multiplier × ATR(Period)
Basic Lower Band = (High + Low) / 2 - Multiplier × ATR(Period)

Final Upper Band = Basic Upper Band < Previous Upper Band OR Previous Close > Previous Upper Band 
                   ? Basic Upper Band : Previous Upper Band

Final Lower Band = Basic Lower Band > Previous Lower Band OR Previous Close < Previous Lower Band 
                   ? Basic Lower Band : Previous Lower Band

Supertrend = Close <= Final Lower Band ? Final Lower Band : Final Upper Band
Trend Direction = Close <= Final Lower Band ? -1 : 1

Meta-Trend Calculation

# For each Supertrend indicator
for st in supertrend_collection:
    if st.is_uptrend():
        uptrend_count += 1
    elif st.is_downtrend():
        downtrend_count += 1

# Calculate agreement ratios
total_indicators = len(supertrend_collection)
uptrend_ratio = uptrend_count / total_indicators
downtrend_ratio = downtrend_count / total_indicators

# Generate meta-signal
if uptrend_ratio >= min_trend_agreement:
    meta_signal = "BUY"
elif downtrend_ratio >= min_trend_agreement:
    meta_signal = "SELL"
else:
    meta_signal = "HOLD"

Process Flow Diagram

Data Input (OHLCV)
        ↓
TimeframeAggregator
        ↓
[15min aggregated data]
        ↓
┌─────────────────────────────────────┐
│        MetaTrend Strategy           │
│                                     │
│  ┌─────────────────────────────────┐│
│  │    SupertrendCollection         ││
│  │                                 ││
│  │  ST1(10,2.0) → Signal1          ││
│  │  ST2(20,3.0) → Signal2          ││
│  │  ST3(30,4.0) → Signal3          ││
│  │                                 ││
│  │  Agreement Analysis:            ││
│  │  - Count BUY signals            ││
│  │  - Count SELL signals           ││
│  │  - Calculate ratios             ││
│  └─────────────────────────────────┘│
│                ↓                    │
│  ┌─────────────────────────────────┐│
│  │      Meta-Signal Logic          ││
│  │                                 ││
│  │  if uptrend_ratio >= threshold: ││
│  │      return BUY                 ││
│  │  elif downtrend_ratio >= thresh:││
│  │      return SELL                ││
│  │  else:                          ││
│  │      return HOLD                ││
│  └─────────────────────────────────┘│
└─────────────────────────────────────┘
        ↓
IncStrategySignal
        ↓
Trader Execution

Implementation Architecture

Class Hierarchy

IncStrategyBase
    ↓
MetaTrendStrategy
    ├── TimeframeAggregator (inherited)
    ├── SupertrendCollection
    │   ├── SupertrendState(10, 2.0)
    │   ├── SupertrendState(20, 3.0)
    │   └── SupertrendState(30, 4.0)
    └── Signal Generation Logic

Key Components

1. SupertrendCollection

class SupertrendCollection:
    def __init__(self, periods: list, multipliers: list):
        # Creates multiple Supertrend indicators
        self.supertrends = [
            SupertrendState(period, multiplier) 
            for period, multiplier in zip(periods, multipliers)
        ]
    
    def update_ohlc(self, high, low, close):
        # Updates all Supertrend indicators
        for st in self.supertrends:
            st.update_ohlc(high, low, close)
    
    def get_meta_signal(self, min_agreement=0.6):
        # Calculates consensus signal
        signals = [st.get_signal() for st in self.supertrends]
        return self._calculate_consensus(signals, min_agreement)

2. Signal Generation Process

def _process_aggregated_data(self, timestamp: int, ohlcv: tuple) -> IncStrategySignal:
    open_price, high, low, close, volume = ohlcv
    
    # Update all Supertrend indicators
    self.supertrend_collection.update_ohlc(high, low, close)
    
    # Check if indicators are ready
    if not self.supertrend_collection.is_ready():
        return IncStrategySignal.HOLD()
    
    # Get meta-signal
    meta_signal = self.supertrend_collection.get_meta_signal(
        min_agreement=self.params['min_trend_agreement']
    )
    
    # Generate strategy signal
    if meta_signal == 'BUY' and self.current_signal.signal_type != 'BUY':
        return IncStrategySignal.BUY(
            confidence=self.supertrend_collection.get_agreement_ratio(),
            metadata={
                'meta_signal': meta_signal,
                'individual_signals': self.supertrend_collection.get_signals(),
                'agreement_ratio': self.supertrend_collection.get_agreement_ratio()
            }
        )
    elif meta_signal == 'SELL' and self.current_signal.signal_type != 'SELL':
        return IncStrategySignal.SELL(
            confidence=self.supertrend_collection.get_agreement_ratio(),
            metadata={
                'meta_signal': meta_signal,
                'individual_signals': self.supertrend_collection.get_signals(),
                'agreement_ratio': self.supertrend_collection.get_agreement_ratio()
            }
        )
    
    return IncStrategySignal.HOLD()

Configuration Parameters

Default Parameters

default_params = {
    "timeframe": "15min",                    # Data aggregation timeframe
    "supertrend_periods": [10, 20, 30],      # ATR periods for each Supertrend
    "supertrend_multipliers": [2.0, 3.0, 4.0],  # Multipliers for each Supertrend
    "min_trend_agreement": 0.6               # Minimum agreement ratio (60%)
}

Parameter Descriptions

Parameter Type Default Description
timeframe str "15min" Data aggregation timeframe
supertrend_periods List[int] [10, 20, 30] ATR periods for Supertrend calculations
supertrend_multipliers List[float] [2.0, 3.0, 4.0] ATR multipliers for band calculation
min_trend_agreement float 0.6 Minimum ratio of indicators that must agree

Parameter Optimization Ranges

optimization_ranges = {
    "supertrend_periods": [
        [10, 20, 30],    # Conservative
        [15, 25, 35],    # Moderate
        [20, 30, 40],    # Aggressive
        [5, 15, 25],     # Fast
        [25, 35, 45]     # Slow
    ],
    "supertrend_multipliers": [
        [1.5, 2.5, 3.5],  # Tight bands
        [2.0, 3.0, 4.0],  # Standard
        [2.5, 3.5, 4.5],  # Wide bands
        [3.0, 4.0, 5.0]   # Very wide bands
    ],
    "min_trend_agreement": [0.4, 0.5, 0.6, 0.7, 0.8, 0.9],
    "timeframe": ["5min", "15min", "30min", "1h"]
}

Signal Generation Logic

Entry Conditions

BUY Signal Generated When:

  1. Meta-trend changes from non-bullish to bullish
  2. Agreement ratio ≥ min_trend_agreement
  3. Previous signal was not already BUY
  4. All Supertrend indicators are ready

SELL Signal Generated When:

  1. Meta-trend changes from non-bearish to bearish
  2. Agreement ratio ≥ min_trend_agreement
  3. Previous signal was not already SELL
  4. All Supertrend indicators are ready

Signal Confidence

The confidence level is calculated as the agreement ratio:

confidence = agreeing_indicators / total_indicators
  • High Confidence (0.8-1.0): Strong consensus among indicators
  • Medium Confidence (0.6-0.8): Moderate consensus
  • Low Confidence (0.4-0.6): Weak consensus (may not generate signal)

Signal Metadata

Each signal includes comprehensive metadata:

metadata = {
    'meta_signal': 'BUY',                    # Overall meta-signal
    'individual_signals': ['BUY', 'BUY', 'HOLD'],  # Individual Supertrend signals
    'agreement_ratio': 0.67,                 # Ratio of agreeing indicators
    'supertrend_values': [45123.45, 45234.56, 45345.67],  # Current Supertrend values
    'trend_directions': [1, 1, 0],           # Trend directions (1=up, -1=down, 0=neutral)
    'timestamp': 1640995200000               # Signal generation timestamp
}

Performance Characteristics

Strengths

  1. Trend Accuracy: High accuracy in strong trending markets
  2. False Signal Reduction: Multiple confirmations reduce whipsaws
  3. Adaptive Sensitivity: Different parameters capture various trend speeds
  4. Risk Management: Clear trend reversal detection
  5. Scalability: Works across different timeframes and markets

Weaknesses

  1. Sideways Markets: May generate false signals in ranging conditions
  2. Lag: Multiple confirmations can delay entry/exit points
  3. Whipsaws: Vulnerable to rapid trend reversals
  4. Parameter Sensitivity: Performance depends on parameter tuning

Optimal Market Conditions

  • Trending Markets: Best performance in clear directional moves
  • Medium Volatility: Works well with moderate price swings
  • Sufficient Volume: Better signals with adequate trading volume
  • Clear Trends: Performs best when trends last longer than indicator periods

Usage Examples

Basic Usage

from IncrementalTrader import MetaTrendStrategy, IncTrader

# Create strategy with default parameters
strategy = MetaTrendStrategy("metatrend")

# Create trader
trader = IncTrader(strategy, initial_usd=10000)

# Process data
for timestamp, ohlcv in data_stream:
    signal = trader.process_data_point(timestamp, ohlcv)
    if signal.signal_type != 'HOLD':
        print(f"Signal: {signal.signal_type} (confidence: {signal.confidence:.2f})")

Custom Configuration

# Custom parameters for aggressive trading
strategy = MetaTrendStrategy("metatrend_aggressive", {
    "timeframe": "5min",
    "supertrend_periods": [5, 10, 15],
    "supertrend_multipliers": [1.5, 2.0, 2.5],
    "min_trend_agreement": 0.5
})

Conservative Configuration

# Conservative parameters for stable trends
strategy = MetaTrendStrategy("metatrend_conservative", {
    "timeframe": "1h",
    "supertrend_periods": [20, 30, 40],
    "supertrend_multipliers": [3.0, 4.0, 5.0],
    "min_trend_agreement": 0.8
})

Backtesting Results

Performance Metrics (Example)

Timeframe: 15min
Period: 2024-01-01 to 2024-12-31
Initial Capital: $10,000

Total Return: 23.45%
Sharpe Ratio: 1.34
Max Drawdown: -8.23%
Win Rate: 58.3%
Profit Factor: 1.67
Total Trades: 127

Parameter Sensitivity Analysis

min_trend_agreement vs Performance:
0.4: Return 18.2%, Sharpe 1.12, Trades 203
0.5: Return 20.1%, Sharpe 1.23, Trades 167
0.6: Return 23.4%, Sharpe 1.34, Trades 127  ← Optimal
0.7: Return 21.8%, Sharpe 1.41, Trades 89
0.8: Return 19.3%, Sharpe 1.38, Trades 54

Implementation Notes

Memory Efficiency

  • Constant Memory: O(1) memory usage regardless of data history
  • Efficient Updates: Each data point processed in O(1) time
  • State Management: Minimal state storage for optimal performance

Real-time Capability

  • Incremental Processing: Designed for live trading applications
  • Low Latency: Minimal processing delay per data point
  • Stateful Design: Maintains indicator state between updates

Error Handling

def _process_aggregated_data(self, timestamp: int, ohlcv: tuple) -> IncStrategySignal:
    try:
        # Validate input data
        if not self._validate_ohlcv(ohlcv):
            self.logger.warning(f"Invalid OHLCV data: {ohlcv}")
            return IncStrategySignal.HOLD()
        
        # Process data
        # ... strategy logic ...
        
    except Exception as e:
        self.logger.error(f"Error in MetaTrend strategy: {e}")
        return IncStrategySignal.HOLD()

Advanced Features

Dynamic Parameter Adjustment

# Adjust parameters based on market volatility
def adjust_parameters_for_volatility(self, volatility):
    if volatility > 0.03:  # High volatility
        self.params['min_trend_agreement'] = 0.7  # Require more agreement
    elif volatility < 0.01:  # Low volatility
        self.params['min_trend_agreement'] = 0.5  # Allow less agreement

Multi-timeframe Analysis

# Combine multiple timeframes for better signals
strategy_5m = MetaTrendStrategy("mt_5m", {"timeframe": "5min"})
strategy_15m = MetaTrendStrategy("mt_15m", {"timeframe": "15min"})
strategy_1h = MetaTrendStrategy("mt_1h", {"timeframe": "1h"})

# Use higher timeframe for trend direction, lower for entry timing

Troubleshooting

Common Issues

  1. No Signals Generated

    • Check if min_trend_agreement is too high
    • Verify sufficient data for indicator warmup
    • Ensure data quality and consistency
  2. Too Many False Signals

    • Increase min_trend_agreement threshold
    • Use wider Supertrend multipliers
    • Consider longer timeframes
  3. Delayed Signals

    • Reduce min_trend_agreement threshold
    • Use shorter Supertrend periods
    • Consider faster timeframes

Debug Information

# Enable debug logging
strategy.logger.setLevel(logging.DEBUG)

# Access internal state
print(f"Current signals: {strategy.supertrend_collection.get_signals()}")
print(f"Agreement ratio: {strategy.supertrend_collection.get_agreement_ratio()}")
print(f"Meta signal: {strategy.supertrend_collection.get_meta_signal()}")

The MetaTrend Strategy provides robust trend-following capabilities through multi-indicator consensus, making it suitable for various market conditions while maintaining computational efficiency for real-time applications.