def setup_optimize_configuration(args: Dict[str, Any],
                                 method: RunMode) -> Dict[str, Any]:
    """
    Prepare the configuration for the Hyperopt module
    :param args: Cli args from Arguments()
    :param method: Bot running mode
    :return: Configuration
    """
    config = setup_utils_configuration(args, method)

    no_unlimited_runmodes = {
        RunMode.BACKTEST: 'backtesting',
        RunMode.HYPEROPT: 'hyperoptimization',
    }
    if method in no_unlimited_runmodes.keys():
        if (config['stake_amount'] != constants.UNLIMITED_STAKE_AMOUNT
                and config['stake_amount'] > config['dry_run_wallet']):
            wallet = round_coin_value(config['dry_run_wallet'],
                                      config['stake_currency'])
            stake = round_coin_value(config['stake_amount'],
                                     config['stake_currency'])
            raise OperationalException(
                f"Starting balance ({wallet}) "
                f"is smaller than stake_amount {stake}.")

    return config
Beispiel #2
0
def text_table_add_metrics(strat_results: Dict) -> str:
    if len(strat_results['trades']) > 0:
        best_trade = max(strat_results['trades'],
                         key=lambda x: x['profit_ratio'])
        worst_trade = min(strat_results['trades'],
                          key=lambda x: x['profit_ratio'])
        metrics = [
            ('Backtesting from',
             strat_results['backtest_start'].strftime(DATETIME_PRINT_FORMAT)),
            ('Backtesting to',
             strat_results['backtest_end'].strftime(DATETIME_PRINT_FORMAT)),
            ('Max open trades', strat_results['max_open_trades']),
            ('', ''),  # Empty line to improve readability
            ('Total trades', strat_results['total_trades']),
            ('Total Profit %',
             f"{round(strat_results['profit_total'] * 100, 2)}%"),
            ('Trades per day', strat_results['trades_per_day']),
            ('', ''),  # Empty line to improve readability
            ('Best Pair', f"{strat_results['best_pair']['key']} "
             f"{round(strat_results['best_pair']['profit_sum_pct'], 2)}%"),
            ('Worst Pair', f"{strat_results['worst_pair']['key']} "
             f"{round(strat_results['worst_pair']['profit_sum_pct'], 2)}%"),
            ('Best trade',
             f"{best_trade['pair']} {round(best_trade['profit_ratio'] * 100, 2)}%"
             ),
            ('Worst trade', f"{worst_trade['pair']} "
             f"{round(worst_trade['profit_ratio'] * 100, 2)}%"),
            ('Best day',
             f"{round(strat_results['backtest_best_day'] * 100, 2)}%"),
            ('Worst day',
             f"{round(strat_results['backtest_worst_day'] * 100, 2)}%"),
            ('Days win/draw/lose', f"{strat_results['winning_days']} / "
             f"{strat_results['draw_days']} / {strat_results['losing_days']}"),
            ('Avg. Duration Winners',
             f"{strat_results['winner_holding_avg']}"),
            ('Avg. Duration Loser', f"{strat_results['loser_holding_avg']}"),
            ('', ''),  # Empty line to improve readability
            ('Abs Profit Min',
             round_coin_value(strat_results['csum_min'],
                              strat_results['stake_currency'])),
            ('Abs Profit Max',
             round_coin_value(strat_results['csum_max'],
                              strat_results['stake_currency'])),
            ('Max Drawdown',
             f"{round(strat_results['max_drawdown'] * 100, 2)}%"),
            ('Drawdown Start',
             strat_results['drawdown_start'].strftime(DATETIME_PRINT_FORMAT)),
            ('Drawdown End',
             strat_results['drawdown_end'].strftime(DATETIME_PRINT_FORMAT)),
            ('Market change',
             f"{round(strat_results['market_change'] * 100, 2)}%"),
        ]

        return tabulate(metrics,
                        headers=["Metric", "Value"],
                        tablefmt="orgtbl")
    else:
        return ''
