| Overall Statistics |
|
Total Trades 0 Average Win 0% Average Loss 0% Compounding Annual Return 0% Drawdown 0% Expectancy 0 Net Profit 0% Sharpe Ratio 0 Probabilistic Sharpe Ratio 0% Loss Rate 0% Win Rate 0% Profit-Loss Ratio 0 Alpha 0 Beta 0 Annual Standard Deviation 0 Annual Variance 0 Information Ratio 0.956 Tracking Error 0.098 Treynor Ratio 0 Total Fees $0.00 Estimated Strategy Capacity $0 Lowest Capacity Asset |
from AlgorithmImports import *
from datetime import timedelta
#from QuantConnect.Data.Custom.CBOE import *
# endregion
class HyperActiveTanCow(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2023, 2, 22) # Set Start Date
self.SetEndDate(2023, 2, 27)
self.SetCash(100000) # Set Strategy Cash
self.equity = self.AddEquity("SPY", Resolution.Minute) # Add the underlying stock: Spy
self.equity.SetDataNormalizationMode(DataNormalizationMode.Raw)
self.symbol = self.equity.Symbol
#self.SetBenchmark(self.equity)
#option = self.AddOption("SPY", Resolution.Minute) # Add the option corresponding to underlying stock
#self.symbol = option.Symbol #can now symbol back and forth
self.contract = str()
self.contractsAdded = set()
#create array to track n amount of 2min ewo bars
self.ewoTracker = []
#this is the array iterator to count each entry space/element
self.i = -1
self.needToPop = False
self.haveHoldings = False
self.buyBar = 0
self.buyCallFlag = False
#Have the algo only look at contracts that are 1 row above or below the strike price and 0 or 1dte
#option.SetFilter(-1, 1, timedelta(0), timedelta(0))
#Create two min consolidator, attach event handler for every 2min, then add consolidator to the engines subscription manager for updates
twoMinConsolidator = TradeBarConsolidator(timedelta(minutes=2))
twoMinConsolidator.DataConsolidated += self.TwoMinBarHandler
self.SubscriptionManager.AddConsolidator("SPY", twoMinConsolidator)
#Create EMA indicators
self.ema5 = ExponentialMovingAverage(5, 0.33)
self.ema35 = ExponentialMovingAverage(35, 0.055)
#Have indicator work w 2min bars
self.RegisterIndicator("SPY", self.ema5, twoMinConsolidator)
self.RegisterIndicator("SPY", self.ema35, twoMinConsolidator)
self.SetWarmUp(timedelta(35))
#Create a scheduled event that sells all holdings before close of day
self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.BeforeMarketClose("SPY", 1), self.ClosePositions)
def OnData(self, data: Slice):
#Ensure indicators are warmed up
if not self.ema5.IsReady and self.ema35.IsReady:
return
self.Plot("ExponentialMovingAverage", "ema5", self.ema5.Current.Value)
self.Plot("ExponentialMovingAverage", "ema35", self.ema35.Current.Value)
#option_invested = [x.Key for x in self.Portfolio if x.Value.Invested and x.Value.Type == SecurityType.Option]
#If two min bar handler flips buy call flag from false to true, then create options chain and call BuyCall()
#if self.buyCallFlag:
#for j in data.OptionChains: #This was from video #12
# self.Debug("Recognized")
# chains = j.Value
# self.BuyCall(chains)
#self.buyCallFlag = False
if self.buyCallFlag:
self.BuyCall(data)
#if option_invested:
#monitor premium price to decide when to sell
#pass
def TwoMinBarHandler(self, sender, consolidated):
#ema5 - ema35 to get 2minEWO value
self.twoMinEWO = float(self.ema5.Current.Value - self.ema35.Current.Value)
#Add current ewo bar to array to track n most recent (still need to implement pop)
self.ewoTracker.append(self.twoMinEWO)
self.i += 1
#Use this block at the end of function call to pop 5th most recent bar to keep storage down
#if self.i >= 4:
# self.needToPop = True
#if self.needToPop:
# self.ewoTracker.pop(self.i - 4)
#Use this to constantly print the EWO array in 5 bar intervals
#if ((self.i+1) % 5 == 0):
#self.Debug(str(self.ewoTracker[self.i-4]) + ", " + str(self.ewoTracker[self.i-3]) + ", " + str(self.ewoTracker[self.i-2]) + ", " + str(self.ewoTracker[self.i-1]) + ", " + str(self.ewoTracker[self.i]))
#self.Debug(str(self.Time))
#Deciding Entry (ONLY 2min red to green flips with CALLS)
#took out the strategy for security purposes
if (self.i >= 3):
#took out strategy, feel free to implement some sort of buy condition for testing
#self.MarketOrder("SPY", 100)
#Call BuyCall function
self.buyCallFlag = True
self.Debug("Buy")
self.Debug(str(self.Time))
self.buyBar = self.i
#Quick test logic to sell after 10mins of holding the position
#if it is 5 bars after buying, sell
#if (self.i == (self.buyBar + 5)):
#self.MarketOrder("SPY", -100)
#self.Debug("Sell")
#self.Debug(str(self.Time))
#self.buyBar = 0
#Buy Call Function
#def BuyCall(self, chains):
#First try, didnt work, got it from TradeOptionsWithMe Video #12
#self.Debug("Buy Call1")
#expiry = sorted(chains, key = lambda x: x.Expiry, reverse=True)[0].Expiry
#calls = [i for i in chains if i.Expiry == expiry and i.Right == OptionRight.Call]
#call_contracts = sorted(calls, key = lambda x: abs(x.Strike - x.UnderlyingLastPrice))
#if len(call_contracts) == 0:
# return
#self.call = call_contracts[0]
#self.Debug(self.call.Expiry)
#self.Debug(self.call.Strike)
#quantity = self.Portfolio.TotalPortfolioValue / self.call.AskPrice
#quantity = int(0.05 * quantity / 100)
#self.Buy(self.call.Symbol, quantity)
#self.Debug("Buy Call2")
#This is from Coding an Options Trading Algoirthm in Python - Code Along
def BuyCall(self, data):
if self.contract == str():
self.contract = self.OptionsFilter(data)
return
elif not self.Portfolio.Invested and data.ContainsKey(self.contract):
quantity = self.Portfolio.TotalPortfolioValue / self.call.AskPrice
#quantity = 100000 / self.call.AskPrice
quantity = int(0.05 * quantity / 100)
self.Buy(self.contract, quantity)
def OptionsFilter(self, data):
contracts = self.OptionChainProvider.GetOptionContractList(self.symbol, data.Time)
self.underlyingPrice = self.Securities[self.symbol].Price
if contracts is None:
return
itm_calls = [i for i in contracts if i.ID.OptionRight == OptionRight.Call and
i.ID.StrikePrice - self.underlyingPrice > 0 and i.ID.StrikePrice - self.underlyingPrice < 1 and
(i.ID.Date - data.Time).days == 0]
self.Debug(str(itm_calls))
if len(itm_calls) > 0:
self.Debug("Buy Call")
self.Debug(str(itm_calls))
return itm_calls[0]
#Liquidate any holdings before close of day
def ClosePositions(self):
self.i = -1
if self.Portfolio.Invested:
self.Liquidate()
#Next step is learning to market buy ATM 0dte options, but not 0dte if after 1pm
#Then tracking the premium and figuring out when to sell based off of percentages
#Then market sell