def run_strategy(self,
                     cash=1000,
                     commission=0.0004,
                     tf=bt.TimeFrame.Minutes,
                     compression=60):
        cerebro = bt.Cerebro()
        cerebro.broker.setcommission(commission=commission)
        cerebro.broker.setcash(cash)

        data = FinamHLOC(dataname=self.file_data,
                         timeframe=tf,
                         compression=compression)

        cerebro.addanalyzer(bt.analyzers.TimeReturn, _name='returns')
        cerebro.adddata(data)
        cerebro.addstrategy(
            TrendBreakerPL,
            pivot_window_len=self.algo_params['pivot_window_len'],
            history_bars_as_multiple_pwl=self.
            algo_params['history_bars_as_multiple_pwl'],
            fixed_tp=self.algo_params['fixed_tp'],
            fixed_sl_as_multiple_tp=self.
            algo_params['fixed_sl_as_multiple_tp'],
            order_full=self.output_settings['order_full'],
            order_status=self.output_settings['order_status'],
            trades=self.output_settings['trades'])

        if self.output_settings['performance']:
            print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
        strats = cerebro.run()
        first_strat = strats[0]

        if self.output_settings['performance']:
            print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())

        od_returns = first_strat.analyzers.getbyname('returns').get_analysis()
        df_returns = pd.DataFrame(od_returns.items(),
                                  columns=['date', 'return'])
        df_returns = df_returns.set_index('date')

        self.stability = self.stability_of_timeseries(df_returns['return'])

        if self.output_settings['performance']:
            print('Performance:')
            print('Return: ' +
                  str((cerebro.broker.getvalue() - cash) / cash * 100) + '%')
            print('Stability:' + str(self.stability))
            print('Top-5 Drawdowns:')
            print(pf.show_worst_drawdown_periods(df_returns['return'], top=5))

        if self.output_settings['plot']:
            # Read Close prices from csv and calculate the returns as a benchmark
            capital_algo = np.cumprod(1.0 + df_returns['return']) * cash
            benchmark_df = pd.read_csv(self.file_data)
            benchmark_returns = benchmark_df['<CLOSE>'].pct_change()
            capital_benchmark = np.cumprod(1.0 + benchmark_returns) * cash
            df_returns['benchmark_return'] = benchmark_returns

            # Plot Capital Curves
            plt.figure(figsize=(12, 7))
            plt.plot(np.array(capital_algo), color='blue')
            plt.plot(np.array(capital_benchmark), color='red')
            plt.legend(['Algorithm', 'Buy & Hold'])
            plt.title('Capital Curve')
            plt.xlabel('Time')
            plt.ylabel('Value')
            plt.show()

            # Plot Drawdown Underwater
            plt.figure(figsize=(12, 7))
            pf.plot_drawdown_underwater(
                df_returns['return']).set_xlabel('Time')
            plt.show()

            # Plot Top-5 Drawdowns
            plt.figure(figsize=(12, 7))
            pf.plot_drawdown_periods(df_returns['return'],
                                     top=5).set_xlabel('Time')
            plt.show()

            # Plot Simple Returns
            plt.figure(figsize=(12, 7))
            plt.plot(df_returns['return'], 'blue')
            plt.title('Returns')
            plt.xlabel('Time')
            plt.ylabel('Return')
            plt.show()

            # Plot Return Quantiles by Timeframe
            plt.figure(figsize=(12, 7))
            pf.plot_return_quantiles(
                df_returns['return']).set_xlabel('Timeframe')
            plt.show()

            # Plot Monthly Returns Dist
            plt.figure(figsize=(12, 7))
            pf.plot_monthly_returns_dist(
                df_returns['return']).set_xlabel('Returns')
            plt.show()
Пример #2
0
def underwater_plot(returns):
    fig = plt.figure(facecolor='white')
    ax = pf.plot_drawdown_underwater(returns)
    plt.savefig('underwater_plot.png')
 df_backtest['Costs'] = abs(df_backtest['Signals'] - df_backtest['Signals'].shift(1))*0.0001
 df_backtest['Strategy_forward_ret'] = df_backtest['Forward_ret'] *df_backtest['Signals']-df_backtest['Costs']
 
 bt_returns = df_backtest['Strategy_forward_ret']
 
 plt.figure(figsize=(10, 8), dpi= 50)
 # Cumulative Returns
 pf.plotting.plot_rolling_returns(bt_returns,live_start_date = df_test.index[0])
 plt.show()
 
 # Daily, Non-Cumulative Returns
 plt.figure(figsize=(10, 8), dpi= 50)
 pf.plot_rolling_sharpe(bt_returns)
 plt.tight_layout()
 plt.show()
 
 plt.figure(figsize=(10, 8), dpi= 50)
 pf.plot_drawdown_underwater(bt_returns);
 plt.show()
     
 fig = plt.figure(1)
 plt.subplot(1,3,1)
 pf.plot_annual_returns(bt_returns)
 plt.subplot(1,3,2)
 pf.plot_monthly_returns_dist(bt_returns)
 plt.subplot(1,3,3)
 pf.plot_monthly_returns_heatmap(bt_returns)
 plt.tight_layout()
 fig.set_size_inches(15,5)
 
 pf.create_interesting_times_tear_sheet(bt_returns)
