Esempio n. 1
0
def main():
    data_provider = container.resolve(GeneralPriceProvider)
    series = data_provider.get_price(QuandlTicker('AAPL', 'WIKI'),
                                     PriceField.Close,
                                     start_date=start_date,
                                     end_date=end_date)
    series = series.to_prices(1)

    vol_manager = VolatilityManager(series)
    managed_series, weights_series = vol_manager.get_managed_series(
        vol_level=0.2,
        window_size=20,
        lag=1,
        min_leverage=min_lev,
        max_leverage=max_lev)
    managed_series = managed_series.to_prices(1)

    line_chart = LineChart()
    series_element = DataElementDecorator(series)
    managed_element = DataElementDecorator(managed_series)

    line_chart.add_decorator(series_element)
    line_chart.add_decorator(managed_element)

    legend = LegendDecorator(legend_placement=Location.BEST, key='legend')
    legend.add_entry(series_element, 'Original')
    legend.add_entry(managed_element, 'Vol_managed')
    line_chart.add_decorator(legend)
    line_chart.plot()
    plt.show(block=True)
Esempio n. 2
0
    def _get_histogram_chart(self):
        colors = Chart.get_axes_colors()
        chart = HistogramChart(self.returns_of_trades * 100)  # expressed in %
        # Format the x-axis so that its labels are shown as a percentage.
        x_axis_formatter = FormatStrFormatter("%0.0f%%")
        axes_formatter_decorator = AxesFormatterDecorator(x_major=x_axis_formatter, key="axes_formatter")
        chart.add_decorator(axes_formatter_decorator)
        # Only show whole numbers on the y-axis.
        y_axis_locator = MaxNLocator(integer=True)
        axes_locator_decorator = AxesLocatorDecorator(y_major=y_axis_locator, key="axes_locator")
        chart.add_decorator(axes_locator_decorator)

        # Add an average line.
        avg_line = VerticalLineDecorator(self.returns_of_trades.values.mean(), color=colors[1],
                                         key="average_line_decorator", linestyle="--", alpha=0.8)
        chart.add_decorator(avg_line)

        # Add a legend.
        legend = LegendDecorator(key="legend_decorator")
        legend.add_entry(avg_line, "Mean")
        chart.add_decorator(legend)

        # Add a title.
        title = TitleDecorator("Distribution of Trades", key="title_decorator")
        chart.add_decorator(title)
        chart.add_decorator(AxesLabelDecorator("Return", "Occurrences"))
        return chart
Esempio n. 3
0
    def _add_up_and_down_trend_strength(self, prices_df: QFDataFrame):
        def _down_trend_fun(df):
            return down_trend_strength(df, self.use_next_open_instead_of_close)

        def _up_trend_fun(df):
            return up_trend_strength(df, self.use_next_open_instead_of_close)

        up_trend_strength_tms = prices_df.rolling_time_window(window_length=self.window_len, step=1,
                                                              func=_down_trend_fun)
        down_trend_strength_tms = prices_df.rolling_time_window(window_length=self.window_len, step=1,
                                                                func=_up_trend_fun)
        chart = LineChart()
        up_trend_elem = DataElementDecorator(up_trend_strength_tms)
        down_trend_elem = DataElementDecorator(down_trend_strength_tms)
        chart.add_decorator(up_trend_elem)
        chart.add_decorator(down_trend_elem)
        legend = LegendDecorator(legend_placement=Location.BEST, key='legend')
        legend.add_entry(up_trend_elem, 'Up trend strength')
        legend.add_entry(down_trend_elem, 'Down trend strength')
        chart.add_decorator(legend)
        title = "Strength of the up and down trend - rolling {} days".format(self.window_len)
        title_decorator = TitleDecorator(title, key="title")
        chart.add_decorator(title_decorator)
        self._add_axes_position_decorator(chart)
        self.document.add_element(ChartElement(chart, figsize=self.image_size, dpi=self.dpi))
Esempio n. 4
0
    def __get_perf_chart(self, series_list, is_large_chart):
        strategy = series_list[0].to_prices(
            1)  # the main strategy should be the first series
        log_scale = True if strategy[
            -1] > 10 else False  # use log scale for returns above 1 000 %

        if is_large_chart:
            chart = LineChart(start_x=strategy.index[0],
                              end_x=strategy.index[-1],
                              log_scale=log_scale)
            position_decorator = AxesPositionDecorator(
                *self.full_image_axis_position)
            chart.add_decorator(position_decorator)
        else:
            chart = LineChart(log_scale=log_scale, rotate_x_axis=True)

        line_decorator = HorizontalLineDecorator(1, key="h_line", linewidth=1)
        chart.add_decorator(line_decorator)
        legend = LegendDecorator()
        for series in series_list:
            strategy_tms = series.to_prices(1)
            series_elem = DataElementDecorator(strategy_tms)
            chart.add_decorator(series_elem)
            legend.add_entry(series_elem, strategy_tms.name)

        chart.add_decorator(legend)
        title_decorator = TitleDecorator("Strategy Performance", key="title")
        chart.add_decorator(title_decorator)

        return chart
