| 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']