Log returns
-
Does backtrader use arithmetic or log returns?
If both, when where and why?
Thanks :-)
-
backtrader
per 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
Analyzer
concept. If visual feedback is wishes, this is usually handled with theObserver
concept.What
backtrader
provides 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 compressionReturns
- Total, Average, Compound and Annualized Returns calculated using a logarithmic approachTimeReturn
-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
or
<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?
Thank you!
-
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.log
is not a built-in operation and cannot be overridden. Furthermore, during the__init__
phase, one uses de delay notation which would beself.data.close(-1)
(notice the round parenthesis rather than the square brackets)This is a calculation which has to happen in
next
.In any case, backtrader already contains an Analyzer which calculates logarithmic returns. It defaults to do so using the same
timeframe
as 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.