Esempio n. 5
0
def _create_legend(bar_chart, data_elements, line_decorators, names_list,
                   quarterly: bool) -> LegendDecorator:
    legend_decorator = LegendDecorator(key='legend')

    i = 0
    for data_element in data_elements:
        bar_label = names_list[i]
        if bar_label is not None:
            date = data_element.data.index[-1]
            formatted_date = date.strftime("%b %y")
            if quarterly:
                formatted_date = "Q{} {}".format(str(date.quarter), date.year)
            last_date_label = " [{}]".format(formatted_date)
            legend_decorator.add_entry(data_element,
                                       bar_label + last_date_label)
        i += 1

    for line_decorator in line_decorators:
        series_label = names_list[i]
        if series_label is not None:
            legend_decorator.add_entry(line_decorator, series_label)
        i += 1

    bar_chart.add_decorator(legend_decorator)
    return legend_decorator
Esempio n. 6
0
    def _add_assets_number_in_portfolio_chart(self):
        chart = LineChart(rotate_x_axis=False)
        chart.add_decorator(AxesPositionDecorator(*self.full_image_axis_position))
        legend = LegendDecorator(key="legend_decorator")

        positions_history = self.backtest_result.portfolio.positions_history()

        # Find all not NaN values (not NaN values indicate that the position was open for this contract at that time)
        # and count their number for each row (for each of the dates)
        number_of_contracts = positions_history.notna().sum(axis=1)
        number_of_contracts_decorator = DataElementDecorator(number_of_contracts)
        chart.add_decorator(number_of_contracts_decorator)
        legend.add_entry(number_of_contracts_decorator, "Contracts")

        # Group tickers by name and for each name and date check if there was at least one position open with any
        # of the corresponding tickers. Finally sum all the assets that had a position open on a certain date.
        number_of_assets = positions_history.groupby(by=lambda ticker: ticker.name, axis='columns') \
            .apply(lambda x: x.notna().any(axis=1)).sum(axis=1)
        number_of_assets_decorator = DataElementDecorator(number_of_assets)
        chart.add_decorator(number_of_assets_decorator)
        legend.add_entry(number_of_assets_decorator, "Assets")

        chart.add_decorator(TitleDecorator("Number of assets in the portfolio"))
        chart.add_decorator(legend)
        chart.add_decorator(AxesLabelDecorator(y_label="Number of contracts / assets"))

        self.document.add_element(ChartElement(chart, figsize=self.full_image_size, dpi=self.dpi))
Esempio n. 7
0
    def _get_distribution_plot(self, data_series: SimpleReturnsSeries, title: str, bins: Union[int, str] = 50,
                               crop: bool = False):
        colors = Chart.get_axes_colors()

        if crop:
            start_x = np.quantile(data_series, 0.01)
            end_x = np.quantile(data_series, 0.99)
            chart = HistogramChart(data_series, bins=bins, start_x=start_x, end_x=end_x)
        else:
            chart = HistogramChart(data_series, bins=bins)

        # Only show whole numbers on the y-axis.
        y_axis_locator = MaxNLocator(integer=True)
        axes_locator_decorator = AxesLocatorDecorator(y_major=y_axis_locator, key="axes_locator")
        chart.add_decorator(axes_locator_decorator)

        # Add an average line.
        avg_line = VerticalLineDecorator(data_series.mean(), color=colors[1],
                                         key="average_line_decorator", linestyle="--", alpha=0.8)
        chart.add_decorator(avg_line)

        # Add a legend.
        legend = LegendDecorator(key="legend_decorator")
        legend.add_entry(avg_line, "Mean")
        chart.add_decorator(legend)

        # Add a title.
        title_decorator = TitleDecorator(title, key="title")
        chart.add_decorator(title_decorator)
        chart.add_decorator(AxesLabelDecorator(title, "Occurrences"))

        position_decorator = AxesPositionDecorator(*self.full_image_axis_position)
        chart.add_decorator(position_decorator)

        return chart
Esempio n. 8
0
    def historical_performance_chart(self) -> LineChart:
        frequency = self.model.input_data.frequency
        analysed_tms = self.model.input_data.analysed_tms
        fitted_tms = self.model.fitted_tms

        cumulative_fund_rets = analysed_tms.to_prices(initial_price=1.0,
                                                      frequency=frequency) - 1
        cumulative_fit_rets = fitted_tms.to_prices(initial_price=1.0,
                                                   frequency=frequency) - 1

        hist_performance_chart = LineChart()
        fund_cummulative_rets_data_elem = DataElementDecorator(
            cumulative_fund_rets)
        fit_cummulative_rets_data_elem = DataElementDecorator(
            cumulative_fit_rets)

        legend_decorator = LegendDecorator(
            legend_placement=Location.LOWER_RIGHT)
        legend_decorator.add_entry(fund_cummulative_rets_data_elem,
                                   self._get_security_name(analysed_tms.name))
        legend_decorator.add_entry(fit_cummulative_rets_data_elem, 'Fit')

        hist_performance_chart.add_decorator(fund_cummulative_rets_data_elem)
        hist_performance_chart.add_decorator(fit_cummulative_rets_data_elem)

        hist_performance_chart.add_decorator(
            TitleDecorator("Historical Performance"))
        hist_performance_chart.add_decorator(
            AxesLabelDecorator(y_label="Cumulative return"))
        hist_performance_chart.add_decorator(legend_decorator)
        hist_performance_chart.add_decorator(
            AxesFormatterDecorator(y_major=PercentageFormatter()))

        return hist_performance_chart
