Expert4x Grid Trend Multiplier [ 8K • HD ]
def detect_trend(self, prices: pd.Series, volume: Optional[pd.Series] = None) -> Tuple[str, float]: """ Detect market trend using multiple indicators Returns: (trend_direction, trend_strength) """ # Calculate EMAs ema_fast = prices.ewm(span=20, adjust=False).mean() ema_slow = prices.ewm(span=50, adjust=False).mean() # Calculate ADX for trend strength high = prices.rolling(window=14).max() low = prices.rolling(window=14).min() plus_dm = high.diff() minus_dm = -low.diff() plus_dm[plus_dm < 0] = 0 minus_dm[minus_dm < 0] = 0 tr = self.calculate_atr( high, low, prices ) if hasattr(self, 'calculate_atr') else pd.Series(index=prices.index) plus_di = 100 * (plus_dm.rolling(14).mean() / tr) minus_di = 100 * (minus_dm.rolling(14).mean() / tr) dx = 100 * abs(plus_di - minus_di) / (plus_di + minus_di) adx = dx.rolling(14).mean() # Determine trend current_ema_fast = ema_fast.iloc[-1] current_ema_slow = ema_slow.iloc[-1] current_adx = adx.iloc[-1] if not pd.isna(adx.iloc[-1]) else 25 if current_ema_fast > current_ema_slow and current_adx > 25: trend = "BULLISH" trend_strength = min(100, current_adx) elif current_ema_fast < current_ema_slow and current_adx > 25: trend = "BEARISH" trend_strength = min(100, current_adx) else: trend = "NEUTRAL" trend_strength = 0 return trend, trend_strength
def __init__(self, initial_balance: float = 10000, grid_distance_pct: float = 0.5, max_grid_levels: int = 10, trend_multiplier: float = 1.5, max_multiplier: float = 5.0, atr_period: int = 14, risk_per_trade: float = 0.02): """ Initialize Grid Trend Multiplier Args: initial_balance: Starting account balance grid_distance_pct: Distance between grid levels (% of price) max_grid_levels: Maximum grid levels trend_multiplier: Position size multiplier for trend direction max_multiplier: Maximum allowed multiplier atr_period: ATR calculation period risk_per_trade: Risk per trade (2% = 0.02) """ self.initial_balance = initial_balance self.balance = initial_balance self.grid_distance_pct = grid_distance_pct self.max_grid_levels = max_grid_levels self.trend_multiplier = trend_multiplier self.max_multiplier = max_multiplier self.atr_period = atr_period self.risk_per_trade = risk_per_trade # Strategy state self.grid_levels = [] self.open_positions = [] self.closed_trades = [] self.current_trend = "NEUTRAL" # BULLISH, BEARISH, NEUTRAL self.trend_strength = 0 # 0-100 self.total_multiplier = 1.0 # Performance metrics self.total_trades = 0 self.winning_trades = 0 self.losing_trades = 0 self.max_drawdown = 0 self.peak_balance = initial_balance def calculate_atr(self, high: pd.Series, low: pd.Series, close: pd.Series) -> pd.Series: """Calculate Average True Range""" tr1 = high - low tr2 = abs(high - close.shift()) tr3 = abs(low - close.shift()) tr = pd.concat([tr1, tr2, tr3], axis=1).max(axis=1) atr = tr.rolling(window=self.atr_period).mean() return atr expert4x grid trend multiplier
def calculate_position_size(self, price: float, stop_loss_pct: float = 0.02) -> float: """ Calculate position size based on trend multiplier and risk management Args: price: Entry price stop_loss_pct: Stop loss percentage Returns: Position size in units """ # Base risk amount risk_amount = self.balance * self.risk_per_trade # Apply trend multiplier if self.current_trend == "BULLISH": position_multiplier = self.total_multiplier elif self.current_trend == "BEARISH": position_multiplier = self.total_multiplier else: position_multiplier = 1.0 # Calculate position size stop_loss_distance = price * stop_loss_pct position_size = (risk_amount * position_multiplier) / stop_loss_distance # Cap position size based on available balance max_position = self.balance * 0.1 / price # Max 10% of balance per trade position_size = min(position_size, max_position) return position_size def detect_trend(self, prices: pd
def get_performance_metrics(self) -> Dict: """ Calculate strategy performance metrics """ win_rate = (self.winning_trades / self.total_trades * 100) if self.total_trades > 0 else 0 profit_factor = 0 # Calculate profit factor gross_profit = sum(t['profit'] for t in self.closed_trades if t.get('profit', 0) > 0) gross_loss = abs(sum(t['profit'] for t in self.closed_trades if t.get('profit', 0) < 0)) profit_factor = gross_profit / gross_loss if gross_loss > 0 else float('inf') total_return = ((self.balance - self.initial_balance) / self.initial_balance) * 100 metrics = { 'total_return_pct': total_return, 'final_balance': self.balance, 'total_trades': self.total_trades, 'winning_trades': self.winning_trades, 'losing_trades': self.losing_trades, 'win_rate_pct': win_rate, 'profit_factor': profit_factor, 'max_drawdown_pct': self.max_drawdown, 'current_trend': self.current_trend, 'trend_strength': self.trend_strength, 'final_multiplier': self.total_multiplier, 'open_positions': len(self.open_positions) } return metrics volume: Optional[pd.Series] = None) ->
def reset_strategy(self): """ Reset strategy to initial state """ self.balance = self.initial_balance self.grid_levels = [] self.open_positions = [] self.closed_trades = [] self.current_trend = "NEUTRAL" self.trend_strength = 0 self.total_multiplier = 1.0 self.total_trades = 0 self.winning_trades = 0 self.losing_trades = 0 self.max_drawdown = 0 self.peak_balance = self.initial_balance logger.info("Strategy reset to initial state") def run_backtest(): """ Run backtest with sample data """ # Generate sample price data np.random.seed(42) dates = pd.date_range('2023-01-01', periods=1000, freq='1H') price = 100 prices = []
class GridTrendMultiplier: """ Expert4x Grid Trend Multiplier Strategy