Overall Statistics
Total Trades
456
Average Win
0.04%
Average Loss
-0.06%
Compounding Annual Return
-38.363%
Drawdown
4.800%
Expectancy
-0.081
Net Profit
-4.027%
Sharpe Ratio
-2.815
Probabilistic Sharpe Ratio
7.535%
Loss Rate
47%
Win Rate
53%
Profit-Loss Ratio
0.74
Alpha
-0.043
Beta
-0.804
Annual Standard Deviation
0.088
Annual Variance
0.008
Information Ratio
-3.551
Tracking Error
0.141
Treynor Ratio
0.307
Total Fees
$452.00
import pandas as pd

class ParticleCalibratedCoil(QCAlgorithm):

    def Initialize(self):
        
        '''
            Parameters for adjusting
        '''
        
        self.numberOfLiquidStocks = 10 # Controls the number of stocks in play
        
        
        
        self.SetStartDate(2019, 11, 18)
        self.SetEndDate(2019, 12, 18)
        self.SetCash(1000000)
        self.UniverseSettings.Resolution = Resolution.Minute
        
        self.AddUniverse(self.CoarseSelectionFilter)
        self.SetSecurityInitializer(lambda x: x.SetDataNormalizationMode(DataNormalizationMode.Raw))
        
        
    def CoarseSelectionFilter(self, coarse):
        '''
            1. Sorts each element of the coarse object by dollar volume
            2. Returns a list of coarse object, limited to top 100 highest volume
            3. Returns a list of symbols we want to initialise into the algorithm
        '''
        
        self.sortedByDollarVolume = sorted(coarse, key=lambda c: c.DollarVolume, reverse=True)
        self.topHundredMostLiquid = self.sortedByDollarVolume[:self.numberOfLiquidStocks]
            
        return [stock.Symbol for stock in self.topHundredMostLiquid]
        
    def OnSecuritiesChanged (self, changes):
        '''
            For any new securities added into the universe
            If the security is an underlying
            Subscribe to the option chains
            
            For any securities we want removed from the universe
            Remove the underlying and then remove the options 
        '''
        for underlying in changes.AddedSecurities:
            if underlying.Symbol.SecurityType != SecurityType.Equity: continue
            option = self.AddOption(underlying.Symbol.Value, Resolution.Minute)
            option.SetFilter(-10, +1, timedelta(30), timedelta(60))
    
        for underlying in changes.RemovedSecurities:
            self.RemoveSecurity(underlying.Symbol)
            for symbol in self.Securities.Keys:
                if symbol.SecurityType == SecurityType.Option and symbol.Underlying == underlying.Symbol:
                    self.RemoveSecurity(symbol)
        
        
    def OnData(self, slice):
        
        '''
            For each OptionChain, the key is the underlying symbol object, while the
            value is the option chain.
            For each chain in OptionChains, each chain represents the entire chain of option contracts
            for the underlying security.
        '''

        for chain in slice.OptionChains.Values:
            contracts = [x for x in chain if x.UnderlyingLastPrice - x.Strike < 0]
            contracts = sorted(contracts, key = lambda x:x.Greeks.Delta)
            
            if len(contracts) == 0: continue
            if not self.Portfolio[contracts[0].Symbol].Invested:
                self.MarketOrder(contracts[0].Symbol, -1)
                
            # df = pd.DataFrame([[x.Right, 
            #               float(x.Strike), 
            #                     x.Expiry, 
            #               float(x.BidPrice), 
            #               float(x.AskPrice)] for x in optionchain],
            #               columns=['type(call 0, put 1', 'strike', 'expiry', 'ask price', 'bid price'])