Beispiel #3
0
def test_round_coin_value():
    assert round_coin_value(222.222222, 'USDT') == '222.222 USDT'
    assert round_coin_value(222.2, 'USDT') == '222.200 USDT'
    assert round_coin_value(222.12745, 'EUR') == '222.127 EUR'
    assert round_coin_value(0.1274512123, 'BTC') == '0.12745121 BTC'
    assert round_coin_value(0.1274512123, 'ETH') == '0.12745 ETH'

    assert round_coin_value(222.222222, 'USDT', False) == '222.222'
    assert round_coin_value(222.2, 'USDT', False) == '222.200'
    assert round_coin_value(222.12745, 'EUR', False) == '222.127'
    assert round_coin_value(0.1274512123, 'BTC', False) == '0.12745121'
    assert round_coin_value(0.1274512123, 'ETH', False) == '0.12745'
def text_table_periodic_breakdown(days_breakdown_stats: List[Dict[str, Any]],
                                  stake_currency: str, period: str) -> str:
    """
    Generate small table with Backtest results by days
    :param days_breakdown_stats: Days breakdown metrics
    :param stake_currency: Stakecurrency used
    :return: pretty printed table with tabulate as string
    """
    headers = [
        period.capitalize(),
        f'Tot Profit {stake_currency}',
        'Wins',
        'Draws',
        'Losses',
    ]
    output = [[
        d['date'],
        round_coin_value(d['profit_abs'], stake_currency, False),
        d['wins'],
        d['draws'],
        d['loses'],
    ] for d in days_breakdown_stats]
    return tabulate(output,
                    headers=headers,
                    tablefmt="orgtbl",
                    stralign="right")
def text_table_exit_reason(exit_reason_stats: List[Dict[str, Any]],
                           stake_currency: str) -> str:
    """
    Generate small table outlining Backtest results
    :param sell_reason_stats: Exit reason metrics
    :param stake_currency: Stakecurrency used
    :return: pretty printed table with tabulate as string
    """
    headers = [
        'Exit Reason',
        'Exits',
        'Win  Draws  Loss  Win%',
        'Avg Profit %',
        'Cum Profit %',
        f'Tot Profit {stake_currency}',
        'Tot Profit %',
    ]

    output = [[
        t.get('exit_reason', t.get('sell_reason')),
        t['trades'],
        _generate_wins_draws_losses(t['wins'], t['draws'], t['losses']),
        t['profit_mean_pct'],
        t['profit_sum_pct'],
        round_coin_value(t['profit_total_abs'], stake_currency, False),
        t['profit_total_pct'],
    ] for t in exit_reason_stats]
    return tabulate(output,
                    headers=headers,
                    tablefmt="orgtbl",
                    stralign="right")
Beispiel #6
0
def generate_strategy_comparison(all_results: Dict) -> List[Dict]:
    """
    Generate summary per strategy
    :param all_results: Dict of <Strategyname: DataFrame> containing results for all strategies
    :return: List of Dicts containing the metrics per Strategy
    """

    tabular_data = []
    for strategy, results in all_results.items():
        tabular_data.append(
            _generate_result_line(results['results'],
                                  results['config']['dry_run_wallet'],
                                  strategy))
        try:
            max_drawdown_per, _, _, _, _ = calculate_max_drawdown(
                results['results'], value_col='profit_ratio')
            max_drawdown_abs, _, _, _, _ = calculate_max_drawdown(
                results['results'], value_col='profit_abs')
        except ValueError:
            max_drawdown_per = 0
            max_drawdown_abs = 0
        tabular_data[-1]['max_drawdown_per'] = round(max_drawdown_per * 100, 2)
        tabular_data[-1]['max_drawdown_abs'] = \
            round_coin_value(max_drawdown_abs, results['config']['stake_currency'], False)
    return tabular_data
def text_table_sell_reason(sell_reason_stats: List[Dict[str, Any]],
                           stake_currency: str) -> str:
    """
    Generate small table outlining Backtest results
    :param sell_reason_stats: Sell reason metrics
    :param stake_currency: Stakecurrency used
    :return: pretty printed table with tabulate as string
    """
    headers = [
        'Sell Reason',
        'Sells',
        'Wins',
        'Draws',
        'Losses',
        'Avg Profit %',
        f'Tot Profit {stake_currency}',
        'Tot Profit %',
    ]

    output = [[
        t['sell_reason'],
        t['trades'],
        t['wins'],
        t['draws'],
        t['losses'],
        t['profit_mean_pct'],
        round_coin_value(t['profit_total_abs'], stake_currency, False),
        t['profit_total_pct'],
    ] for t in sell_reason_stats]
    return tabulate(output,
                    headers=headers,
                    tablefmt="orgtbl",
                    stralign="right")
