Overall Statistics |
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe 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 Tracking Error 0 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset |
# region imports from AlgorithmImports import * # endregion class HyperActiveOrangeCat(QCAlgorithm): def Initialize(self): # Backtesting / Papertrading parameters if necessary self.SetCash(100000) self.SetStartDate(2022, 11, 11) self.SetEndDate(2022, 11, 11) # Request ES data with tick resolution, filter for expirations in between 5 and 100 days self.es = self.AddFuture(Futures.Indices.SP500EMini, Resolution.Tick) self.es.SetFilter(5, 100) # Variables for both short and long entry and exit tickets, trade cooldowns, prices for trailing stops and cancellations, and contracts per trade # !!! EXHIBIT EXTREME CAUTION USING LEVERAGE ; MANUALLY MANAGE CONTRACT QUANTITY self.longEntryTicket = None self.shortEntryTicket = None self.longExitTicket = None self.shortExitTicket = None self.liquidateTicket = None self.exitFillTime = datetime.min self.cancelTime = datetime.min self.triggerPrice = 0 self.highestPrice = 0 self.lowestPrice = 25000 self.qty = 1 # Variables for price levels # ! Intended to be updated daily, ensure correct futures contract prices # Daily Support and Resistance price levels self.resi6 = 0 self.resi5 = 0 self.resi4 = 0 self.resi3 = 0 self.resi2 = 0 self.resi1 = 0 self.supp1 = 0 self.supp2 = 0 self.supp3 = 0 self.supp4 = 0 self.supp5 = 0 self.supp6 = 0 # Dynamic price levels {e.g. previous day low, overnight high, etc.} self.dyna1 = 0 self.dyna2 = 0 self.dyna3 = 0 self.dyna4 = 0 self.dyna5 = 0 # Macroenvironment price levels self.macr1 = 0 self.macr2 = 0 self.macr3 = 0 # Multiples of one-hundred self.hund1 = 0 self.hund2 = 0 self.hund3 = 0 # Miscellaneous price levels self.misc1 = 0 self.misc2 = 0 self.misc3 = 0 # Variables to halt entries, cancel open entry orders, and liquidate positions around major news events {intended to be updated daily} # Variables to ensure no entries occur outside of RTH self.event1Start = self.Time.replace(hour=1, minute=30, second=0) self.event1End = self.Time.replace(hour=1, minute=30, second=0) self.event2Start = self.Time.replace(hour=1, minute=30, second=0) self.event2End = self.Time.replace(hour=1, minute=30, second=0) self.stopPreM = self.Time.replace(hour=9, minute=32, second=59) self.stopAftM = self.Time.replace(hour=15, minute=55, second=59) def OnData(self, slice): # Sort contracts for highest Open Interest and create a variable for the highest OI for chain in slice.FutureChains: self.popularContracts = [contract for contract in chain.Value if contract.OpenInterest > 1000] if len(self.popularContracts) == 0: continue sortedByOIContracts = sorted(self.popularContracts, key=lambda k : k.OpenInterest, reverse=True) self.liquidContract = sortedByOIContracts[0] # Variable for liquid contract price price = self.Securities[self.liquidContract.Symbol].Price # Enable 30sec cooldown between exit fills and entry submissions, 15sec cooldown between cancellations and entry submissions if (self.Time - self.exitFillTime).seconds <= 30 or (self.Time - self.cancelTime).seconds <= 15: return # Submit entry order if there are no positions or open orders and time conditions are met if not self.Portfolio.Invested and not self.Transactions.GetOpenOrders(self.liquidContract.Symbol) and not self.Time < self.stopPreM and not self.Time > self.stopAftM and not self.event1Start < self.Time < self.event1End and not self.event2Start < self.Time < self.event2End: # Long entry, submit if price comes within 1.5 points above a level if self.resi6 + 1.5 >= price > self.resi6 or self.resi5 + 1.5 >= price > self.resi5 or self.resi4 + 1.5 >= price > self.resi4 or self.resi3 + 1.5 >= price > self.resi3 or self.resi2 + 1.5 >= price > self.resi2 or self.resi1 + 1.5 >= price > self.resi1 or self.supp6 + 1.5 >= price > self.supp6 or self.supp5 + 1.5 >= price > self.supp5 or self.supp4 + 1.5 >= price > self.supp4 or self.supp3 + 1.5 >= price > self.supp3 or self.supp2 + 1.5 >= price > self.supp2 or self.supp1 + 1.5 >= price > self.supp1 or self.dyna1 + 1.5 >= price > self.dyna1 or self.dyna2 + 1.5 >= price > self.dyna2 or self.dyna3 + 1.5 >= price > self.dyna3 or self.dyna4 + 1.5 >= price > self.dyna4 or self.dyna5 + 1.5 >= price > self.dyna5 or self.macr1 + 1.5 >= price > self.macr1 or self.macr2 + 1.5 >= price > self.macr2 or self.macr3 + 1.5 >= price > self.macr3 or self.hund1 + 1.5 >= price > self.hund1 or self.hund2 + 1.5 >= price > self.hund2 or self.hund3 + 1.5 >= price > self.hund3 or self.misc1 + 1.5 >= price > self.misc1 or self.misc2 + 1.5 >= price > self.misc2 or self.misc3 + 1.5 >= price > self.misc3: self.longEntryTicket = self.StopMarketOrder(self.liquidContract.Symbol, self.qty, price + 1.25) # Save price at submission time self.triggerPrice = price # Short entry, submit if price comes within 1.5 points below a level if self.resi6 - 1.5 <= price < self.resi6 or self.resi5 - 1.5 <= price < self.resi5 or self.resi4 - 1.5 <= price < self.resi4 or self.resi3 - 1.5 <= price < self.resi3 or self.resi2 - 1.5 <= price < self.resi2 or self.resi1 - 1.5 <= price < self.resi1 or self.supp6 - 1.5 <= price < self.supp6 or self.supp5 - 1.5 <= price < self.supp5 or self.supp4 - 1.5 <= price < self.supp4 or self.supp3 - 1.5 <= price < self.supp3 or self.supp2 - 1.5 <= price < self.supp2 or self.supp1 - 1.5 <= price < self.supp1 or self.dyna1 - 1.5 <= price < self.dyna1 or self.dyna2 - 1.5 <= price < self.dyna2 or self.dyna3 - 1.5 <= price < self.dyna3 or self.dyna4 - 1.5 <= price < self.dyna4 or self.dyna5 - 1.5 <= price < self.dyna5 or self.macr1 - 1.5 <= price < self.macr1 or self.macr2 - 1.5 <= price < self.macr2 or self.macr3 - 1.5 <= price < self.macr3 or self.hund1 - 1.5 <= price < self.hund1 or self.hund2 - 1.5 <= price < self.hund2 or self.hund3 - 1.5 <= price < self.hund3 or self.misc1 - 1.5 <= price < self.misc1 or self.misc2 - 1.5 <= price < self.misc2 or self.misc3 - 1.5 <= price < self.misc3: self.shortEntryTicket = self.StopMarketOrder(self.liquidContract.Symbol, -self.qty, price - 1.25) # Save price at submission for cancellation self.triggerPrice = price # Trailing stop and possible cancellation if a long entry order is open if self.longEntryTicket is not None and self.longEntryTicket.Status != OrderStatus.Filled: # Trailing stop if price < self.lowestPrice: self.lowestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price + 1.25 self.longEntryTicket.Update(updateFields) # Cancel order and save time if price is not rejecting the level if price <= self.triggerPrice - 4: self.longEntryTicket.Cancel() self.cancelTime = self.Time # Cancel order and save time if time nears end of RTH or news/data event if self.Time > self.stopAftM or self.event1Start < self.Time < self.event1End or self.event2Start < self.Time < self.event2End: self.longEntryTicket.Cancel() self.cancelTime = self.Time # Reset long entry ticket, lowest price, and trigger price variables if order is canceled if self.longEntryTicket.Status == OrderStatus.Canceled: self.longEntryTicket = None self.lowestPrice = 25000 self.triggerPrice = 0 # Trailing stop and possible cancellation if a short entry order is open if self.shortEntryTicket is not None and self.shortEntryTicket.Status != OrderStatus.Filled: # Trailing stop if price > self.highestPrice: self.highestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price - 1.25 self.shortEntryTicket.Update(updateFields) # Cancel order and save time if price is not rejecting the level if price >= self.triggerPrice + 4: self.shortEntryTicket.Cancel() self.cancelTime = self.Time # Cancel order and save time if time nears end of RTH or news/data event if self.Time > self.stopAftM or self.event1Start < self.Time < self.event1End or self.event2Start < self.Time < self.event2End: self.shortEntryTicket.Cancel() self.cancelTime = self.Time # Reset long entry ticket, lowest price, and trigger price variables if order is canceled if self.shortEntryTicket.Status == OrderStatus.Canceled: self.shortEntryTicket = None self.highestPrice = 25000 self.triggerPrice = 0 # Trailing stop and possible cancellation and liquidation if a long closing order is open if self.longExitTicket is not None and self.Portfolio.Invested: # Trailing stop which updates as the position moves favorably if price > self.highestPrice and price < self.longEntryTicket.AverageFillPrice + 1.25: self.highestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price - 1.75 self.longExitTicket.Update(updateFields) if price > self.highestPrice and self.longEntryTicket.AverageFillPrice + 1.25 <= price < self.longEntryTicket.AverageFillPrice + 3.5: self.highestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price - 2.25 self.longExitTicket.Update(updateFields) if price > self.highestPrice and self.longEntryTicket.AverageFillPrice + 3.5 <= price < self.longEntryTicket.AverageFillPrice + 6: self.highestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price - 3 self.longExitTicket.Update(updateFields) if price > self.highestPrice and self.longEntryTicket.AverageFillPrice + 6 <= price < self.longEntryTicket.AverageFillPrice + 8: self.highestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price - 4 self.longExitTicket.Update(updateFields) if price > self.highestPrice and self.longEntryTicket.AverageFillPrice + 8 <= price < self.longEntryTicket.AverageFillPrice + 11.5: self.highestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price - 5.75 self.longExitTicket.Update(updateFields) if price > self.highestPrice and self.longEntryTicket.AverageFillPrice + 11.5 <= price < self.longEntryTicket.AverageFillPrice + 17.5: self.highestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price - 7.75 self.longExitTicket.Update(updateFields) if price > self.highestPrice and self.longEntryTicket.AverageFillPrice + 17.5 <= price < self.longEntryTicket.AverageFillPrice + 23: self.highestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price - 9 self.longExitTicket.Update(updateFields) if price > self.highestPrice and self.longEntryTicket.AverageFillPrice + 23 <= price < self.longEntryTicket.AverageFillPrice + 30: self.highestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price - 11.5 self.longExitTicket.Update(updateFields) if price > self.highestPrice and self.longEntryTicket.AverageFillPrice + 30 <= price < self.longEntryTicket.AverageFillPrice + 40: self.highestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price - 14 self.longExitTicket.Update(updateFields) if price > self.highestPrice and self.longEntryTicket.AverageFillPrice + 40 <= price < self.longEntryTicket.AverageFillPrice + 50: self.highestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price - 20 self.longExitTicket.Update(updateFields) if price > self.highestPrice and self.longEntryTicket.AverageFillPrice + 50 <= price < self.longEntryTicket.AverageFillPrice + 70: self.highestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price - 18 self.longExitTicket.Update(updateFields) if price > self.highestPrice and self.longEntryTicket.AverageFillPrice + 70 <= price < self.longEntryTicket.AverageFillPrice + 80: self.highestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price - 13 self.longExitTicket.Update(updateFields) if price > self.highestPrice and self.longEntryTicket.AverageFillPrice + 80 <= price < self.longEntryTicket.AverageFillPrice + 90: self.highestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price - 8 self.longExitTicket.Update(updateFields) if price > self.highestPrice and self.longEntryTicket.AverageFillPrice + 90 <= price: self.highestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price - 5 self.longExitTicket.Update(updateFields) # Liquidate position on news/data event and reset relevant variables if self.event1Start < self.Time < self.event1End or self.event2Start < self.Time < self.event2End: self.longExitTicket.Cancel() if self.longExitTicket.Status == OrderStatus.Canceled: self.liquidateTicket = self.MarketOrder(self.liquidContract.Symbol, -self.qty) self.longEntryTicket = None self.longExitTicket = None self.highestPrice = 0 # Trailing stop and possible cancellation and liquidation if a short closing order is open if self.shortExitTicket is not None and self.Portfolio.Invested: # Trailing stop which updates as the position moves favorably if price < self.lowestPrice and price > self.shortEntryTicket.AverageFillPrice - 1.25: self.lowestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price + 1.75 self.shortExitTicket.Update(updateFields) if price < self.lowestPrice and self.shortEntryTicket.AverageFillPrice - 1.25 >= price > self.shortEntryTicket.AverageFillPrice - 3.5: self.lowestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price + 2.25 self.shortExitTicket.Update(updateFields) if price < self.lowestPrice and self.shortEntryTicket.AverageFillPrice - 3.5 >= price > self.shortEntryTicket.AverageFillPrice - 6: self.lowestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price + 3 self.shortExitTicket.Update(updateFields) if price < self.lowestPrice and self.shortEntryTicket.AverageFillPrice - 6 >= price > self.shortEntryTicket.AverageFillPrice - 8: self.lowestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price + 4 self.shortExitTicket.Update(updateFields) if price < self.lowestPrice and self.shortEntryTicket.AverageFillPrice - 8 >= price > self.shortEntryTicket.AverageFillPrice - 11.5: self.lowestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price + 5.75 self.shortExitTicket.Update(updateFields) if price < self.lowestPrice and self.shortEntryTicket.AverageFillPrice - 11.5 >= price > self.shortEntryTicket.AverageFillPrice - 17.5: self.lowestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price + 7.75 self.shortExitTicket.Update(updateFields) if price < self.lowestPrice and self.shortEntryTicket.AverageFillPrice - 17.5 >= price > self.shortEntryTicket.AverageFillPrice - 23: self.lowestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price + 9 self.shortExitTicket.Update(updateFields) if price < self.lowestPrice and self.shortEntryTicket.AverageFillPrice - 23 >= price > self.shortEntryTicket.AverageFillPrice - 30: self.lowestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price + 11.5 self.shortExitTicket.Update(updateFields) if price < self.lowestPrice and self.shortEntryTicket.AverageFillPrice - 30 >= price > self.shortEntryTicket.AverageFillPrice - 40: self.lowestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price + 14 self.shortExitTicket.Update(updateFields) if price < self.lowestPrice and self.shortEntryTicket.AverageFillPrice - 40 >= price > self.shortEntryTicket.AverageFillPrice - 50: self.lowestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price + 20 self.shortExitTicket.Update(updateFields) if price < self.lowestPrice and self.shortEntryTicket.AverageFillPrice - 50 >= price > self.shortEntryTicket.AverageFillPrice - 70: self.lowestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price + 18 self.shortExitTicket.Update(updateFields) if price < self.lowestPrice and self.shortEntryTicket.AverageFillPrice - 70 >= price > self.shortEntryTicket.AverageFillPrice - 80: self.lowestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price + 13 self.shortExitTicket.Update(updateFields) if price < self.lowestPrice and self.shortEntryTicket.AverageFillPrice - 80 >= price > self.shortEntryTicket.AverageFillPrice - 90: self.lowestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price + 8 self.shortExitTicket.Update(updateFields) if price < self.lowestPrice and self.shortEntryTicket.AverageFillPrice - 90 >= price: self.lowestPrice = price updateFields = UpdateOrderFields() updateFields.StopPrice = price + 5 self.shortExitTicket.Update(updateFields) # Liquidate position on news/data event and reset relevant variables if self.event1Start < self.Time < self.event1End or self.event2Start < self.Time < self.event2End: self.shortExitTicket.Cancel() if self.shortExitTicket.Status == OrderStatus.Canceled: self.liquidateTicket = self.MarketOrder(self.liquidContract.Symbol, self.qty) self.shortEntryTicket = None self.shortExitTicket = None self.lowestPrice = 25000 def OnOrderEvent(self, orderEvent): if orderEvent.Status != OrderStatus.Filled: return # Submit long exit order when long entry is filled if self.longEntryTicket is not None and self.Portfolio.Invested: self.longExitTicket = self.StopMarketOrder(self.liquidContract.Symbol, -self.qty, self.longEntryTicket.AverageFillPrice - 1.75) # Reset price variables self.triggerPrice = 0 self.highestPrice = 0 self.lowestPrice = 25000 # Submit short exit order when short entry is filled if self.shortEntryTicket is not None and self.Portfolio.Invested: self.shortExitTicket = self.StopMarketOrder(self.liquidContract.Symbol, self.qty, self.shortEntryTicket.AverageFillPrice + 1.75) # Reset price variables self.triggerPrice = 0 self.highestPrice = 0 self.lowestPrice = 25000 # Save time and reset price and ticket variables when a long exit order fills: if self.longExitTicket is not None and self.longExitTicket.OrderId == orderEvent.OrderId: self.exitFillTime = self.Time self.longEntryTicket = None self.longExitTicket = None self.highestPrice = 0 self.lowestPrice = 25000 # Save time and reset price and ticket variables when a short exit order fills: if self.shortExitTicket is not None and self.shortExitTicket.OrderId == orderEvent.OrderId: self.exitFillTime = self.Time self.shortEntryTicket = None self.shortExitTicket = None self.highestPrice = 0 self.lowestPrice = 25000