Skip to content

Commit de07cd0

Browse files
committed
Add atr support and disabled volume for renko plots
1 parent 046fe5c commit de07cd0

File tree

3 files changed

+50
-17
lines changed

3 files changed

+50
-17
lines changed

examples/customization_and_styles.ipynb

Lines changed: 11 additions & 9 deletions
Large diffs are not rendered by default.

src/mplfinance/_utils.py

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,22 @@ def roundTime(dt=None, roundTo=60):
8282
rounding = (seconds+roundTo/2) // roundTo * roundTo
8383
return dt + datetime.timedelta(0,rounding-seconds,-dt.microsecond)
8484

85+
def calculate_atr(atr_length, highs, lows, closes):
86+
"""Calculate the average true range
87+
atr_length : time period to calculate over
88+
all_highs : list of highs
89+
all_lows : list of lows
90+
all_closes : list of closes
91+
"""
92+
atr = 0
93+
for i in range(len(highs)-atr_length, len(highs)):
94+
high = highs[i]
95+
low = lows[i]
96+
close_prev = closes[i-1]
97+
tr = max(abs(high-low), abs(high-close_prev), abs(low-close_prev))
98+
atr += tr
99+
return atr/atr_length
100+
85101
def _updown_colors(upcolor,downcolor,opens,closes,use_prev_close=False):
86102
if upcolor == downcolor:
87103
return upcolor
@@ -263,11 +279,17 @@ def _construct_candlestick_collections(dates, opens, highs, lows, closes, market
263279

264280
return rangeCollection, barCollection
265281

266-
def _construct_renko_collections(dates, renko_params, closes, marketcolors=None):
282+
def _construct_renko_collections(dates, highs, lows, renko_params, closes, marketcolors=None):
267283
"""Represent the price change with bricks
268284
269285
Parameters
270286
----------
287+
dates : sequence
288+
sequence of dates
289+
highs : sequence
290+
sequence of high values
291+
lows : sequence
292+
sequence of low values
271293
renko_params : dictionary
272294
type : type of renko chart
273295
brick_size : size of each brick
@@ -289,6 +311,12 @@ def _construct_renko_collections(dates, renko_params, closes, marketcolors=None)
289311
brick_size = renko_params['brick_size']
290312
atr_length = renko_params['atr_length']
291313

314+
if atr_length > len(closes):
315+
raise ValueError("Specified atr_length is larger than the length of the dataset: " + str(len(closes)))
316+
317+
if brick_size == 'atr':
318+
brick_size = calculate_atr(atr_length, highs, lows, closes)
319+
292320
alpha = marketcolors['alpha']
293321

294322
uc = mcolors.to_rgba(marketcolors['candle'][ 'up' ], alpha)

src/mplfinance/plotting.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -225,9 +225,11 @@ def plot( data, **kwargs ):
225225
if apdict['panel'] == 'lower':
226226
need_lower_panel = True
227227
break
228+
229+
ptype = config['type']
228230

229231
# fig.add_axes( [left, bottom, width, height] ) ... numbers are fraction of fig
230-
if need_lower_panel or config['volume']:
232+
if need_lower_panel or config['volume'] and ptype is not 'renko':
231233
ax1 = fig.add_axes( [0.15, 0.38, 0.70, 0.50] )
232234
ax2 = fig.add_axes( [0.15, 0.18, 0.70, 0.20], sharex=ax1 )
233235
plt.xticks(rotation=45) # must do this after creation of axis, and
@@ -258,7 +260,7 @@ def plot( data, **kwargs ):
258260
else:
259261
fmtstring = '%b %d'
260262

261-
ptype = config['type']
263+
262264

263265
if ptype is not 'renko':
264266
if config['show_nontrading']:
@@ -282,8 +284,8 @@ def plot( data, **kwargs ):
282284
collections = _construct_ohlc_collections(xdates, opens, highs, lows, closes,
283285
marketcolors=style['marketcolors'] )
284286
elif ptype == 'renko':
285-
renko_params = _process_kwargs(kwargs['renko_params'], _valid_renko_kwargs())
286-
collections, new_dates = _construct_renko_collections(dates, renko_params, closes,
287+
renko_params = _process_kwargs(kwargs['renko_params'] if 'renko_params' in kwargs else dict(), _valid_renko_kwargs())
288+
collections, new_dates = _construct_renko_collections(dates, highs, lows, renko_params, closes,
287289
marketcolors=style['marketcolors'] )
288290

289291
formatter = IntegerIndexDateTimeFormatter(new_dates, fmtstring)
@@ -318,6 +320,7 @@ def plot( data, **kwargs ):
318320
else:
319321
ax1.plot(xdates, mavprices)
320322

323+
321324
if ptype == 'renko':
322325
ax1.autoscale()
323326
else:
@@ -329,7 +332,7 @@ def plot( data, **kwargs ):
329332
corners = (minx, miny), (maxx, maxy)
330333
ax1.update_datalim(corners)
331334

332-
if config['volume']:
335+
if config['volume'] and ptype is not 'renko':
333336
vup,vdown = style['marketcolors']['volume'].values()
334337
#-- print('vup,vdown=',vup,vdown)
335338
vcolors = _updown_colors(vup, vdown, opens, closes, use_prev_close=style['marketcolors']['vcdopcod'])
@@ -448,7 +451,7 @@ def plot( data, **kwargs ):
448451
ax4.yaxis.set_label_position('right')
449452
ax4.yaxis.tick_right()
450453

451-
if need_lower_panel or config['volume']:
454+
if need_lower_panel or config['volume'] and ptype is not 'renko':
452455
ax1.spines['bottom'].set_linewidth(0.25)
453456
ax2.spines['top' ].set_linewidth(0.25)
454457
plt.setp(ax1.get_xticklabels(), visible=False)
@@ -475,7 +478,7 @@ def plot( data, **kwargs ):
475478

476479
ax1.set_ylabel(config['ylabel'])
477480

478-
if config['volume']:
481+
if config['volume'] and ptype is not 'renko':
479482
ax2.figure.canvas.draw() # This is needed to calculate offset
480483
offset = ax2.yaxis.get_major_formatter().get_offset()
481484
ax2.yaxis.offsetText.set_visible(False)

0 commit comments

Comments
 (0)