def generate_strategy_comparison(bt_stats: Dict) -> List[Dict]:
    """
    Generate summary per strategy
    :param bt_stats: Dict of <Strategyname: DataFrame> containing results for all strategies
    :return: List of Dicts containing the metrics per Strategy
    """

    tabular_data = []
    for strategy, result in bt_stats.items():
        tabular_data.append(deepcopy(result['results_per_pair'][-1]))
        # Update "key" to strategy (results_per_pair has it as "Total").
        tabular_data[-1]['key'] = strategy
        tabular_data[-1]['max_drawdown_account'] = result[
            'max_drawdown_account']
        tabular_data[-1]['max_drawdown_abs'] = round_coin_value(
            result['max_drawdown_abs'], result['stake_currency'], False)
    return tabular_data
Beispiel #9
0
    def get_result_table(config: dict, results: list, total_epochs: int,
                         highlight_best: bool, print_colorized: bool,
                         remove_header: int) -> str:
        """
        Log result table
        """
        if not results:
            return ''

        tabulate.PRESERVE_WHITESPACE = True
        trials = json_normalize(results, max_level=1)

        legacy_mode = 'results_metrics.total_trades' not in trials
        has_drawdown = 'results_metrics.max_drawdown_abs' in trials.columns

        trials = HyperoptTools.prepare_trials_columns(trials, legacy_mode,
                                                      has_drawdown)

        trials['is_profit'] = False
        trials.loc[trials['is_initial_point'], 'Best'] = '*     '
        trials.loc[trials['is_best'], 'Best'] = 'Best'
        trials.loc[trials['is_initial_point'] & trials['is_best'],
                   'Best'] = '* Best'
        trials.loc[trials['Total profit'] > 0, 'is_profit'] = True
        trials['Trades'] = trials['Trades'].astype(str)
        perc_multi = 1 if legacy_mode else 100
        trials['Epoch'] = trials['Epoch'].apply(lambda x: '{}/{}'.format(
            str(x).rjust(len(str(total_epochs)), ' '), total_epochs))
        trials['Avg profit'] = trials['Avg profit'].apply(
            lambda x: f'{x * perc_multi:,.2f}%'.rjust(7, ' ')
            if not isna(x) else "--".rjust(7, ' '))
        trials['Avg duration'] = trials['Avg duration'].apply(
            lambda x: f'{x:,.1f} m'.rjust(7, ' ') if isinstance(
                x, float) else f"{x}" if not isna(x) else "--".rjust(7, ' '))
        trials['Objective'] = trials['Objective'].apply(
            lambda x: f'{x:,.5f}'.rjust(8, ' ')
            if x != 100000 else "N/A".rjust(8, ' '))

        stake_currency = config['stake_currency']

        if has_drawdown:
            trials['Max Drawdown'] = trials.apply(
                lambda x: '{} {}'.format(
                    round_coin_value(x['max_drawdown_abs'], stake_currency),
                    '({:,.2f}%)'.format(x['Max Drawdown'] * perc_multi).rjust(
                        10, ' ')).rjust(25 + len(stake_currency))
                if x['Max Drawdown'] != 0.0 else '--'.rjust(25 + len(
                    stake_currency)),
                axis=1)
        else:
            trials = trials.drop(columns=['Max Drawdown'])

        trials = trials.drop(columns=['max_drawdown_abs'])

        trials['Profit'] = trials.apply(lambda x: '{} {}'.format(
            round_coin_value(x['Total profit'], stake_currency), '({:,.2f}%)'.
            format(x['Profit'] * perc_multi).rjust(10, ' ')).rjust(25 + len(
                stake_currency)) if x['Total profit'] != 0.0 else '--'.rjust(
                    25 + len(stake_currency)),
                                        axis=1)
        trials = trials.drop(columns=['Total profit'])

        if print_colorized:
            for i in range(len(trials)):
                if trials.loc[i]['is_profit']:
                    for j in range(len(trials.loc[i]) - 3):
                        trials.iat[i, j] = "{}{}{}".format(
                            Fore.GREEN, str(trials.loc[i][j]), Fore.RESET)
                if trials.loc[i]['is_best'] and highlight_best:
                    for j in range(len(trials.loc[i]) - 3):
                        trials.iat[i, j] = "{}{}{}".format(
                            Style.BRIGHT, str(trials.loc[i][j]),
                            Style.RESET_ALL)

        trials = trials.drop(
            columns=['is_initial_point', 'is_best', 'is_profit'])
        if remove_header > 0:
            table = tabulate.tabulate(trials.to_dict(orient='list'),
                                      tablefmt='orgtbl',
                                      headers='keys',
                                      stralign="right")

            table = table.split("\n", remove_header)[remove_header]
        elif remove_header < 0:
            table = tabulate.tabulate(trials.to_dict(orient='list'),
                                      tablefmt='psql',
                                      headers='keys',
                                      stralign="right")
            table = "\n".join(table.split("\n")[0:remove_header])
        else:
            table = tabulate.tabulate(trials.to_dict(orient='list'),
                                      tablefmt='psql',
                                      headers='keys',
                                      stralign="right")
        return table