Пример #4
0
def show_result(daily_return, period, benchmark_daily_return, benchmark_title):
    """
    plot from daily return of strategy and benchmark

    input
    ---------------------------
    daily_return: daily return of strategy
    benchmark_daily_return: daily return of benchmark
    benchmark_title: title of benchmark

    output
    ---------------------------
    return: None
    """
    daily_return.dropna(inplace=True)
    benchmark_daily_return.dropna(inplace=True)
    sharpe_ratio, max_drawdown, annual_return, _, total_return = utils.metrics(
        daily_return, period=period)
    bench_sharpe, bench_max_drawdown, bench_annual_return, _, bench_total_return = utils.metrics(
        benchmark_daily_return)
    metrics_dict = {
        "sharpe": sharpe_ratio,
        "max_drawdown": max_drawdown,
        "annual_return": annual_return,
        "total_return": total_return,
        "benchmark_sharpe": bench_sharpe,
        "benchmark_max_drawdown": bench_max_drawdown,
        "benchmark_annual_return": bench_annual_return,
        "benchmark_total_return": bench_total_return
    }

    font_size = 15
    value_font_size = 12
    label_height, value_height = 0.8, 0.6
    label_height2, value_height2 = 0.35, 0.15
    red = "#aa4643"
    blue = "#4572a7"
    black = "#000000"

    fig_data = [
        (0.00, label_height, value_height, "Total Returns",
         "{0:.3%}".format(metrics_dict["total_return"]), red, black),
        (0.00, label_height2, value_height2, "Benchmark Total",
         "{0:.3%}".format(metrics_dict["benchmark_total_return"]), blue,
         black),
        (0.25, label_height, value_height, "Annual Returns",
         "{0:.3%}".format(metrics_dict["annual_return"]), red, black),
        (0.25, label_height2, value_height2, "Benchmark Annual",
         "{0:.3%}".format(metrics_dict["benchmark_annual_return"]), blue,
         black),
        (0.50, label_height, value_height, "Sharpe",
         "{0:.4}".format(metrics_dict["sharpe"]), red, black),
        (0.50, label_height2, value_height2, "Benchmark Sharpe",
         "{0:.4}".format(metrics_dict["benchmark_sharpe"]), blue, black),
        (0.75, label_height, value_height, "MaxDrawdown",
         "{0:.4}".format(metrics_dict["max_drawdown"]), red, black),
        (0.75, label_height2, value_height2, "Benchmark MaxDrawdown",
         "{0:.4}".format(metrics_dict["benchmark_max_drawdown"]), blue, black),
    ]

    f, (ax1, ax2, ax3) = plt.subplots(3, figsize=(12, 8))
    ax1.axis('off')
    for x, y1, y2, label, value, label_color, value_color in fig_data:
        ax1.text(x, y1, label, color=label_color, fontsize=font_size)
        ax1.text(x, y2, value, color=value_color, fontsize=value_font_size)
    ax2.set_title("Net value")
    ax2.set_xticklabels('')
    ax2.plot((1 + benchmark_daily_return).index,
             (1 + benchmark_daily_return).cumprod(),
             label=benchmark_title)
    ax2.plot((1 + daily_return).index, (1 + daily_return).cumprod(),
             label='Net value')
    ax2.legend()
    ax3 = pf.plot_drawdown_underwater(daily_return)
    plt.show()
Пример #5
0
############################
pf.plot_return_quantiles(backtest_returns)

############################
#        Rolling Plot      #
#      frequency = M/Y     #
#            BETA          #
############################
pf.plot_rolling_beta(backtest_returns, benchmark_returns)

############################
#        Rolling Plot      #
#      frequency = M/Y     #
#        SHARPE RATIO      #
############################
pf.plot_rolling_sharpe(backtest_returns)

############################
#  Top 10 Drawdown Periods #
#      frequency = M/Y     #
############################
pf.plot_drawdown_periods(backtest_returns)

