Does backtrader use arithmetic or log returns?
If both, when where and why?
backtraderper sé doesn't use returns. This is something apparently somehow shocking for people who ask where the performance data happen to be.
As a library/framework it allows the user to plug in whatever the user may wish to use as performance measurement in the form of the
Analyzerconcept. If visual feedback is wishes, this is usually handled with the
backtraderprovides is a set of built-in analyzers which can then be plugged. For the reference see Doc - Analyzers Reference. For example:
AnnualReturn- First and oldest implementation which is only meant for annual returns (non-log)
LogReturnsRolling- This analyzer calculates rolling returns for a given timeframe and compression
Returns- Total, Average, Compound and Annualized Returns calculated using a logarithmic approach
This analyzer calculates the Returns by looking at the beginning and end of the timeframe
How could one actually compute log returns of a series and eventually return sign by making use of an indicator class?
I have tried with the following code, but not great success:
class RET(bt.Indicator): ''' Compute Log Returns ''' # Indicator Variables plotlines = dict(RET=dict(_method='bar', alpha=0.50, width=1.0)) lines = ('RET', 'SIGN') def __init__(self): # Store Values to Lines sign = abs(self.data.close - self.data.open) / (self.data.close - self.data.open) self.lines.SIGN = sign self.lines.RET = math.log(self.data.close) - math.log(self.data.close[-1])
This ends up in the following errors:
<ipython-input-47-c83fca8591c6> in __init__(self) 12 #sign = (self.data.close - self.data.open) / (self.data.close - self.data.open) 13 #self.lines.SIGN = sign ---> 14 self.lines.RET = math.log(self.data.close) - math.log(self.data.close[-1]) TypeError: a float is required
<ipython-input-50-cf0b74bdd9aa> in __init__(self) 10 def __init__(self): 11 # Store Values to Lines ---> 12 sign = (self.data.close - self.data.open) / (self.data.close - self.data.open) 13 self.lines.SIGN = sign 14 #self.lines.RET = math.log(self.data.close) - math.log(self.data.close[-1]) TypeError: unsupported operand type(s) for /: 'LinesOperation' and 'LinesOperation'
I suppose this errors are because of the way my code is accessing the data. Any hints on how to perform this calculations?
TypeError: unsupported operand type(s) for /: 'LinesOperation' and 'LinesOperation'
The error is generated because you, likely, are not using this:
from future import division
and the code is likely being run under Python 2.7.x (a chain of assumptions here)
That means that the
/operation is using the old division style. This was also uncovered by another use case a few days ago and support for old style division has been added to the development branch.
This other error
---> 14 self.lines.RET = math.log(self.data.close) - math.log(self.data.close[-1])
happens because the statement is wrong.
math.logis not a built-in operation and cannot be overridden. Furthermore, during the
__init__phase, one uses de delay notation which would be
self.data.close(-1)(notice the round parenthesis rather than the square brackets)
This is a calculation which has to happen in
In any case, backtrader already contains an Analyzer which calculates logarithmic returns. It defaults to do so using the same
timeframeas the data under analysis. But you can for example calculate weekly logarithmic returns of daily data.
See Docs - Analyzers Reference and look for LogReturnsRolling. It doesn't calculate the sign, but you can probably simply extend it to do so.