def create_returns_distribution(returns: QFSeries, frequency: Frequency = Frequency.MONTHLY, title: str = None) -> \
        HistogramChart:
    """
    Creates a new returns distribution histogram with the specified frequency.

    Parameters
    ----------
    returns: QFSeries
        The returns series to use in the histogram.
    frequency: Frequency
        frequency of the returns after aggregation
    title
        title of the chart
    Returns
    -------
    HistogramChart
        A new ``HistogramChart`` instance.
    """
    colors = Chart.get_axes_colors()
    aggregate_returns = get_aggregate_returns(returns,
                                              frequency,
                                              multi_index=True).multiply(100)

    chart = HistogramChart(aggregate_returns)

    # Format the x-axis so that its labels are shown as a percentage.
    x_axis_formatter = FormatStrFormatter("%.0f%%")
    axes_formatter_decorator = AxesFormatterDecorator(x_major=x_axis_formatter,
                                                      key="axes_formatter")
    chart.add_decorator(axes_formatter_decorator)
    # Only show whole numbers on the y-axis.
    y_axis_locator = MaxNLocator(integer=True)
    axes_locator_decorator = AxesLocatorDecorator(y_major=y_axis_locator,
                                                  key="axes_locator")
    chart.add_decorator(axes_locator_decorator)

    # Add an average line.
    avg_line = VerticalLineDecorator(aggregate_returns.values.mean(),
                                     color=colors[1],
                                     key="average_line_decorator",
                                     linestyle="--",
                                     alpha=0.8)
    chart.add_decorator(avg_line)

    # Add a legend.
    legend = LegendDecorator(key="legend_decorator")
    legend.add_entry(avg_line, "Mean")
    chart.add_decorator(legend)

    # Add a title.
    if title is None:
        title = "Distribution of " + str(frequency).capitalize() + " Returns"
    title = TitleDecorator(title, key="title_decorator")
    chart.add_decorator(title)
    chart.add_decorator(AxesLabelDecorator("Returns", "Occurrences"))

    return chart
Esempio n. 10
0
    def _add_concentration_of_portfolio_chart(self, top_assets_numbers: tuple = (1, 5)):
        chart = LineChart(rotate_x_axis=False)

        position_decorator = AxesPositionDecorator(*self.full_image_axis_position)
        chart.add_decorator(position_decorator)

        # Define a legend
        legend = LegendDecorator(key="legend_decorator")

        # Add y label
        label_decorator = AxesLabelDecorator(y_label="Mean total exposure of top assets")
        chart.add_decorator(label_decorator)

        # Add top asset contribution
        positions_history = self.backtest_result.portfolio.positions_history()
        if positions_history.empty:
            raise ValueError("No positions found in positions history")

        positions_history = positions_history.applymap(
            lambda x: x.total_exposure if isinstance(x, BacktestPositionSummary) else 0)

        # Map all the single contracts onto tickers (including future tickers) and take the maximal total exposure for
        # each of the groups - in case if two contracts for a single asset will be included in the open positions in
        # the portfolio at any point of time, only one (with higher total exposure) will be considered while generating
        # the top assets plot
        def contract_to_ticker(c: Contract):
            return self.backtest_result.portfolio.contract_ticker_mapper. \
                contract_to_ticker(c, strictly_to_specific_ticker=False)

        assets_history = positions_history.rename(columns=contract_to_ticker)
        assets_history = assets_history.groupby(level=0, axis=1).apply(func=(
            lambda x: x.abs().max(axis=1).astype(float)
        ))

        for assets_number in top_assets_numbers:
            # For each date (row), find the top_assets largest assets and compute the mean value of their market value
            top_assets_mean_values = assets_history.stack(dropna=False).groupby(level=0).apply(
                lambda group: group.nlargest(assets_number).mean()
            ).resample('D').last()
            # Divide the computed mean values by the portfolio value, for each of the dates
            top_assets_percentage_value = top_assets_mean_values / self.backtest_result.portfolio.portfolio_eod_series()

            concentration_top_asset = DataElementDecorator(top_assets_percentage_value)
            chart.add_decorator(concentration_top_asset)

            # Add to legend
            legend.add_entry(concentration_top_asset, "TOP {} assets".format(assets_number))

        # Add title
        title_decorator = TitleDecorator("Concentration of assets")
        chart.add_decorator(title_decorator)

        # Add legend
        chart.add_decorator(legend)

        self.document.add_element(ChartElement(chart, figsize=self.full_image_size, dpi=self.dpi))
