Overall Statistics
Total Trades
0
Average Win
0%
Average Loss
0%
Compounding Annual Return
0%
Drawdown
0%
Expectancy
0
Net Profit
0%
Sharpe Ratio
0
Probabilistic Sharpe Ratio
0%
Loss Rate
0%
Win Rate
0%
Profit-Loss Ratio
0
Alpha
0
Beta
0
Annual Standard Deviation
0
Annual Variance
0
Information Ratio
3.385
Tracking Error
0.281
Treynor Ratio
0
Total Fees
$0.00
from QuantConnect.Securities.Option import OptionPriceModels
from Selection.OptionUniverseSelectionModel import OptionUniverseSelectionModel
from OptionUniverseSelection import OptionUniverseSelectionModel2

class BasicTemplateOptionsFilterUniverseAlgorithm(QCAlgorithm):

    def Initialize(self):
        self.SetStartDate(2019, 1, 1)
        self.SetEndDate(2019, 1, 3)
        self.SetCash(100000)
        
        self.UniverseSettings.Resolution = Resolution.Minute
        self.SetUniverseSelection(OptionUniverseSelectionModel2(timedelta(days=1), self.SelectOptionChainSymbols))
        
        self.alpha = MyAlphaModel()
        self.AddAlpha(self.alpha)
        
        self.SetWarmUp(TimeSpan.FromDays(30))
        
    
    def OnEndOfDay(self):
        self.alpha.shown = False
        
    def SelectOptionChainSymbols(self, utcTime):
        newYorkTime = Extensions.ConvertFromUtc(utcTime, TimeZones.NewYork)
        ticker = "TWX" if newYorkTime.date() < date(2014, 6, 6) else "AAPL"
        return [ Symbol.Create(ticker, SecurityType.Option, Market.USA, f"?{ticker}") ]
        

class MyAlphaModel(AlphaModel):
    iterations = 0

    def Update(self, algorithm, slice):
        
        if algorithm.IsWarmingUp or algorithm.Portfolio.Invested:
            return []

        # Limit number of iterations for demonstration purposes
        if self.iterations > 0:
            return []
        self.iterations += 1
        
        for symbol, chain in slice.OptionChains.items():
            for contract in chain:
                d = contract.Greeks.Delta
                g = contract.Greeks.Gamma
                l = contract.Greeks.Lambda
                r = contract.Greeks.Rho
                t = contract.Greeks.Theta
                v = contract.Greeks.Vega
                
        return []
        
    def OnSecuritiesChanged(self, algorithm, changes):
        equities = [x for x in changes.AddedSecurities if x.Type == SecurityType.Equity]
        if equities:
            symbols = [x.Symbol for x in equities]
            history = algorithm.History(symbols, 30, Resolution.Daily)
            for equity in equities:
                df = history.loc[equity.Symbol]
                for idx, row in df.iterrows():
                    tradebar = TradeBar(idx, equity.Symbol, row.open, row.high, row.low, row.close, row.volume)
                    equity.VolatilityModel.Update(equity, tradebar)
from datetime import date, timedelta
# QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
# Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

from clr import AddReference
from clr import GetClrType as typeof
AddReference("System")
AddReference("QuantConnect.Common")
AddReference("QuantConnect.Algorithm.Framework")

from QuantConnect import *
from QuantConnect.Securities import *
from QuantConnect.Data.Auxiliary import ZipEntryName
from QuantConnect.Data.UniverseSelection import OptionChainUniverse
from Selection.UniverseSelectionModel import UniverseSelectionModel
from datetime import datetime
from QuantConnect.Securities.Option import OptionPriceModels