def text_table_add_metrics(strat_results: Dict) -> str:
    if len(strat_results['trades']) > 0:
        best_trade = max(strat_results['trades'],
                         key=lambda x: x['profit_ratio'])
        worst_trade = min(strat_results['trades'],
                          key=lambda x: x['profit_ratio'])

        short_metrics = [
            ('', ''),  # Empty line to improve readability
            ('Long / Short',
             f"{strat_results.get('trade_count_long', 'total_trades')} / "
             f"{strat_results.get('trade_count_short', 0)}"),
            ('Total profit Long %',
             f"{strat_results['profit_total_long']:.2%}"),
            ('Total profit Short %',
             f"{strat_results['profit_total_short']:.2%}"),
            ('Absolute profit Long',
             round_coin_value(strat_results['profit_total_long_abs'],
                              strat_results['stake_currency'])),
            ('Absolute profit Short',
             round_coin_value(strat_results['profit_total_short_abs'],
                              strat_results['stake_currency'])),
        ] if strat_results.get('trade_count_short', 0) > 0 else []

        # Newly added fields should be ignored if they are missing in strat_results. hyperopt-show
        # command stores these results and newer version of freqtrade must be able to handle old
        # results with missing new fields.
        metrics = [
            ('Backtesting from', strat_results['backtest_start']),
            ('Backtesting to', strat_results['backtest_end']),
            ('Max open trades', strat_results['max_open_trades']),
            ('', ''),  # Empty line to improve readability
            ('Total/Daily Avg Trades',
             f"{strat_results['total_trades']} / {strat_results['trades_per_day']}"
             ),
            ('Starting balance',
             round_coin_value(strat_results['starting_balance'],
                              strat_results['stake_currency'])),
            ('Final balance',
             round_coin_value(strat_results['final_balance'],
                              strat_results['stake_currency'])),
            ('Absolute profit ',
             round_coin_value(strat_results['profit_total_abs'],
                              strat_results['stake_currency'])),
            ('Total profit %', f"{strat_results['profit_total']:.2%}"),
            ('Trades per day', strat_results['trades_per_day']),
            ('Avg. daily profit %',
             f"{(strat_results['profit_total'] / strat_results['backtest_days']):.2%}"
             ),
            ('Avg. stake amount',
             round_coin_value(strat_results['avg_stake_amount'],
                              strat_results['stake_currency'])),
            ('Total trade volume',
             round_coin_value(strat_results['total_volume'],
                              strat_results['stake_currency'])),
            *short_metrics,
            ('', ''),  # Empty line to improve readability
            ('Best Pair', f"{strat_results['best_pair']['key']} "
             f"{strat_results['best_pair']['profit_sum']:.2%}"),
            ('Worst Pair', f"{strat_results['worst_pair']['key']} "
             f"{strat_results['worst_pair']['profit_sum']:.2%}"),
            ('Best trade',
             f"{best_trade['pair']} {best_trade['profit_ratio']:.2%}"),
            ('Worst trade', f"{worst_trade['pair']} "
             f"{worst_trade['profit_ratio']:.2%}"),
            ('Best day',
             round_coin_value(strat_results['backtest_best_day_abs'],
                              strat_results['stake_currency'])),
            ('Worst day',
             round_coin_value(strat_results['backtest_worst_day_abs'],
                              strat_results['stake_currency'])),
            ('Days win/draw/lose', f"{strat_results['winning_days']} / "
             f"{strat_results['draw_days']} / {strat_results['losing_days']}"),
            ('Avg. Duration Winners',
             f"{strat_results['winner_holding_avg']}"),
            ('Avg. Duration Loser', f"{strat_results['loser_holding_avg']}"),
            ('Rejected Entry signals',
             strat_results.get('rejected_signals', 'N/A')),
            ('Entry/Exit Timeouts',
             f"{strat_results.get('timedout_entry_orders', 'N/A')} / "
             f"{strat_results.get('timedout_exit_orders', 'N/A')}"),
            ('', ''),  # Empty line to improve readability
            ('Min balance',
             round_coin_value(strat_results['csum_min'],
                              strat_results['stake_currency'])),
            ('Max balance',
             round_coin_value(strat_results['csum_max'],
                              strat_results['stake_currency'])),

            # Compatibility to show old hyperopt results
            ('Drawdown (Account)',
             f"{strat_results['max_drawdown_account']:.2%}")
            if 'max_drawdown_account' in strat_results else
            ('Drawdown', f"{strat_results['max_drawdown']:.2%}"),
            ('Drawdown',
             round_coin_value(strat_results['max_drawdown_abs'],
                              strat_results['stake_currency'])),
            ('Drawdown high',
             round_coin_value(strat_results['max_drawdown_high'],
                              strat_results['stake_currency'])),
            ('Drawdown low',
             round_coin_value(strat_results['max_drawdown_low'],
                              strat_results['stake_currency'])),
            ('Drawdown Start', strat_results['drawdown_start']),
            ('Drawdown End', strat_results['drawdown_end']),
            ('Market change', f"{strat_results['market_change']:.2%}"),
        ]

        return tabulate(metrics,
                        headers=["Metric", "Value"],
                        tablefmt="orgtbl")
    else:
        start_balance = round_coin_value(strat_results['starting_balance'],
                                         strat_results['stake_currency'])
        stake_amount = round_coin_value(
            strat_results['stake_amount'],
            strat_results['stake_currency']) if strat_results[
                'stake_amount'] != UNLIMITED_STAKE_AMOUNT else 'unlimited'

        message = ("No trades made. "
                   f"Your starting balance was {start_balance}, "
                   f"and your stake was {stake_amount}.")
        return message
