export open/close rate for backtesting too

preparation to allow plotting of backtest results
This commit is contained in:
xmatthias 2018-06-23 14:19:50 +02:00
parent 909fd39b80
commit 0440a19171
2 changed files with 28 additions and 12 deletions

View File

@ -37,6 +37,8 @@ class BacktestResult(NamedTuple):
close_index: int close_index: int
trade_duration: float trade_duration: float
open_at_end: bool open_at_end: bool
open_rate: float
close_rate: float
class Backtesting(object): class Backtesting(object):
@ -115,11 +117,13 @@ class Backtesting(object):
def _store_backtest_result(self, recordfilename: Optional[str], results: DataFrame) -> None: def _store_backtest_result(self, recordfilename: Optional[str], results: DataFrame) -> None:
records = [(trade_entry.pair, trade_entry.profit_percent, # columns = ["pair", "profit", "opents", "closets", "index", "duration",
trade_entry.open_time.timestamp(), # "open_rate", "close_rate", "open_at_end"]
trade_entry.close_time.timestamp(),
trade_entry.open_index - 1, trade_entry.trade_duration) records = [(t.pair, t.profit_percent, t.open_time.timestamp(),
for index, trade_entry in results.iterrows()] t.close_time.timestamp(), t.open_index - 1, t.trade_duration,
t.open_rate, t.close_rate, t.open_at_end)
for index, t in results.iterrows()]
if records: if records:
logger.info('Dumping backtest results to %s', recordfilename) logger.info('Dumping backtest results to %s', recordfilename)
@ -158,7 +162,9 @@ class Backtesting(object):
trade_duration=(sell_row.date - buy_row.date).seconds // 60, trade_duration=(sell_row.date - buy_row.date).seconds // 60,
open_index=buy_row.Index, open_index=buy_row.Index,
close_index=sell_row.Index, close_index=sell_row.Index,
open_at_end=False open_at_end=False,
open_rate=buy_row.close,
close_rate=sell_row.close
) )
if partial_ticker: if partial_ticker:
# no sell condition found - trade stil open at end of backtest period # no sell condition found - trade stil open at end of backtest period
@ -171,7 +177,9 @@ class Backtesting(object):
trade_duration=(sell_row.date - buy_row.date).seconds // 60, trade_duration=(sell_row.date - buy_row.date).seconds // 60,
open_index=buy_row.Index, open_index=buy_row.Index,
close_index=sell_row.Index, close_index=sell_row.Index,
open_at_end=True open_at_end=True,
open_rate=buy_row.close,
close_rate=sell_row.close
) )
logger.debug('Force_selling still open trade %s with %s perc - %s', btr.pair, logger.debug('Force_selling still open trade %s with %s perc - %s', btr.pair,
btr.profit_percent, btr.profit_abs) btr.profit_percent, btr.profit_abs)

View File

@ -604,9 +604,13 @@ def test_backtest_record(default_conf, fee, mocker):
Arrow(2017, 11, 14, 22, 10, 00).datetime, Arrow(2017, 11, 14, 22, 10, 00).datetime,
Arrow(2017, 11, 14, 22, 43, 00).datetime, Arrow(2017, 11, 14, 22, 43, 00).datetime,
Arrow(2017, 11, 14, 22, 58, 00).datetime], Arrow(2017, 11, 14, 22, 58, 00).datetime],
"open_rate": [0.002543, 0.003003, 0.003089, 0.003214],
"close_rate": [0.002546, 0.003014, 0.003103, 0.003217],
"open_index": [1, 119, 153, 185], "open_index": [1, 119, 153, 185],
"close_index": [118, 151, 184, 199], "close_index": [118, 151, 184, 199],
"trade_duration": [123, 34, 31, 14]}) "trade_duration": [123, 34, 31, 14],
"open_at_end": [False, False, False, True]
})
backtesting._store_backtest_result("backtest-result.json", results) backtesting._store_backtest_result("backtest-result.json", results)
assert len(results) == 4 assert len(results) == 4
# Assert file_dump_json was only called once # Assert file_dump_json was only called once
@ -617,12 +621,16 @@ def test_backtest_record(default_conf, fee, mocker):
# ('UNITTEST/BTC', 0.00331158, '1510684320', '1510691700', 0, 117) # ('UNITTEST/BTC', 0.00331158, '1510684320', '1510691700', 0, 117)
# Below follows just a typecheck of the schema/type of trade-records # Below follows just a typecheck of the schema/type of trade-records
oix = None oix = None
for (pair, profit, date_buy, date_sell, buy_index, dur) in records: for (pair, profit, date_buy, date_sell, buy_index, dur,
openr, closer, open_at_end) in records:
assert pair == 'UNITTEST/BTC' assert pair == 'UNITTEST/BTC'
isinstance(profit, float) assert isinstance(profit, float)
# FIX: buy/sell should be converted to ints # FIX: buy/sell should be converted to ints
isinstance(date_buy, str) assert isinstance(date_buy, float)
isinstance(date_sell, str) assert isinstance(date_sell, float)
assert isinstance(openr, float)
assert isinstance(closer, float)
assert isinstance(open_at_end, bool)
isinstance(buy_index, pd._libs.tslib.Timestamp) isinstance(buy_index, pd._libs.tslib.Timestamp)
if oix: if oix:
assert buy_index > oix assert buy_index > oix