From ed47ee4e294ca190e82962d006ef1fc1c3d006b5 Mon Sep 17 00:00:00 2001 From: kryofly Date: Thu, 11 Jan 2018 15:45:39 +0100 Subject: [PATCH] backtest export json2 --- docs/backtesting.md | 5 +++++ freqtrade/misc.py | 8 ++++++++ freqtrade/optimize/backtesting.py | 16 ++++++++++++++-- freqtrade/tests/optimize/test_backtesting.py | 1 + 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/docs/backtesting.md b/docs/backtesting.md index c426e2b5c..69797cb05 100644 --- a/docs/backtesting.md +++ b/docs/backtesting.md @@ -51,6 +51,11 @@ python3 ./freqtrade/main.py backtesting --realistic-simulation --live python3 ./freqtrade/main.py backtesting --datadir freqtrade/tests/testdata-20180101 ``` +**Exporting trades to file** +```bash +freqtrade backtesting --export trades +``` + For help about backtesting usage, please refer to [Backtesting commands](#backtesting-commands). diff --git a/freqtrade/misc.py b/freqtrade/misc.py index 00d431723..9c581bd47 100644 --- a/freqtrade/misc.py +++ b/freqtrade/misc.py @@ -188,6 +188,14 @@ def build_subcommands(parser: argparse.ArgumentParser) -> None: action='store_true', dest='refresh_pairs', ) + backtesting_cmd.add_argument( + '--export', + help='Export backtest results, argument are: trades\ + Example --export trades', + type=str, + default=None, + dest='export', + ) # Add hyperopt subcommand hyperopt_cmd = subparsers.add_parser('hyperopt', help='hyperopt module') diff --git a/freqtrade/optimize/backtesting.py b/freqtrade/optimize/backtesting.py index 8296dc900..dd813cd33 100644 --- a/freqtrade/optimize/backtesting.py +++ b/freqtrade/optimize/backtesting.py @@ -1,6 +1,5 @@ # pragma pylint: disable=missing-docstring,W0212 - import logging from typing import Tuple, Dict @@ -121,6 +120,8 @@ def backtest(args) -> DataFrame: processed = args['processed'] max_open_trades = args.get('max_open_trades', 0) realistic = args.get('realistic', True) + record = args.get('record', None) + records = [] trades = [] trade_count_lock: dict = {} exchange._API = Bittrex({'key': '', 'secret': ''}) @@ -148,6 +149,16 @@ def backtest(args) -> DataFrame: if ret: lock_pair_until, trade_entry = ret trades.append(trade_entry) + if record: + # Note, need to be json.dump friendly + # record a tuple of pair, current_profit_percent, entry-date, duration + records.append((pair, trade_entry[1], + row.Index, trade_entry[3])) + # For now export inside backtest(), maybe change so that backtest() + # returns a tuple like: (dataframe, records, logs, etc) + if record and record.find('trades') >= 0: + logger.info('Dumping backtest results') + misc.file_dump_json('backtest-result.json', records) labels = ['currency', 'profit_percent', 'profit_BTC', 'duration', 'profit', 'loss'] return DataFrame.from_records(trades, columns=labels) @@ -202,7 +213,8 @@ def start(args): 'realistic': args.realistic_simulation, 'sell_profit_only': sell_profit_only, 'use_sell_signal': use_sell_signal, - 'stoploss': config.get('stoploss') + 'stoploss': config.get('stoploss'), + 'record': args.export }) logger.info( '\n==================================== BACKTESTING REPORT ====================================\n%s', # noqa diff --git a/freqtrade/tests/optimize/test_backtesting.py b/freqtrade/tests/optimize/test_backtesting.py index a9c58e719..5c01004b8 100644 --- a/freqtrade/tests/optimize/test_backtesting.py +++ b/freqtrade/tests/optimize/test_backtesting.py @@ -175,6 +175,7 @@ def test_backtest_start(default_conf, mocker, caplog): args.level = 10 args.live = False args.datadir = None + args.export = None backtesting.start(args) # check the logs, that will contain the backtest result exists = ['Using max_open_trades: 1 ...',