Overall Statistics |
Total Trades 2177 Average Win 0.00% Average Loss 0.00% Compounding Annual Return -0.215% Drawdown 0.500% Expectancy -0.476 Net Profit -0.433% Sharpe Ratio -1.133 Probabilistic Sharpe Ratio 0.011% Loss Rate 66% Win Rate 34% Profit-Loss Ratio 0.55 Alpha -0.002 Beta 0.004 Annual Standard Deviation 0.001 Annual Variance 0 Information Ratio -0.378 Tracking Error 0.151 Treynor Ratio -0.366 Total Fees $4680.55 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: #if self.print2: # self.Debug(f"quote bid price {tick.BidPrice} ask price {tick.AskPrice} tick price {tick.Price}") # self.print2 = False symbolData.bidPrice = tick.BidPrice if tick.BidPrice != 0 else symbolData.bidPrice symbolData.askPrice = tick.AskPrice if tick.AskPrice != 0 else symbolData.askPrice if tick.TickType == TickType.Trade: #if tick.Price - symbolData.bidPrice > symbolData.askPrice - tick.Price: 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 #self.Log(f"price l reset time->: {tick.Time}") #if tick.Price == symbolData.bidPrice and tick.Price == symbolData.bidIceberg: 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.askPrice and tick.Price == symbolData.askIceberg: 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 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.bidPrice > 10 and self.print1: # self.Log(f"symbol bid price {symbolData.bidPrice}") # self.print1 = False #if symbolData.askPrice > 10 and self.print2: # self.Log(f"symbol ask price {symbolData.askPrice}") # self.print2 = False #if symbolData.bidIceberg > 10 and self.print3: # self.Log(f"symbol bid ice {symbolData.bidIceberg}") # self.print3 = False #if symbolData.askIceberg > 10 and self.print4: # self.Log(f"symbol ask ice {symbolData.askIceberg}") # self.print4 = False #add oneshot logic when askcooldown ends: if symbolData.askCounter > 700 and tick.Time > self.askcooldown: self.MarketOrder(self.contract.Mapped, -1) self.askcooldown = tick.Time + timedelta(minutes=5) symbolData.askCounter = 0 symbolData.askIceberg = 0 if symbolData.bidCounter > 700 and tick.Time > self.bidcooldown: #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 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