For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

Optimize strategy where indicators have same parameter name?



  • Would it be possible to natively optimize a strategy where two indicators take the same parameter name - ie a moving average cross where both indicators expect "period" as an input? Or would a custom loop be required?

    For example here I pass the inputs to the __init__ method of the strategy to avoid that issue, but I assume this is not valid syntax for the optimizer, as I tried to pass in a tuple of values to optimize over, but only saw a single output.

    class EMACross(bt.Strategy):
    
        def __init__(self, fast_period, slow_period):
            self.dataclose = self.datas[0]
            self.fastma  = bt.ind.ExponentialMovingAverage(period=fast_period)
            self.slowma  = bt.ind.ExponentialMovingAverage(period=slow_period)
            self.signal  = bt.ind.CrossOver(self.fastma, self.slowma)
            self.order   = None
    
    
        def log(self, txt, dt=None):
            dt = dt or self.datas[0].datetime.date(0)
            print('%s, %s' % (dt.isoformat(), txt))
    
        def notify_order(self, order):
            if order.status in [order.Submitted, order.Accepted]:
                return
    
            if order.status in [order.Completed]:
                if order.isbuy():
                    self.log('BUY EXECUTED, %.2f' % order.executed.price)
                elif order.issell():
                    self.log('SELL EXECUTED, %.2f' % order.executed.price)
    
            elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                self.log('Order Cancelled/Margin/Rejected')
    
            self.order = None
    
        def next(self):
            self.log('Close, %.2f' % self.dataclose[0])
    
            if self.crossover > 0:
                self.order = self.buy()
                self.log('BUY CREATE, %.2f' % self.dataclose[0])
    
            elif self.crossover < 0:
                self.order = self.sell()
                self.log('SELL CREATE, %.2f' % self.dataclose[0])
    
            else:
                return
    
    strats = cerebro.optstrategy(EMACross, fast_period = range(10,12), slow_period = range(20,22))
    

    Even just a suggestion would be much appreciated!

    Thanks,


  • administrators

    @jmarks512 said in Optimize strategy where indicators have same parameter name?:

      def __init__(self, fast_period, slow_period):
    

    Fully unclear why you do that. Why don't you use the standard params syntax?


  • administrators

    See Docs - Platform Concepts, specifically the section about Parameters



  • @backtrader Because the two functions calls both expect the same keyword argument "period" and I want to use a different value for each of them. So my question is, how can I pass a range of values to optimize over when they both expect the same keyword argument?


  • administrators

    I fear you haven't read neither the documentation linked above about params nor the sample which shows how optimization works and which actually shows the params syntax just like any other.

    What you actually mean with the same name is unclear. Thousands of functions have arguments which share the name and that doesn't make them incompatible.

    You use fast_period and slow_period as params and then assign them to whatever indicator you have.