Overall Statistics
Total Trades
240
Average Win
0.28%
Average Loss
-0.39%
Compounding Annual Return
17.020%
Drawdown
1.600%
Expectancy
0.106
Net Profit
5.015%
Sharpe Ratio
3.037
Probabilistic Sharpe Ratio
91.485%
Loss Rate
36%
Win Rate
64%
Profit-Loss Ratio
0.72
Alpha
0.11
Beta
0.034
Annual Standard Deviation
0.038
Annual Variance
0.001
Information Ratio
-0.562
Tracking Error
0.128
Treynor Ratio
3.446
Total Fees
$240.00
Estimated Strategy Capacity
$37000.00
Lowest Capacity Asset
SPXW Y7QDMKELZ9TA|SPX 31
Portfolio Turnover
1.22%
#author : Nguyen Tung nttssv@gmail.com
# strategy -1) volatility play 2) Sell ATM strangle at 1650 and close at 9:45 the next day DTE 1


from AlgorithmImports import *


class BasicTemplateSPXWeeklyIndexOptionsAlgorithm(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2023,1, 1)
        #self.SetEndDate(2023, 2, 13)
        self.SetCash(300000)
        self.SetTimeZone(TimeZones.NewYork)
        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage,AccountType.Margin)
        
        self.spx = self.AddIndex("SPX", Resolution.Minute)
        self.SetBenchmark("SPX")


        # 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(-3, 3)
                                     .Expiration(1,1)
                                     .IncludeWeeklys()))

        self.spxw_option = spxw.Symbol
        self.order_call = 0
        self.order_put = 0

    def OnData(self,slice):
        #day high and day low
        current_price = self.spx.Price
        
        #if self.Portfolio.Invested:
        #    return

        
        if self.Time.hour == 15 and self.Time.minute == 50: 
            self.Debug(f'current spx value is {current_price}')                       
            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.Strike) - current_price))
            call_contract = sorted(call,key = lambda x: abs(x.Strike - current_price))

            # if found, trade it
            if len(put_contract) == 0 and self.order_put == 0: 
                return
            else:
                put_ = put_contract[0].Symbol
                self.Debug(f'{self.order_put}')
                self.order_put = 1
                self.MarketOrder(put_, -1)
                

            if len(call_contract) == 0 and self.order_call == 0: 
                return
            else:
                call_ = call_contract[0].Symbol
                self.Debug(f'{self.order_call}')
                self.order_call = 1
                self.MarketOrder(call_, -1)
        elif self.Time.hour == 9 and self.Time.minute == 45:
                self.Liquidate()
                self.order_call = 0
                self.order_put = 0
        
        else:
            return



    def OnOrderEvent(self, orderEvent):
        self.Debug(str(orderEvent))
        self.Debug(self.spx.Price)
        self.Debug(self.Time)