def text_table_add_metrics(strat_results: Dict) -> str:
    if len(strat_results['trades']) > 0:
        best_trade = max(strat_results['trades'],
                         key=lambda x: x['profit_ratio'])
        worst_trade = min(strat_results['trades'],
                          key=lambda x: x['profit_ratio'])
        metrics = [
            ('Backtesting from',
             strat_results['backtest_start'].strftime(DATETIME_PRINT_FORMAT)),
            ('Backtesting to',
             strat_results['backtest_end'].strftime(DATETIME_PRINT_FORMAT)),
            ('Max open trades', strat_results['max_open_trades']),
            ('', ''),  # Empty line to improve readability
            ('Total trades', strat_results['total_trades']),
            ('Starting balance',
             round_coin_value(strat_results['starting_balance'],
                              strat_results['stake_currency'])),
            ('Final balance',
             round_coin_value(strat_results['final_balance'],
                              strat_results['stake_currency'])),
            ('Absolute profit ',
             round_coin_value(strat_results['profit_total_abs'],
                              strat_results['stake_currency'])),
            ('Total profit %',
             f"{round(strat_results['profit_total'] * 100, 2)}%"),
            ('Trades per day', strat_results['trades_per_day']),
            ('Avg. stake amount',
             round_coin_value(strat_results['avg_stake_amount'],
                              strat_results['stake_currency'])),
            ('Total trade volume',
             round_coin_value(strat_results['total_volume'],
                              strat_results['stake_currency'])),
            ('', ''),  # Empty line to improve readability
            ('Best Pair', f"{strat_results['best_pair']['key']} "
             f"{round(strat_results['best_pair']['profit_sum_pct'], 2)}%"),
            ('Worst Pair', f"{strat_results['worst_pair']['key']} "
             f"{round(strat_results['worst_pair']['profit_sum_pct'], 2)}%"),
            ('Best trade',
             f"{best_trade['pair']} {round(best_trade['profit_ratio'] * 100, 2)}%"
             ),
            ('Worst trade', f"{worst_trade['pair']} "
             f"{round(worst_trade['profit_ratio'] * 100, 2)}%"),
            ('Best day',
             round_coin_value(strat_results['backtest_best_day_abs'],
                              strat_results['stake_currency'])),
            ('Worst day',
             round_coin_value(strat_results['backtest_worst_day_abs'],
                              strat_results['stake_currency'])),
            ('Days win/draw/lose', f"{strat_results['winning_days']} / "
             f"{strat_results['draw_days']} / {strat_results['losing_days']}"),
            ('Avg. Duration Winners',
             f"{strat_results['winner_holding_avg']}"),
            ('Avg. Duration Loser', f"{strat_results['loser_holding_avg']}"),
            ('', ''),  # Empty line to improve readability
            ('Min balance',
             round_coin_value(strat_results['csum_min'],
                              strat_results['stake_currency'])),
            ('Max balance',
             round_coin_value(strat_results['csum_max'],
                              strat_results['stake_currency'])),
            ('Drawdown', f"{round(strat_results['max_drawdown'] * 100, 2)}%"),
            ('Drawdown',
             round_coin_value(strat_results['max_drawdown_abs'],
                              strat_results['stake_currency'])),
            ('Drawdown high',
             round_coin_value(strat_results['max_drawdown_high'],
                              strat_results['stake_currency'])),
            ('Drawdown low',
             round_coin_value(strat_results['max_drawdown_low'],
                              strat_results['stake_currency'])),
            ('Drawdown Start',
             strat_results['drawdown_start'].strftime(DATETIME_PRINT_FORMAT)),
            ('Drawdown End',
             strat_results['drawdown_end'].strftime(DATETIME_PRINT_FORMAT)),
            ('Market change',
             f"{round(strat_results['market_change'] * 100, 2)}%"),
        ]

        return tabulate(metrics,
                        headers=["Metric", "Value"],
                        tablefmt="orgtbl")
    else:
        start_balance = round_coin_value(strat_results['starting_balance'],
                                         strat_results['stake_currency'])
        stake_amount = round_coin_value(
            strat_results['stake_amount'],
            strat_results['stake_currency']) if strat_results[
                'stake_amount'] != UNLIMITED_STAKE_AMOUNT else 'unlimited'

        message = ("No trades made. "
                   f"Your starting balance was {start_balance}, "
                   f"and your stake was {stake_amount}.")
        return message
