Skip to content

Commit 97fbd7f

Browse files
committed
Add Histogram indicator plot style kernc#195
1 parent 44b2519 commit 97fbd7f

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:
@@ -536,7 +537,11 @@ def __eq__(self, other):
536537
tooltips.append(f'@{{{source_name}}}{{0,0.0[0000]}}')
537538
if is_overlay:
538539
ohlc_extreme_values[source_name] = arr
539-
if is_scatter:
540+
if is_histogram:
541+
fig.vbar(x=source.data['index'], legend_label=legend_label,
542+
bottom=[0 for _ in source.data['index']],
543+
top=arr, width=BAR_WIDTH, color=color)
544+
elif is_scatter:
540545
fig.scatter(
541546
'index', source_name, source=source,
542547
legend_label=legend_label, color=color,
@@ -548,7 +553,11 @@ def __eq__(self, other):
548553
legend_label=legend_label, line_color=color,
549554
line_width=1.3)
550555
else:
551-
if is_scatter:
556+
if is_histogram:
557+
r = fig.vbar(x=source.data['index'], legend_label=LegendStr(legend_label),
558+
bottom=[0 for _ in source.data['index']],
559+
top=arr, width=BAR_WIDTH, color=color)
560+
elif is_scatter:
552561
r = fig.scatter(
553562
'index', source_name, source=source,
554563
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
@@ -772,6 +772,24 @@ def next(self):
772772
plot_drawdown=False, plot_equity=False, plot_pl=False, plot_volume=False,
773773
open_browser=False)
774774

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

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

0 commit comments

Comments
 (0)