Overall Statistics |
Total Trades 5524 Average Win 0.00% Average Loss 0.00% Compounding Annual Return -0.330% Drawdown 0.800% Expectancy -0.423 Net Profit -0.666% Sharpe Ratio -1.058 Probabilistic Sharpe Ratio 0.017% Loss Rate 65% Win Rate 35% Profit-Loss Ratio 0.66 Alpha -0.002 Beta 0.001 Annual Standard Deviation 0.002 Annual Variance 0 Information Ratio -0.382 Tracking Error 0.151 Treynor Ratio -1.702 Total Fees $11876.60 Estimated Strategy Capacity $0 Lowest Capacity Asset ES XKGCMV4QK9VL |
#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(2020, 9, 17) # Set Start Date self.SetEndDate(2022, 9, 23) self.SetCash(1000000000) # Set Strategy Cash self.symbolData = {} self.canLong = True self.canShort = True #symbol = self.AddSecurity(SecurityType.Future, Futures.Indices.SP500EMini , Resolution.Tick, extendedMarketHours = False, dataNormalizationMode = DataNormalizationMode.BackwardsRatio, dataMappingMode = DataMappingMode.OpenInterest, contractDepthOffset = 0).Symbol 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) 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) #self.v_price_window = RollingWindow[list()](5) #symbol.SetFilter(lambda x: x.FrontMonth().OnlyApplyFilterAtMarketOpen()) #self.contracts = [symbol] self.printonce = True #self.SetWarmUp(5) self.dfmax = 0 self.dfmin = 0 self.volumeBoxReady = False self.tickcount = 0 self.bidCounter = 0 self.askCounter = 0 self.bidIceberg = 0 self.askIceberg = 0 self.askcooldown = datetime(2000,7,6,10,0,0) self.bidcooldown = datetime(2000,7,6,10,0,0) self.print1 = True self.print2 = True self.print3 = True self.print4 = True self.bidreset = 0 self.askreset = 0 self.pricehreset = 0 self.pricelreset = 0 self.tickcount = 0 def OnData(self, data): 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 if symbolData.bidIceberg == 0 and symbolData.bidPrice != 0: #fix this logic, how do i know if its a ask ice or bid ice symbolData.bidIceberg = symbolData.bidPrice symbolData.bidCounter = 0 if tick.Price < symbolData.bidIceberg: symbolData.bidIceberg = tick.Price symbolData.bidCounter = 0 self.pricelreset += 1 if tick.Price == symbolData.bidIceberg: symbolData.bidCounter += tick.Quantity if tick.Price > symbolData.bidIceberg / 0.995: symbolData.bidIceberg = 0 symbolData.bidCounter = 0 self.bidreset += 1 #delete if symbolData.askIceberg == 0 and symbolData.askPrice != 0: symbolData.askIceberg = symbolData.askPrice symbolData.askCounter = 0 if tick.Price > symbolData.askIceberg: symbolData.askIceberg = tick.Price symbolData.askCounter = 0 self.pricehreset += 1 if tick.Price == symbolData.askIceberg: symbolData.askCounter += tick.Quantity if tick.Price < symbolData.askIceberg * 0.995: symbolData.askIceberg = 0 symbolData.askCounter = 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 > 400 and tick.Time > self.askcooldown: #and symbolData.askPacman != symbolData.askIceberg: self.MarketOrder(self.contract.Mapped, -1) self.askcooldown = tick.Time + timedelta(minutes=5) symbolData.askCounter = 0 symbolData.askIceberg = 0 if symbolData.bidCounter > 400 and tick.Time > self.bidcooldown: #and symbolData.bidPacman != symbolData.bidIceberg: #self.Log(f"{test}") self.MarketOrder(self.contract.Mapped, 1) self.bidcooldown = tick.Time + timedelta(minutes=5) symbolData.bidCounter = 0 symbolData.bidIceberg = 0 #self.MarketOrder(self.contract.Mapped, -1) """tick_df = self.PandasConverter.GetDataFrame[Tick](self.volume_window)""" def OnEndOfDay(self, symbol): symbolData = self.symbolData[symbol] #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 symbolData.ClearDay() 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 def ClearDay(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 def ClearIntra(self): self.buyIntraVolume = 0 self.sellIntraVolume = 0