Beispiel #12
0
def test_round_coin_value():
    assert round_coin_value(222.222222, 'USDT') == '222.222 USDT'
    assert round_coin_value(222.2, 'USDT', keep_trailing_zeros=True) == '222.200 USDT'
    assert round_coin_value(222.2, 'USDT') == '222.2 USDT'
    assert round_coin_value(222.12745, 'EUR') == '222.127 EUR'
    assert round_coin_value(0.1274512123, 'BTC') == '0.12745121 BTC'
    assert round_coin_value(0.1274512123, 'ETH') == '0.12745 ETH'

    assert round_coin_value(222.222222, 'USDT', False) == '222.222'
    assert round_coin_value(222.2, 'USDT', False) == '222.2'
    assert round_coin_value(222.00, 'USDT', False) == '222'
    assert round_coin_value(222.12745, 'EUR', False) == '222.127'
    assert round_coin_value(0.1274512123, 'BTC', False) == '0.12745121'
    assert round_coin_value(0.1274512123, 'ETH', False) == '0.12745'
    assert round_coin_value(222.2, 'USDT', False, True) == '222.200'
Beispiel #13
0
    def get_result_table(config: dict, results: list, total_epochs: int,
                         highlight_best: bool, print_colorized: bool,
                         remove_header: int) -> str:
        """
        Log result table
        """
        if not results:
            return ''

        tabulate.PRESERVE_WHITESPACE = True

        trials = json_normalize(results, max_level=1)
        trials['Best'] = ''
        if 'results_metrics.winsdrawslosses' not in trials.columns:
            # Ensure compatibility with older versions of hyperopt results
            trials['results_metrics.winsdrawslosses'] = 'N/A'
        legacy_mode = True

        if 'results_metrics.total_trades' in trials:
            legacy_mode = False
            # New mode, using backtest result for metrics
            trials['results_metrics.winsdrawslosses'] = trials.apply(
                lambda x:
                f"{x['results_metrics.wins']} {x['results_metrics.draws']:>4} "
                f"{x['results_metrics.losses']:>4}",
                axis=1)
            trials = trials[[
                'Best', 'current_epoch', 'results_metrics.total_trades',
                'results_metrics.winsdrawslosses',
                'results_metrics.profit_mean',
                'results_metrics.profit_total_abs',
                'results_metrics.profit_total', 'results_metrics.holding_avg',
                'loss', 'is_initial_point', 'is_best'
            ]]
        else:
            # Legacy mode
            trials = trials[[
                'Best', 'current_epoch', 'results_metrics.trade_count',
                'results_metrics.winsdrawslosses',
                'results_metrics.avg_profit', 'results_metrics.total_profit',
                'results_metrics.profit', 'results_metrics.duration', 'loss',
                'is_initial_point', 'is_best'
            ]]

        trials.columns = [
            'Best', 'Epoch', 'Trades', ' Win Draw Loss', 'Avg profit',
            'Total profit', 'Profit', 'Avg duration', 'Objective',
            'is_initial_point', 'is_best'
        ]
        trials['is_profit'] = False
        trials.loc[trials['is_initial_point'], 'Best'] = '*     '
        trials.loc[trials['is_best'], 'Best'] = 'Best'
        trials.loc[trials['is_initial_point'] & trials['is_best'],
                   'Best'] = '* Best'
        trials.loc[trials['Total profit'] > 0, 'is_profit'] = True
        trials['Trades'] = trials['Trades'].astype(str)
        perc_multi = 1 if legacy_mode else 100
        trials['Epoch'] = trials['Epoch'].apply(lambda x: '{}/{}'.format(
            str(x).rjust(len(str(total_epochs)), ' '), total_epochs))
        trials['Avg profit'] = trials['Avg profit'].apply(
            lambda x: f'{x * perc_multi:,.2f}%'.rjust(7, ' ')
            if not isna(x) else "--".rjust(7, ' '))
        trials['Avg duration'] = trials['Avg duration'].apply(
            lambda x: f'{x:,.1f} m'.rjust(7, ' ') if isinstance(
                x, float) else f"{x}" if not isna(x) else "--".rjust(7, ' '))
        trials['Objective'] = trials['Objective'].apply(
            lambda x: f'{x:,.5f}'.rjust(8, ' ')
            if x != 100000 else "N/A".rjust(8, ' '))

        stake_currency = config['stake_currency']
        trials['Profit'] = trials.apply(lambda x: '{} {}'.format(
            round_coin_value(x['Total profit'], stake_currency), '({:,.2f}%)'.
            format(x['Profit'] * perc_multi).rjust(10, ' ')).rjust(25 + len(
                stake_currency)) if x['Total profit'] != 0.0 else '--'.rjust(
                    25 + len(stake_currency)),
                                        axis=1)
        trials = trials.drop(columns=['Total profit'])

        if print_colorized:
            for i in range(len(trials)):
                if trials.loc[i]['is_profit']:
                    for j in range(len(trials.loc[i]) - 3):
                        trials.iat[i, j] = "{}{}{}".format(
                            Fore.GREEN, str(trials.loc[i][j]), Fore.RESET)
                if trials.loc[i]['is_best'] and highlight_best:
                    for j in range(len(trials.loc[i]) - 3):
                        trials.iat[i, j] = "{}{}{}".format(
                            Style.BRIGHT, str(trials.loc[i][j]),
                            Style.RESET_ALL)

        trials = trials.drop(
            columns=['is_initial_point', 'is_best', 'is_profit'])
        if remove_header > 0:
            table = tabulate.tabulate(trials.to_dict(orient='list'),
                                      tablefmt='orgtbl',
                                      headers='keys',
                                      stralign="right")

            table = table.split("\n", remove_header)[remove_header]
        elif remove_header < 0:
            table = tabulate.tabulate(trials.to_dict(orient='list'),
                                      tablefmt='psql',
                                      headers='keys',
                                      stralign="right")
            table = "\n".join(table.split("\n")[0:remove_header])
        else:
            table = tabulate.tabulate(trials.to_dict(orient='list'),
                                      tablefmt='psql',
                                      headers='keys',
                                      stralign="right")
        return table