############################
#      UnderWater Plot     #
#      Drawdown Periods    #
#      frequency = M/Y     #
#      in values of = %    #
############################
pf.plot_drawdown_underwater(backtest_returns)
Пример #6
0
#  E. Summary Statistics on performance of strategy
xtickrange = pd.date_range(allcumReturns.index[0], end, freq="Q")
ytickrange = np.arange(0.75, 1.85, 0.1)
ax = allcumReturns.plot(title="Pure and Blended Strategy vs Benchmarks")
ax.set(xlabel="Date",
       ylabel="Cumulative Return",
       xticks=xtickrange,
       yticks=ytickrange)
ax.yaxis.grid(True)
legend = ax.legend(loc="lower right")
plt.savefig('Pure and Blended Strategy vs Benchmarks.png', bbox_inches='tight')
plt.close()

# Drawdown Charts
ax1 = pf.plot_drawdown_underwater(benchReturns['Port'])
ax1.set(title="Strategy portfolio Drawdowns",
        xlabel="Date",
        ylabel="Percentage Down from Peak",
        xticks=xtickrange)
plt.savefig('Strategy Drawdowns.png', bbox_inches='tight')
plt.close()

ax2 = pf.plot_drawdown_underwater(benchReturns['50/50 SPY Port'])
ax2.set(title="Blended portfolio Drawdowns",
        xlabel="Date",
        ylabel="Percentage Down from Peak",
        xticks=xtickrange)
plt.savefig('Blended Drawdowns.png', bbox_inches='tight')
plt.close()
Пример #7
0
def plot_performance(
    returns, 
    benchmark_prices,
    plot_stats=False,
    startcash=None,
    log_returns=False,
    save_dir=None
):
    """
    :param returns: pd.Series, return data
    :param benchmark_prices: pd.Series, benchmark return data
    :param startcash: int, rebase the benchmark if provided
    :return: None
    """
    if save_dir and not os.path.exists(save_dir):
        os.makedirs(save_dir)
    
    # Rebase benchmark prices, the same as portfolio prices
    if startcash is not None:
        benchmark_prices = (benchmark_prices / benchmark_prices.iloc[0]) * startcash
    benchmark_rets = pyp.expected_returns.returns_from_prices(benchmark_prices)

    if log_returns:
        portfolio_value = returns.cumsum().apply(np.exp) * startcash
    else:
        portfolio_value = (1 + returns).cumprod() * startcash

    # Performance statistics
    if plot_stats:
        pf.show_perf_stats(returns)
        pf.show_perf_stats(benchmark_rets)
    
    # Fig 1: price and return
    fig, ax = plt.subplots(2, 1, sharex=True, figsize=[14, 8])
    portfolio_value.plot(ax=ax[0], label='Portfolio')
    benchmark_prices.plot(ax=ax[0], label='Benchmark')
    ax[0].set_ylabel('Price')
    ax[0].grid(True)
    ax[0].legend()
    
    returns.plot(ax=ax[1], label='Portfolio', alpha=0.5)
    benchmark_rets.plot(ax=ax[1], label='Benchmark', alpha=0.5)
    ax[1].set_ylabel('Return')

    fig.suptitle('Black–Litterman Portfolio Optimization', fontsize=16)
    plt.grid(True)
    plt.legend()
    plt.show()
    if save_dir:
        fig.savefig(os.path.join(save_dir, 'price_and_return'), dpi=300)

    # Fig 2: return performance
    fig, ax = plt.subplots(nrows=2, ncols=2, figsize=(16, 9), constrained_layout=False)
    axes = ax.flatten()
    pf.plot_rolling_beta(returns=returns, factor_returns=benchmark_rets, ax=axes[0])
    pf.plot_return_quantiles(returns=returns, ax=axes[1])
    pf.plot_annual_returns(returns=returns, ax=axes[2])
    pf.plot_monthly_returns_heatmap(returns=returns, ax=axes[3])
    axes[0].grid(True)
    axes[1].grid(True)
    axes[2].grid(True)
    fig.suptitle('Return performance', fontsize=16, y=1.0)
    plt.tight_layout()
    if save_dir:
        fig.savefig(os.path.join(save_dir, 'return_performance'), dpi=300)
        
    # Fig 3: risk performance
    fig, ax = plt.subplots(nrows=2, ncols=2, figsize=(14, 8), constrained_layout=False)
    axes = ax.flatten()
    pf.plot_drawdown_periods(returns=returns, ax=axes[0])
    pf.plot_rolling_volatility(returns=returns, factor_returns=benchmark_rets, ax=axes[1])
    pf.plot_drawdown_underwater(returns=returns, ax=axes[2])
    pf.plot_rolling_sharpe(returns=returns, ax=axes[3])
    axes[0].grid(True)
    axes[1].grid(True)
    axes[2].grid(True)
    axes[3].grid(True)
    fig.suptitle('Risk performance', fontsize=16, y=1.0)
    plt.tight_layout()
    if save_dir:
        fig.savefig(os.path.join(save_dir, 'risk_performance'), dpi=300)