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

Analyzers.Returns - ValueError: math domain error



  • I often face an error using this analyzer during optimization.

    cerebro.addanalyzer(bt.analyzers.Returns, _name='return')
    

    Full traceback:

    multiprocessing.pool.RemoteTraceback:
    
    Traceback (most recent call last):
      File "C:\ProgramData\Anaconda3\lib\multiprocessing\pool.py", line 119, in worker
        result = (True, func(*args, **kwds))
      File "C:\ProgramData\Anaconda3\lib\site-packages\backtrader\cerebro.py", line 1007, in __call__
        return self.runstrategies(iterstrat, predata=predata)
      File "C:\ProgramData\Anaconda3\lib\site-packages\backtrader\cerebro.py", line 1301, in runstrategies
        strat._stop()
      File "C:\ProgramData\Anaconda3\lib\site-packages\backtrader\strategy.py", line 464, in _stop
        analyzer._stop()
      File "C:\ProgramData\Anaconda3\lib\site-packages\backtrader\analyzer.py", line 200, in _stop
        self.stop()
      File "C:\ProgramData\Anaconda3\lib\site-packages\backtrader\analyzers\returns.py", line 128, in stop
        math.log(self._value_end / self._value_start))
    ValueError: math domain error
    
    The above exception was the direct cause of the following exception:
    
    Traceback (most recent call last):
      File "Optimize Client.py", line 156, in <module>
        bt_tools.optimization(strategy, params)
      File "..\core.py", line 327, in optimization
        def optimization_results_handler(self, results_raw):
      File "C:\ProgramData\Anaconda3\lib\site-packages\backtrader\cerebro.py", line 1143, in run
        for r in pool.imap(self, iterstrats):
      File "C:\ProgramData\Anaconda3\lib\multiprocessing\pool.py", line 735, in next
        raise value
    ValueError: math domain error


  • Just as a guess - looks like it comes frommath.log which means that self._value_end / self._value_start is less than or equal to zero. So check the equity numbers, maybe it goes to zero some how.



  • to fix this added two lines:

            # Compound return
            if self._value_end <= 0:
                self._value_end = 0.00001
    
            self.rets['rtot'] = rtot = (
                math.log(self._value_end / self._value_start))
    

    it may be not the best solution, but it works


  • administrators

    The proper value should/would be float('-inf'), which is what the logarithmic function tends to when it approaches zero.

    There is a fix in the development branch at: https://github.com/backtrader/backtrader/commit/57545348763060e1077654f9a94ca71c090f0d2c