Esempio n. 11
0
    def _add_rolling_alpha_and_beta(self, timeseries_list):
        freq = timeseries_list[0].get_frequency()
        timeseries_list = [
            tms.dropna().to_simple_returns() for tms in timeseries_list
        ]
        df = pd.concat(timeseries_list, axis=1).fillna(0)

        rolling_window_len = int(freq.value / 2)  # 6M rolling
        step = round(freq.value / 6)  # 2M shift

        legend = LegendDecorator()
        chart = LineChart(start_x=df.index[0], end_x=df.index[-1])
        line_decorator = HorizontalLineDecorator(0, key="h_line", linewidth=1)
        chart.add_decorator(line_decorator)

        def alpha_function(df_in_window):
            strategy_returns = df_in_window.iloc[:, 0]
            benchmark_returns = df_in_window.iloc[:, 1]
            beta, alpha, _, _, _ = stats.linregress(benchmark_returns,
                                                    strategy_returns)
            return beta, alpha

        rolling = df.rolling_time_window(rolling_window_len, step,
                                         alpha_function)
        rolling = pd.DataFrame([[b, a] for b, a in rolling.values],
                               columns=["beta", "alpha"],
                               index=rolling.index)

        rolling_element = DataElementDecorator(rolling["beta"])
        chart.add_decorator(rolling_element)
        legend.add_entry(rolling_element, "beta")

        rolling_element = DataElementDecorator(rolling["alpha"],
                                               use_secondary_axes=True)
        chart.add_decorator(rolling_element)
        legend.add_entry(rolling_element, "alpha")

        chart.add_decorator(legend)
        chart.add_decorator(
            AxesFormatterDecorator(use_secondary_axes=True,
                                   y_major=PercentageFormatter(".1f")))

        # modify axes position to make secondary scale visible
        axes_position = list(self.full_image_axis_position)
        axes_position[2] = axes_position[2] - 0.07
        position_decorator = AxesPositionDecorator(*axes_position)
        chart.add_decorator(position_decorator)

        title_str = "Rolling alpha and beta [{} {} samples]".format(
            rolling_window_len, freq)
        title_decorator = TitleDecorator(title_str, key="title")
        chart.add_decorator(title_decorator)
        self.document.add_element(
            ChartElement(chart, figsize=self.full_image_size, dpi=self.dpi))
Esempio n. 12
0
    def _add_assets_number_in_portfolio_chart(self):
        chart = LineChart(rotate_x_axis=False)
        legend = LegendDecorator(key="legend_decorator")

        position_decorator = AxesPositionDecorator(
            *self.full_image_axis_position)
        chart.add_decorator(position_decorator)

        positions_history = self.backtest_result.portfolio.positions_history()

        # Find all not NaN values (not NaN values indicate that the position was open for this contract at that time)
        # and count their number for each row (for each of the dates)
        number_of_contracts = positions_history.notnull().sum(axis=1)
        number_of_contracts_decorator = DataElementDecorator(
            number_of_contracts)

        chart.add_decorator(number_of_contracts_decorator)
        legend.add_entry(number_of_contracts_decorator, "Contracts")

        # Count number of assets in the portfolio (if on two contracts from same future family exist in the same time,
        # e.g. during rolling day, in the portfolio, they are counted as one asset)
        def contract_to_ticker(c: Contract):
            return self.backtest_result.portfolio.contract_ticker_mapper. \
                contract_to_ticker(c, strictly_to_specific_ticker=False)

        assets_history = positions_history.rename(columns=contract_to_ticker)
        assets_history = assets_history.groupby(level=0, axis=1).apply(func=(
            # For each asset, group all of the corresponding columns (each of which corresponds to one contract),
            # and check if at any given timestamp the "value" of any of the contracts was different than None - this
            # indicates that at this point of time a position concerning the given asset was open in the portfolio
            # (which in the resulting series will be denoted as 1, otherwise - 0, so that it will be possible to
            # sum positions of all open assets at any given point of time)
            lambda x: x.notna().any(axis=1).astype(int)))

        number_of_assets = assets_history.sum(axis=1)
        number_of_assets_decorator = DataElementDecorator(number_of_assets)
        chart.add_decorator(number_of_assets_decorator)
        legend.add_entry(number_of_assets_decorator, "Assets")

        # Add title
        title_decorator = TitleDecorator("Number of assets in the portfolio")
        chart.add_decorator(title_decorator)

        # Add legend
        chart.add_decorator(legend)

        # Add y label
        label_decorator = AxesLabelDecorator(
            y_label="Number of contracts / assets")
        chart.add_decorator(label_decorator)

        self.document.add_element(
            ChartElement(chart, figsize=self.full_image_size, dpi=self.dpi))
Esempio n. 13
0
def create_returns_bar_chart(
        returns: QFSeries,
        frequency: Frequency = Frequency.YEARLY) -> BarChart:
    """
    Constructs a new returns bar chart based on the returns specified. By default a new annual returns bar chart will
    be created.
    """
    colors = Chart.get_axes_colors()
    # Calculate data.
    aggregate_returns = get_aggregate_returns(returns,
                                              frequency,
                                              multi_index=True)
    data_series = QFSeries(aggregate_returns.sort_index(ascending=True))

    chart = BarChart(Orientation.Horizontal, align="center")
    chart.add_decorator(DataElementDecorator(data_series))
    chart.add_decorator(BarValuesDecorator(data_series))

    # Format the x-axis so that its labels are shown as a percentage.
    chart.add_decorator(AxesFormatterDecorator(x_major=PercentageFormatter()))

    # Format Y axis to make sure we have a tick for each year or 2 years
    if len(data_series) > 10:
        y_labels = data_series[data_series.index % 2 == 1].index
    else:
        y_labels = data_series.index
    chart.add_decorator(
        AxisTickLabelsDecorator(labels=y_labels,
                                axis=Axis.Y,
                                tick_values=y_labels))

    # Add an average line.
    avg_line = VerticalLineDecorator(aggregate_returns.values.mean(),
                                     color=colors[1],
                                     key="avg_line",
                                     linestyle="--",
                                     alpha=0.8)
    chart.add_decorator(avg_line)

    # Add a legend.
    legend = LegendDecorator(key="legend_decorator")
    legend.add_entry(avg_line, "Mean")
    chart.add_decorator(legend)

    # Add a title.
    title = TitleDecorator(str(frequency).capitalize() + " Returns",
                           key="title_decorator")
    chart.add_decorator(title)
    chart.add_decorator(AxesLabelDecorator("Returns", "Year"))

    return chart
