Overall Statistics |
Total Trades 13 Average Win 0.73% Average Loss 0% Compounding Annual Return 123.911% Drawdown 2.400% Expectancy 0 Net Profit 2.233% Sharpe Ratio 5.218 Loss Rate 0% Win Rate 100% Profit-Loss Ratio 0 Alpha 0.41 Beta 0.981 Annual Standard Deviation 0.108 Annual Variance 0.012 Information Ratio 4.135 Tracking Error 0.099 Treynor Ratio 0.573 Total Fees $7.00 |
from universe import getUniverse import pandas as pd class OptionsTrading(QCAlgorithm): def Initialize(self): self.SetStartDate(2017, 1, 4) #Set Start Date self.SetEndDate(2017, 1, 15) #Set End Date self.SetCash(50000) #Set Strategy Cash self.happened = False self.boundUp = 0.05 self.boundDown = 0.03 tickerList = getUniverse() for ticker in tickerList: self.AddEquity( ticker, Resolution.Minute ) option = self.AddOption( ticker, Resolution.Minute) # Add the option corresponding to underlying stock option.SetFilter(lambda universe: universe.IncludeWeeklys().Strikes(0, 10).Expiration(timedelta(0), timedelta(30))) def onceADay( self, startHour = 10, resetHour = 15 ): if self.Time.hour >= resetHour: self.happened = False return False elif self.Time.hour >= startHour and self.happened == False : self.happened = True return True return False def isInvested( self, ticker ): for inst in self.Portfolio: if ticker == inst.Value.Symbol.Underlying: self.Debug('%s != %s' % ( ticker, inst.Value.Symbol.Underlying )) return True return False def getOption( self, ticker, chain, right, distance = 0.05 ): bound = chain.Underlying.Price * ( 1 + distance ) if right == OptionRight.Put: optionList = [i for i in chain if i.Right == 1 ] option = max( optionList, key = lambda x : abs( x.Strike - bound )) elif right == OptionRight.Call: optionList = [i for i in chain if i.Right == 0 ] option = min( optionList, key = lambda x : abs( x.Strike - bound )) return option def OnAssignmentOrderEvent(self, assignmentEvent): self.Log(str(assignmentEvent)) def OnData(self, slice): self.Debug(f"Time: {self.Time}") if self.onceADay(): self.Log(str(self.Time)) for chain in slice.OptionChains.Values: if not self.isInvested( chain.Underlying ): optionCall = self.getOption( chain.Underlying.Symbol, chain, right = OptionRight.Call, distance = 0.1 ) optionPut = self.getOption( chain.Underlying.Symbol, chain, right = OptionRight.Put, distance = 0.1 ) if optionCall.BidPrice > 0.05 and optionPut.BidPrice > 0.05 : self.Log('Selling in %s' % chain.Underlying.Symbol ) self.Sell( optionCall.Symbol, 1 ) self.Sell( optionPut.Symbol, 1 ) #self.Sell( highCall.Symbol, 1 ) # For validation we get the strikes of the selected contracts #strikes = [x.Strike for x in contracts if x.Strike > lowerBound and x.Strike < upperBound] #self.Log(f"stock: {chain.Underlying.Symbol}\nLower strike: {lowPut.Strike} \n Upper strike: {highCall.Strike} \n price: {chain.Underlying.Price}")
def getUniverse(): #return ['aapl','intc','goog'] return ['aapl', 'goog', 'amzn']