Overall Statistics |
Total Trades 2 Average Win 3.74% Average Loss 0% Compounding Annual Return 3.741% Drawdown 3.500% Expectancy 0 Net Profit 3.738% Sharpe Ratio 0.747 Probabilistic Sharpe Ratio 37.912% Loss Rate 0% Win Rate 100% Profit-Loss Ratio 0 Alpha 0.004 Beta 0.111 Annual Standard Deviation 0.035 Annual Variance 0.001 Information Ratio -1.685 Tracking Error 0.102 Treynor Ratio 0.238 Total Fees $8.60 Estimated Strategy Capacity $49000000.00 Lowest Capacity Asset ES XPFJZVPGHL35 Portfolio Turnover 0.41% |
# region imports from AlgorithmImports import * # endregion class EnergeticAsparagusCormorant(QCAlgorithm): def Initialize(self): self.SetStartDate(2021, 1, 1) # Set Start Date self.SetEndDate(2022, 1, 1) # Set End Date self.SetCash(500000) # Set Strategy Cash self.future = self.AddFuture(Futures.Indices.SP500EMini, extendedMarketHours= True) self.future.SetFilter(0, 182) #self.future.SetFilter(lambda future_filter_universe: future_filter_universe.FrontMonth()) self.symbol = self.future.Symbol self.Vix = self.AddFuture(Futures.Indices.VIX, extendedMarketHours= True) self.Vix.SetFilter(0, 182) #self.Vix.SetFilter(lambda future_filter_universe: future_filter_universe.FrontMonth()) self.Vixsymbol = self.Vix.Symbol # ES vars self.Longentry_ticket = None self.Shortentry_ticket = None self.ESstopTicket = None self.ESprofitTicket = None self.LongcontractSymbol = None self.ShortcontractSymbol = None self.Esprice = None self.ShortEsprice = None # VIX vars self.Vixentry_ticket = None self.ShortVixentry_ticket = None self.VixstopTicket = None self.VixprofitTicket = None self.VixcontractSymbol = None self.ShortVixcontractSymbol = None self.VixPrice = None self.ShortVixPrice = None self.sma = SimpleMovingAverage(200) self.RegisterIndicator(self.symbol, self.sma, Resolution.Daily) def OnData(self, data: Slice): if (self.Longentry_ticket is None and self.Vixentry_ticket is None) and (self.Shortentry_ticket == None and self.ShortVixentry_ticket == None): if self.Securities[self.symbol].Price > self.sma.Current.Value: self.BuyFuture(data) elif self.Securities[self.symbol].Price < self.sma.Current.Value: self.ShortFuture(data) if self.Portfolio.Invested: # avoids error if self.LongcontractSymbol == None or self.VixcontractSymbol == None or self.ShortVixcontractSymbol == None or self.ShortcontractSymbol == None: return # will sell before an expiration or delisting: if self.Portfolio[self.LongcontractSymbol.Symbol].IsLong: if self.Time + timedelta(1) > self.LongcontractSymbol.Expiry: self.Liquidate(self.LongcontractSymbol.Symbol, "Future too close to expiration.") self.Longentry_ticket = None if self.Portfolio[self.VixcontractSymbol.Symbol].IsLong: if self.Time + timedelta(1) > self.VixcontractSymbol.Expiry: self.Liquidate(self.VixcontractSymbol.Symbol, "Future too close to expiration.") self.Vixentry_ticket = None if self.Portfolio[self.ShortVixcontractSymbol.Symbol].IsShort: if self.Time + timedelta(1) > self.ShortVixcontractSymbol.Expiry: self.Liquidate(self.ShortVixcontractSymbol.Symbol, "Future too close to expiration.") self.ShortVixentry_ticket = None if self.Portfolio[self.ShortcontractSymbol.Symbol].IsShort: if self.Time + timedelta(1) > self.ShortcontractSymbol.Expiry: self.Liquidate(self.ShortcontractSymbol.Symbol, "Future too close to expiration.") self.Shortentry_ticket = None def BuyFuture(self, data: Slice): # get the ES chain chain = data.FuturesChains.get(self.symbol) if chain: self.LongcontractSymbol = sorted(chain, key=lambda contract: contract.Expiry, reverse=True)[0] # save price and enter with limit order self.Esprice = self.Securities[self.LongcontractSymbol.Symbol].Price self.Longentry_ticket = self.LimitOrder(self.LongcontractSymbol.Symbol, 2, self.Esprice) # send out bracket order self.ESprofitTicket = self.LimitOrder(self.LongcontractSymbol.Symbol, -2, self.Esprice*1.05) self.ESstopTicket = self.StopMarketOrder(self.LongcontractSymbol.Symbol, -2, self.Esprice*0.95) # get the Vix chain Vixchain = data.FuturesChains.get(self.Vixsymbol) if Vixchain: self.VixcontractSymbol = sorted(Vixchain, key=lambda Vixcontract: Vixcontract.Expiry, reverse=True)[0] # save price and enter with limit order self.VixPrice = self.Securities[self.VixcontractSymbol.Symbol].Price self.Vixentry_ticket = self.LimitOrder(self.VixcontractSymbol.Symbol, 4, self.VixPrice) # send out bracket order self.VixprofitTicket = self.LimitOrder(self.VixcontractSymbol.Symbol, -4, self.VixPrice*1.05) self.VixstopTicket = self.StopMarketOrder(self.VixcontractSymbol.Symbol, -4, self.VixPrice*0.95) else: self.Log("failed to get Vix chain") return def BuyVix(self, data: Slice): # get the Vix chain Vixchain = data.FuturesChains.get(self.Vixsymbol) if Vixchain: self.VixcontractSymbol = sorted(Vixchain, key=lambda Vixcontract: Vixcontract.Expiry, reverse=True)[0] # save price and enter with limit order self.VixPrice = self.Securities[self.VixcontractSymbol.Symbol].Price self.Vixentry_ticket = self.LimitOrder(self.VixcontractSymbol.Symbol, 4, self.VixPrice) # send out bracket order self.VixprofitTicket = self.LimitOrder(self.VixcontractSymbol.Symbol, -4, self.VixPrice*1.05) self.VixstopTicket = self.StopMarketOrder(self.VixcontractSymbol.Symbol, -4, self.VixPrice*0.95) else: self.Log("failed to get Vix chain") return def ShortFuture(self, data: Slice): chain = data.FuturesChains.get(self.symbol) if chain: self.ShortcontractSymbol = sorted(chain, key=lambda contract: contract.Expiry, reverse=True)[0] # save price and enter with limit order self.Esprice = self.Securities[self.ShortcontractSymbol.Symbol].Price self.Shortentry_ticket = self.LimitOrder(self.ShortcontractSymbol.Symbol, -2, self.Esprice) # send out bracket order self.ESprofitTicket = self.LimitOrder(self.ShortcontractSymbol.Symbol, 2, self.Esprice*0.95) self.ESstopTicket = self.StopMarketOrder(self.ShortcontractSymbol.Symbol, 2, self.Esprice*1.05) Vixchain = data.FuturesChains.get(self.Vixsymbol) if Vixchain: self.ShortVixcontractSymbol = sorted(chain, key=lambda Vixcontract: Vixcontract.Expiry, reverse=True)[0] # save price and enter with limit order self.VixPrice = self.Securities[self.ShortVixcontractSymbol.Symbol].Price self.ShortVixentry_ticket = self.LimitOrder(self.ShortVixcontractSymbol.Symbol, -4, self.VixPrice) # send out bracket order self.VixprofitTicket = self.LimitOrder(self.ShortVixcontractSymbol.Symbol, 4, self.VixPrice*0.95) self.VixstopTicket = self.StopMarketOrder(self.ShortVixcontractSymbol.Symbol, 4, self.VixPrice*1.05) else: self.Log("failed to get Vix chain") return def ShortVix(self, data: Slice): Vixchain = data.FuturesChains.get(self.Vixsymbol) if Vixchain: self.ShortVixcontractSymbol = sorted(chain, key=lambda Vixcontract: Vixcontract.Expiry, reverse=True)[0] # save price and enter with limit order self.VixPrice = self.Securities[self.ShortVixcontractSymbol.Symbol].Price self.ShortVixentry_ticket = self.LimitOrder(self.ShortVixcontractSymbol.Symbol, -4, self.VixPrice) # send out bracket order self.VixprofitTicket = self.LimitOrder(self.ShortVixcontractSymbol.Symbol, 4, self.VixPrice*0.95) self.VixstopTicket = self.StopMarketOrder(self.ShortVixcontractSymbol.Symbol, 4, self.VixPrice*1.05) else: self.Log("failed to get Vix chain") return def OnOrderEvent(self, orderEvent): #self.Log(str(orderEvent)) # Invalid order is blocking new orders if orderEvent.Status == OrderStatus.Invalid: self.Longentry_ticket = None self.Vixentry_ticket = None self.Shortentry_ticket = None self.ShortVixentry_ticket = None return if orderEvent.Status != OrderStatus.Filled: return # avoids error if self.LongcontractSymbol is None or self.ShortcontractSymbol is None: return #if orderEvent.OrderId == self.Longentry_ticket.OrderId: #return # cancel the other ES order after one gets hit if orderEvent.Symbol == self.LongcontractSymbol.Symbol: if orderEvent.OrderId == self.ESprofitTicket.OrderId or orderEvent.OrderId == self.ESstopTicket.OrderId: self.Transactions.CancelOpenOrders(self.LongcontractSymbol.Symbol) self.Longentry_ticket = None return elif orderEvent.Symbol == self.ShortcontractSymbol.Symbol: if orderEvent.OrderId == self.ESprofitTicket.OrderId or orderEvent.OrderId == self.ESstopTicket.OrderId: self.Transactions.CancelOpenOrders(self.ShortcontractSymbol.Symbol) self.Shortentry_ticket = None return # avoids error if self.VixcontractSymbol is None or self.ShortVixcontractSymbol is None: return #if orderEvent.OrderId == self.Vixentry_ticket.OrderId: #return # cancel the other Vix order after one gets hit if orderEvent.Symbol == self.VixcontractSymbol.Symbol: if orderEvent.OrderId == self.VixstopTicket.OrderId or orderEvent.OrderId == self.VixprofitTicket.OrderId: self.Transactions.CancelOpenOrders(self.VixcontractSymbol.Symbol) self.Vixentry_ticket = None return elif orderEvent.Symbol == self.ShortVixcontractSymbol.Symbol: if orderEvent.OrderId == self.VixstopTicket.OrderId or orderEvent.OrderId == self.VixprofitTicket.OrderId: self.Transactions.CancelOpenOrders(self.ShortVixcontractSymbol.Symbol) self.ShortVixentry_ticket = None return