Skip to content

Commit bf2585c

Browse files
committed
Add Histogram indicator plot style kernc#195
1 parent 0a76e96 commit bf2585c

File tree

3 files changed

+35
-4
lines changed

3 files changed

+35
-4
lines changed

backtesting/_plotting.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,7 @@ def __eq__(self, other):
513513

514514
is_overlay = value._opts['overlay']
515515
is_scatter = value._opts['scatter']
516+
is_histogram = value._opts['histogram']
516517
if is_overlay:
517518
fig = fig_ohlc
518519
else:
@@ -532,7 +533,11 @@ def __eq__(self, other):
532533
tooltips.append(f'@{{{source_name}}}{{0,0.0[0000]}}')
533534
if is_overlay:
534535
ohlc_extreme_values[source_name] = arr
535-
if is_scatter:
536+
if is_histogram:
537+
fig.vbar(x=source.data['index'], legend_label=legend_label,
538+
bottom=[0 for _ in source.data['index']],
539+
top=arr, width=BAR_WIDTH, color=color)
540+
elif is_scatter:
536541
fig.scatter(
537542
'index', source_name, source=source,
538543
legend_label=legend_label, color=color,
@@ -544,7 +549,11 @@ def __eq__(self, other):
544549
legend_label=legend_label, line_color=color,
545550
line_width=1.3)
546551
else:
547-
if is_scatter:
552+
if is_histogram:
553+
r = fig.vbar(x=source.data['index'], legend_label=LegendStr(legend_label),
554+
bottom=[0 for _ in source.data['index']],
555+
top=arr, width=BAR_WIDTH, color=color)
556+
elif is_scatter:
548557
r = fig.scatter(
549558
'index', source_name, source=source,
550559
legend_label=LegendStr(legend_label), color=color,

backtesting/backtesting.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ def _check_params(self, params):
7575

7676
def I(self, # noqa: E741, E743
7777
func: Callable, *args,
78-
name=None, plot=True, overlay=None, color=None, scatter=False,
78+
name=None, plot=True, overlay=None, color=None, scatter=False, histogram=False,
7979
**kwargs) -> np.ndarray:
8080
"""
8181
Declare indicator. An indicator is just an array of values,
@@ -105,6 +105,10 @@ def I(self, # noqa: E741, E743
105105
If `scatter` is `True`, the plotted indicator marker will be a
106106
circle instead of a connected line segment (default).
107107
108+
If `histogram` is `True`, the indicator values will be plotted
109+
as a histogram instead of line or circle. When `histogram` is
110+
`True`, 'scatter' value will be ignored even if it's set.
111+
108112
Additional `*args` and `**kwargs` are passed to `func` and can
109113
be used for parameters.
110114
@@ -151,7 +155,7 @@ def init():
151155
overlay = ((x < 1.4) & (x > .6)).mean() > .6
152156

153157
value = _Indicator(value, name=name, plot=plot, overlay=overlay,
154-
color=color, scatter=scatter,
158+
color=color, scatter=scatter, histogram=histogram,
155159
# _Indicator.s Series accessor uses this:
156160
index=self.data.index)
157161
self._indicators.append(value)

backtesting/test/_test.py

+18
Original file line numberDiff line numberDiff line change
@@ -771,6 +771,24 @@ def next(self):
771771
plot_drawdown=False, plot_equity=False, plot_pl=False, plot_volume=False,
772772
open_browser=False)
773773

774+
def test_indicator_histogram(self):
775+
class S(Strategy):
776+
def init(self):
777+
self.I(SMA, self.data.Close, 5, overlay=True, scatter=False, histogram=True)
778+
self.I(SMA, self.data.Close, 10, overlay=False, scatter=False, histogram=True)
779+
780+
def next(self):
781+
pass
782+
783+
bt = Backtest(GOOG, S)
784+
bt.run()
785+
with _tempfile() as f:
786+
bt.plot(filename=f,
787+
plot_drawdown=False, plot_equity=False, plot_pl=False, plot_volume=False,
788+
open_browser=True)
789+
# Give browser time to open before tempfile is removed
790+
time.sleep(1)
791+
774792

775793
class TestLib(TestCase):
776794
def test_barssince(self):

0 commit comments

Comments
 (0)