Overall Statistics
Total Trades
4
Average Win
7.69%
Average Loss
-13.33%
Compounding Annual Return
21.563%
Drawdown
37.400%
Expectancy
-0.212
Net Profit
196.647%
Sharpe Ratio
0.752
Probabilistic Sharpe Ratio
19.320%
Loss Rate
50%
Win Rate
50%
Profit-Loss Ratio
0.58
Alpha
0.056
Beta
1.237
Annual Standard Deviation
0.234
Annual Variance
0.055
Information Ratio
0.767
Tracking Error
0.103
Treynor Ratio
0.142
Total Fees
$2.00
Estimated Strategy Capacity
$0
Lowest Capacity Asset
VGT SVS2QA8SPHET
Portfolio Turnover
0.06%
#region imports
from AlgorithmImports import *
#endregion
class TransdimensionalCalibratedRadiator(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2018, 1, 1)  # Set Start Date
        self.SetCash(15000)  # Set Strategy Cash

        option = self.AddOption("VGT")
        self.symbol = option.Symbol
        option.SetFilter(-40, 40, timedelta(8), timedelta(8))

    def OnData(self, slice: Slice) -> None:
        
        if self.Portfolio.Invested: return

        # Get the OptionChain
        chain = slice.OptionChains.get(self.symbol, None)
        if not chain: return

        # Get the furthest expiration date of the contracts
        expiry = sorted(chain, key = lambda x: x.Expiry, reverse=True)[0].Expiry
        
        # Select the put Option contracts with the furthest expiry
        puts = [i for i in chain if i.Expiry == expiry and i.Right == OptionRight.Put]
        if len(puts) == 0: return

        # Select the ITM and OTM contract strikes from the remaining contracts
        put_strikes = sorted([x.Strike for x in puts])
        for kvp in slice.OptionChains:
            if kvp.Key != self.symbol: continue
            chain = kvp.Value
            contracts = [i for i in chain]
            if len(contracts) == 0: continue
            contracts = sorted(contracts, key=lambda x: (x.Strike))
            self.shortContract = min(contracts, key=lambda x: x.Strike < 1.055*chain.Underlying.Price)
            self.longContract = min([c for c in contracts if c.Expiry==self.shortContract.Expiry], key=lambda x: x.Strike > 0.92*chain.Underlying.Price)
        
        #self.Buy(option_strategy, 1)
            if self.shortContract != self.longContract: 
                pass
                self.allChecksPassed = True
                self.Sell(self.shortContract.Symbol, 1)
                self.Buy(self.longContract.Symbol, 1)
                self.expirydate = self.longContract.Expiry 
                break

#        for chain in data.OptionChains.Values:
#             lowerBound = chain.Underlying.Price * 0.9
#             upperBound = chain.Underlying.Price * 1.0
#             # Option contracts sorted by their strikes
#             contracts = sorted(chain, key=lambda x: x.Strike)
#             # The contracts from -5% to 5%
#             selectedContracts = [x for x in contracts if x.Strike > lowerBound and x.Strike < upperBound and x.Symbol.ID.OptionRight == OptionRight.Put ]
            
#             # 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"Lower Bound: {lowerBound} \n Upper Bound: {upperBound} \n Strikes: {strikes}")
#             self.longOption = selectedContracts[0]
#             self.shortOption = selectedContracts[0]
#             self.Buy(self.longOption.Symbol, 1)
#             self.Sell(self.shortOption.Symbol, 1)