Re: ZigZag indicator for live trading.
"""
Referance other's zigzag and other bt's indicator code ,and rewrite it!!
"""
from future import (absolute_import, division, print_function, unicode_literals)
import backtrader as bt
class Zigzag(bt.Indicator):
"""
extdepth:bars for start and stop to calculate
extdevation: up to or down to extdevation's points need to renew the peak or the valley
extbackstep if extdevation is true ,lookback how many bars to the near peak ou valley,if less than extdevation
we need renew the peck or vvalley
"""
alias = ('zigzag', 'ZIGZAG',)
lines = ('zig',)
parms = (
('extdepth', 12),
('extdevation', 0.0005),
('extbackstep', 3),
('zig_arr_count', 10),
('defalt', 0.0),
)
plotinfo = dict(subplot=False)
def __init__(self):
# 取最小周期数,用于延迟索引
self.peak = [0, 0.00]
self.valley = [0, 0.00]
self.addminperiod(self.parms[0][1] + 1)
def highest(self):
highest = [0, 0.00]
for i in range(self.parms[0][1]):
if self.data.high[-i] > highest[1]:
highest[0] = -i
highest[1] = self.data.high[-i]
return highest
def lowest(self):
lowest = [0, 100000000.00]
for i in range(self.parms[0][1]):
if self.data.low[-i] < lowest[1]:
lowest[0] = -i
lowest[1] = self.data.high[-i]
return lowest
def initialize(self):
highest = self.highest()
lowest = self.lowest()
if self.peak[1] == 0.00 and self.valley[1] == 0.00:
if highest[0] - lowest[0] > self.parms[2][1]:
self.lines.zig[lowest[0]] = lowest[1]
# self.add_zig_arr(lowest[1])
self.peak = highest
print('peak = ' + str(highest))
return
if lowest[0] - highest[0] > self.parms[2][1]:
self.lines.zig[highest[0]] = highest[1]
# print('self.lines.zig[highest[0]] =' + str(highest[1]))
# self.add_zig_arr(highest[1])
self.valley = lowest
print('valley :' + str(lowest))
return
def find_peak(self):
highest = self.highest()
lowest = self.lowest()
if highest[0] - self.valley[0] > self.parms[2][1]:
self.peak = highest
# find the peak , and the front valley is a decided zigzag point
self.lines.zig[self.valley[0]] = self.valley[1]
# self.add_zig_arr(self.valley[1])
# make sure valley 's value defalt
self.valley = [0, 0.00]
return
# if a new lowest appear and meet self.parms.extdevation condition,renew valley
if lowest[1] < self.valley[1] - self.parms[1][1]:
if lowest[0] - self.valley[0] < self.parms[2][1]:
self.valley = lowest
return
def find_valley(self):
highest = self.highest()
lowest = self.lowest()
if lowest[0] - self.peak[0] > self.parms[2][1]:
self.valley = lowest
self.lines.zig[self.peak[0]] = self.peak[1]
# self.add_zig_arr(self.peak[1])
self.peak = [0, 0.00]
return
if highest[1] > self.peak[1] + self.parms[1][1]:
if highest[0] - self.peak[0] < self.parms[2][1]:
self.peak = highest
return
def next(self):
self.lines.zig[0] = self.parms[4][1] # defalt
if self.peak[1] != 0.00:
self.peak[0] -= 1
if self.valley[1] != 0.00:
self.valley[0] -= 1
# 1st step: no peak ,no valley, we must finf the fist peak or valley
if self.peak == [0, 0.00] and self.valley == [0, 0.00]:
# print('initialize')
self.initialize()
if self.peak == [0, 0.00] and self.valley != [0, 0.00]:
# print('find_peak')
self.find_peak()
if self.valley == [0, 0.00] and self.peak != [0, 0.00]:
# print('find_valley')
self.find_valley()