Esempio n. 14
0
 def _add_price_chart(self, prices_df: QFDataFrame):
     close_tms = prices_df[PriceField.Close]
     price_tms = close_tms.to_prices(1)
     chart = LineChart(start_x=price_tms.index[0], end_x=price_tms.index[-1])
     price_elem = DataElementDecorator(price_tms)
     chart.add_decorator(price_elem)
     line_decorator = HorizontalLineDecorator(1, key="h_line", linewidth=1)
     chart.add_decorator(line_decorator)
     legend = LegendDecorator()
     legend.add_entry(price_elem, "Close Price")
     chart.add_decorator(legend)
     title_decorator = TitleDecorator("Price of the instrument", key="title")
     chart.add_decorator(title_decorator)
     self._add_axes_position_decorator(chart)
     self.document.add_element(ChartElement(chart, figsize=self.image_size, dpi=self.dpi))
Esempio n. 15
0
    def _plot_ticker_performance(self, ticker_name: str, performance):
        self.document.add_element(HeadingElement(level=2, text="PnL of {}".format(ticker_name)))

        chart = LineChart()
        legend = LegendDecorator(key="legend_decorator")
        line_colors = iter(("#add8e6", "#000000", "#fa8072"))

        for title, pnl_series in performance.iteritems():
            # Plot series only in case if it consist anything else then 0
            if (pnl_series != 0).any():
                data_series = DataElementDecorator(pnl_series, **{"color": next(line_colors)})
                legend.add_entry(data_series, title)
                chart.add_decorator(data_series)

        chart.add_decorator(legend)
        self.document.add_element(ChartElement(chart, figsize=self.full_image_size, dpi=self.dpi))
Esempio n. 16
0
    def _add_trend_strength_chart(self, prices_df: QFDataFrame):

        def _fun(df):
            return trend_strength(df, self.use_next_open_instead_of_close)

        trend_strength_tms = prices_df.rolling_time_window(window_length=self.window_len, step=1, func=_fun)

        chart = LineChart()
        trend_elem = DataElementDecorator(trend_strength_tms, color='black')
        chart.add_decorator(trend_elem)
        legend = LegendDecorator(legend_placement=Location.BEST, key='legend')
        legend.add_entry(trend_elem, 'Trend strength')
        chart.add_decorator(legend)
        title_decorator = TitleDecorator("Strength of the trend - rolling {} days".format(self.window_len), key="title")
        chart.add_decorator(title_decorator)
        self._add_axes_position_decorator(chart)
        self.document.add_element(ChartElement(chart, figsize=self.image_size, dpi=self.dpi))
Esempio n. 17
0
    def _create_line_chart(self, rolling_values, title):
        line_chart = LineChart()
        legend = LegendDecorator()

        for column_name, values_tms in rolling_values.iteritems():
            coeff_tms_data_elem = DataElementDecorator(values_tms)
            line_chart.add_decorator(coeff_tms_data_elem)
            legend.add_entry(coeff_tms_data_elem, column_name)

        full_title_str = "".join([
            title,
            ' {:d} samples rolling'.format(self.rolling_model.window_size_)
        ])
        line_chart.add_decorator(TitleDecorator(full_title_str))
        line_chart.add_decorator(
            AxesFormatterDecorator(x_major=DateFormatter(
                fmt=str(DateFormat.YEAR_DOT_MONTH))))
        line_chart.add_decorator(legend)

        return line_chart
Esempio n. 18
0
def main():
    data_provider = container.resolve(GeneralPriceProvider)
    prices_tms = data_provider.get_price(QuandlTicker('AAPL', 'WIKI'),
                                         PriceField.Close, start_date,
                                         end_date)

    line_chart = LineChart()
    data_element = DataElementDecorator(prices_tms)
    line_chart.add_decorator(data_element)
    legend = LegendDecorator(legend_placement=Location.BEST, key='legend')
    legend.add_entry(data_element, 'SPY')
    line_chart.add_decorator(legend)

    cone_decorator = ConeDecorator(live_start_date=live_start_date,
                                   series=prices_tms,
                                   key='cone')
    line_chart.add_decorator(cone_decorator)
    line_chart.plot()

    plt.show(block=True)
