예제 #1
0
    def build_strategy_data(self,
                            strategy: bt.Strategy,
                            start: Optional[datetime.datetime] = None,
                            end: Optional[datetime.datetime] = None,
                            num_back: Optional[int] = None,
                            startidx: int = 0):
        """startidx: index number to write into the dataframe for the index column"""
        strategydf = pd.DataFrame()

        start, end = Bokeh._get_start_end(strategy, start, end)

        strat_clk: array[float] = strategy.lines.datetime.plotrange(start, end)

        # if patches occured then we see duplicate entries in the strategie clock -> clean them
        strat_clk = np.unique(strat_clk)

        if num_back is None:
            num_back = len(strat_clk)

        strat_clk = strat_clk[-num_back:]

        # we use timezone of first data. we might see duplicated timestamps here
        dtline = [bt.num2date(x, strategy.datas[0]._tz) for x in strat_clk]

        # add an index line to use as x-axis (instead of datetime axis) to avoid datetime gaps (e.g. weekends)
        indices = list(range(startidx, startidx + len(dtline)))
        strategydf['index'] = indices

        strategydf['datetime'] = dtline

        for data in strategy.datas:
            source_id = FigureEnvelope._source_id(data)
            df_data = convert_to_pandas(strat_clk, data, start, end, source_id)

            strategydf = strategydf.join(df_data)

            df_colors = FigureEnvelope.build_color_lines(
                df_data,
                self.p.scheme,
                col_open=source_id + 'open',
                col_close=source_id + 'close',
                col_prefix=source_id)
            strategydf = strategydf.join(df_colors)

        for obj in itertools.chain(strategy.getindicators(),
                                   strategy.getobservers()):
            for lineidx in range(obj.size()):
                line = obj.lines[lineidx]
                source_id = FigureEnvelope._source_id(line)
                dataline = line.plotrange(start, end)

                line_clk = get_clock_line(obj).plotrange(start, end)
                dataline = convert_by_line_clock(dataline, line_clk, strat_clk)
                strategydf[source_id] = dataline

        # apply a proper index (should be identical to 'index' column)
        if strategydf.shape[0] > 0:
            strategydf.index = indices
        return strategydf
예제 #2
0
    def _build_graph(self,
                     datas,
                     inds,
                     obs,
                     tradingdomain=None) -> Tuple[Dict, List]:
        data_graph = {}
        volume_graph = []
        for d in datas:
            if not d.plotinfo.plot or not FigureEnvelope.should_filter_by_tradingdomain(
                    d, tradingdomain):
                continue

            pmaster = Bokeh._resolve_plotmaster(d.plotinfo.plotmaster)
            if pmaster is None:
                data_graph[d] = []
            else:
                if pmaster not in data_graph:
                    data_graph[pmaster] = []
                data_graph[pmaster].append(d)

            if self.p.scheme.volume and self.p.scheme.voloverlay is False:
                volume_graph.append(d)

        for obj in itertools.chain(inds, obs):
            if not hasattr(obj, 'plotinfo'):
                # no plotting support - so far LineSingle derived classes
                continue

            # should this indicator be plotted?
            if not obj.plotinfo.plot or obj.plotinfo.plotskip or not FigureEnvelope.should_filter_by_tradingdomain(
                    obj, tradingdomain):
                continue

            # subplot = create a new figure for this indicator
            subplot: bool = obj.plotinfo.subplot
            plotmaster: str = obj.plotinfo.plotmaster
            if subplot and plotmaster is None:
                data_graph[obj] = []
            else:
                plotmaster = plotmaster if plotmaster is not None else get_indicator_data(
                    obj)

                if plotmaster not in data_graph:
                    data_graph[plotmaster] = []
                data_graph[plotmaster].append(obj)

        return data_graph, volume_graph
예제 #3
0
    def list_tradingdomains(self, strategy: bt.Strategy):
        data_graph, volume_graph = self._build_graph(strategy.datas,
                                                     strategy.getindicators(),
                                                     strategy.getobservers())

        lgs = list()
        for master in itertools.chain(data_graph.keys(), volume_graph):
            lg = FigureEnvelope._resolve_tradingdomain(master)
            if isinstance(lg, str) and lg not in lgs:
                lgs.append(lg)

        return lgs
예제 #4
0
    def _blueprint_strategy(self,
                            strategy: bt.Strategy,
                            start=None,
                            end=None,
                            tradingdomain=None,
                            **kwargs) -> None:
        if not strategy.datas:
            return

        self._cur_figurepage.analyzers += [
            a for _, a in strategy.analyzers.getitems()
        ]

        data_graph, volume_graph = self._build_graph(strategy.datas,
                                                     strategy.getindicators(),
                                                     strategy.getobservers(),
                                                     tradingdomain)

        start, end = Bokeh._get_start_end(strategy, start, end)

        # reset hover container to not mix hovers with other strategies
        hoverc = HoverContainer(
            hover_tooltip_config=self.p.scheme.hover_tooltip_config,
            is_multidata=len(strategy.datas) > 1)

        strat_figures = []
        for master, slaves in data_graph.items():
            plotorder = getattr(master.plotinfo, 'plotorder', 0)
            figure = FigureEnvelope(strategy, self._cur_figurepage.cds, hoverc,
                                    start, end, self.p.scheme, master,
                                    plotorder,
                                    len(strategy.datas) > 1)

            figure.plot(master, None)

            for s in slaves:
                figure.plot(s, master)
            strat_figures.append(figure)

        for f in strat_figures:
            f.figure.legend.click_policy = self.p.scheme.legend_click
            f.figure.legend.location = self.p.scheme.legend_location
            f.figure.legend.background_fill_color = self.p.scheme.legend_background_color
            f.figure.legend.label_text_color = self.p.scheme.legend_text_color
            f.figure.legend.orientation = self.p.scheme.legend_orientation

        # link axis
        for i in range(1, len(strat_figures)):
            strat_figures[i].figure.x_range = strat_figures[0].figure.x_range

        # configure xaxis visibility
        if self.p.scheme.xaxis_pos == "bottom":
            for i, f in enumerate(strat_figures):
                f.figure.xaxis.visible = False if i <= len(
                    strat_figures) else True

        hoverc.apply_hovertips(strat_figures)

        self._cur_figurepage.figure_envs += strat_figures

        # volume graphs
        for v in volume_graph:
            plotorder = getattr(v.plotinfo, 'plotorder', 0)
            figure = FigureEnvelope(strategy,
                                    self._cur_figurepage.cds,
                                    hoverc,
                                    start,
                                    end,
                                    self.p.scheme,
                                    v,
                                    plotorder,
                                    is_multidata=len(strategy.datas) > 1)
            figure.plot_volume(v)
            self._cur_figurepage.figure_envs.append(figure)