def get_plotlineinfo(obj, lineidx): lineplotinfo = None if not isinstance(obj.lines, list): linealias = obj.lines._getlinealias(lineidx) lineplotinfo = getattr(obj.plotlines, '_%d' % lineidx, None) if not lineplotinfo and linealias is not None: lineplotinfo = getattr(obj.plotlines, linealias, None) if not lineplotinfo: lineplotinfo = bt.AutoInfoClass() return lineplotinfo
def _plot_indicator_observer(self, obj: Union[bt.Indicator, bt.Observer], master, strat_clk: array = None): pl = plotobj2label(obj) self._figure_append_title(pl) indlabel = obj.plotlabel() plotinfo = obj.plotinfo for lineidx in range(obj.size()): line = obj.lines[lineidx] source_id = Figure._source_id(line) linealias = obj.lines._getlinealias(lineidx) lineplotinfo = getattr(obj.plotlines, '_%d' % lineidx, None) if not lineplotinfo: lineplotinfo = getattr(obj.plotlines, linealias, None) if not lineplotinfo: lineplotinfo = bt.AutoInfoClass() if lineplotinfo._get('_plotskip', False): continue marker = lineplotinfo._get("marker", None) method = lineplotinfo._get('_method', "line") color = getattr(lineplotinfo, "color", None) if color is None: if not lineplotinfo._get('_samecolor', False): self._nextcolor() color = self._color() color = convert_color(color) kwglyphs = {'name': linealias} dataline = line.plotrange(self._start, self._end) line_clk = get_data_obj(obj).lines.datetime.plotrange( self._start, self._end) dataline = resample_line(dataline, line_clk, strat_clk) self._add_to_cds(dataline, source_id) label = None if master is None or lineidx == 0 or plotinfo.plotlinelabels: label = indlabel if master is None or plotinfo.plotlinelabels: label += " " + (lineplotinfo._get("_name", "") or linealias) kwglyphs['legend_label'] = label if marker is not None: kwglyphs['size'] = lineplotinfo.markersize * 1.2 kwglyphs['color'] = color kwglyphs['y'] = source_id mrk_fncs = { '^': self.figure.triangle, 'v': self.figure.inverted_triangle, 'o': self.figure.circle, '<': self.figure.circle_cross, '>': self.figure.circle_x, '1': self.figure.diamond, '2': self.figure.diamond_cross, '3': self.figure.hex, '4': self.figure.square, '8': self.figure.square_cross, 's': self.figure.square_x, 'p': self.figure.triangle, '*': self.figure.asterisk, 'h': self.figure.hex, 'H': self.figure.hex, '+': self.figure.asterisk, 'x': self.figure.x, 'D': self.figure.diamond_cross, 'd': self.figure.diamond, } if marker not in mrk_fncs: raise Exception( f"Sorry, unsupported marker: '{marker}'. Please report to GitHub." ) glyph_fnc = mrk_fncs[marker] elif method == "bar": kwglyphs['bottom'] = 0 kwglyphs['line_color'] = 'black' kwglyphs['fill_color'] = color kwglyphs['width'] = get_bar_width() kwglyphs['top'] = source_id glyph_fnc = self.figure.vbar elif method == "line": kwglyphs['line_width'] = 1 kwglyphs['color'] = color kwglyphs['y'] = source_id linestyle = getattr(lineplotinfo, "ls", None) if linestyle is not None: kwglyphs['line_dash'] = convert_linestyle(linestyle) glyph_fnc = self.figure.line else: raise Exception(f"Unknown plotting method '{method}'") renderer = glyph_fnc("index", source=self._cds, **kwglyphs) # for markers add additional renderer so hover pops up for all of them if marker is None: self._set_single_hover_renderer(renderer) else: self._add_hover_renderer(renderer) hover_label_suffix = f" - {linealias}" if obj.size( ) > 1 else "" # we need no suffix if there is just one line in the indicator anyway hover_label = indlabel + hover_label_suffix hover_data = f"@{source_id}{{{self._scheme.number_format}}}" self._hoverc.add_hovertip(hover_label, hover_data, obj) # adapt y-axis if needed if master is None or getattr(master.plotinfo, 'plotylimited', False) is False: adapt_yranges(self.figure.y_range, dataline) self._set_yticks(obj) self._plot_hlines(obj)
def _plot_indicator_observer(self, obj: Union[bt.Indicator, bt.Observer], master): # pl = plotobj2label(obj) pl = "" self._figure_append_title(pl) indlabel = obj.plotlabel() plotinfo = obj.plotinfo is_multiline = obj.size() > 1 for lineidx in range(obj.size()): line = obj.lines[lineidx] source_id = FigureEnvelope._source_id(line) linealias = obj.lines._getlinealias(lineidx) lineplotinfo = getattr(obj.plotlines, '_%d' % lineidx, None) if not lineplotinfo: lineplotinfo = getattr(obj.plotlines, linealias, None) if not lineplotinfo: lineplotinfo = bt.AutoInfoClass() if lineplotinfo._get('_plotskip', False): continue marker = lineplotinfo._get("marker", None) method = lineplotinfo._get('_method', "line") color = getattr(lineplotinfo, "color", None) if color is None: if not lineplotinfo._get('_samecolor', False): self._nextcolor() color = self._color() color = convert_color(color) kwglyphs = {'name': linealias} self._add_column(source_id, np.float64) # either all individual lines of are displayed in the legend or only the ind/obs as a whole label = indlabel if is_multiline and plotinfo.plotlinelabels: label += " " + (lineplotinfo._get("_name", "") or linealias) kwglyphs['legend_label'] = label if marker is not None: kwglyphs['size'] = lineplotinfo.markersize * 1.2 kwglyphs['color'] = color kwglyphs['y'] = source_id if marker not in FigureEnvelope._mrk_fncs: raise Exception(f"Sorry, unsupported marker: '{marker}'. Please report to GitHub.") glyph_fnc_name = FigureEnvelope._mrk_fncs[marker] glyph_fnc = getattr(self.figure, glyph_fnc_name) elif method == "bar": kwglyphs['bottom'] = 0 kwglyphs['line_color'] = 'black' kwglyphs['fill_color'] = color kwglyphs['width'] = get_bar_width() kwglyphs['top'] = source_id glyph_fnc = self.figure.vbar elif method == "line": kwglyphs['line_width'] = 1 kwglyphs['color'] = color kwglyphs['y'] = source_id linestyle = getattr(lineplotinfo, "ls", None) if linestyle is not None: kwglyphs['line_dash'] = convert_linestyle(linestyle) glyph_fnc = self.figure.line else: raise Exception(f"Unknown plotting method '{method}'") renderer = glyph_fnc("index", source=self._cds, **kwglyphs) # make sure the regular y-axis only scales to the normal data (data + ind/obs) on 1st axis (not to e.g. volume data on 2nd axis) self.figure.y_range.renderers.append(renderer) # for markers add additional renderer so hover pops up for all of them if marker is None: self._set_single_hover_renderer(renderer) else: self._add_hover_renderer(renderer) hover_label_suffix = f" - {linealias}" if obj.size() > 1 else "" # we need no suffix if there is just one line in the indicator anyway hover_label = indlabel + hover_label_suffix hover_data = f"@{source_id}{{{self._scheme.number_format}}}" # self._hoverc.add_hovertip(hover_label, hover_data, obj) self._set_yticks(obj) self._plot_hlines(obj)
def plot_indicator(self, obj: Union[bt.Indicator, bt.Observer], master): pl = obj.plotlabel() if isinstance(obj, bt.Indicator): pl += Figure._get_datas_description(obj) elif isinstance(obj, bt.Observer): pl += get_strategy_label(obj._owner) self._figure_append_title(pl) indlabel = obj.plotlabel() plotinfo = obj.plotinfo for lineidx in range(obj.size()): line = obj.lines[lineidx] source_id = Figure._source_id(line) linealias = obj.lines._getlinealias(lineidx) lineplotinfo = getattr(obj.plotlines, '_%d' % lineidx, None) if not lineplotinfo: lineplotinfo = getattr(obj.plotlines, linealias, None) if not lineplotinfo: lineplotinfo = bt.AutoInfoClass() if lineplotinfo._get('_plotskip', False): continue marker = lineplotinfo._get("marker", None) method = lineplotinfo._get('_method', "line") color = getattr(lineplotinfo, "color", None) if color is None: if not lineplotinfo._get('_samecolor', False): self._nextcolor() color = self._color() color = convert_color(color) kwglyphs = {'name': linealias} dataline = line.plotrange(self._start, self._end) self._add_to_cds(dataline, source_id) label = None if master is None or lineidx == 0 or plotinfo.plotlinelabels: label = indlabel if master is None or plotinfo.plotlinelabels: label += " " + (lineplotinfo._get("_name", "") or linealias) kwglyphs['legend'] = label if marker is not None: kwglyphs['size'] = lineplotinfo.markersize * 1.2 kwglyphs['color'] = color kwglyphs['y'] = source_id mrk_fncs = { '^': self.figure.triangle, 'v': self.figure.inverted_triangle, 'o': self.figure.circle, } glyph_fnc = mrk_fncs[marker] elif method == "bar": kwglyphs['bottom'] = 0 kwglyphs['line_color'] = 'black' kwglyphs['fill_color'] = color kwglyphs['width'] = get_bar_length_ms(obj._clock) kwglyphs['top'] = source_id glyph_fnc = self.figure.vbar elif method == "line": kwglyphs['line_width'] = 1 kwglyphs['color'] = color kwglyphs['y'] = source_id linestyle = getattr(lineplotinfo, "ls", None) if linestyle is not None: kwglyphs['line_dash'] = convert_linestyle(linestyle) glyph_fnc = self.figure.line else: raise Exception(f"Unknown plotting method '{method}'") renderer = glyph_fnc("datetime", source=self._cds, **kwglyphs) # for markers add additional renderer so hover pops up for all of them if marker is None: self._set_single_hover_renderer(renderer) else: self._add_hover_renderer(renderer) hover_target = None is_obs = isinstance(obj, bt.Observer) if is_obs and master is None: hover_target = self.figure self._hoverc.add_hovertip(f"{indlabel} - {linealias}", f"@{source_id}{{0,0.000}}", hover_target) # adapt y-axis if needed if master is None or getattr(master.plotinfo, 'plotylimited', False) is False: adapt_yranges(self.figure.y_range, dataline) self._set_yticks(obj) self._plot_hlines(obj)