| Overall Statistics |
|
Total Trades 2071 Average Win 0.00% Average Loss 0.00% Compounding Annual Return 0.316% Drawdown 0.100% Expectancy 0.505 Net Profit 0.080% Sharpe Ratio 1.518 Probabilistic Sharpe Ratio 62.801% Loss Rate 37% Win Rate 63% Profit-Loss Ratio 1.37 Alpha 0.001 Beta 0.006 Annual Standard Deviation 0.001 Annual Variance 0 Information Ratio -0.808 Tracking Error 0.201 Treynor Ratio 0.366 Total Fees $4452.65 Estimated Strategy Capacity $0 Lowest Capacity Asset ES XZDYPWUWC7I9 |
#region imports
from datetime import timedelta
from AlgorithmImports import *
#endregion
class RetrospectiveTanButterfly(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2022, 5, 17) # Set Start Date
self.SetEndDate(2022, 8, 17)
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.futureSP500 = self.AddFuture(Futures.Indices.SP500EMini, extendedMarketHours = True)
#self.futureGold = self.AddFuture(Futures.Metals.Gold, extendedMarketHours = True)
#future = self.AddFuture(Futures.Indices.SP500EMini , Resolution.Tick, extendedMarketHours = False)
#future.SetFilter(0, 90)
#symbol = future.Symbol
#continuousContract = [Futures.Indices.SP500EMini]
#currentContract = self.Securities[symbol.Mapped]
self.symbolData[symbol] = SymbolData()
self.symbolData[symbol].bidPrice = self.Securities[symbol].BidPrice
self.symbolData[symbol].askPrice = self.Securities[symbol].AskPrice
#symbol.SetFilter(lambda x: x.FrontMonth().OnlyApplyFilterAtMarketOpen())
#self.contracts = [symbol]
#tickers = ["SPY", "QQQ"]
#for ticker in tickers:
# symbol = self.AddEquity(ticker, Resolution.Tick).Symbol
# self.symbolData[symbol] = SymbolData()
# self.symbolData[symbol].bidPrice = self.Securities[symbol].BidPrice
# self.symbolData[symbol].askPrice = self.Securities[symbol].AskPrice
def OnData(self, data):
for symbol, symbolData in self.symbolData.items():
if not data.Ticks.ContainsKey(symbol): continue
#underlying = symbol.Underlying
if self.Time.second == 00 or self.Time.second == 30:
symbolData.buyRollingVolume5 = symbolData.buyRollingVolume4
symbolData.sellRollingVolume5 = symbolData.sellRollingVolume4
symbolData.buyRollingVolume4 = symbolData.buyRollingVolume3
symbolData.sellRollingVolume4 = symbolData.sellRollingVolume3
symbolData.buyRollingVolume3 = symbolData.buyRollingVolume2
symbolData.sellRollingVolume3 = symbolData.sellRollingVolume2
symbolData.buyRollingVolume2 = symbolData.buyRollingVolume1
symbolData.sellRollingVolume2 = symbolData.sellRollingVolume1
symbolData.buyRollingVolume1 = 0
symbolData.sellRollingVolume1 = 0
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
elif tick.TickType == TickType.Trade:
if tick.Price - symbolData.bidPrice > symbolData.askPrice - tick.Price:
symbolData.sellVolume += tick.Quantity
symbolData.sellRollingVolume1 += tick.Quantity
else:
symbolData.buyVolume += tick.Quantity
symbolData.buyRollingVolume1 += tick.Quantity
if (symbolData.buyRollingVolume1 + symbolData.buyRollingVolume2 + symbolData.buyRollingVolume3 + symbolData.buyRollingVolume4 + symbolData.buyRollingVolume5) - (symbolData.sellRollingVolume1 + symbolData.sellRollingVolume2 + symbolData.sellRollingVolume3 + symbolData.sellRollingVolume4 + symbolData.sellRollingVolume5) < 5: #and > 5:
#self.Log(f"Can Long volume buy Delta: {symbolData.buyIntraVolume - symbolData.sellIntraVolume}")
self.canLong = True
elif (symbolData.sellRollingVolume1 + symbolData.sellRollingVolume2 + symbolData.sellRollingVolume3 + symbolData.sellRollingVolume4 + symbolData.sellRollingVolume5) - (symbolData.buyRollingVolume1 + symbolData.buyRollingVolume2 + symbolData.buyRollingVolume3 + symbolData.buyRollingVolume4 + symbolData.buyRollingVolume5) < 5:
#self.Log(f"Can Short volume sell Delta: {symbolData.sellIntraVolume - symbolData.buyIntraVolume}")
self.canShort = True
if (symbolData.buyRollingVolume1 + symbolData.buyRollingVolume2 + symbolData.buyRollingVolume3 + symbolData.buyRollingVolume4 + symbolData.buyRollingVolume5) - (symbolData.sellRollingVolume1 + symbolData.sellRollingVolume2 + symbolData.sellRollingVolume3 + symbolData.sellRollingVolume4 + symbolData.sellRollingVolume5) >= 700 and self.canLong == True:
self.Log(f"volume buy Delta: {(symbolData.buyRollingVolume1 + symbolData.buyRollingVolume2 + symbolData.buyRollingVolume3 + symbolData.buyRollingVolume4 + symbolData.buyRollingVolume5) - (symbolData.sellRollingVolume1 + symbolData.sellRollingVolume2 + symbolData.sellRollingVolume3 + symbolData.sellRollingVolume4 + symbolData.sellRollingVolume5)}")
self.canLong = False
self.MarketOrder(self.contract.Mapped, 1)
#self.Buy(symbol, 1)
elif (symbolData.sellRollingVolume1 + symbolData.sellRollingVolume2 + symbolData.sellRollingVolume3 + symbolData.sellRollingVolume4 + symbolData.sellRollingVolume5) - (symbolData.buyRollingVolume1 + symbolData.buyRollingVolume2 + symbolData.buyRollingVolume3 + symbolData.buyRollingVolume4 + symbolData.buyRollingVolume5) >= 700 and self.canShort == True:
self.Log(f"volume sell Delta: {(symbolData.sellRollingVolume1 + symbolData.sellRollingVolume2 + symbolData.sellRollingVolume3 + symbolData.sellRollingVolume4 + symbolData.sellRollingVolume5) - (symbolData.buyRollingVolume1 + symbolData.buyRollingVolume2 + symbolData.buyRollingVolume3 + symbolData.buyRollingVolume4 + symbolData.buyRollingVolume5)}")
self.canShort = False
self.MarketOrder(self.contract.Mapped, -1)
#self.Buy(symbol, -1)
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")
symbolData.ClearDay()
class SymbolData:
def __init__(self):
self.buyVolume = 0
self.sellVolume = 0
self.buyRollingVolume1 = 0
self.sellRollingVolume1 = 0
self.buyRollingVolume2 = 0
self.sellRollingVolume2 = 0
self.buyRollingVolume3 = 0
self.sellRollingVolume3 = 0
self.buyRollingVolume4 = 0
self.sellRollingVolume4 = 0
self.buyRollingVolume5 = 0
self.sellRollingVolume5 = 0
self.buyRollingVolume = self.buyRollingVolume1 + self.buyRollingVolume2 + self.buyRollingVolume3 + self.buyRollingVolume4 + self.buyRollingVolume5
self.sellRollingVolume = self.sellRollingVolume1 + self.sellRollingVolume2 + self.sellRollingVolume3 + self.sellRollingVolume4 + self.sellRollingVolume5
self.bidPrice = 0
self.askPrice = 0
self.canShort = True
self.canLong = True
def ClearDay(self):
self.buyVolume = 0
self.sellVolume = 0
def ClearIntra(self):
self.buyIntraVolume = 0
self.sellIntraVolume = 0