Overall Statistics
Total Trades
1684
Average Win
0.10%
Average Loss
-0.17%
Compounding Annual Return
-100.000%
Drawdown
79.300%
Expectancy
-0.529
Net Profit
-71.108%
Sharpe Ratio
-0.291
Probabilistic Sharpe Ratio
7.542%
Loss Rate
70%
Win Rate
30%
Profit-Loss Ratio
0.58
Alpha
5.473
Beta
15.622
Annual Standard Deviation
3.442
Annual Variance
11.846
Information Ratio
-0.176
Tracking Error
3.331
Treynor Ratio
-0.064
Total Fees
$7342.50
Estimated Strategy Capacity
$420000.00
Lowest Capacity Asset
SPY XTN6UC1W8WDI|SPY R735QTJ8XC9X
class ETFSimple(QCAlgorithm):
    def Initialize(self):
        self.SetStartDate(2021,9,13) 
        self.SetCash(1000000) 
        self.SetPortfolioConstruction(InsightWeightingPortfolioConstructionModel()) #we want our portfolio to be made up of insights
        self.SetExecution(ImmediateExecutionModel()) 
        self.SetBrokerageModel(BrokerageName.AlphaStreams) #required brokerage model for submission
 
 
        ############################################################################
        ## OPTIONS
        ############################################################################
        self.STRIKES = 10       # no of strikes around ATM => for uni selection
        self.MIN_EXPIRY = 30 # min num of days to expiration => for uni selection
        self.MAX_EXPIRY = 60 # max num of days to expiration => for uni selection
 
        self.MIN_DELTA = 0.25
        self.MAX_DELTA = 0.45
        self.MIN_PREMIUM = 0.05
 
        equity = self.AddEquity("SPY", Resolution.Minute)
        option = self.AddOption("SPY", Resolution.Minute)
        self.optionSymbol = option.Symbol
 
        # set strike/expiry filter for this option chain
        option.SetFilter(-self.STRIKES, self.STRIKES, timedelta(self.MIN_EXPIRY), timedelta(self.MAX_EXPIRY))
 
        # for greeks and pricer (needs some warmup) - https://github.com/QuantConnect/Lean/blob/21cd972e99f70f007ce689bdaeeafe3cb4ea9c77/Common/Securities/Option/OptionPriceModels.cs#L81
        option.PriceModel = OptionPriceModels.CrankNicolsonFD()  # both European & American, automatically
 
        # this is needed for Greeks calcs 
        self.SetWarmUp(TimeSpan.FromDays(30))
        
 
    def OnData(self, slice):
 
        if (self.IsWarmingUp): return
 
        chain = slice.OptionChains.get(self.optionSymbol, None)
        
        if not chain:
            return
 
        # filter the put options contracts
        calls = [x for x in chain if x.Right == OptionRight.Call and abs(x.Greeks.Delta) > self.MIN_DELTA and abs(x.Greeks.Delta) < self.MAX_DELTA and x.BidPrice > self.MIN_PREMIUM] 

        # sorted the contracts according to their expiration dates
        contracts = sorted(sorted(calls, key = lambda x: x.BidPrice, reverse=True), 
                                         key = lambda x: x.Expiry)

        if len(contracts) == 0: return

        call = contracts[0].Symbol

        self.EmitInsights(Insight.Price(call, timedelta(self.MIN_EXPIRY), InsightDirection.Up, None, None, None, 1))