Merge pull request #3242 from freqtrade/feat/trade_show
New subcommand show-trades
This commit is contained in:
commit
1b448f57b9
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user