Overall Statistics |
Total Orders 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Start Equity 100000 End Equity 100000 Net Profit 0% Sharpe Ratio 0 Sortino Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -0.712 Tracking Error 0.143 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset Portfolio Turnover 0% |
#region imports from AlgorithmImports import * #endregion from QuantConnect.Indicators import MovingAverageConvergenceDivergence class BootCampTask(QCAlgorithm): """ BootCampTask algorithm trades the most liquid future contract of S&P 500 E-mini based on the MACD signal. It takes a long position when the MACD value is significantly less than the signal (suggesting an upward trend), and a short position when the MACD value is significantly greater than the signal (suggesting a downward trend). It places corresponding stop loss and take profit orders for risk management. """ def Initialize(self): """ Initialize the algorithm with necessary parameters. """ self.SetStartDate(2013, 12, 20) # Set the algorithm start date self.SetEndDate(2014, 6, 21) # Set the algorithm end date self.SetCash(1000000) # Set the starting cash # Add the future contract for the S&P 500 E-mini and set filters for expiration range. self.spy = self.AddFuture(Futures.Indices.SP500EMini) self.spy.SetFilter(5, 120) # Only include contracts expiring in 5 to 120 days # Initialize variables to store the most liquid contract, the MACD indicator, # and order tickets for take profit and stop loss. self.oi_contract = None # Most liquid contract based on open interest self.macd = None # MACD indicator self.takeProfit = None # Take profit order ticket self.stopLoss = None # Stop loss order ticket def OnData(self, slice): """ Event handler for new data. """ # Iterate through each future chain in the data slice. for chain in slice.FutureChains: # Select contracts from the chain and sort them by open interest. contracts = sorted([contract for contract in chain.Value], key=lambda k: k.OpenInterest, reverse=True) # If there are no contracts, reset variables and break the loop. if len(contracts) == 0: self.oi_contract = None self.macd = None break # Pick the most liquid contract. contract = contracts[0] # If we have already stored the most liquid contract and it is unchanged, skip updates. if self.oi_contract is not None and contract.Symbol == self.oi_contract.Symbol: break # Update the most liquid contract and initialize the MACD indicator. self.oi_contract = contract self.macd = self.MACD(contract.Symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Minute) # If the MACD indicator is not ready, return early. if self.macd is None or not self.macd.IsReady: return # Define the trade logic for new positions. symbol = self.oi_contract.Symbol security = self.Securities[symbol] # Do not trade if we're already invested in this contract. if security.Invested: return price = security.Price tolerance = 0.003 # Tolerance for MACD signal deviation signalDeltaPercent = self.macd.Current.Value - self.macd.Signal.Current.Value # Determine the trading signal based on MACD and tolerance. if signalDeltaPercent < -tolerance: # If MACD is significantly below the signal line, go long. self.MarketOrder(symbol, 1) # Set take profit and stop loss orders. self.takeProfit = self.LimitOrder(symbol, -1, price * 1.01) self.stopLoss = self.StopMarketOrder(symbol, -1, price * 0.99) elif signalDeltaPercent > tolerance: # If MACD is significantly above the signal line, go short. self.MarketOrder(symbol, -1) # Set take profit and stop loss orders. self.takeProfit = self.LimitOrder(symbol, 1, price * 0.99) self.stopLoss = self.StopMarketOrder(symbol, 1, price * 1.01) def OnOrderEvent(self, orderEvent): """ Event handler for order events. """ # Only act on filled orders. if orderEvent.Status != OrderStatus.Filled: return # Attempt to cancel the opposite order when one is filled. self.Cancel(orderEvent.OrderId) def Cancel(self, orderId): """ Cancel the opposite pending order when one of the take profit or stop loss orders is filled. Args: orderId: The ID of the filled order to identify the opposite order to cancel. """ # If the filled order is the take profit order, cancel the stop loss. if self.takeProfit is not None and orderId == self.takeProfit.OrderId: self.stopLoss.Cancel() # If the filled order is the stop loss order, cancel the take profit. elif self.stopLoss is not None and orderId == self.stopLoss.OrderId: self.takeProfit.Cancel() # Reset the order tickets to None after cancellation. self.takeProfit = None self.stopLoss = None
from AlgorithmImports import * class MultiTimeframeTrendStrategy(QCAlgorithm): def Initialize(self): # Initialize algorithm parameters self.SetStartDate(2010, 1, 1) # self.SetEndDate(2015, 1, 1) self.SetCash(100000) # Add SPY Equity with hourly resolution spy = self.AddEquity("SPY", Resolution.Hour) spy.SetDataNormalizationMode(DataNormalizationMode.Raw) self.spySymbol = spy.Symbol # Set Benchmark self.SetBenchmark("SPY") self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin) # Initialize opening and previous bar prices for multiple time frames self.weeklyOpenPrice = None self.dailyOpenPrice = None self.hourlyOpenPrice = None self.lastDailyHigh = None self.lastDailyLow = None self.lastHourlyHigh = None self.lastHourlyLow = None # Schedule functions to update weekly, daily, and hourly opening prices self.lastTradeWeek = -1 # Initialize to an invalid week number self.Schedule.On(self.DateRules.EveryDay(self.spySymbol), self.TimeRules.AfterMarketOpen(self.spySymbol, 1), self.CheckIfNewWeek) self.Schedule.On(self.DateRules.EveryDay(self.spySymbol), self.TimeRules.At(9, 30), self.DailyOpen) # Initialize last hour self.lastHour = self.Time.hour def OnData(self, data): # Ensure the algorithm isn't warming up and that SPY data is available. if self.IsWarmingUp or self.spySymbol not in data or data[self.spySymbol] is None: return # Update hourly price data and track high/low for Inside Bar detection. if self.Time.hour != self.lastHour: if data.Bars.ContainsKey(self.spySymbol): bar = data.Bars[self.spySymbol] self.hourlyOpenPrice = bar.Open self.lastHourlyHigh = bar.High self.lastHourlyLow = bar.Low self.lastHour = self.Time.hour self.insideBarDetected = False # Reset inside bar detection for the new hour # Detect an Inside Bar based on the last hourly high and low. if self.lastHourlyHigh is not None and self.lastHourlyLow is not None: if self.hourlyOpenPrice < self.lastHourlyHigh and self.hourlyOpenPrice > self.lastHourlyLow: self.Debug("Detected an Inside Bar at the hourly time frame") self.insideBarDetected = True # Ensure all necessary prices are set before proceeding. if None in [self.weeklyOpenPrice, self.dailyOpenPrice, self.hourlyOpenPrice]: return # Current price from the data. price = data[self.spySymbol].Price # Execute trades based on Inside Bar breakout and trend continuity. if self.insideBarDetected: # Entry condition for a long position when current price breaks above the Inside Bar's high if price > self.lastHourlyHigh and price > self.weeklyOpenPrice and price > self.dailyOpenPrice and price > self.hourlyOpenPrice: if not self.Portfolio[self.spySymbol].Invested: self.Log("Inside Bar broken upwards, aligning with TFC for a long position") self.SetHoldings(self.spySymbol, 1) # Exit condition if the price breaks below the Inside Bar's low elif price < self.lastHourlyLow: if self.Portfolio[self.spySymbol].Invested: self.Log("Inside Bar broken downwards, exiting position.") self.Liquidate(self.spySymbol) def CheckIfNewWeek(self): currentWeek = self.Time.isocalendar()[1] if currentWeek != self.lastTradeWeek: self.lastTradeWeek = currentWeek self.WeeklyOpen() def WeeklyOpen(self): self.weeklyOpenPrice = self.Securities[self.spySymbol].Price self.Log(f"Weekly open price updated on {self.Time.strftime('%Y-%m-%d')}: {self.weeklyOpenPrice}") def DailyOpen(self): bar = self.Securities[self.spySymbol] self.dailyOpenPrice = bar.Price self.lastDailyHigh = bar.High self.lastDailyLow = bar.Low self.Log(f"Daily open price updated on {self.Time.strftime('%Y-%m-%d')}: {self.dailyOpenPrice}")
from AlgorithmImports import * from QuantConnect.DataSource import * class USFuturesSecurityMasterDataClassicAlgorithm (QCAlgorithm): """ This algorithm demonstrates the use of the US futures security master to trade a continuous futures contract based on its price relative to a simple moving average (SMA). It goes long when the price is above the SMA by a certain threshold and goes short when the price is below the SMA by the same threshold. The algorithm also handles contract rollovers and logs when these events occur. """ threshold = 0.01 # Define a threshold for price deviation from the SMA (1%) def Initialize(self) -> None: """ Initialize the algorithm settings, add the future contract, and set up the indicators. """ self.SetCash(1000000) # Set starting cash self.SetStartDate(2019, 2, 1) # Set start date for the backtest self.SetEndDate(2021, 6, 1) # Set end date for the backtest # Request continuous future data for Crude Oil WTI with specific data normalization and mapping modes. self.continuous_contract = self.AddFuture(Futures.Energies.CrudeOilWTI, dataNormalizationMode=DataNormalizationMode.BackwardsRatio, dataMappingMode=DataMappingMode.OpenInterest, contractDepthOffset=0) self.symbol = self.continuous_contract.Symbol # Get the continuous contract symbol # Request historical data to warm up the SMA indicator history = self.History(self.symbol, 500, Resolution.Minute) self.Debug(f"We got {len(history)} items from our history request") # Initialize a 10-period SMA indicator with daily resolution self.sma = self.SMA(self.symbol, 10, Resolution.Daily) # Warm up the SMA with historical data if not history.empty: for time, row in history.droplevel(0).loc[self.symbol].iterrows(): self.sma.Update(IndicatorDataPoint(time, row.close)) def OnData(self, slice: Slice) -> None: """ Event handler for new data. Checks for rollover events and trading signals based on the SMA. """ # Check for contract rollover events and handle them for symbol, changed_event in slice.SymbolChangedEvents.items(): old_symbol = changed_event.OldSymbol # The symbol of the old contract new_symbol = changed_event.NewSymbol # The symbol of the new contract tag = f"Rollover - Symbol changed at {self.Time}: {old_symbol} -> {new_symbol}" quantity = self.Portfolio[old_symbol].Quantity # Quantity held of the old contract # Liquidate the old contract position and open a new position in the new contract if necessary self.Liquidate(old_symbol, tag=tag) if quantity != 0: self.MarketOrder(new_symbol, quantity, tag=tag) self.Log(tag) mapped_symbol = self.continuous_contract.Mapped # The currently mapped contract symbol # Check if there is a price update for the continuous contract and the SMA is ready if not (slice.Bars.ContainsKey(self.symbol) and self.sma.IsReady and mapped_symbol): return # Trading logic based on the relationship between the current price and the SMA current_price = slice.Bars[self.symbol].Price # The current price of the continuous contract sma_value = self.sma.Current.Value # The current value of the SMA # If the current price is significantly above the SMA, and we're not already long, go long if current_price > sma_value * (1 + self.threshold) and not self.Portfolio[mapped_symbol].IsLong: self.MarketOrder(mapped_symbol, 1) # If the current price is significantly below the SMA, and we're not already short, go short elif current_price < sma_value * (1 - self.threshold) and not self.Portfolio[mapped_symbol].IsShort: self.MarketOrder(mapped_symbol, -1)
from AlgorithmImports import * class MultiTimeframeTrendStrategy(QCAlgorithm): def Initialize(self): # Initialize algorithm parameters self.SetStartDate(2010, 1, 1) # self.SetEndDate(2015, 1, 1) self.SetCash(100000) # Add SPY Equity with hourly resolution spy = self.AddEquity("SPY", Resolution.Hour) spy.SetDataNormalizationMode(DataNormalizationMode.Raw) self.spySymbol = spy.Symbol # Set Benchmark self.SetBenchmark("SPY") self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin) # Initialize opening and previous bar prices for multiple time frames self.weeklyOpenPrice = None self.dailyOpenPrice = None self.hourlyOpenPrice = None self.lastDailyHigh = None self.lastDailyLow = None self.lastHourlyHigh = None self.lastHourlyLow = None # Schedule functions to update weekly, daily, and hourly opening prices self.lastTradeWeek = -1 # Initialize to an invalid week number self.Schedule.On(self.DateRules.EveryDay(self.spySymbol), self.TimeRules.AfterMarketOpen(self.spySymbol, 1), self.CheckIfNewWeek) self.Schedule.On(self.DateRules.EveryDay(self.spySymbol), self.TimeRules.At(9, 30), self.DailyOpen) # Initialize last hour self.lastHour = self.Time.hour def OnData(self, data): # Check for necessary conditions if self.IsWarmingUp or self.spySymbol not in data or data[self.spySymbol] is None: return # Update hourly open and track high/low if self.Time.hour != self.lastHour: if data.Bars.ContainsKey(self.spySymbol): bar = data.Bars[self.spySymbol] self.hourlyOpenPrice = bar.Open self.lastHourlyHigh = bar.High self.lastHourlyLow = bar.Low self.lastHour = self.Time.hour else: self.Debug(f"No hourly open data for {self.spySymbol} at {self.Time}") # Check for Inside Bar at the hourly time frame if self.hourlyOpenPrice and self.lastHourlyHigh and self.lastHourlyLow: if self.hourlyOpenPrice < self.lastHourlyHigh and self.hourlyOpenPrice > self.lastHourlyLow: self.Debug("Detected an Inside Bar at the hourly time frame") # Ensure all opening prices are set if None in [self.weeklyOpenPrice, self.dailyOpenPrice, self.hourlyOpenPrice]: return # Trading logic based on trend continuity and Inside Bar detection price = data[self.spySymbol].Price if price > self.weeklyOpenPrice and price > self.dailyOpenPrice and price > self.hourlyOpenPrice: if not self.Portfolio[self.spySymbol].Invested: self.Log("Timeframes aligned for long position") self.SetHoldings(self.spySymbol, 1) # Long position elif price < self.weeklyOpenPrice and price < self.dailyOpenPrice and price < self.hourlyOpenPrice: self.Log("Timeframes down, exiting.") self.Liquidate(self.spySymbol) # Exit position def CheckIfNewWeek(self): currentWeek = self.Time.isocalendar()[1] if currentWeek != self.lastTradeWeek: self.lastTradeWeek = currentWeek self.WeeklyOpen() def WeeklyOpen(self): self.weeklyOpenPrice = self.Securities[self.spySymbol].Price self.Log(f"Weekly open price updated on {self.Time.strftime('%Y-%m-%d')}: {self.weeklyOpenPrice}") def DailyOpen(self): bar = self.Securities[self.spySymbol] self.dailyOpenPrice = bar.Price self.lastDailyHigh = bar.High self.lastDailyLow = bar.Low self.Log(f"Daily open price updated on {self.Time.strftime('%Y-%m-%d')}: {self.dailyOpenPrice}")