# MetaTrend Strategy Documentation ## Overview The `IncMetaTrendStrategy` implements a sophisticated trend-following strategy using multiple Supertrend indicators to determine market direction. It generates entry/exit signals based on meta-trend changes, providing robust trend detection with reduced false signals. ## Class: `IncMetaTrendStrategy` ### Purpose - **Trend Detection**: Uses 3 Supertrend indicators to identify strong trends - **Meta-trend Analysis**: Combines multiple timeframes for robust signal generation - **Real-time Processing**: Processes minute-level data with configurable timeframe aggregation ### Key Features - **Multi-Supertrend Analysis**: 3 Supertrend indicators with different parameters - **Meta-trend Logic**: Signals only when all indicators agree - **High Accuracy**: 98.5% accuracy vs corrected original implementation - **Fast Processing**: <1ms updates, sub-millisecond signal generation ## Strategy Logic ### Supertrend Configuration ```python supertrend_configs = [ (12, 3.0), # period=12, multiplier=3.0 (Conservative) (10, 1.0), # period=10, multiplier=1.0 (Sensitive) (11, 2.0) # period=11, multiplier=2.0 (Balanced) ] ``` ### Meta-trend Calculation - **Meta-trend = 1**: All 3 Supertrends indicate uptrend (BUY condition) - **Meta-trend = -1**: All 3 Supertrends indicate downtrend (SELL condition) - **Meta-trend = 0**: Supertrends disagree (NEUTRAL - no action) ### Signal Generation - **Entry Signal**: Meta-trend changes from != 1 to == 1 - **Exit Signal**: Meta-trend changes from != -1 to == -1 ## Configuration Parameters ```python params = { "timeframe": "15min", # Primary analysis timeframe "enable_logging": False, # Enable detailed logging "buffer_size_multiplier": 2.0 # Memory management multiplier } ``` ## Real-time Usage Example ### Basic Implementation ```python from cycles.IncStrategies.metatrend_strategy import IncMetaTrendStrategy import pandas as pd from datetime import datetime, timedelta import random # Initialize MetaTrend strategy strategy = IncMetaTrendStrategy( name="metatrend", weight=1.0, params={ "timeframe": "15min", # 15-minute analysis "enable_logging": True # Enable detailed logging } ) # Simulate real-time minute data stream def simulate_market_data(): """Generate realistic market data with trends""" base_price = 50000.0 # Starting price (e.g., BTC) timestamp = datetime.now() trend_direction = 1 # 1 for up, -1 for down trend_strength = 0.001 # Trend strength while True: # Add trend and noise trend_move = trend_direction * trend_strength * base_price noise = (random.random() - 0.5) * 0.002 * base_price # ±0.2% noise price_change = trend_move + noise close = base_price + price_change high = close + random.random() * 0.001 * base_price low = close - random.random() * 0.001 * base_price open_price = base_price volume = random.randint(100, 1000) # Occasionally change trend direction if random.random() < 0.01: # 1% chance per minute trend_direction *= -1 print(f"šŸ“ˆ Trend direction changed to {'UP' if trend_direction > 0 else 'DOWN'}") yield { 'timestamp': timestamp, 'open': open_price, 'high': high, 'low': low, 'close': close, 'volume': volume } base_price = close timestamp += timedelta(minutes=1) # Process real-time data print("šŸš€ Starting MetaTrend Strategy Real-time Processing...") print("šŸ“Š Waiting for 15-minute bars to form...") for minute_data in simulate_market_data(): # Strategy handles minute-to-15min aggregation automatically result = strategy.update_minute_data( timestamp=pd.Timestamp(minute_data['timestamp']), ohlcv_data=minute_data ) # Check if a complete 15-minute bar was formed if result is not None: current_price = minute_data['close'] timestamp = minute_data['timestamp'] print(f"\nā° Complete 15min bar at {timestamp}") print(f"šŸ’° Price: ${current_price:,.2f}") # Get current meta-trend state meta_trend = strategy.get_current_meta_trend() individual_trends = strategy.get_individual_supertrend_states() print(f"šŸ“ˆ Meta-trend: {meta_trend}") print(f"šŸ” Individual Supertrends: {[s['trend'] for s in individual_trends]}") # Check for signals only if strategy is warmed up if strategy.is_warmed_up: entry_signal = strategy.get_entry_signal() exit_signal = strategy.get_exit_signal() # Process entry signals if entry_signal.signal_type == "ENTRY": print(f"🟢 ENTRY SIGNAL GENERATED!") print(f" šŸ’Ŗ Confidence: {entry_signal.confidence:.2f}") print(f" šŸ’µ Price: ${entry_signal.price:,.2f}") print(f" šŸ“Š Meta-trend: {entry_signal.metadata.get('meta_trend')}") print(f" šŸŽÆ All Supertrends aligned for UPTREND") # execute_buy_order(entry_signal) # Process exit signals if exit_signal.signal_type == "EXIT": print(f"šŸ”“ EXIT SIGNAL GENERATED!") print(f" šŸ’Ŗ Confidence: {exit_signal.confidence:.2f}") print(f" šŸ’µ Price: ${exit_signal.price:,.2f}") print(f" šŸ“Š Meta-trend: {exit_signal.metadata.get('meta_trend')}") print(f" šŸŽÆ All Supertrends aligned for DOWNTREND") # execute_sell_order(exit_signal) else: warmup_progress = len(strategy._meta_trend_history) min_required = max(strategy.get_minimum_buffer_size().values()) print(f"šŸ”„ Warming up... ({warmup_progress}/{min_required} bars)") ``` ### Advanced Trading System Integration ```python class MetaTrendTradingSystem: def __init__(self, initial_capital=10000): self.strategy = IncMetaTrendStrategy( name="metatrend_live", weight=1.0, params={ "timeframe": "15min", "enable_logging": False # Disable for production } ) self.capital = initial_capital self.position = None self.trades = [] self.equity_curve = [] def process_market_data(self, timestamp, ohlcv_data): """Process incoming market data and manage positions""" # Update strategy result = self.strategy.update_minute_data(timestamp, ohlcv_data) if result is not None and self.strategy.is_warmed_up: self._check_signals(timestamp, ohlcv_data['close']) self._update_equity(timestamp, ohlcv_data['close']) def _check_signals(self, timestamp, current_price): """Check for trading signals and execute trades""" entry_signal = self.strategy.get_entry_signal() exit_signal = self.strategy.get_exit_signal() # Handle entry signals if entry_signal.signal_type == "ENTRY" and self.position is None: self._execute_entry(timestamp, entry_signal) # Handle exit signals if exit_signal.signal_type == "EXIT" and self.position is not None: self._execute_exit(timestamp, exit_signal) def _execute_entry(self, timestamp, signal): """Execute entry trade""" # Calculate position size (risk 2% of capital) risk_amount = self.capital * 0.02 # Simple position sizing - could be more sophisticated shares = risk_amount / signal.price self.position = { 'entry_time': timestamp, 'entry_price': signal.price, 'shares': shares, 'confidence': signal.confidence, 'meta_trend': signal.metadata.get('meta_trend'), 'individual_trends': signal.metadata.get('individual_trends', []) } print(f"🟢 LONG POSITION OPENED") print(f" šŸ“… Time: {timestamp}") print(f" šŸ’µ Price: ${signal.price:,.2f}") print(f" šŸ“Š Shares: {shares:.4f}") print(f" šŸ’Ŗ Confidence: {signal.confidence:.2f}") print(f" šŸ“ˆ Meta-trend: {self.position['meta_trend']}") def _execute_exit(self, timestamp, signal): """Execute exit trade""" if self.position: # Calculate P&L pnl = (signal.price - self.position['entry_price']) * self.position['shares'] pnl_percent = (pnl / (self.position['entry_price'] * self.position['shares'])) * 100 # Update capital self.capital += pnl # Record trade trade = { 'entry_time': self.position['entry_time'], 'exit_time': timestamp, 'entry_price': self.position['entry_price'], 'exit_price': signal.price, 'shares': self.position['shares'], 'pnl': pnl, 'pnl_percent': pnl_percent, 'duration': timestamp - self.position['entry_time'], 'entry_confidence': self.position['confidence'], 'exit_confidence': signal.confidence } self.trades.append(trade) print(f"šŸ”“ LONG POSITION CLOSED") print(f" šŸ“… Time: {timestamp}") print(f" šŸ’µ Exit Price: ${signal.price:,.2f}") print(f" šŸ’° P&L: ${pnl:,.2f} ({pnl_percent:+.2f}%)") print(f" ā±ļø Duration: {trade['duration']}") print(f" šŸ’¼ New Capital: ${self.capital:,.2f}") self.position = None def _update_equity(self, timestamp, current_price): """Update equity curve""" if self.position: unrealized_pnl = (current_price - self.position['entry_price']) * self.position['shares'] current_equity = self.capital + unrealized_pnl else: current_equity = self.capital self.equity_curve.append({ 'timestamp': timestamp, 'equity': current_equity, 'position': self.position is not None }) def get_performance_summary(self): """Get trading performance summary""" if not self.trades: return {"message": "No completed trades yet"} trades_df = pd.DataFrame(self.trades) total_trades = len(trades_df) winning_trades = len(trades_df[trades_df['pnl'] > 0]) losing_trades = len(trades_df[trades_df['pnl'] < 0]) win_rate = (winning_trades / total_trades) * 100 total_pnl = trades_df['pnl'].sum() avg_win = trades_df[trades_df['pnl'] > 0]['pnl'].mean() if winning_trades > 0 else 0 avg_loss = trades_df[trades_df['pnl'] < 0]['pnl'].mean() if losing_trades > 0 else 0 return { 'total_trades': total_trades, 'winning_trades': winning_trades, 'losing_trades': losing_trades, 'win_rate': win_rate, 'total_pnl': total_pnl, 'avg_win': avg_win, 'avg_loss': avg_loss, 'profit_factor': abs(avg_win / avg_loss) if avg_loss != 0 else float('inf'), 'final_capital': self.capital } # Usage Example trading_system = MetaTrendTradingSystem(initial_capital=10000) print("šŸš€ MetaTrend Trading System Started") print("šŸ’° Initial Capital: $10,000") # Simulate live trading for market_data in simulate_market_data(): trading_system.process_market_data( timestamp=pd.Timestamp(market_data['timestamp']), ohlcv_data=market_data ) # Print performance summary every 100 bars if len(trading_system.equity_curve) % 100 == 0 and trading_system.trades: performance = trading_system.get_performance_summary() print(f"\nšŸ“Š Performance Summary (after {len(trading_system.equity_curve)} bars):") print(f" šŸ’¼ Capital: ${performance['final_capital']:,.2f}") print(f" šŸ“ˆ Total Trades: {performance['total_trades']}") print(f" šŸŽÆ Win Rate: {performance['win_rate']:.1f}%") print(f" šŸ’° Total P&L: ${performance['total_pnl']:,.2f}") ``` ### Backtesting Example ```python def backtest_metatrend_strategy(historical_data, timeframe="15min"): """Comprehensive backtesting of MetaTrend strategy""" strategy = IncMetaTrendStrategy( name="metatrend_backtest", weight=1.0, params={ "timeframe": timeframe, "enable_logging": False } ) signals = [] trades = [] current_position = None print(f"šŸ”„ Backtesting MetaTrend Strategy on {timeframe} timeframe...") print(f"šŸ“Š Data period: {historical_data.index[0]} to {historical_data.index[-1]}") # Process historical data for timestamp, row in historical_data.iterrows(): ohlcv_data = { 'open': row['open'], 'high': row['high'], 'low': row['low'], 'close': row['close'], 'volume': row['volume'] } # Update strategy result = strategy.update_minute_data(timestamp, ohlcv_data) if result is not None and strategy.is_warmed_up: entry_signal = strategy.get_entry_signal() exit_signal = strategy.get_exit_signal() # Record entry signals if entry_signal.signal_type == "ENTRY": signals.append({ 'timestamp': timestamp, 'type': 'ENTRY', 'price': entry_signal.price, 'confidence': entry_signal.confidence, 'meta_trend': entry_signal.metadata.get('meta_trend') }) # Open position if none exists if current_position is None: current_position = { 'entry_time': timestamp, 'entry_price': entry_signal.price, 'confidence': entry_signal.confidence } # Record exit signals if exit_signal.signal_type == "EXIT": signals.append({ 'timestamp': timestamp, 'type': 'EXIT', 'price': exit_signal.price, 'confidence': exit_signal.confidence, 'meta_trend': exit_signal.metadata.get('meta_trend') }) # Close position if exists if current_position is not None: pnl = exit_signal.price - current_position['entry_price'] pnl_percent = (pnl / current_position['entry_price']) * 100 trades.append({ 'entry_time': current_position['entry_time'], 'exit_time': timestamp, 'entry_price': current_position['entry_price'], 'exit_price': exit_signal.price, 'pnl': pnl, 'pnl_percent': pnl_percent, 'duration': timestamp - current_position['entry_time'], 'entry_confidence': current_position['confidence'], 'exit_confidence': exit_signal.confidence }) current_position = None # Convert to DataFrames for analysis signals_df = pd.DataFrame(signals) trades_df = pd.DataFrame(trades) # Calculate performance metrics if len(trades_df) > 0: total_trades = len(trades_df) winning_trades = len(trades_df[trades_df['pnl'] > 0]) win_rate = (winning_trades / total_trades) * 100 total_return = trades_df['pnl_percent'].sum() avg_return = trades_df['pnl_percent'].mean() max_win = trades_df['pnl_percent'].max() max_loss = trades_df['pnl_percent'].min() print(f"\nšŸ“Š Backtest Results:") print(f" šŸ“ˆ Total Signals: {len(signals_df)}") print(f" šŸ’¼ Total Trades: {total_trades}") print(f" šŸŽÆ Win Rate: {win_rate:.1f}%") print(f" šŸ’° Total Return: {total_return:.2f}%") print(f" šŸ“Š Average Return: {avg_return:.2f}%") print(f" šŸš€ Max Win: {max_win:.2f}%") print(f" šŸ“‰ Max Loss: {max_loss:.2f}%") return signals_df, trades_df else: print("āŒ No completed trades in backtest period") return signals_df, pd.DataFrame() # Run backtest (example) # historical_data = pd.read_csv('btc_1min_data.csv', index_col='timestamp', parse_dates=True) # signals, trades = backtest_metatrend_strategy(historical_data, timeframe="15min") ``` ## Performance Characteristics ### Timing Benchmarks - **Update Time**: <1ms per 15-minute bar - **Signal Generation**: <0.5ms per signal - **Memory Usage**: ~5MB constant - **Accuracy**: 98.5% vs original implementation ## Troubleshooting ### Common Issues 1. **No Signals**: Check if strategy is warmed up (needs ~50+ bars) 2. **Conflicting Trends**: Normal behavior - wait for alignment 3. **Late Signals**: Meta-trend prioritizes accuracy over speed 4. **Memory Usage**: Monitor buffer sizes in long-running systems ### Debug Information ```python # Get detailed strategy state state = strategy.get_current_state_summary() print(f"Strategy State: {state}") # Get meta-trend history history = strategy.get_meta_trend_history(limit=10) for entry in history: print(f"{entry['timestamp']}: Meta-trend={entry['meta_trend']}, Trends={entry['individual_trends']}") ```