| Overall Statistics |
|
Total Trades 164 Average Win 0.33% Average Loss -0.08% Compounding Annual Return 0.721% Drawdown 10.500% Expectancy 1.520 Net Profit 0.155% Sharpe Ratio 0.124 Probabilistic Sharpe Ratio 31.921% Loss Rate 50% Win Rate 50% Profit-Loss Ratio 4.04 Alpha 0.038 Beta -0.243 Annual Standard Deviation 0.179 Annual Variance 0.032 Information Ratio -0.182 Tracking Error 0.246 Treynor Ratio -0.091 Total Fees $102.50 Estimated Strategy Capacity $0 Lowest Capacity Asset SPXW Y5WEOAUNBDKE|SPX 31 |
# This is not a very good strategy.
#
from AlgorithmImports import *
pos_size = 5 # number of orders
class BasicTemplateSPXWeeklyIndexOptionsAlgorithm(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2022, 12, 1)
self.SetEndDate(2023, 2, 18)
self.SetCash(50000)
self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin)
self.spx = self.AddIndex("SPX", Resolution.Minute)
self.SetBenchmark(self.spx.Symbol)
# weekly option SPX contracts
spxw = self.AddIndexOption(self.spx.Symbol, "SPXW")
# set our strike/expiry filter for this option chain
spxw.SetFilter(lambda u: (u.Strikes(-50,50)
.Expiration(0,0)
.IncludeWeeklys()))
self.spxw_option = spxw.Symbol
self.day_low = 10000
self.day_high = 0
self.Schedule.On(self.DateRules.EveryDay(),
self.TimeRules.At(9,30,00),
self.MarketOpen)
self.day_high = self.MAX(self.spx.Symbol, 1000000, Resolution.Minute, Field.High)
self.day_low = self.MIN(self.spx.Symbol, 1000000, Resolution.Minute, Field.Low)
self.SetWarmup(timedelta(2),Resolution.Minute)
def OnData(self,slice):
#day high and day low
if self.IsWarmingUp: return
current_price = self.spx.Price
#self.Debug('Hello')
self.Debug(f'current price is {current_price}')
self.Debug(f'day high is {self.day_high}')
self.Debug(f'day low is {self.day_low}')
if (self.day_high.Current.Value - self.day_low.Current.Value) == 0: return
else:
ratio = (current_price-self.day_low.Current.Value)/(self.day_high.Current.Value - self.day_low.Current.Value)
self.Debug(f'current ratio is {ratio}')
if self.Portfolio.Invested: return
if self.Time.hour <= 13: return
delta = 0.05
chain = slice.OptionChains.GetValue(self.spxw_option)
if chain is None:
return
call = [x for x in chain if x.Right == OptionRight.Call]
put = [x for x in chain if x.Right == OptionRight.Put]
# we sort the contracts to find contract with the right delta
put_contract = sorted(put,key = lambda x: abs(abs(x.Greeks.Delta) - delta))
call_contract = sorted(call,key = lambda x: abs(x.Greeks.Delta - delta))
# if found, sell spread
if len(put_contract) == 0:
return
else:
if ratio < 0.05:
put_ = put_contract[0].Symbol
strike = put_contract[0].Strike - 30
put_1 = sorted(put,key = lambda x: abs(abs(x.Strike) - strike))
put_1 = put_1[0].Symbol
self.MarketOrder(put_,-pos_size)
self.MarketOrder(put_1,pos_size)
if len(call_contract) == 0:
return
else:
if ratio > 0.95:
call_ = call_contract[0].Symbol
strike = call_contract[0].Strike + 30
call_1 = sorted(call,key = lambda x: abs(abs(x.Strike) - strike))
call_1 = call_1[0].Symbol
self.MarketOrder(call_,-pos_size)
self.MarketOrder(call_1,pos_size)
def OnOrderEvent(self, orderEvent):
self.Debug(str(orderEvent))
def MarketOpen(self):
self.day_high = self.MAX(self.spx.Symbol, 1000000, Resolution.Minute, Field.High)
self.day_low = self.MIN(self.spx.Symbol, 1000000, Resolution.Minute, Field.Low)