Skip to content

Commit 9bfc4ab

Browse files
committed
Rewrite of LaguerreRSI and test case template. mementum#265
1 parent 3286c5e commit 9bfc4ab

2 files changed

Lines changed: 85 additions & 35 deletions

File tree

backtrader/indicators/lrsi.py

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -21,59 +21,59 @@
2121
from __future__ import (absolute_import, division, print_function,
2222
unicode_literals)
2323

24-
from . import Indicator
24+
from . import PeriodN
2525

26-
__all__ = ['LaguerreRSI']
26+
__all__ = ['LaguerreRSI', 'LRSI']
2727

28-
class LaguerreRSI(Indicator):
28+
29+
class LaguerreRSI(PeriodN):
2930
alias = ('LRSI',)
3031
lines = ('lrsi',)
31-
params = (('gamma', 0.5),)
32+
params = (
33+
('gamma', 0.5),
34+
('period', 6),
35+
)
3236

3337
plotinfo = dict(
3438
plotymargin=0.15,
3539
plotyticks=[0.0, 0.2, 0.5, 0.8, 1.0]
3640
)
3741

3842
def __init__(self):
39-
self.addminperiod(6)
40-
self.l0 = [0, 0]
41-
self.l1 = [0, 0]
42-
self.l2 = [0, 0]
43-
self.l3 = [0, 0]
43+
self.l0, self.l1, self.l2, self.l3 = 0.0, 0.0, 0.0, 0.0
4444

4545
super(LaguerreRSI, self).__init__()
4646

47-
def next(self):
48-
tp = (self.data.high + self.data.low) / 2
49-
self.l0.insert(0, ((1 - self.p.gamma) * tp +
50-
self.p.gamma * self.l0[0]))
51-
self.l1.insert(0, (-self.p.gamma * self.l0[0] + self.l0[1] +
52-
self.p.gamma * self.l1[0]))
53-
self.l2.insert(0, (-self.p.gamma * self.l1[0] + self.l1[1] +
54-
self.p.gamma * self.l2[0]))
55-
self.l3.insert(0, (-self.p.gamma * self.l2[0] + self.l2[1] +
56-
self.p.gamma * self.l3[0]))
57-
del self.l0[2:]
58-
del self.l1[2:]
59-
del self.l2[2:]
60-
del self.l3[2:]
47+
def prenext(self):
48+
self.next(notpre=False)
49+
50+
def next(self, notpre=True):
51+
tp_0 = (self.data.high + self.data.low) / 2 # price point
52+
l0_1 = self.l0 # cache previous intermediate values
53+
l1_1 = self.l1
54+
l2_1 = self.l2
55+
56+
g = self.p.gamma # avoid more lookups
57+
self.l0 = l0 = (1 - g) * tp_0 + g * l0_1 * notpre # interm values
58+
self.l1 = l1 = -g * l0 + l0_1 + g * l1_1 * notpre
59+
self.l2 = l2 = -g * l1 + l1_1 + g * l2_1 * notpre
60+
self.l3 = l3 = -g * l2 + l2_1 + g * self.l3 * notpre
6161

62-
cd = 0
63-
cu = 0
64-
if self.l0[0] >= self.l1[0]:
65-
cu = self.l0[0] - self.l1[0]
62+
cd = 0.0
63+
cu = 0.0
64+
if l0 >= l1:
65+
cu = l0 - 11
6666
else:
67-
cd = self.l1[0] - self.l0[0]
67+
cd = l1 - l0
6868

69-
if self.l1[0] >= self.l2[0]:
70-
cu = cu + self.l1[0] - self.l2[0]
69+
if l1 >= l2:
70+
cu = cu + l1 - l2
7171
else:
72-
cd = cd + self.l2[0] - self.l1[0]
72+
cd = cd + l2 - l1
7373

74-
if self.l2[0] >= self.l3[0]:
75-
cu = cu + self.l2[0] - self.l3[0]
74+
if l2 >= l3:
75+
cu = cu + l2 - l3
7676
else:
77-
cd = cd + self.l3[0] - self.l2[0]
77+
cd = cd + l3 - l2
7878

79-
self.lines.lrsi[0] = cu / (cu + cd)
79+
self.lines.lrsi[0] = cu / (cu + cd) # store line value

tests/test_ind_lrsi.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#!/usr/bin/env python
2+
# -*- coding: utf-8; py-indent-offset:4 -*-
3+
###############################################################################
4+
#
5+
# Copyright (C) 2015, 2016 Daniel Rodriguez
6+
#
7+
# This program is free software: you can redistribute it and/or modify
8+
# it under the terms of the GNU General Public License as published by
9+
# the Free Software Foundation, either version 3 of the License, or
10+
# (at your option) any later version.
11+
#
12+
# This program is distributed in the hope that it will be useful,
13+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
# GNU General Public License for more details.
16+
#
17+
# You should have received a copy of the GNU General Public License
18+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
#
20+
###############################################################################
21+
from __future__ import (absolute_import, division, print_function,
22+
unicode_literals)
23+
24+
import testcommon
25+
26+
import backtrader as bt
27+
import backtrader.indicators as btind
28+
29+
chkdatas = 1
30+
chkvals = [
31+
['4063.463000', '3644.444667', '3554.693333'],
32+
]
33+
34+
chkmin = 30
35+
chkind = btind.LRSI
36+
37+
38+
def test_run(main=False):
39+
datas = [testcommon.getdata(i) for i in range(chkdatas)]
40+
testcommon.runtest(datas,
41+
testcommon.TestStrategy,
42+
main=main,
43+
plot=main,
44+
chkind=chkind,
45+
chkmin=chkmin,
46+
chkvals=chkvals)
47+
48+
49+
if __name__ == '__main__':
50+
test_run(main=True)

0 commit comments

Comments
 (0)