Merge pull request #3242 from freqtrade/feat/trade_show
New subcommand show-trades
This commit is contained in:
		| @@ -521,3 +521,48 @@ Prints JSON data with details for the last best epoch (i.e., the best of all epo | |||||||
| ``` | ``` | ||||||
| freqtrade hyperopt-show --best -n -1 --print-json --no-header | freqtrade hyperopt-show --best -n -1 --print-json --no-header | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
|  | ## Show trades | ||||||
|  |  | ||||||
|  | Print selected (or all) trades from database to screen. | ||||||
|  |  | ||||||
|  | ``` | ||||||
|  | usage: freqtrade show-trades [-h] [-v] [--logfile FILE] [-V] [-c PATH] | ||||||
|  |                              [-d PATH] [--userdir PATH] [--db-url PATH] | ||||||
|  |                              [--trade-ids TRADE_IDS [TRADE_IDS ...]] | ||||||
|  |                              [--print-json] | ||||||
|  |  | ||||||
|  | optional arguments: | ||||||
|  |   -h, --help            show this help message and exit | ||||||
|  |   --db-url PATH         Override trades database URL, this is useful in custom | ||||||
|  |                         deployments (default: `sqlite:///tradesv3.sqlite` for | ||||||
|  |                         Live Run mode, `sqlite:///tradesv3.dryrun.sqlite` for | ||||||
|  |                         Dry Run). | ||||||
|  |   --trade-ids TRADE_IDS [TRADE_IDS ...] | ||||||
|  |                         Specify the list of trade ids. | ||||||
|  |   --print-json          Print output in JSON format. | ||||||
|  |  | ||||||
|  | Common arguments: | ||||||
|  |   -v, --verbose         Verbose mode (-vv for more, -vvv to get all messages). | ||||||
|  |   --logfile FILE        Log to the file specified. Special values are: | ||||||
|  |                         'syslog', 'journald'. See the documentation for more | ||||||
|  |                         details. | ||||||
|  |   -V, --version         show program's version number and exit | ||||||
|  |   -c PATH, --config PATH | ||||||
|  |                         Specify configuration file (default: | ||||||
|  |                         `userdir/config.json` or `config.json` whichever | ||||||
|  |                         exists). Multiple --config options may be used. Can be | ||||||
|  |                         set to `-` to read config from stdin. | ||||||
|  |   -d PATH, --datadir PATH | ||||||
|  |                         Path to directory with historical backtesting data. | ||||||
|  |   --userdir PATH, --user-data-dir PATH | ||||||
|  |                         Path to userdata directory. | ||||||
|  | ``` | ||||||
|  |  | ||||||
|  | ### Examples | ||||||
|  |  | ||||||
|  | Print trades with id 2 and 3 as json | ||||||
|  |  | ||||||
|  | ``` bash | ||||||
|  | freqtrade show-trades --db-url sqlite:///tradesv3.sqlite --trade-ids 2 3 --print-json | ||||||
|  | ``` | ||||||
|   | |||||||
| @@ -19,7 +19,8 @@ from freqtrade.commands.list_commands import (start_list_exchanges, | |||||||
|                                               start_list_hyperopts, |                                               start_list_hyperopts, | ||||||
|                                               start_list_markets, |                                               start_list_markets, | ||||||
|                                               start_list_strategies, |                                               start_list_strategies, | ||||||
|                                               start_list_timeframes) |                                               start_list_timeframes, | ||||||
|  |                                               start_show_trades) | ||||||
| from freqtrade.commands.optimize_commands import (start_backtesting, | from freqtrade.commands.optimize_commands import (start_backtesting, | ||||||
|                                                   start_edge, start_hyperopt) |                                                   start_edge, start_hyperopt) | ||||||
| from freqtrade.commands.pairlist_commands import start_test_pairlist | from freqtrade.commands.pairlist_commands import start_test_pairlist | ||||||
|   | |||||||
| @@ -64,6 +64,8 @@ ARGS_PLOT_DATAFRAME = ["pairs", "indicators1", "indicators2", "plot_limit", | |||||||
| ARGS_PLOT_PROFIT = ["pairs", "timerange", "export", "exportfilename", "db_url", | ARGS_PLOT_PROFIT = ["pairs", "timerange", "export", "exportfilename", "db_url", | ||||||
|                     "trade_source", "ticker_interval"] |                     "trade_source", "ticker_interval"] | ||||||
|  |  | ||||||
|  | ARGS_SHOW_TRADES = ["db_url", "trade_ids", "print_json"] | ||||||
|  |  | ||||||
| ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable", | ARGS_HYPEROPT_LIST = ["hyperopt_list_best", "hyperopt_list_profitable", | ||||||
|                       "hyperopt_list_min_trades", "hyperopt_list_max_trades", |                       "hyperopt_list_min_trades", "hyperopt_list_max_trades", | ||||||
|                       "hyperopt_list_min_avg_time", "hyperopt_list_max_avg_time", |                       "hyperopt_list_min_avg_time", "hyperopt_list_max_avg_time", | ||||||
| @@ -78,7 +80,7 @@ ARGS_HYPEROPT_SHOW = ["hyperopt_list_best", "hyperopt_list_profitable", "hyperop | |||||||
| NO_CONF_REQURIED = ["convert-data", "convert-trade-data", "download-data", "list-timeframes", | NO_CONF_REQURIED = ["convert-data", "convert-trade-data", "download-data", "list-timeframes", | ||||||
|                     "list-markets", "list-pairs", "list-strategies", |                     "list-markets", "list-pairs", "list-strategies", | ||||||
|                     "list-hyperopts", "hyperopt-list", "hyperopt-show", |                     "list-hyperopts", "hyperopt-list", "hyperopt-show", | ||||||
|                     "plot-dataframe", "plot-profit"] |                     "plot-dataframe", "plot-profit", "show-trades"] | ||||||
|  |  | ||||||
| NO_CONF_ALLOWED = ["create-userdir", "list-exchanges", "new-hyperopt", "new-strategy"] | NO_CONF_ALLOWED = ["create-userdir", "list-exchanges", "new-hyperopt", "new-strategy"] | ||||||
|  |  | ||||||
| @@ -163,7 +165,7 @@ class Arguments: | |||||||
|                                         start_list_markets, start_list_strategies, |                                         start_list_markets, start_list_strategies, | ||||||
|                                         start_list_timeframes, start_new_config, |                                         start_list_timeframes, start_new_config, | ||||||
|                                         start_new_hyperopt, start_new_strategy, |                                         start_new_hyperopt, start_new_strategy, | ||||||
|                                         start_plot_dataframe, start_plot_profit, |                                         start_plot_dataframe, start_plot_profit, start_show_trades, | ||||||
|                                         start_backtesting, start_hyperopt, start_edge, |                                         start_backtesting, start_hyperopt, start_edge, | ||||||
|                                         start_test_pairlist, start_trading) |                                         start_test_pairlist, start_trading) | ||||||
|  |  | ||||||
| @@ -330,6 +332,15 @@ class Arguments: | |||||||
|         plot_profit_cmd.set_defaults(func=start_plot_profit) |         plot_profit_cmd.set_defaults(func=start_plot_profit) | ||||||
|         self._build_args(optionlist=ARGS_PLOT_PROFIT, parser=plot_profit_cmd) |         self._build_args(optionlist=ARGS_PLOT_PROFIT, parser=plot_profit_cmd) | ||||||
|  |  | ||||||
|  |         # Add show-trades subcommand | ||||||
|  |         show_trades = subparsers.add_parser( | ||||||
|  |             'show-trades', | ||||||
|  |             help='Show trades.', | ||||||
|  |             parents=[_common_parser], | ||||||
|  |         ) | ||||||
|  |         show_trades.set_defaults(func=start_show_trades) | ||||||
|  |         self._build_args(optionlist=ARGS_SHOW_TRADES, parser=show_trades) | ||||||
|  |  | ||||||
|         # Add hyperopt-list subcommand |         # Add hyperopt-list subcommand | ||||||
|         hyperopt_list_cmd = subparsers.add_parser( |         hyperopt_list_cmd = subparsers.add_parser( | ||||||
|             'hyperopt-list', |             'hyperopt-list', | ||||||
|   | |||||||
| @@ -217,7 +217,7 @@ AVAILABLE_CLI_OPTIONS = { | |||||||
|     ), |     ), | ||||||
|     "print_json": Arg( |     "print_json": Arg( | ||||||
|         '--print-json', |         '--print-json', | ||||||
|         help='Print best result detailization in JSON format.', |         help='Print output in JSON format.', | ||||||
|         action='store_true', |         action='store_true', | ||||||
|         default=False, |         default=False, | ||||||
|     ), |     ), | ||||||
| @@ -425,6 +425,11 @@ AVAILABLE_CLI_OPTIONS = { | |||||||
|         choices=["DB", "file"], |         choices=["DB", "file"], | ||||||
|         default="file", |         default="file", | ||||||
|     ), |     ), | ||||||
|  |     "trade_ids": Arg( | ||||||
|  |         '--trade-ids', | ||||||
|  |         help='Specify the list of trade ids.', | ||||||
|  |         nargs='+', | ||||||
|  |     ), | ||||||
|     # hyperopt-list, hyperopt-show |     # hyperopt-list, hyperopt-show | ||||||
|     "hyperopt_list_profitable": Arg( |     "hyperopt_list_profitable": Arg( | ||||||
|         '--profitable', |         '--profitable', | ||||||
|   | |||||||
| @@ -197,3 +197,25 @@ def start_list_markets(args: Dict[str, Any], pairs_only: bool = False) -> None: | |||||||
|                   args.get('list_pairs_print_json', False) or |                   args.get('list_pairs_print_json', False) or | ||||||
|                   args.get('print_csv', False)): |                   args.get('print_csv', False)): | ||||||
|             print(f"{summary_str}.") |             print(f"{summary_str}.") | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def start_show_trades(args: Dict[str, Any]) -> None: | ||||||
|  |     """ | ||||||
|  |     Show trades | ||||||
|  |     """ | ||||||
|  |     from freqtrade.persistence import init, Trade | ||||||
|  |     import json | ||||||
|  |     config = setup_utils_configuration(args, RunMode.UTIL_NO_EXCHANGE) | ||||||
|  |     init(config['db_url'], clean_open_orders=False) | ||||||
|  |     tfilter = [] | ||||||
|  |  | ||||||
|  |     if config.get('trade_ids'): | ||||||
|  |         tfilter.append(Trade.id.in_(config['trade_ids'])) | ||||||
|  |  | ||||||
|  |     trades = Trade.get_trades(tfilter).all() | ||||||
|  |     logger.info(f"Printing {len(trades)} Trades: ") | ||||||
|  |     if config.get('print_json', False): | ||||||
|  |         print(json.dumps([trade.to_json() for trade in trades], indent=4)) | ||||||
|  |     else: | ||||||
|  |         for trade in trades: | ||||||
|  |             print(trade) | ||||||
|   | |||||||
| @@ -351,8 +351,12 @@ class Configuration: | |||||||
|         self._args_to_config(config, argname='indicators2', |         self._args_to_config(config, argname='indicators2', | ||||||
|                              logstring='Using indicators2: {}') |                              logstring='Using indicators2: {}') | ||||||
|  |  | ||||||
|  |         self._args_to_config(config, argname='trade_ids', | ||||||
|  |                              logstring='Filtering on trade_ids: {}') | ||||||
|  |  | ||||||
|         self._args_to_config(config, argname='plot_limit', |         self._args_to_config(config, argname='plot_limit', | ||||||
|                              logstring='Limiting plot to: {}') |                              logstring='Limiting plot to: {}') | ||||||
|  |  | ||||||
|         self._args_to_config(config, argname='trade_source', |         self._args_to_config(config, argname='trade_source', | ||||||
|                              logstring='Using trades from: {}') |                              logstring='Using trades from: {}') | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,11 +10,13 @@ from freqtrade.commands import (start_convert_data, start_create_userdir, | |||||||
|                                 start_list_hyperopts, start_list_markets, |                                 start_list_hyperopts, start_list_markets, | ||||||
|                                 start_list_strategies, start_list_timeframes, |                                 start_list_strategies, start_list_timeframes, | ||||||
|                                 start_new_hyperopt, start_new_strategy, |                                 start_new_hyperopt, start_new_strategy, | ||||||
|                                 start_test_pairlist, start_trading) |                                 start_show_trades, start_test_pairlist, | ||||||
|  |                                 start_trading) | ||||||
| from freqtrade.configuration import setup_utils_configuration | from freqtrade.configuration import setup_utils_configuration | ||||||
| from freqtrade.exceptions import OperationalException | from freqtrade.exceptions import OperationalException | ||||||
| from freqtrade.state import RunMode | from freqtrade.state import RunMode | ||||||
| from tests.conftest import (get_args, log_has, log_has_re, patch_exchange, | from tests.conftest import (create_mock_trades, get_args, log_has, log_has_re, | ||||||
|  |                             patch_exchange, | ||||||
|                             patched_configuration_load_config_file) |                             patched_configuration_load_config_file) | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -1040,3 +1042,38 @@ def test_convert_data_trades(mocker, testdatadir): | |||||||
|     assert trades_mock.call_args[1]['convert_from'] == 'jsongz' |     assert trades_mock.call_args[1]['convert_from'] == 'jsongz' | ||||||
|     assert trades_mock.call_args[1]['convert_to'] == 'json' |     assert trades_mock.call_args[1]['convert_to'] == 'json' | ||||||
|     assert trades_mock.call_args[1]['erase'] is False |     assert trades_mock.call_args[1]['erase'] is False | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @pytest.mark.usefixtures("init_persistence") | ||||||
|  | def test_show_trades(mocker, fee, capsys, caplog): | ||||||
|  |     mocker.patch("freqtrade.persistence.init") | ||||||
|  |     create_mock_trades(fee) | ||||||
|  |     args = [ | ||||||
|  |         "show-trades", | ||||||
|  |         "--db-url", | ||||||
|  |         "sqlite:///" | ||||||
|  |     ] | ||||||
|  |     pargs = get_args(args) | ||||||
|  |     pargs['config'] = None | ||||||
|  |     start_show_trades(pargs) | ||||||
|  |     assert log_has("Printing 3 Trades: ", caplog) | ||||||
|  |     captured = capsys.readouterr() | ||||||
|  |     assert "Trade(id=1" in captured.out | ||||||
|  |     assert "Trade(id=2" in captured.out | ||||||
|  |     assert "Trade(id=3" in captured.out | ||||||
|  |     args = [ | ||||||
|  |         "show-trades", | ||||||
|  |         "--db-url", | ||||||
|  |         "sqlite:///", | ||||||
|  |         "--print-json", | ||||||
|  |         "--trade-ids", "1", "2" | ||||||
|  |     ] | ||||||
|  |     pargs = get_args(args) | ||||||
|  |     pargs['config'] = None | ||||||
|  |     start_show_trades(pargs) | ||||||
|  |  | ||||||
|  |     captured = capsys.readouterr() | ||||||
|  |     assert log_has("Printing 2 Trades: ", caplog) | ||||||
|  |     assert '"trade_id": 1' in captured.out | ||||||
|  |     assert '"trade_id": 2' in captured.out | ||||||
|  |     assert '"trade_id": 3' not in captured.out | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user