Hi QuantConnect Community, 

I'm enountering an issue with the CoarseSelectionFunction while running a Python code for a mean reversion high-frequency trading strategy - this applied to CBOT exchange listed futures using InteractiveBrokers on margin & using an optimizer plus insights towards trading signals.

Please find below the error message.

During the algorithm initialization, the following exception has occurred: Trying to dynamically access a method that does not exist throws a TypeError exception. To prevent the exception, ensure each parameter type matches those required by the 'method'>) method. Please checkout the API documentation.  at Initialize    self.SetUniverseSelection(ManualUniverseSelectionModel(self.CoarseSelectionFunction))   at Python.Runtime.PythonException.ThrowLastAsClrException()   at Python.Runtime.PyObject.Invoke(PyTuple args in main.py: line 22 No method matches given arguments for .ctor: ()

I understand the error message occurrs during the initialization of the algorithm - this when calling the SetUniverseSelection method with a ManualUniverseSelectionModel object that takes a CoarseSelectionFunction method as a parameter. Also that the CoarseSelectionFunction method has a parameter type mismatch or perhaps is not implemented correctly.

Yet, I couldn't find anything in the QuantConnect documentation helpful in identifying the correct parameter types and the CoarseSelectionFunction method.

It would be great if you could please advice on how I could correct this - thank you. 

Regards,

Marcello Cultrera

 

from datetime import timedelta

from QuantConnect import *

from QuantConnect.Algorithm import *

from QuantConnect.Brokerages import *

from QuantConnect.Data import *

from QuantConnect.Data.Market import *

from QuantConnect.Orders import *

from QuantConnect.Securities import *

from QuantConnect.Algorithm.Framework.Alphas import *

from QuantConnect.Algorithm.Framework.Portfolio import *

from QuantConnect.Algorithm.Framework.Execution import *

from QuantConnect.Algorithm.Framework.Risk import *

from QuantConnect.Algorithm.Framework.Selection import *

from QuantConnect.Optimizer import *


 

class MeanReversionAlgorithm(QCAlgorithm):


 

    def Initialize(self):

        self.SetStartDate(2022, 1, 1)

        self.SetEndDate(2022, 1, 31)

        self.SetCash(100000)

        self.SetBrokerageModel(BrokerageName.InteractiveBrokersBrokerage, AccountType.Margin)

        self.SetUniverseSelection(ManualUniverseSelectionModel(self.CoarseSelectionFunction))

        self.UniverseSettings.Resolution = Resolution.Minute

        self.SetAlpha(MeanReversionAlphaModel())

        self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())

        self.SetExecution(ImmediateExecutionModel())

        self.SetRiskManagement(MaximumDrawdownPercentPerSecurity(0.01))


 

        # Set up the optimizer

        self.optimizer = PortfolioOptimizer(self)

        self.optimizer.Settings.TargetPercentage = 0.1

        self.optimizer.Settings.MaximumSharpeRatio = 2

        self.optimizer.Settings.MaximumDrawdown = 0.05

        self.optimizer.Settings.MaximumPortfolioTurnover = 0.05

        self.optimizer.Settings.MaximumAllocation = 0.2

        self.optimizer.Settings.MinimumAllocation = -0.2

        self.optimizer.Settings.MaximumShortAllocation = -0.1

        self.optimizer.Settings.MaximumLongAllocation = 0.1


 

    def CoarseSelectionFunction(self, coarse):

        symbols = ["ZC", "ZS", "ZW"]

        return [Symbol.Create(x, SecurityType.Future, Market.CBOT) for x in symbols]


 

class MeanReversionAlphaModel(AlphaModel):

    def __init__(self, lookback=20):

        self.lookback = lookback

        self.symbolDataBySymbol = {}


 

    def Update(self, algorithm, data):

        insights = []

        for symbol, symbolData in self.symbolDataBySymbol.items():

            if not data.Bars.ContainsKey(symbol) or not symbolData.IsReady:

                continue

            price = data.Bars[symbol].Close

            symbolData.Update(price)

            if symbolData.IsOversold():

                insights.append(Insight.Price(symbol, timedelta(minutes=1), InsightDirection.Up))

            elif symbolData.IsOverbought():

                insights.append(Insight.Price(symbol, timedelta(minutes=1), InsightDirection.Down))

        return insights


 

    def OnSecuritiesChanged(self, algorithm, changes):

        for security in changes.RemovedSecurities:

            symbolData = self.symbolDataBySymbol.pop(security.Symbol, None)

            if symbolData is not None:

                symbolData.Dispose()

        addedSymbols = [x.Symbol for x in changes.AddedSecurities if x.Symbol not in self.symbolDataBySymbol]

        history = algorithm.History(addedSymbols, self.lookback, Resolution.Minute)

        for symbol in addedSymbols:

            symbolData = SymbolData(symbol, self.lookback, history)

            self.symbolDataBySymbol[symbol] = symbolData


 

class SymbolData:

    def __init__(self, symbol, lookback, history):

        self.symbol = symbol

        self.lookback = lookback

        self.history = history

        self.IsReady = False


 

    def Update(self, price):

        self.prices.append(price)

        if len(self.prices) > self.lookback:

            self.prices.pop(0)

            self.IsReady = True


 

    def IsOversold(self):

        if not self.IsReady:

            return False

        return self.prices[-1] < np.mean(self.prices) - 2 * np.std(self.prices)


 

    def IsOverbought(self):

        if not self.IsReady:

            return False

        return self.prices[-1] > np.mean(self.prices) + 2 * np.std(self.prices)


 

    def Dispose(self):

        pass


 

    def Optimize(self):

        self.optimizer.Optimize(self.PortfolioConstructionModel, self.alphaModel, self.riskManagementModel)