Skip to content

Commit cb88069

Browse files
committed
Introduce flexible height by proportially sizing elements
1 parent 7677461 commit cb88069

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

backtesting/_plotting.py

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -190,7 +190,7 @@ def f(s, new_index=pd.Index(df.index.astype(np.int64)), bars=trades[column]):
190190
def plot(*, results: pd.Series,
191191
df: pd.DataFrame,
192192
indicators: List[_Indicator],
193-
filename='', plot_width=None,
193+
filename='', plot_width=None, plot_height=400,
194194
plot_equity=True, plot_return=False, plot_pl=True,
195195
plot_volume=True, plot_drawdown=False, plot_trades=True,
196196
smooth_equity=False, relative_equity=True,
@@ -199,6 +199,15 @@ def plot(*, results: pd.Series,
199199
show_legend=True, open_browser=True):
200200
"""
201201
Like much of GUI code everywhere, this is a mess.
202+
203+
Parameters:
204+
-----------
205+
plot_width : int, optional
206+
Width of the plot in pixels. If None (default), the plot is made
207+
to span 100% of browser width.
208+
plot_height : int, optional
209+
Height of the main OHLC chart in pixels. Other sections are sized
210+
proportionally. Default is 400.
202211
"""
203212
# We need to reset global Bokeh state, otherwise subsequent runs of
204213
# plot() contain some previous run's cruft data (was noticed when
@@ -207,6 +216,16 @@ def plot(*, results: pd.Series,
207216
filename = _windos_safe_filename(str(results._strategy))
208217
_bokeh_reset(filename)
209218

219+
# Calculate proportional heights based on original ratios
220+
# Original OHLC height was 400px, use that as base ratio
221+
base_height = plot_height
222+
equity_height = int(base_height * 0.25) # was 100px
223+
equity_height_with_dd = int(base_height * 0.2) # was 80px
224+
drawdown_height = int(base_height * 0.2) # was 80px
225+
pl_height = int(base_height * 0.2) # was 80px
226+
volume_height = int(base_height * 0.175) # was 70px
227+
indicator_height = int(base_height * 0.125) # was 50px
228+
210229
COLORS = [BEAR_COLOR, BULL_COLOR]
211230
BAR_WIDTH = .8
212231

@@ -240,7 +259,7 @@ def plot(*, results: pd.Series,
240259
_figure,
241260
x_axis_type='linear',
242261
width=plot_width,
243-
height=400,
262+
height=base_height,
244263
# TODO: xwheel_pan on horizontal after https://github.com/bokeh/bokeh/issues/14363
245264
tools="xpan,xwheel_zoom,xwheel_pan,box_zoom,undo,redo,reset,save",
246265
active_drag='xpan',
@@ -296,7 +315,7 @@ def plot(*, results: pd.Series,
296315
('Volume', '@Volume{0,0}')]
297316

298317
def new_indicator_figure(**kwargs):
299-
kwargs.setdefault('height', _INDICATOR_HEIGHT)
318+
kwargs.setdefault('height', indicator_height)
300319
fig = new_bokeh_figure(x_range=fig_ohlc.x_range,
301320
active_scroll='xwheel_zoom',
302321
active_drag='xpan',
@@ -362,7 +381,7 @@ def _plot_equity_section(is_return=False):
362381
source.add(equity, source_key)
363382
fig = new_indicator_figure(
364383
y_axis_label=yaxis_label,
365-
**(dict(height=80) if plot_drawdown else dict(height=100)))
384+
**(dict(height=equity_height_with_dd) if plot_drawdown else dict(height=equity_height)))
366385

367386
# High-watermark drawdown dents
368387
fig.patch('index', 'equity_dd',
@@ -413,7 +432,7 @@ def _plot_equity_section(is_return=False):
413432

414433
def _plot_drawdown_section():
415434
"""Drawdown section"""
416-
fig = new_indicator_figure(y_axis_label="Drawdown", height=80)
435+
fig = new_indicator_figure(y_axis_label="Drawdown", height=drawdown_height)
417436
drawdown = equity_data['DrawdownPct']
418437
argmax = drawdown.idxmax()
419438
source.add(drawdown, 'drawdown')
@@ -427,7 +446,7 @@ def _plot_drawdown_section():
427446

428447
def _plot_pl_section():
429448
"""Profit/Loss markers section"""
430-
fig = new_indicator_figure(y_axis_label="Profit / Loss", height=80)
449+
fig = new_indicator_figure(y_axis_label="Profit / Loss", height=pl_height)
431450
fig.add_layout(Span(location=0, dimension='width', line_color='#666666',
432451
line_dash='dashed', level='underlay', line_width=1))
433452
trade_source.add(trades['ReturnPct'], 'returns')
@@ -454,7 +473,7 @@ def _plot_pl_section():
454473

455474
def _plot_volume_section():
456475
"""Volume section"""
457-
fig = new_indicator_figure(height=70, y_axis_label="Volume")
476+
fig = new_indicator_figure(height=volume_height, y_axis_label="Volume")
458477
fig.yaxis.ticker.desired_num_ticks = 3
459478
fig.xaxis.formatter = fig_ohlc.xaxis[0].formatter
460479
fig.xaxis.visible = True

backtesting/backtesting.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1640,7 +1640,8 @@ def _mp_task(arg):
16401640
for shmem in shm:
16411641
shmem.close()
16421642

1643-
def plot(self, *, results: pd.Series = None, filename=None, plot_width=None,
1643+
def plot(self, *, results: pd.Series = None, filename=None,
1644+
plot_width=None, plot_height=400,
16441645
plot_equity=True, plot_return=False, plot_pl=True,
16451646
plot_volume=True, plot_drawdown=False, plot_trades=True,
16461647
smooth_equity=False, relative_equity=True,
@@ -1661,8 +1662,10 @@ def plot(self, *, results: pd.Series = None, filename=None, plot_width=None,
16611662
current working directory.
16621663
16631664
`plot_width` is the width of the plot in pixels. If None (default),
1664-
the plot is made to span 100% of browser width. The height is
1665-
currently non-adjustable.
1665+
the plot is made to span 100% of browser width.
1666+
1667+
`plot_height` is the height of the main OHLC chart in pixels. Other
1668+
sections are sized proportionally. Default is 400.
16661669
16671670
If `plot_equity` is `True`, the resulting plot will contain
16681671
an equity (initial cash plus assets) graph section. This is the same
@@ -1737,6 +1740,7 @@ def plot(self, *, results: pd.Series = None, filename=None, plot_width=None,
17371740
indicators=results._strategy._indicators,
17381741
filename=filename,
17391742
plot_width=plot_width,
1743+
plot_height=plot_height,
17401744
plot_equity=plot_equity,
17411745
plot_return=plot_return,
17421746
plot_pl=plot_pl,

0 commit comments

Comments
 (0)