Esempio n. 19
0
def get_cone_chart(paths_data_frame,
                   series_list,
                   names_list,
                   title=None,
                   log_sacle=True):
    """
    Helper function to plot simulated paths together with significant lines (like expectation)
    """
    line_chart = LineChart(log_scale=log_sacle)

    # plot all paths
    for series_name in paths_data_frame:
        series_element = DataElementDecorator(paths_data_frame[series_name],
                                              linewidth=1)
        line_chart.add_decorator(series_element)

    legend_decorator = LegendDecorator(key='legend')
    colors = ['black', 'red', 'green', 'purple', 'lime']
    for i in range(len(series_list)):
        series = series_list[i]
        name = names_list[i]
        series_element = DataElementDecorator(series,
                                              color=colors[i % len(colors)],
                                              linewidth=3)
        line_chart.add_decorator(series_element)
        legend_decorator.add_entry(series_element, name)

        point = (series.index[-1], series[series.index[-1]])
        point_emphasis = PointEmphasisDecorator(series_element,
                                                point,
                                                move_point=False)
        line_chart.add_decorator(point_emphasis)

    line_chart.add_decorator(legend_decorator)

    # Create a title.
    if title is not None:
        title_decorator = TitleDecorator(title, "title")
        line_chart.add_decorator(title_decorator)

    return line_chart
Esempio n. 20
0
def main():
    tms = data_provider.get_price(QuandlTicker('AAPL', 'WIKI'), PriceField.Close, start_date, end_date)
    tms2 = data_provider.get_price(QuandlTicker('MSFT', 'WIKI'), PriceField.Close, start_date, end_date)

    line_chart = LineChart()
    data_element = DataElementDecorator(tms)
    line_chart.add_decorator(data_element)

    data_element2 = DataElementDecorator(tms2, use_secondary_axes=True)
    line_chart.add_decorator(data_element2)

    axes_decorator = AxesLabelDecorator(x_label='dates', y_label='primary', secondary_y_label='secondary')
    line_chart.add_decorator(axes_decorator)

    legend = LegendDecorator(legend_placement=Location.BEST)
    legend.add_entry(data_element, 'AAPL')
    legend.add_entry(data_element2, 'MSFT')
    line_chart.add_decorator(legend)

    line_chart.plot()
    plt.show(block=True)
Esempio n. 21
0
def main():
    tms = QFSeries(data=[200, 20, 300, 40], index=[1, 2, 3, 4])
    tms2 = QFSeries(data=[80, 20, 100, 40], index=[1, 2, 3, 4])
    tms3 = QFSeries(data=[80, 20, 100, 40], index=[1, 2, 3, 4])

    bar_chart = BarChart(Orientation.Vertical)
    data_element = DataElementDecorator(tms)
    bar_chart.add_decorator(data_element)

    data_element2 = DataElementDecorator(tms2)
    bar_chart.add_decorator(data_element2)

    bar_chart.add_decorator(SeriesLineDecorator(tms3, use_secondary_axes=True))

    legend = LegendDecorator(legend_placement=Location.BEST)
    legend.add_entry(data_element, 'Series 1')
    legend.add_entry(data_element2, 'Series 2')
    bar_chart.add_decorator(legend)

    bar_chart.plot()
    plt.show(block=True)
Esempio n. 22
0
    def _add_rolling_chart(self):
        days_rolling = int(252 / 2)  # 6M rolling
        step = round(days_rolling / 5)

        strategy = self.strategy_series.to_prices(1)
        chart = LineChart(start_x=strategy.index[0], end_x=strategy.index[-1])
        line_decorator = HorizontalLineDecorator(0, key="h_line", linewidth=1)
        chart.add_decorator(line_decorator)

        legend = LegendDecorator()

        def tot_return(window):
            return PricesSeries(window).total_cumulative_return()

        def volatility(window):
            return get_volatility(PricesSeries(window), Frequency.DAILY)

        functions = [tot_return, volatility]
        names = ['Rolling Return', 'Rolling Volatility']
        for func, name in zip(functions, names):
            rolling = strategy.rolling_window(days_rolling, func, step=step)
            rolling_element = DataElementDecorator(rolling)
            chart.add_decorator(rolling_element)
            legend.add_entry(rolling_element, name)

        chart.add_decorator(legend)

        chart.add_decorator(
            AxesFormatterDecorator(y_major=PercentageFormatter(".0f")))

        left, bottom, width, height = self.full_image_axis_position
        position_decorator = AxesPositionDecorator(left, bottom, width, height)
        chart.add_decorator(position_decorator)

        title_decorator = TitleDecorator(
            "Rolling Statistics [6 Months]".format(days_rolling), key="title")
        chart.add_decorator(title_decorator)

        self.document.add_element(
            ChartElement(chart, figsize=self.full_image_size, dpi=self.dpi))
Esempio n. 23
0
    def _get_rolling_ret_and_vol_chart(self, timeseries):
        freq = timeseries.get_frequency()

        rolling_window_len = int(freq.value / 2)  # 6M rolling
        step = round(freq.value / 6)  # 2M shift

        tms = timeseries.to_prices(1)
        chart = LineChart(start_x=tms.index[0], end_x=tms.index[-1])
        line_decorator = HorizontalLineDecorator(0, key="h_line", linewidth=1)
        chart.add_decorator(line_decorator)

        legend = LegendDecorator()

        def tot_return(window):
            return PricesSeries(window).total_cumulative_return()

        def volatility(window):
            return get_volatility(PricesSeries(window), freq)

        functions = [tot_return, volatility]
        names = ['Rolling Return', 'Rolling Volatility']
        for func, name in zip(functions, names):
            rolling = tms.rolling_window(rolling_window_len, func, step=step)
            rolling_element = DataElementDecorator(rolling)
            chart.add_decorator(rolling_element)
            legend.add_entry(rolling_element, name)

        chart.add_decorator(legend)
        chart.add_decorator(
            AxesFormatterDecorator(y_major=PercentageFormatter(".0f")))

        position_decorator = AxesPositionDecorator(
            *self.full_image_axis_position)
        chart.add_decorator(position_decorator)
        title_str = "Rolling Stats [{} {} samples]".format(
            rolling_window_len, freq)

        title_decorator = TitleDecorator(title_str, key="title")
        chart.add_decorator(title_decorator)
        return chart
