From 6a15d36d14525ff20083a788848230ee3150fa45 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 18 Jun 2022 11:14:28 +0200 Subject: [PATCH 1/5] Add Drawdown and profit_factor to /profit #6816 --- freqtrade/optimize/optimize_reports.py | 2 ++ freqtrade/rpc/api_server/api_schemas.py | 3 +++ freqtrade/rpc/rpc.py | 23 +++++++++++++++++++++++ freqtrade/rpc/telegram.py | 11 ++++++++--- tests/rpc/test_rpc_apiserver.py | 15 ++++++++++++--- tests/rpc/test_rpc_telegram.py | 5 +++-- 6 files changed, 51 insertions(+), 8 deletions(-) diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index 44b524a4c..79cb8a2bd 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -497,8 +497,10 @@ def generate_strategy_stats(pairlist: List[str], (drawdown_abs, drawdown_start, drawdown_end, high_val, low_val, max_drawdown) = calculate_max_drawdown( results, value_col='profit_abs', starting_balance=start_balance) + # max_relative_drawdown = Underwater (_, _, _, _, _, max_relative_drawdown) = calculate_max_drawdown( results, value_col='profit_abs', starting_balance=start_balance, relative=True) + strat_stats.update({ 'max_drawdown': max_drawdown_legacy, # Deprecated - do not use 'max_drawdown_account': max_drawdown, diff --git a/freqtrade/rpc/api_server/api_schemas.py b/freqtrade/rpc/api_server/api_schemas.py index 11fdc0121..fda2d7ea0 100644 --- a/freqtrade/rpc/api_server/api_schemas.py +++ b/freqtrade/rpc/api_server/api_schemas.py @@ -104,6 +104,9 @@ class Profit(BaseModel): best_pair_profit_ratio: float winning_trades: int losing_trades: int + profit_factor: float + max_drawdown: float + max_drawdown_abs: float class SellReason(BaseModel): diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index 8b1cdb851..bae90b3bc 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -18,6 +18,7 @@ from freqtrade import __version__ from freqtrade.configuration.timerange import TimeRange from freqtrade.constants import CANCEL_REASON, DATETIME_PRINT_FORMAT from freqtrade.data.history import load_data +from freqtrade.data.metrics import calculate_max_drawdown from freqtrade.enums import (CandleType, ExitCheckTuple, ExitType, SignalDirection, State, TradingMode) from freqtrade.exceptions import ExchangeError, PricingError @@ -415,6 +416,8 @@ class RPC: durations = [] winning_trades = 0 losing_trades = 0 + winning_profit = 0.0 + losing_profit = 0.0 for trade in trades: current_rate: float = 0.0 @@ -430,8 +433,10 @@ class RPC: profit_closed_ratio.append(profit_ratio) if trade.close_profit >= 0: winning_trades += 1 + winning_profit += trade.close_profit_abs else: losing_trades += 1 + losing_profit += trade.close_profit_abs else: # Get current rate try: @@ -470,6 +475,21 @@ class RPC: profit_closed_ratio_fromstart = profit_closed_coin_sum / starting_balance profit_all_ratio_fromstart = profit_all_coin_sum / starting_balance + profit_factor = winning_profit / abs(losing_profit) if losing_profit else float('inf') + + trades_df = DataFrame([{'close_date': trade.close_date.strftime(DATETIME_PRINT_FORMAT), + 'profit_abs': trade.close_profit_abs} + for trade in trades if not trade.is_open]) + max_drawdown_abs = 0.0 + max_drawdown = 0.0 + if len(trades_df) > 0: + try: + (max_drawdown_abs, _, _, _, _, max_drawdown) = calculate_max_drawdown( + trades_df, value_col='profit_abs', starting_balance=starting_balance) + except ValueError: + # ValueError if no losing trade. + pass + profit_all_fiat = self._fiat_converter.convert_amount( profit_all_coin_sum, stake_currency, @@ -508,6 +528,9 @@ class RPC: 'best_pair_profit_ratio': best_pair[1] if best_pair else 0, 'winning_trades': winning_trades, 'losing_trades': losing_trades, + 'profit_factor': profit_factor, + 'max_drawdown': max_drawdown, + 'max_drawdown_abs': max_drawdown_abs, } def _rpc_balance(self, stake_currency: str, fiat_display_currency: str) -> Dict: diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index 15e919e30..a7130d691 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -730,12 +730,17 @@ class Telegram(RPCHandler): f"*Total Trade Count:* `{trade_count}`\n" f"*{'First Trade opened' if not timescale else 'Showing Profit since'}:* " f"`{first_trade_date}`\n" - f"*Latest Trade opened:* `{latest_trade_date}\n`" + f"*Latest Trade opened:* `{latest_trade_date}`\n" f"*Win / Loss:* `{stats['winning_trades']} / {stats['losing_trades']}`" ) if stats['closed_trade_count'] > 0: - markdown_msg += (f"\n*Avg. Duration:* `{avg_duration}`\n" - f"*Best Performing:* `{best_pair}: {best_pair_profit_ratio:.2%}`") + markdown_msg += ( + f"\n*Avg. Duration:* `{avg_duration}`\n" + f"*Best Performing:* `{best_pair}: {best_pair_profit_ratio:.2%}`\n" + f"*Profit factor:* `{stats['profit_factor']:.2f}`\n" + f"*Max Drawdown:* `{stats['max_drawdown']:.2%} " + f"({round_coin_value(stats['max_drawdown_abs'], stake_cur)})`" + ) self._send_msg(markdown_msg, reload_able=True, callback_path="update_profit", query=update.callback_query) diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index ada1a82ec..afbc92c5d 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -724,7 +724,9 @@ def test_api_edge_disabled(botclient, mocker, ticker, fee, markets): 'profit_closed_fiat': -83.19455985, 'profit_closed_ratio_mean': -0.0075, 'profit_closed_percent_mean': -0.75, 'profit_closed_ratio_sum': -0.015, 'profit_closed_percent_sum': -1.5, 'profit_closed_ratio': -6.739057628404269e-06, - 'profit_closed_percent': -0.0, 'winning_trades': 0, 'losing_trades': 2} + 'profit_closed_percent': -0.0, 'winning_trades': 0, 'losing_trades': 2, + 'profit_factor': 0.0, + } ), ( False, @@ -737,7 +739,9 @@ def test_api_edge_disabled(botclient, mocker, ticker, fee, markets): 'profit_closed_fiat': 9.124559849999999, 'profit_closed_ratio_mean': 0.0075, 'profit_closed_percent_mean': 0.75, 'profit_closed_ratio_sum': 0.015, 'profit_closed_percent_sum': 1.5, 'profit_closed_ratio': 7.391275897987988e-07, - 'profit_closed_percent': 0.0, 'winning_trades': 2, 'losing_trades': 0} + 'profit_closed_percent': 0.0, 'winning_trades': 2, 'losing_trades': 0, + 'profit_factor': None, + } ), ( None, @@ -750,7 +754,9 @@ def test_api_edge_disabled(botclient, mocker, ticker, fee, markets): 'profit_closed_fiat': -67.02260985, 'profit_closed_ratio_mean': 0.0025, 'profit_closed_percent_mean': 0.25, 'profit_closed_ratio_sum': 0.005, 'profit_closed_percent_sum': 0.5, 'profit_closed_ratio': -5.429078808526421e-06, - 'profit_closed_percent': -0.0, 'winning_trades': 1, 'losing_trades': 1} + 'profit_closed_percent': -0.0, 'winning_trades': 1, 'losing_trades': 1, + 'profit_factor': 0.02775724835771106, + } ) ]) def test_api_profit(botclient, mocker, ticker, fee, markets, is_short, expected): @@ -803,6 +809,9 @@ def test_api_profit(botclient, mocker, ticker, fee, markets, is_short, expected) 'closed_trade_count': 2, 'winning_trades': expected['winning_trades'], 'losing_trades': expected['losing_trades'], + 'profit_factor': expected['profit_factor'], + 'max_drawdown': ANY, + 'max_drawdown_abs': ANY, } diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index d6845be57..65917a6e2 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -704,11 +704,12 @@ def test_profit_handle(default_conf_usdt, update, ticker_usdt, ticker_sell_up, f assert '∙ `6.253 USD`' in msg_mock.call_args_list[-1][0][0] assert '*Best Performing:* `ETH/USDT: 9.45%`' in msg_mock.call_args_list[-1][0][0] + assert '*Max Drawdown:*' in msg_mock.call_args_list[-1][0][0] + assert '*Profit factor:*' in msg_mock.call_args_list[-1][0][0] @pytest.mark.parametrize('is_short', [True, False]) -def test_telegram_stats(default_conf, update, ticker, ticker_sell_up, fee, - limit_buy_order, limit_sell_order, mocker, is_short) -> None: +def test_telegram_stats(default_conf, update, ticker, fee, mocker, is_short) -> None: mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0) mocker.patch.multiple( 'freqtrade.exchange.Exchange', From 40c9abc7e1b2120d80884f00f260ce635a52d74a Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 18 Jun 2022 11:40:32 +0200 Subject: [PATCH 2/5] Add trading volume to /profit output --- freqtrade/persistence/trade_model.py | 16 ++++++++++++++++ freqtrade/rpc/rpc.py | 2 ++ freqtrade/rpc/telegram.py | 1 + tests/rpc/test_rpc_telegram.py | 1 + 4 files changed, 20 insertions(+) diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index eb405942a..3a52c0660 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -1352,3 +1352,19 @@ class Trade(_DECL_BASE, LocalTrade): .group_by(Trade.pair) \ .order_by(desc('profit_sum')).first() return best_pair + + @staticmethod + def get_trading_volume(start_date: datetime = datetime.fromtimestamp(0)) -> float: + """ + Get Trade volume based on Orders + NOTE: Not supported in Backtesting. + :returns: Tuple containing (pair, profit_sum) + """ + trading_volume = Order.query.with_entities( + func.sum(Order.cost).label('volume') + ).filter( + (Order.order_filled_date >= start_date) + & (Order.status == 'closed') + ) \ + .scalar() + return trading_volume diff --git a/freqtrade/rpc/rpc.py b/freqtrade/rpc/rpc.py index bae90b3bc..31fe4c469 100644 --- a/freqtrade/rpc/rpc.py +++ b/freqtrade/rpc/rpc.py @@ -452,6 +452,7 @@ class RPC: profit_all_ratio.append(profit_ratio) best_pair = Trade.get_best_pair(start_date) + trading_volume = Trade.get_trading_volume(start_date) # Prepare data to display profit_closed_coin_sum = round(sum(profit_closed_coin), 8) @@ -531,6 +532,7 @@ class RPC: 'profit_factor': profit_factor, 'max_drawdown': max_drawdown, 'max_drawdown_abs': max_drawdown_abs, + 'trading_volume': trading_volume, } def _rpc_balance(self, stake_currency: str, fiat_display_currency: str) -> Dict: diff --git a/freqtrade/rpc/telegram.py b/freqtrade/rpc/telegram.py index a7130d691..58bfc6bf7 100644 --- a/freqtrade/rpc/telegram.py +++ b/freqtrade/rpc/telegram.py @@ -737,6 +737,7 @@ class Telegram(RPCHandler): markdown_msg += ( f"\n*Avg. Duration:* `{avg_duration}`\n" f"*Best Performing:* `{best_pair}: {best_pair_profit_ratio:.2%}`\n" + f"*Trading volume:* `{round_coin_value(stats['trading_volume'], stake_cur)}`\n" f"*Profit factor:* `{stats['profit_factor']:.2f}`\n" f"*Max Drawdown:* `{stats['max_drawdown']:.2%} " f"({round_coin_value(stats['max_drawdown_abs'], stake_cur)})`" diff --git a/tests/rpc/test_rpc_telegram.py b/tests/rpc/test_rpc_telegram.py index 65917a6e2..e36d98083 100644 --- a/tests/rpc/test_rpc_telegram.py +++ b/tests/rpc/test_rpc_telegram.py @@ -706,6 +706,7 @@ def test_profit_handle(default_conf_usdt, update, ticker_usdt, ticker_sell_up, f assert '*Best Performing:* `ETH/USDT: 9.45%`' in msg_mock.call_args_list[-1][0][0] assert '*Max Drawdown:*' in msg_mock.call_args_list[-1][0][0] assert '*Profit factor:*' in msg_mock.call_args_list[-1][0][0] + assert '*Trading volume:* `60 USDT`' in msg_mock.call_args_list[-1][0][0] @pytest.mark.parametrize('is_short', [True, False]) From b7e4dea6c5d6004e51a823f4bacdb5ac200d3016 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 18 Jun 2022 11:43:50 +0200 Subject: [PATCH 3/5] Document new Profit metrics --- docs/telegram-usage.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/telegram-usage.md b/docs/telegram-usage.md index 773a1b67a..95e7eaa16 100644 --- a/docs/telegram-usage.md +++ b/docs/telegram-usage.md @@ -270,10 +270,15 @@ Return a summary of your profit/loss and performance. > **Latest Trade opened:** `2 minutes ago` > **Avg. Duration:** `2:33:45` > **Best Performing:** `PAY/BTC: 50.23%` +> **Trading volume:** `0.5 BTC` +> **Profit factor:** `1.04` +> **Max Drawdown:** `9.23% (0.01255 BTC)` The relative profit of `1.2%` is the average profit per trade. The relative profit of `15.2 Σ%` is be based on the starting capital - so in this case, the starting capital was `0.00485701 * 1.152 = 0.00738 BTC`. Starting capital is either taken from the `available_capital` setting, or calculated by using current wallet size - profits. +Profit Factor is calculated as gross profits / gross losses - and should serve as an overall metric for the strategy. +Max drawdown corresponds to the backtesting metric `Absolute Drawdown (Account)` - calculated as `(Absolute Drawdown) / (DrawdownHigh + startingBalance)`. ### /forceexit From 474e6705e622aa7372c7a9b203df8553dbdcded3 Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 18 Jun 2022 16:27:43 +0200 Subject: [PATCH 4/5] Add Profit factor to backtesting --- docs/backtesting.md | 4 ++++ docs/telegram-usage.md | 6 +++--- freqtrade/optimize/optimize_reports.py | 6 ++++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/docs/backtesting.md b/docs/backtesting.md index 76718d206..50fc96923 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -300,6 +300,7 @@ A backtesting result will look like that: | Absolute profit | 0.00762792 BTC | | Total profit % | 76.2% | | CAGR % | 460.87% | +| Profit factor | 1.11 | | Avg. stake amount | 0.001 BTC | | Total trade volume | 0.429 BTC | | | | @@ -399,6 +400,7 @@ It contains some useful key metrics about performance of your strategy on backte | Absolute profit | 0.00762792 BTC | | Total profit % | 76.2% | | CAGR % | 460.87% | +| Profit factor | 1.11 | | Avg. stake amount | 0.001 BTC | | Total trade volume | 0.429 BTC | | | | @@ -444,6 +446,8 @@ It contains some useful key metrics about performance of your strategy on backte - `Final balance`: Final balance - starting balance + absolute profit. - `Absolute profit`: Profit made in stake currency. - `Total profit %`: Total profit. Aligned to the `TOTAL` row's `Tot Profit %` from the first table. Calculated as `(End capital − Starting capital) / Starting capital`. +- `CAGR %`: Compound annual growth rate. +- `Profit factor`: profit / loss. - `Avg. stake amount`: Average stake amount, either `stake_amount` or the average when using dynamic stake amount. - `Total trade volume`: Volume generated on the exchange to reach the above profit. - `Best Pair` / `Worst Pair`: Best and worst performing pair, and it's corresponding `Cum Profit %`. diff --git a/docs/telegram-usage.md b/docs/telegram-usage.md index 95e7eaa16..2145797b4 100644 --- a/docs/telegram-usage.md +++ b/docs/telegram-usage.md @@ -275,9 +275,9 @@ Return a summary of your profit/loss and performance. > **Max Drawdown:** `9.23% (0.01255 BTC)` The relative profit of `1.2%` is the average profit per trade. -The relative profit of `15.2 Σ%` is be based on the starting capital - so in this case, the starting capital was `0.00485701 * 1.152 = 0.00738 BTC`. -Starting capital is either taken from the `available_capital` setting, or calculated by using current wallet size - profits. -Profit Factor is calculated as gross profits / gross losses - and should serve as an overall metric for the strategy. +The relative profit of `15.2 Σ%` is be based on the starting capital - so in this case, the starting capital was `0.00485701 * 1.152 = 0.00738 BTC`. +Starting capital is either taken from the `available_capital` setting, or calculated by using current wallet size - profits. +Profit Factor is calculated as gross profits / gross losses - and should serve as an overall metric for the strategy. Max drawdown corresponds to the backtesting metric `Absolute Drawdown (Account)` - calculated as `(Absolute Drawdown) / (DrawdownHigh + startingBalance)`. ### /forceexit diff --git a/freqtrade/optimize/optimize_reports.py b/freqtrade/optimize/optimize_reports.py index 79cb8a2bd..44ac4a5b3 100644 --- a/freqtrade/optimize/optimize_reports.py +++ b/freqtrade/optimize/optimize_reports.py @@ -416,6 +416,9 @@ def generate_strategy_stats(pairlist: List[str], key=lambda x: x['profit_sum']) if len(pair_results) > 1 else None worst_pair = min([pair for pair in pair_results if pair['key'] != 'TOTAL'], key=lambda x: x['profit_sum']) if len(pair_results) > 1 else None + winning_profit = results.loc[results['profit_abs'] > 0, 'profit_abs'].sum() + losing_profit = results.loc[results['profit_abs'] < 0, 'profit_abs'].sum() + profit_factor = winning_profit / abs(losing_profit) if losing_profit else 0.0 backtest_days = (max_date - min_date).days or 1 strat_stats = { @@ -443,6 +446,7 @@ def generate_strategy_stats(pairlist: List[str], 'profit_total_long_abs': results.loc[~results['is_short'], 'profit_abs'].sum(), 'profit_total_short_abs': results.loc[results['is_short'], 'profit_abs'].sum(), 'cagr': calculate_cagr(backtest_days, start_balance, content['final_balance']), + 'profit_factor': profit_factor, 'backtest_start': min_date.strftime(DATETIME_PRINT_FORMAT), 'backtest_start_ts': int(min_date.timestamp() * 1000), 'backtest_end': max_date.strftime(DATETIME_PRINT_FORMAT), @@ -779,6 +783,8 @@ def text_table_add_metrics(strat_results: Dict) -> str: strat_results['stake_currency'])), ('Total profit %', f"{strat_results['profit_total']:.2%}"), ('CAGR %', f"{strat_results['cagr']:.2%}" if 'cagr' in strat_results else 'N/A'), + ('Profit factor', f'{strat_results["profit_factor"]:.2f}' if 'profit_factor' + in strat_results else 'N/A'), ('Trades per day', strat_results['trades_per_day']), ('Avg. daily profit %', f"{(strat_results['profit_total'] / strat_results['backtest_days']):.2%}"), From 0168343b7656eb572c0bda50daa774e2f9549e5f Mon Sep 17 00:00:00 2001 From: Matthias Date: Sat, 18 Jun 2022 16:53:25 +0200 Subject: [PATCH 5/5] Add trading-volume to api schema --- freqtrade/persistence/trade_model.py | 7 +++---- freqtrade/rpc/api_server/api_schemas.py | 1 + tests/conftest_trades.py | 14 ++++++++++++++ tests/rpc/test_rpc_apiserver.py | 7 ++++--- tests/test_persistence.py | 1 + 5 files changed, 23 insertions(+), 7 deletions(-) diff --git a/freqtrade/persistence/trade_model.py b/freqtrade/persistence/trade_model.py index 3a52c0660..39ebd75b4 100644 --- a/freqtrade/persistence/trade_model.py +++ b/freqtrade/persistence/trade_model.py @@ -1363,8 +1363,7 @@ class Trade(_DECL_BASE, LocalTrade): trading_volume = Order.query.with_entities( func.sum(Order.cost).label('volume') ).filter( - (Order.order_filled_date >= start_date) - & (Order.status == 'closed') - ) \ - .scalar() + Order.order_filled_date >= start_date, + Order.status == 'closed' + ).scalar() return trading_volume diff --git a/freqtrade/rpc/api_server/api_schemas.py b/freqtrade/rpc/api_server/api_schemas.py index fda2d7ea0..7566e2ac0 100644 --- a/freqtrade/rpc/api_server/api_schemas.py +++ b/freqtrade/rpc/api_server/api_schemas.py @@ -107,6 +107,7 @@ class Profit(BaseModel): profit_factor: float max_drawdown: float max_drawdown_abs: float + trading_volume: Optional[float] class SellReason(BaseModel): diff --git a/tests/conftest_trades.py b/tests/conftest_trades.py index 006eab98f..1a8cf3183 100644 --- a/tests/conftest_trades.py +++ b/tests/conftest_trades.py @@ -29,6 +29,7 @@ def mock_order_1(is_short: bool): 'average': 0.123, 'amount': 123.0, 'filled': 123.0, + 'cost': 15.129, 'remaining': 0.0, } @@ -65,6 +66,7 @@ def mock_order_2(is_short: bool): 'price': 0.123, 'amount': 123.0, 'filled': 123.0, + 'cost': 15.129, 'remaining': 0.0, } @@ -79,6 +81,7 @@ def mock_order_2_sell(is_short: bool): 'price': 0.128, 'amount': 123.0, 'filled': 123.0, + 'cost': 15.129, 'remaining': 0.0, } @@ -126,6 +129,7 @@ def mock_order_3(is_short: bool): 'price': 0.05, 'amount': 123.0, 'filled': 123.0, + 'cost': 15.129, 'remaining': 0.0, } @@ -141,6 +145,7 @@ def mock_order_3_sell(is_short: bool): 'average': 0.06, 'amount': 123.0, 'filled': 123.0, + 'cost': 15.129, 'remaining': 0.0, } @@ -186,6 +191,7 @@ def mock_order_4(is_short: bool): 'price': 0.123, 'amount': 123.0, 'filled': 0.0, + 'cost': 15.129, 'remaining': 123.0, } @@ -225,6 +231,7 @@ def mock_order_5(is_short: bool): 'price': 0.123, 'amount': 123.0, 'filled': 123.0, + 'cost': 15.129, 'remaining': 0.0, } @@ -239,6 +246,7 @@ def mock_order_5_stoploss(is_short: bool): 'price': 0.123, 'amount': 123.0, 'filled': 0.0, + 'cost': 0.0, 'remaining': 123.0, } @@ -281,6 +289,7 @@ def mock_order_6(is_short: bool): 'price': 0.15, 'amount': 2.0, 'filled': 2.0, + 'cost': 0.3, 'remaining': 0.0, } @@ -295,6 +304,7 @@ def mock_order_6_sell(is_short: bool): 'price': 0.15 if is_short else 0.20, 'amount': 2.0, 'filled': 0.0, + 'cost': 0.0, 'remaining': 2.0, } @@ -337,6 +347,7 @@ def short_order(): 'price': 0.123, 'amount': 123.0, 'filled': 123.0, + 'cost': 15.129, 'remaining': 0.0, } @@ -351,6 +362,7 @@ def exit_short_order(): 'price': 0.128, 'amount': 123.0, 'filled': 123.0, + 'cost': 15.744, 'remaining': 0.0, } @@ -424,6 +436,7 @@ def leverage_order(): 'amount': 123.0, 'filled': 123.0, 'remaining': 0.0, + 'cost': 15.129, 'leverage': 5.0 } @@ -439,6 +452,7 @@ def leverage_order_sell(): 'amount': 123.0, 'filled': 123.0, 'remaining': 0.0, + 'cost': 15.744, 'leverage': 5.0 } diff --git a/tests/rpc/test_rpc_apiserver.py b/tests/rpc/test_rpc_apiserver.py index afbc92c5d..b0ff5e1b2 100644 --- a/tests/rpc/test_rpc_apiserver.py +++ b/tests/rpc/test_rpc_apiserver.py @@ -725,7 +725,7 @@ def test_api_edge_disabled(botclient, mocker, ticker, fee, markets): 'profit_closed_percent_mean': -0.75, 'profit_closed_ratio_sum': -0.015, 'profit_closed_percent_sum': -1.5, 'profit_closed_ratio': -6.739057628404269e-06, 'profit_closed_percent': -0.0, 'winning_trades': 0, 'losing_trades': 2, - 'profit_factor': 0.0, + 'profit_factor': 0.0, 'trading_volume': 91.074, } ), ( @@ -740,7 +740,7 @@ def test_api_edge_disabled(botclient, mocker, ticker, fee, markets): 'profit_closed_percent_mean': 0.75, 'profit_closed_ratio_sum': 0.015, 'profit_closed_percent_sum': 1.5, 'profit_closed_ratio': 7.391275897987988e-07, 'profit_closed_percent': 0.0, 'winning_trades': 2, 'losing_trades': 0, - 'profit_factor': None, + 'profit_factor': None, 'trading_volume': 91.074, } ), ( @@ -755,7 +755,7 @@ def test_api_edge_disabled(botclient, mocker, ticker, fee, markets): 'profit_closed_percent_mean': 0.25, 'profit_closed_ratio_sum': 0.005, 'profit_closed_percent_sum': 0.5, 'profit_closed_ratio': -5.429078808526421e-06, 'profit_closed_percent': -0.0, 'winning_trades': 1, 'losing_trades': 1, - 'profit_factor': 0.02775724835771106, + 'profit_factor': 0.02775724835771106, 'trading_volume': 91.074, } ) ]) @@ -812,6 +812,7 @@ def test_api_profit(botclient, mocker, ticker, fee, markets, is_short, expected) 'profit_factor': expected['profit_factor'], 'max_drawdown': ANY, 'max_drawdown_abs': ANY, + 'trading_volume': expected['trading_volume'], } diff --git a/tests/test_persistence.py b/tests/test_persistence.py index 8c12d2ea0..357233dfa 100644 --- a/tests/test_persistence.py +++ b/tests/test_persistence.py @@ -2269,6 +2269,7 @@ def test_Trade_object_idem(): 'get_exit_reason_performance', 'get_enter_tag_performance', 'get_mix_tag_performance', + 'get_trading_volume', )