| Overall Statistics |
|
Total Trades 6 Average Win 2.04% Average Loss -3.09% Compounding Annual Return -1.619% Drawdown 1.200% Expectancy 0.106 Net Profit -0.271% Sharpe Ratio -0.576 Loss Rate 33% Win Rate 67% Profit-Loss Ratio 0.66 Alpha -0.014 Beta 0.092 Annual Standard Deviation 0.026 Annual Variance 0.001 Information Ratio -0.049 Tracking Error 0.17 Treynor Ratio -0.162 Total Fees $1.00 |
class BullCallSpreadAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2017, 5, 1)
self.SetEndDate(2017, 7, 1)
self.SetCash(100000)
equity = self.AddEquity("GOOG", Resolution.Minute)
self.underlyingsymbol = equity.Symbol
self.SetBenchmark(equity.Symbol)
def OnData(self,slice):
''' OptionChainProvider gets the option chain provider,
used to get the list of option contracts for an underlying symbol.
Then you can manually filter the contract list returned by GetOptionContractList.
The manual filtering will be limited to the information
included in the Symbol (strike, expiration, type, style) and/or prices from a History call '''
if not self.Portfolio.Invested:
self.TradeOptions()
def TradeOptions(self):
filtered_contracts = self.InitialFilter(-7, 7, 30, 60)
# sorted the optionchain by expiration date and choose the furthest date
if len(filtered_contracts) > 1:
expiry = sorted(filtered_contracts,key = lambda x: x.ID.Date, reverse=True)[0].ID.Date
# filter the call options from the contracts expires on that date
call = [i for i in filtered_contracts if i.ID.Date == expiry and i.ID.OptionRight == 0]
# sorted the contracts according to their strike prices
call_contracts = sorted(call,key = lambda x: x.ID.StrikePrice)
# call option contract with lower strike
self.call_low = call_contracts[0]
# call option contract with higher strike
self.call_high = call_contracts[-1]
self.AddOptionContract(self.call_low, Resolution.Minute)
self.AddOptionContract(self.call_high, Resolution.Minute)
self.Buy(self.call_low ,1)
self.Sell(self.call_high ,1)
def InitialFilter(self, 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 '''
contracts = self.OptionChainProvider.GetOptionContractList(self.underlyingsymbol, self.Time.date())
if len(contracts) == 0 : return []
# fitler the contracts based on the expiry range
contract_list = [i for i in contracts 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[self.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:
strikes = strike_list[(atm_strike_rank + min_strike_rank):(atm_strike_rank + max_strike_rank)]
except:
strikes = strike_list
filtered_contracts = [i for i in contract_list if i.ID.StrikePrice in strikes]
return filtered_contracts
def OnOrderEvent(self, orderEvent):
self.Log(str(orderEvent))