Overall Statistics |
Total Orders 54 Average Win 16.33% Average Loss -6.46% Compounding Annual Return 15.793% Drawdown 34.000% Expectancy 0.569 Start Equity 10000 End Equity 21092.00 Net Profit 110.920% Sharpe Ratio 0.44 Sortino Ratio 0.325 Probabilistic Sharpe Ratio 9.025% Loss Rate 56% Win Rate 44% Profit-Loss Ratio 2.53 Alpha 0.078 Beta 0.549 Annual Standard Deviation 0.288 Annual Variance 0.083 Information Ratio 0.132 Tracking Error 0.282 Treynor Ratio 0.23 Total Fees $90.99 Estimated Strategy Capacity $150000000.00 Lowest Capacity Asset TQQQ UK280CGTCB51 Portfolio Turnover 2.90% |
# region imports from AlgorithmImports import * # endregion import importlib # Set the strategy name (must match file and class name exactly) STRATEGY_NAME = "breakoutsmacrossoverstrategy" # Matches file: BreakoutRSIStrategy.py and class: BreakoutRSIStrategy # Convert file name to lowercase for import strategy_module = importlib.import_module(f"strategies.{STRATEGY_NAME.lower()}") # Get the strategy class (same as STRATEGY_NAME) strategy_class_name = STRATEGY_NAME # Retrieve the strategy class dynamically StrategyClass = getattr(strategy_module, strategy_class_name) # Inherit and run the selected strategy class Main(StrategyClass): def Initialize(self): super().Initialize() # Call the selected strategy's Initialize method
# region imports from AlgorithmImports import * # endregion # Your New Python File
from AlgorithmImports import * class breakoutrsistrategy(QCAlgorithm): def Initialize(self): self.SetStartDate(2020, 1, 1) self.SetEndDate(2025, 2, 1) self.SetCash(10000) # Select stock self.symbol = self.AddEquity("SMH", Resolution.Daily).Symbol # Breakout settings self.breakout_period = 10 self.breakdown_period = 5 self.rsi = self.RSI(self.symbol, 14, MovingAverageType.Wilders, Resolution.Daily) self.highs = RollingWindow[float](self.breakout_period) self.lows = RollingWindow[float](self.breakdown_period) self.entry_price = 0 self.stop_loss_pct = 0.05 # Warm up the algorithm until all indicators are ready self.SetWarmUp(self.breakout_period) def OnData(self, data): if not data.ContainsKey(self.symbol) or self.IsWarmingUp: return # Update high/low rolling windows self.highs.Add(self.Securities[self.symbol].High) self.lows.Add(self.Securities[self.symbol].Low) if not self.highs.IsReady or not self.lows.IsReady or not self.rsi.IsReady: return # Get breakout and RSI values high_breakout = max(list(self.highs)[1:]) low_breakout = min(list(self.lows)[1:]) current_price = self.Securities[self.symbol].Close rsi_value = self.rsi.Current.Value # Buy when RSI is above 50 and price breaks above previous highs if rsi_value > 50 and not self.Portfolio.Invested and current_price > high_breakout: self.SetHoldings(self.symbol, 1) self.entry_price = current_price self.Debug(f"BUY at {current_price} - {self.Time} | RSI: {rsi_value}") # Sell if price breaks below previous lows or falls below stop-loss level elif self.Portfolio.Invested and (current_price < low_breakout or current_price < self.entry_price * (1 - self.stop_loss_pct)): self.Liquidate(self.symbol) self.Debug(f"SELL at {current_price} - {self.Time} | RSI: {rsi_value}")
from AlgorithmImports import * class breakoutsmacrossoverstrategy(QCAlgorithm): def Initialize(self): # Set backtest period self.SetStartDate(2020, 1, 1) self.SetEndDate(2025, 2, 1) # Set initial capital self.SetCash(10000) # Select stock self.symbol = self.AddEquity("TQQQ", Resolution.Daily).Symbol # Define breakout periods self.breakout_period = 10 self.breakdown_period = 10 # Create 50 and 150 period SMAs self.sma50 = self.SMA(self.symbol, 50, Resolution.Daily) self.sma150 = self.SMA(self.symbol, 150, Resolution.Daily) # Track highest high and lowest low using rolling windows self.highs = RollingWindow[float](self.breakout_period) self.lows = RollingWindow[float](self.breakdown_period) # Store entry price for stop-loss self.entry_price = 0 self.stop_loss_pct = 0.05 # Use the longer period for warmup (150 days) self.SetWarmUp(150) def OnData(self, data): # Ensure data for our symbol is available and we are not warming up if not data.ContainsKey(self.symbol) or self.IsWarmingUp: return # Add the latest high and low to the rolling windows self.highs.Add(self.Securities[self.symbol].High) self.lows.Add(self.Securities[self.symbol].Low) # Ensure our rolling windows and SMA indicators are ready if not self.highs.IsReady or not self.lows.IsReady or not self.sma50.IsReady or not self.sma150.IsReady: return # Get breakout levels (excluding today's high/low) high_breakout = max(list(self.highs)[1:]) low_breakout = min(list(self.lows)[1:]) current_price = self.Securities[self.symbol].Close # ENTRY CONDITION: # Only take long trades if 50 SMA is above 150 SMA and there's a breakout above the recent high if not self.Portfolio.Invested and self.sma50.Current.Value > self.sma150.Current.Value and current_price > high_breakout: self.SetHoldings(self.symbol, 1) # Invest 100% of portfolio self.entry_price = current_price # Record entry price for stop-loss calculation self.Debug(f"BUY at {current_price} - {self.Time} | SMA50: {self.sma50.Current.Value}, SMA150: {self.sma150.Current.Value}") # EXIT CONDITION: # Exit if current price drops below the recent low breakout, # hits the stop-loss, or if the SMA crossover turns bearish (50 SMA falls below 150 SMA) elif self.Portfolio.Invested and (current_price < low_breakout or current_price < self.entry_price * (1 - self.stop_loss_pct) or self.sma50.Current.Value < self.sma150.Current.Value): self.Liquidate(self.symbol) self.Debug(f"SELL at {current_price} - {self.Time} | SMA50: {self.sma50.Current.Value}, SMA150: {self.sma150.Current.Value}")
from AlgorithmImports import * class SMACrossoverStrategy(QCAlgorithm): def Initialize(self): # Set backtest period self.SetStartDate(2020, 1, 1) self.SetEndDate(2025, 2, 1) # Set initial capital self.SetCash(10000) # Select stock self.symbol = self.AddEquity("SMH", Resolution.Daily).Symbol # Create 50 and 150 period SMAs self.sma50 = self.SMA(self.symbol, 50, Resolution.Daily) self.sma150 = self.SMA(self.symbol, 150, Resolution.Daily) # Warm up the algorithm until both SMAs are ready self.SetWarmUp(150) def OnData(self, data): # Ensure we have data for our symbol if not data.ContainsKey(self.symbol): return # Do not trade until warmup is complete if self.IsWarmingUp: return # Check that our indicators are ready if not self.sma50.IsReady or not self.sma150.IsReady: return current_price = self.Securities[self.symbol].Close # Check for a bullish crossover: # If not invested and the 50 SMA is above the 150 SMA, go long if not self.Portfolio.Invested and self.sma50.Current.Value > self.sma150.Current.Value: self.SetHoldings(self.symbol, 1) # Invest 100% of portfolio in the stock self.Debug(f"BUY at {current_price} - {self.Time}") # Check for a bearish crossover: # If already invested and the 50 SMA falls below the 150 SMA, liquidate the position elif self.Portfolio.Invested and self.sma50.Current.Value < self.sma150.Current.Value: self.Liquidate(self.symbol) self.Debug(f"SELL at {current_price} - {self.Time}")