class OptionUniverseSelectionModel2(UniverseSelectionModel):
    show = 0
    
    '''Provides an implementation of IUniverseSelectionMode that subscribes to option chains'''
    def __init__(self,
                 refreshInterval,
                 optionChainSymbolSelector,
                 universeSettings = None,
                 securityInitializer = None):
        '''Creates a new instance of OptionUniverseSelectionModel
        Args:
            refreshInterval: Time interval between universe refreshes</param>
            optionChainSymbolSelector: Selects symbols from the provided option chain
            universeSettings: Universe settings define attributes of created subscriptions, such as their resolution and the minimum time in universe before they can be removed
            securityInitializer: [Obsolete, will not be used] Performs extra initialization (such as setting models) after we create a new security object'''
        self.nextRefreshTimeUtc = datetime.min

        self.refreshInterval = refreshInterval
        self.optionChainSymbolSelector = optionChainSymbolSelector
        self.universeSettings = universeSettings
        self.securityInitializer = securityInitializer

    def GetNextRefreshTimeUtc(self):
        '''Gets the next time the framework should invoke the `CreateUniverses` method to refresh the set of universes.'''
        return self.nextRefreshTimeUtc

    def CreateUniverses(self, algorithm):
        '''Creates a new fundamental universe using this class's selection functions
        Args:
            algorithm: The algorithm instance to create universes for
        Returns:
            The universe defined by this model'''
        self.nextRefreshTimeUtc = (algorithm.UtcTime + self.refreshInterval).date()

        uniqueUnderlyingSymbols = set()
        for optionSymbol in self.optionChainSymbolSelector(algorithm.UtcTime):
            if optionSymbol.SecurityType != SecurityType.Option:
                raise ValueError("optionChainSymbolSelector must return option symbols.")

            # prevent creating duplicate option chains -- one per underlying
            if optionSymbol.Underlying not in uniqueUnderlyingSymbols:
                uniqueUnderlyingSymbols.add(optionSymbol.Underlying)
                yield self.CreateOptionChain(algorithm, optionSymbol)

    def CreateOptionChain(self, algorithm, symbol):
        '''Creates a OptionChainUniverse for a given symbol
        Args:
            algorithm: The algorithm instance to create universes for
            symbol: Symbol of the option
        Returns:
            OptionChainUniverse for the given symbol'''
        if symbol.SecurityType != SecurityType.Option:
            raise ValueError("CreateOptionChain requires an option symbol.")

        # rewrite non-canonical symbols to be canonical
        market = symbol.ID.Market
        underlying = symbol.Underlying
        if not symbol.IsCanonical():
            alias = f"?{underlying.Value}"
            symbol = Symbol.Create(underlying.Value, SecurityType.Option, market, alias)

        # resolve defaults if not specified
        settings = self.universeSettings if self.universeSettings is not None else algorithm.UniverseSettings
        initializer = self.securityInitializer if self.securityInitializer is not None else algorithm.SecurityInitializer
        # create canonical security object, but don't duplicate if it already exists
        securities = [s for s in algorithm.Securities if s.Key == symbol]
        if len(securities) == 0:
            optionChain = self.CreateOptionChainSecurity(algorithm, symbol, settings, initializer)
        else:
            optionChain = securities[0]

        # set the option chain contract filter function
        optionChain.SetFilter(self.Filter)

        # force option chain security to not be directly tradable AFTER it's configured to ensure it's not overwritten
        optionChain.IsTradable = False
        
        if self.show < 10:
            self.show += 1
            algorithm.Log(f"Called on {algorithm.Time}")
        
        #################### setting PricingModel ##########################################
        optionChain.PriceModel = OptionPriceModels.CrankNicolsonFD()
        ####################################################################################

        return OptionChainUniverse(optionChain, settings, initializer, algorithm.LiveMode)

    def CreateOptionChainSecurity(self, algorithm, symbol, settings, initializer):
        '''Creates the canonical option chain security for a given symbol
        Args:
            algorithm: The algorithm instance to create universes for
            symbol: Symbol of the option
            settings: Universe settings define attributes of created subscriptions, such as their resolution and the minimum time in universe before they can be removed
            initializer: [Obsolete, will not be used] Performs extra initialization (such as setting models) after we create a new security object
        Returns
            Option for the given symbol'''
        config = algorithm.SubscriptionManager.SubscriptionDataConfigService.Add(typeof(ZipEntryName),
                                                                                 symbol,
                                                                                 settings.Resolution,
                                                                                 settings.FillForward,
                                                                                 settings.ExtendedMarketHours,
                                                                                 False)

        return algorithm.Securities.CreateSecurity(symbol, config, settings.Leverage, False)

    def Filter(self, filter):
        ## Cerco le opzioni tra +/- 10 strike, a partire da 6 mesi in avanti(180) +1 anno(540) o +2 anni(900)
        # vorrei solo le Call LEAPS di Gennaio
        #filter è un tipo particolare di oggetto:
        #https://www.quantconnect.com/lean/documentation/topic26710.html
        filtered = (filter.Strikes(-1, +1)
        .Expiration(timedelta(10), timedelta(30)))
        
        return (filtered)