Overall Statistics |
Total Trades 210 Average Win 0.00% Average Loss 0.00% Compounding Annual Return 0.128% Drawdown 0.000% Expectancy -0.528 Net Profit 0.001% Sharpe Ratio 3.451 Probabilistic Sharpe Ratio 0% Loss Rate 69% Win Rate 31% Profit-Loss Ratio 0.52 Alpha 0.045 Beta -0.013 Annual Standard Deviation 0 Annual Variance 0 Information Ratio -139.442 Tracking Error 0.024 Treynor Ratio -0.084 Total Fees $451.50 Estimated Strategy Capacity $0 Lowest Capacity Asset ES WSVU0MELFS3L |
#region imports from datetime import datetime, timedelta import datetime from AlgorithmImports import * import pandas as pd from QuantConnect.Python import * from QuantConnect.Indicators import RollingWindow #endregion class RetrospectiveTanButterfly(QCAlgorithm): def Initialize(self): self.SetStartDate(2018, 1, 1) # Set Start Date self.SetEndDate(2018, 1, 4) self.SetCash(1000000000) # Set Strategy Cash self.symbolData = {} self.canLong = True self.canShort = True self.contract = self.AddFuture(Futures.Indices.SP500EMini , Resolution.Tick, extendedMarketHours = False, dataNormalizationMode = DataNormalizationMode.BackwardsRatio, dataMappingMode = DataMappingMode.OpenInterest , contractDepthOffset = 0) symbol = self.contract.Symbol #symbol.SetFilter(0, 90) #Futures.Grains.Corn, Futures.Indices.SP500EMini, Futures.Energies.CrudeOilWTI #Energies.CrudeOilWTI self.symbolData[symbol] = SymbolData() self.symbolData[symbol].bidPrice = self.Securities[symbol].BidPrice self.symbolData[symbol].askPrice = self.Securities[symbol].AskPrice self.v_quantity_window = RollingWindow[float](10000) self.v_price_window = RollingWindow[float](10000) #symbol.SetFilter(lambda x: x.FrontMonth().OnlyApplyFilterAtMarketOpen()) self.marketclose = 17*60 self.tickcount = 0 #self.treset = datetime(2000,7,6,10,0,0) self.askcooldown = True self.bidcooldown = True self.bidreset = 0 self.askreset = 0 self.pricehreset = 0 self.pricelreset = 0 self.tickcount = 0 self.orderIDs = pd.DataFrame([],columns=['id','fillprice','quantity','time']) self.BuyFlag = False self.trigger = False self.ticklist = [] self.askLimitTicket = 0 self.bidLimitTicket = 0 self.asklock = 0 self.bidlock = 0 def OnData(self, data): for changedEvent in data.SymbolChangedEvents.Values: if changedEvent.Symbol == self.contract.Symbol: self.Log(f"SymbolChanged event: {changedEvent}") self.Log(f"contract mapped symbol: {self.contract.Mapped}") for symbol, symbolData in self.symbolData.items(): if not data.Ticks.ContainsKey(symbol): continue #underlying = symbol.Underlying ticks = data.Ticks[symbol] for tick in ticks: if tick.TickType == TickType.Quote: symbolData.bidPrice = tick.BidPrice if tick.BidPrice != 0 else symbolData.bidPrice symbolData.askPrice = tick.AskPrice if tick.AskPrice != 0 else symbolData.askPrice #symbolData.bidSize = tick.BidSize if tick.BidSize != 0 else symbolData.bidSize #symbolData.askSize = tick.AskSize if tick.AskSize != 0 else symbolData.askSize if tick.TickType == TickType.Trade: self.tickcount += 1 def ask_ticket_reset(): if not self.askLimitTicket == 0: askTag = str(symbolData.askCounter) self.askLimitTicket.Cancel(askTag) self.askLimitTicket = 0 symbolData.askCounter = 0 self.askcooldown = True def bid_ticket_reset(): if not self.bidLimitTicket == 0: bidTag = str(symbolData.bidCounter) self.bidLimitTicket.Cancel(bidTag) self.bidLimitTicket = 0 symbolData.bidCounter = 0 self.bidcooldown = True if symbolData.bidIceberg == 0 and symbolData.bidPrice != 0: bid_ticket_reset() symbolData.bidIceberg = symbolData.bidPrice if tick.Price < symbolData.bidIceberg: bid_ticket_reset() symbolData.bidIceberg = tick.Price #self.pricelreset += 1 if tick.Price == symbolData.bidIceberg: symbolData.bidCounter += tick.Quantity if tick.Price > symbolData.bidIceberg / 0.995: bid_ticket_reset() symbolData.bidIceberg = 0 #self.bidreset += 1 #delete if symbolData.askIceberg == 0 and symbolData.askPrice != 0: ask_ticket_reset() symbolData.askIceberg = symbolData.askPrice if tick.Price > symbolData.askIceberg: ask_ticket_reset() symbolData.askIceberg = tick.Price #self.pricehreset += 1 if tick.Price == symbolData.askIceberg: symbolData.askCounter += tick.Quantity if tick.Price < symbolData.askIceberg * 0.995: ask_ticket_reset() symbolData.askIceberg = 0 #self.askreset += 1 #delete if symbolData.bidSize > 400: symbolData.bidPacman = symbolData.bidPrice if symbolData.askSize > 400: symbolData.askPacman = symbolData.askPrice #symbolData.bidPrice = symbolData #mark bid price as variable, so that price cant be used as an iceberg #if self.tickcount < 1075 and self.tickcount > 1000: #self.Log(f"tick price->: {tick.Price} tick quantity->: {tick.Quantity} bid ice->: {symbolData.bidIceberg} ask ice->: {symbolData.askIceberg} bid count->: {symbolData.bidCounter} ask count->: {symbolData.askCounter} bid price->: {symbolData.bidPrice} ask price->: {symbolData.askPrice} tick sus->: {tick.Suspicious}") #if tick.Time > datetime(2020,7,6,10,0,0) and tick.Time < datetime(2020,7,6,10,0,10):#2020-07-06 10:00:03 #self.Log(f"tick price->: {tick.Price} tick quantity->: {tick.Quantity} bid ice->: {symbolData.bidIceberg} ask ice->: {symbolData.askIceberg} bid count->: {symbolData.bidCounter} ask count->: {symbolData.askCounter} bid price->: {symbolData.bidPrice} ask price->: {symbolData.askPrice} tick sus->: {tick.Suspicious}") #if symbolData.askCounter < 100: # symbolData.askIceberg = 0 # symbolData.askCounter = 0 # self.askreset += 1 #delete if symbolData.askCounter > 400 and self.askcooldown and self.asklock != symbolData.askIceberg: #and symbolData.askPacman == symbolData.askIceberg: self.BuyFlag = True self.MarketOrder(self.contract.Mapped, 1) self.askcooldown = False self.Log(f"ask counter: {symbolData.askCounter}") self.Log(f"ask lock: {self.asklock}") self.asklock = symbolData.askIceberg #symbolData.askCounter = 0 #symbolData.askIceberg = 0 self.askLimitTicket = self.LimitOrder(self.contract.Mapped, 1, 1) if symbolData.bidCounter > 400 and self.bidcooldown and self.bidlock != symbolData.bidIceberg: # and symbolData.bidPacman == symbolData.bidIceberg: self.BuyFlag = True self.MarketOrder(self.contract.Mapped, -1) self.bidcooldown = False self.Log(f"bid counter: {symbolData.bidCounter}") self.Log(f"bid lock: {self.bidlock}") self.bidlock = symbolData.bidIceberg #symbolData.bidCounter = 0 #symbolData.bidIceberg = 0 self.bidLimitTicket = self.LimitOrder(self.contract.Mapped, -1, 1) def OnEndOfDay(self, symbol): #symbolData = self.symbolData[symbol] x = 5 #self.Debug(f"{symbol.Value}'s buy volume is {symbolData.buyVolume} and sell volume is {symbolData.sellVolume} for today") #self.Log(f"{symbol.Value}'s buy volume is {symbolData.buyVolume} and sell volume is {symbolData.sellVolume} for today") #self.v_quantity_window.Reset() #self.v_price_window.Reset() #self.Log(f"bid resets for today {self.bidreset}") #self.Log(f"ask resets for today {self.askreset}") #self.bidreset = 0 #self.askreset = 0 #self.Log(f"bid higher resets for today {self.pricehreset}") #self.Log(f"ask lower resets for today {self.pricelreset}") #self.pricehreset = 0 #self.pricelreset = 0 class SymbolData: def __init__(self): self.buyVolume = 0 self.sellVolume = 0 self.bidPrice = 0 self.askPrice = 0 self.bidCounter = 0 self.askCounter = 0 self.bidIceberg = 0 self.askIceberg = 0 self.bidSize = 0 self.askSize = 0 self.bidPacman = 0 self.askPacman = 0