Esempio n. 24
0
    def regressors_and_explained_variable_chart(self) -> LineChart:
        regressors_df = self.model.input_data.regressors_df
        fund_tms = self.model.input_data.analysed_tms

        chart = LineChart()
        legend = LegendDecorator()

        # add data to the chart and the legend
        marker_props_template = {'alpha': 0.5}
        stemline_props_template = {'linestyle': '-.', 'linewidth': 0.2}
        baseline_props = {'visible': False}

        regressors_and_fund_df = pd.concat([regressors_df, fund_tms], axis=1)
        colors = cycle(Chart.get_axes_colors())

        for ticker, series in regressors_and_fund_df.iteritems():
            marker_props = marker_props_template.copy()
            stemline_props = stemline_props_template.copy()

            color = next(colors)
            marker_props['markeredgecolor'] = color
            marker_props['markerfacecolor'] = color
            stemline_props['color'] = color
            data_elem = StemDecorator(series,
                                      marker_props=marker_props,
                                      stemline_props=stemline_props,
                                      baseline_props=baseline_props)
            chart.add_decorator(data_elem)
            legend.add_entry(data_elem, self._get_security_name(ticker))

        # add decorators to the chart
        chart.add_decorator(TitleDecorator("Returns"))
        chart.add_decorator(AxesLabelDecorator(y_label="return [%]"))
        chart.add_decorator(legend)
        chart.add_decorator(
            AxesFormatterDecorator(y_major=PercentageFormatter()))

        return chart
Esempio n. 25
0
    def _get_rolling_chart(self, timeseries_list, rolling_function,
                           function_name):
        freq = timeseries_list[0].get_frequency()
        timeseries_list = [
            tms.dropna().to_prices(1) for tms in timeseries_list
        ]
        df = pd.concat(timeseries_list, axis=1).fillna(method='ffill')

        rolling_window_len = int(freq.value / 2)  # 6M rolling
        step = round(freq.value / 6)  # 2M shift

        legend = LegendDecorator()

        chart = LineChart(start_x=df.index[0], end_x=df.index[-1])
        line_decorator = HorizontalLineDecorator(0, key="h_line", linewidth=1)
        chart.add_decorator(line_decorator)

        for _, tms in df.iteritems():
            rolling = tms.rolling_window(rolling_window_len,
                                         rolling_function,
                                         step=step)
            rolling_element = DataElementDecorator(rolling)
            chart.add_decorator(rolling_element)
            legend.add_entry(rolling_element, tms.name)

        chart.add_decorator(legend)
        chart.add_decorator(
            AxesFormatterDecorator(y_major=PercentageFormatter(".0f")))

        position_decorator = AxesPositionDecorator(
            *self.full_image_axis_position)
        chart.add_decorator(position_decorator)
        title_str = "{} - Rolling Stats [{} {} samples]".format(
            function_name, rolling_window_len, freq)

        title_decorator = TitleDecorator(title_str, key="title")
        chart.add_decorator(title_decorator)
        return chart
Esempio n. 26
0
    def _get_underwater_chart(self,
                              series: QFSeries,
                              title="Drawdown",
                              benchmark_series: QFSeries = None,
                              rotate_x_axis: bool = False):
        underwater_chart = LineChart(start_x=series.index[0],
                                     end_x=series.index[-1],
                                     log_scale=False,
                                     rotate_x_axis=rotate_x_axis)
        underwater_chart.add_decorator(UnderwaterDecorator(series))
        underwater_chart.add_decorator(TitleDecorator(title))

        if benchmark_series is not None:
            legend = LegendDecorator()
            benchmark_dd = PricesSeries(drawdown_tms(benchmark_series))
            benchmark_dd *= -1
            benchmark_dd_elem = DataElementDecorator(benchmark_dd,
                                                     color="black",
                                                     linewidth=0.5)
            legend.add_entry(benchmark_dd_elem, "Benchmark DD")
            underwater_chart.add_decorator(benchmark_dd_elem)
            underwater_chart.add_decorator(legend)
        return underwater_chart
