from datetime import timedelta

class OptionsAlgorithm(QCAlgorithm):

def Initialize(self):
self.SetStartDate(2019, 1, 1)
self.SetEndDate(2020, 12, 1)
self.SetCash(20000)
self.syl = 'SPY'
equity = self.AddEquity(self.syl, Resolution.Minute)
equity.SetDataNormalizationMode(DataNormalizationMode.Raw)
self.macd = self.MACD(self.syl, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily)
self.rsi = self.RSI("SPY", 14)
self.underlyingsymbol = equity.Symbol
# use the underlying equity as the benchmark
self.SetBenchmark(equity.Symbol)


def OnData(self,slice):
if not self.rsi.IsReady:
return

if self.rsi.Current.Value < 25 and self.Portfolio.Invested <= 0:

if self.macd.IsReady:
if self.Portfolio[self.contract].Quantity == 0 and self.macd.Current.Value > self.macd.Signal.Current.Value and self.macd.Current.Value < 0:
self.BuyCall()

if self.rsi.Current.Value > 50 and self.Portfolio.Invested >= 1:

if self.Portfolio[self.contract].Quantity > 0 and self.macd.Current.Value > self.macd.Signal.Current.Value and self.macd.Current.Value > 0:

if self.Portfolio.Invested:
self.Liquidate()


def BuyCall(self):
contracts = self.OptionChainProvider.GetOptionContractList(self.underlyingsymbol, self.Time.date())
if len(contracts) == 0: return
filtered_contracts = self.InitialFilter(self.underlyingsymbol, contracts, -3, 3, 0, 30)
call = [x for x in filtered_contracts if x.ID.OptionRight == 1]
# sorted the contracts according to their expiration dates and choose the ATM options
contracts = sorted(sorted(call, key = lambda x: abs(self.Securities[self.syl].Price - x.ID.StrikePrice)),
key = lambda x: x.ID.Date, reverse=True)
self.contract = contracts[0]
self.AddOptionContract(self.contract, Resolution.Minute)
self.Buy(self.contract, 1)


def InitialFilter(self, underlyingsymbol, symbol_list, min_strike_rank, max_strike_rank, min_expiry, max_expiry):

''' This method is an initial filter of option contracts
according to the range of strike price and the expiration date '''

if len(symbol_list) == 0 : return
# fitler the contracts based on the expiry range
contract_list = [i for i in symbol_list if min_expiry < (i.ID.Date.date() - self.Time.date()).days < max_expiry]
# find the strike price of ATM option
atm_strike = sorted(contract_list,
key = lambda x: abs(x.ID.StrikePrice - self.Securities[underlyingsymbol].Price))[0].ID.StrikePrice
strike_list = sorted(set([i.ID.StrikePrice for i in contract_list]))
# find the index of ATM strike in the sorted strike list
atm_strike_rank = strike_list.index(atm_strike)
try:
min_strike = strike_list[atm_strike_rank + min_strike_rank]
max_strike = strike_list[atm_strike_rank + max_strike_rank]
except:
min_strike = strike_list[0]
max_strike = strike_list[-1]

filtered_contracts = [i for i in contract_list if i.ID.StrikePrice >= min_strike and i.ID.StrikePrice <= max_strike]

return filtered_contracts

I am trying to buy ATM call options for "SPY" for essentially the nearest options chain date and then sell the purchased contract.  My conditions that need to be met are as follows:

Buy Call option:

RSI < 25

MACD signal crossover (current value > signal value) and current value is (-) or < 0

*Another condition i want to add is MACD difference (between the current value and signal value) set to 0.4 or greater (from histogram)

if these conditions are met, buy call option ATM strike, current "bid" price (1 contract).

Once invested, look to sell using the following conditions:

Sell purchased option contract:

RSI > 50

MACD current value is (+) or > 0

if these conditions are met, sell the purcahsed contract at current "bid" price

 

Would greatly appreciate any help, what i have so far above are pieces from other code that i have seen.  But the code isn't running - type and attribute errors.  

 

Also, in the end i'm not looking for an active trading platform.. more looking for a "notification" algo so i can further investigate the opportunity.

 

Author