Beispiel #14
0
def text_table_add_metrics(strat_results: Dict) -> str:
    if len(strat_results['trades']) > 0:
        best_trade = max(strat_results['trades'],
                         key=lambda x: x['profit_ratio'])
        worst_trade = min(strat_results['trades'],
                          key=lambda x: x['profit_ratio'])

        # Newly added fields should be ignored if they are missing in strat_results. hyperopt-show
        # command stores these results and newer version of freqtrade must be able to handle old
        # results with missing new fields.
        zero_duration_trades = '--'

        if 'zero_duration_trades' in strat_results:
            zero_duration_trades_per = \
                100.0 / strat_results['total_trades'] * strat_results['zero_duration_trades']
            zero_duration_trades = f'{zero_duration_trades_per:.2f}% ' \
                                   f'({strat_results["zero_duration_trades"]})'

        metrics = [
            ('Backtesting from', strat_results['backtest_start']),
            ('Backtesting to', strat_results['backtest_end']),
            ('Max open trades', strat_results['max_open_trades']),
            ('', ''),  # Empty line to improve readability
            ('Total trades', strat_results['total_trades']),
            ('Starting balance',
             round_coin_value(strat_results['starting_balance'],
                              strat_results['stake_currency'])),
            ('Final balance',
             round_coin_value(strat_results['final_balance'],
                              strat_results['stake_currency'])),
            ('Absolute profit ',
             round_coin_value(strat_results['profit_total_abs'],
                              strat_results['stake_currency'])),
            ('Total profit %',
             f"{round(strat_results['profit_total'] * 100, 2):}%"),
            ('Trades per day', strat_results['trades_per_day']),
            ('Avg. stake amount',
             round_coin_value(strat_results['avg_stake_amount'],
                              strat_results['stake_currency'])),
            ('Total trade volume',
             round_coin_value(strat_results['total_volume'],
                              strat_results['stake_currency'])),
            ('', ''),  # Empty line to improve readability
            ('Best Pair', f"{strat_results['best_pair']['key']} "
             f"{round(strat_results['best_pair']['profit_sum_pct'], 2)}%"),
            ('Worst Pair', f"{strat_results['worst_pair']['key']} "
             f"{round(strat_results['worst_pair']['profit_sum_pct'], 2)}%"),
            ('Best trade',
             f"{best_trade['pair']} {round(best_trade['profit_ratio'] * 100, 2)}%"
             ),
            ('Worst trade', f"{worst_trade['pair']} "
             f"{round(worst_trade['profit_ratio'] * 100, 2)}%"),
            ('Best day',
             round_coin_value(strat_results['backtest_best_day_abs'],
                              strat_results['stake_currency'])),
            ('Worst day',
             round_coin_value(strat_results['backtest_worst_day_abs'],
                              strat_results['stake_currency'])),
            ('Days win/draw/lose', f"{strat_results['winning_days']} / "
             f"{strat_results['draw_days']} / {strat_results['losing_days']}"),
            ('Avg. Duration Winners',
             f"{strat_results['winner_holding_avg']}"),
            ('Avg. Duration Loser', f"{strat_results['loser_holding_avg']}"),
            ('Zero Duration Trades', zero_duration_trades),
            ('Rejected Buy signals',
             strat_results.get('rejected_signals', 'N/A')),
            ('', ''),  # Empty line to improve readability
            ('Min balance',
             round_coin_value(strat_results['csum_min'],
                              strat_results['stake_currency'])),
            ('Max balance',
             round_coin_value(strat_results['csum_max'],
                              strat_results['stake_currency'])),
            ('Drawdown', f"{round(strat_results['max_drawdown'] * 100, 2)}%"),
            ('Drawdown',
             round_coin_value(strat_results['max_drawdown_abs'],
                              strat_results['stake_currency'])),
            ('Drawdown high',
             round_coin_value(strat_results['max_drawdown_high'],
                              strat_results['stake_currency'])),
            ('Drawdown low',
             round_coin_value(strat_results['max_drawdown_low'],
                              strat_results['stake_currency'])),
            ('Drawdown Start', strat_results['drawdown_start']),
            ('Drawdown End', strat_results['drawdown_end']),
            ('Market change',
             f"{round(strat_results['market_change'] * 100, 2)}%"),
        ]

        return tabulate(metrics,
                        headers=["Metric", "Value"],
                        tablefmt="orgtbl")
    else:
        start_balance = round_coin_value(strat_results['starting_balance'],
                                         strat_results['stake_currency'])
        stake_amount = round_coin_value(
            strat_results['stake_amount'],
            strat_results['stake_currency']) if strat_results[
                'stake_amount'] != UNLIMITED_STAKE_AMOUNT else 'unlimited'

        message = ("No trades made. "
                   f"Your starting balance was {start_balance}, "
                   f"and your stake was {stake_amount}.")
        return message