Esempio n. 27
0
def main():
    # GENERATE DATA
    regressors_and_fund_df = QFDataFrame(data=[[1, 3, 5], [2, 3, 1], [3, 1, 2],
                                               [4, 2, 3], [5, 3, 4]],
                                         index=pd.bdate_range(
                                             start='2015-01-01', periods=5),
                                         columns=['a', 'b', 'c'])

    # add data to the chart and the legend
    marker_props_template = {'alpha': 0.5}
    stemline_props_template = {'linestyle': '-.', 'linewidth': 0.2}
    baseline_props = {'visible': True}

    colors = cycle(Chart.get_axes_colors())
    chart = LineChart(start_x=str_to_date('2014-12-31'),
                      end_x=str_to_date('2015-01-08'))
    legend = LegendDecorator()

    for name, series in regressors_and_fund_df.iteritems():
        marker_props = marker_props_template.copy()
        stemline_props = stemline_props_template.copy()

        color = next(colors)
        marker_props['markeredgecolor'] = color
        marker_props['markerfacecolor'] = color
        stemline_props['color'] = color
        data_elem = StemDecorator(series,
                                  marker_props=marker_props,
                                  stemline_props=stemline_props,
                                  baseline_props=baseline_props)
        chart.add_decorator(data_elem)
        legend.add_entry(data_elem, name)

    chart.add_decorator(legend)
    chart.plot()

    plt.show(block=True)
Esempio n. 28
0
    def _get_simulation_plot(self, scenarios_df: PricesDataFrame) -> Chart:
        chart = LineChart(log_scale=True)

        for _, scenario in scenarios_df.items():
            data_element = DataElementDecorator(scenario, linewidth=0.5)
            chart.add_decorator(data_element)

        # Add a legend
        legend = LegendDecorator(key="legend_decorator")

        # Add Ensemble average
        ensemble_avg = scenarios_df.mean(axis=1)
        ensemble_avg_data_element = DataElementDecorator(ensemble_avg, color="#e1e5f4", linewidth=3)
        chart.add_decorator(ensemble_avg_data_element)
        legend.add_entry(ensemble_avg_data_element, "Ensemble average")

        # Add Expectation (vol adjusted)
        trade_returns = QFSeries(data=[trade.percentage_pnl for trade in self.trades])
        std = trade_returns.std()
        expectation_adj_series = np.ones(len(ensemble_avg)) * (trade_returns.mean() - 0.5 * std * std)
        expectation_adj_series = SimpleReturnsSeries(data=expectation_adj_series, index=ensemble_avg.index)
        expectation_adj_series = expectation_adj_series.to_prices()

        data_element = DataElementDecorator(expectation_adj_series, color="#46474b", linewidth=2)
        chart.add_decorator(data_element)
        legend.add_entry(data_element, "Expectation (vol adjusted)")

        # Add title
        title_decorator = TitleDecorator("Monte Carlo Simulations (log scale)", key="title")
        chart.add_decorator(title_decorator)

        position_decorator = AxesPositionDecorator(*self.full_image_axis_position)
        chart.add_decorator(position_decorator)

        chart.add_decorator(legend)

        return chart
Esempio n. 29
0
    def _get_rolling_chart(self, timeseries_list, rolling_function,
                           function_name):
        days_rolling = int(BUSINESS_DAYS_PER_YEAR / 2)  # 6M rolling
        step = round(days_rolling / 5)

        legend = LegendDecorator()
        chart = None

        for i, tms in enumerate(timeseries_list):
            if i == 0:
                chart = LineChart(start_x=tms.index[0], end_x=tms.index[-1])
                line_decorator = HorizontalLineDecorator(0,
                                                         key="h_line",
                                                         linewidth=1)
                chart.add_decorator(line_decorator)

            tms = tms.to_prices(1)
            rolling = tms.rolling_window(days_rolling,
                                         rolling_function,
                                         step=step)
            rolling_element = DataElementDecorator(rolling)
            chart.add_decorator(rolling_element)
            legend.add_entry(rolling_element, tms.name)

        chart.add_decorator(legend)
        chart.add_decorator(
            AxesFormatterDecorator(y_major=PercentageFormatter(".0f")))

        position_decorator = AxesPositionDecorator(
            *self.full_image_axis_position)
        chart.add_decorator(position_decorator)
        title_str = "{} - Rolling Stats [{} days]".format(
            function_name, days_rolling)

        title_decorator = TitleDecorator(title_str, key="title")
        chart.add_decorator(title_decorator)
        return chart
Esempio n. 30
0
    def _add_relative_performance_chart(
            self,
            strategy_tms: QFSeries,
            benchmark_tms: QFSeries,
            chart_title: str = "Relative Performance",
            legend_subtitle: str = "Strategy - Benchmark"):
        diff = strategy_tms.to_simple_returns().subtract(
            benchmark_tms.to_simple_returns(), fill_value=0)
        diff = diff.to_prices(1) - 1

        chart = LineChart(start_x=diff.index[0],
                          end_x=diff.index[-1],
                          log_scale=False)
        position_decorator = AxesPositionDecorator(
            *self.full_image_axis_position)
        chart.add_decorator(position_decorator)

        line_decorator = HorizontalLineDecorator(0, key="h_line", linewidth=1)
        chart.add_decorator(line_decorator)
        legend = LegendDecorator()

        series_elem = DataElementDecorator(diff)
        chart.add_decorator(series_elem)
        legend.add_entry(series_elem, legend_subtitle)

        chart.add_decorator(legend)
        title_decorator = TitleDecorator(chart_title, key="title")
        chart.add_decorator(title_decorator)

        chart.add_decorator(
            AxesFormatterDecorator(y_major=PercentageFormatter(".0f")))

        fill_decorator = FillBetweenDecorator(diff)
        chart.add_decorator(fill_decorator)
        self.document.add_element(
            ChartElement(chart, figsize=self.full_image_size, dpi=self.dpi))