Merge branch 'develop' into feat_readjust_entry

This commit is contained in:
eSeR1805
2022-04-16 15:20:50 +03:00
35 changed files with 247 additions and 110 deletions

View File

@@ -1429,7 +1429,7 @@ def test_backtesting_show(mocker, testdatadir, capsys):
args = [
"backtesting-show",
"--export-filename",
f"{testdatadir / 'backtest-result_new.json'}",
f"{testdatadir / 'backtest_results/backtest-result_new.json'}",
"--show-pair-list"
]
pargs = get_args(args)

View File

@@ -27,18 +27,19 @@ def test_get_latest_backtest_filename(testdatadir, mocker):
with pytest.raises(ValueError,
match=r"Directory .* does not seem to contain .*"):
get_latest_backtest_filename(testdatadir.parent)
get_latest_backtest_filename(testdatadir)
res = get_latest_backtest_filename(testdatadir)
testdir_bt = testdatadir / "backtest_results"
res = get_latest_backtest_filename(testdir_bt)
assert res == 'backtest-result_new.json'
res = get_latest_backtest_filename(str(testdatadir))
res = get_latest_backtest_filename(str(testdir_bt))
assert res == 'backtest-result_new.json'
mocker.patch("freqtrade.data.btanalysis.json_load", return_value={})
with pytest.raises(ValueError, match=r"Invalid '.last_result.json' format."):
get_latest_backtest_filename(testdatadir)
get_latest_backtest_filename(testdir_bt)
def test_get_latest_hyperopt_file(testdatadir):
@@ -81,7 +82,7 @@ def test_load_backtest_data_old_format(testdatadir, mocker):
def test_load_backtest_data_new_format(testdatadir):
filename = testdatadir / "backtest-result_new.json"
filename = testdatadir / "backtest_results/backtest-result_new.json"
bt_data = load_backtest_data(filename)
assert isinstance(bt_data, DataFrame)
assert set(bt_data.columns) == set(BT_DATA_COLUMNS + ['close_timestamp', 'open_timestamp'])
@@ -92,19 +93,19 @@ def test_load_backtest_data_new_format(testdatadir):
assert bt_data.equals(bt_data2)
# Test loading from folder (must yield same result)
bt_data3 = load_backtest_data(testdatadir)
bt_data3 = load_backtest_data(testdatadir / "backtest_results")
assert bt_data.equals(bt_data3)
with pytest.raises(ValueError, match=r"File .* does not exist\."):
load_backtest_data(str("filename") + "nofile")
with pytest.raises(ValueError, match=r"Unknown dataformat."):
load_backtest_data(testdatadir / LAST_BT_RESULT_FN)
load_backtest_data(testdatadir / "backtest_results" / LAST_BT_RESULT_FN)
def test_load_backtest_data_multi(testdatadir):
filename = testdatadir / "backtest-result_multistrat.json"
filename = testdatadir / "backtest_results/backtest-result_multistrat.json"
for strategy in ('StrategyTestV2', 'TestStrategy'):
bt_data = load_backtest_data(filename, strategy=strategy)
assert isinstance(bt_data, DataFrame)
@@ -182,7 +183,7 @@ def test_extract_trades_of_period(testdatadir):
def test_analyze_trade_parallelism(testdatadir):
filename = testdatadir / "backtest-result_new.json"
filename = testdatadir / "backtest_results/backtest-result_new.json"
bt_data = load_backtest_data(filename)
res = analyze_trade_parallelism(bt_data, "5m")
@@ -256,7 +257,7 @@ def test_combine_dataframes_with_mean_no_data(testdatadir):
def test_create_cum_profit(testdatadir):
filename = testdatadir / "backtest-result_new.json"
filename = testdatadir / "backtest_results/backtest-result_new.json"
bt_data = load_backtest_data(filename)
timerange = TimeRange.parse_timerange("20180110-20180112")
@@ -272,7 +273,7 @@ def test_create_cum_profit(testdatadir):
def test_create_cum_profit1(testdatadir):
filename = testdatadir / "backtest-result_new.json"
filename = testdatadir / "backtest_results/backtest-result_new.json"
bt_data = load_backtest_data(filename)
# Move close-time to "off" the candle, to make sure the logic still works
bt_data.loc[:, 'close_date'] = bt_data.loc[:, 'close_date'] + DateOffset(seconds=20)
@@ -294,7 +295,7 @@ def test_create_cum_profit1(testdatadir):
def test_calculate_max_drawdown(testdatadir):
filename = testdatadir / "backtest-result_new.json"
filename = testdatadir / "backtest_results/backtest-result_new.json"
bt_data = load_backtest_data(filename)
_, hdate, lowdate, hval, lval, drawdown = calculate_max_drawdown(
bt_data, value_col="profit_abs")
@@ -318,7 +319,7 @@ def test_calculate_max_drawdown(testdatadir):
def test_calculate_csum(testdatadir):
filename = testdatadir / "backtest-result_new.json"
filename = testdatadir / "backtest_results/backtest-result_new.json"
bt_data = load_backtest_data(filename)
csum_min, csum_max = calculate_csum(bt_data)

View File

@@ -231,6 +231,10 @@ def test_validate_order_time_in_force(default_conf, mocker, caplog):
(2.34559, 2, 3, 1, 2.345, 'spot'),
(2.9999, 2, 3, 1, 2.999, 'spot'),
(2.9909, 2, 3, 1, 2.990, 'spot'),
(2.9909, 2, 0, 1, 2, 'spot'),
(29991.5555, 2, 0, 1, 29991, 'spot'),
(29991.5555, 2, -1, 1, 29990, 'spot'),
(29991.5555, 2, -2, 1, 29900, 'spot'),
# Tests for Tick-size
(2.34559, 4, 0.0001, 1, 2.3455, 'spot'),
(2.34559, 4, 0.00001, 1, 2.34559, 'spot'),
@@ -382,11 +386,11 @@ def test__get_stake_amount_limit(mocker, default_conf) -> None:
)
# min
result = exchange.get_min_pair_stake_amount('ETH/BTC', 1, stoploss)
expected_result = 2 * (1+0.05) / (1-abs(stoploss))
expected_result = 2 * (1 + 0.05) / (1 - abs(stoploss))
assert isclose(result, expected_result)
# With Leverage
result = exchange.get_min_pair_stake_amount('ETH/BTC', 1, stoploss, 3.0)
assert isclose(result, expected_result/3)
assert isclose(result, expected_result / 3)
# max
result = exchange.get_max_pair_stake_amount('ETH/BTC', 2)
assert result == 10000
@@ -401,11 +405,11 @@ def test__get_stake_amount_limit(mocker, default_conf) -> None:
PropertyMock(return_value=markets)
)
result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss)
expected_result = 2 * 2 * (1+0.05) / (1-abs(stoploss))
expected_result = 2 * 2 * (1 + 0.05) / (1 - abs(stoploss))
assert isclose(result, expected_result)
# With Leverage
result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss, 5.0)
assert isclose(result, expected_result/5)
assert isclose(result, expected_result / 5)
# max
result = exchange.get_max_pair_stake_amount('ETH/BTC', 2)
assert result == 20000
@@ -420,11 +424,11 @@ def test__get_stake_amount_limit(mocker, default_conf) -> None:
PropertyMock(return_value=markets)
)
result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss)
expected_result = max(2, 2 * 2) * (1+0.05) / (1-abs(stoploss))
expected_result = max(2, 2 * 2) * (1 + 0.05) / (1 - abs(stoploss))
assert isclose(result, expected_result)
# With Leverage
result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss, 10)
assert isclose(result, expected_result/10)
assert isclose(result, expected_result / 10)
# min amount and cost are set (amount is minial)
markets["ETH/BTC"]["limits"] = {
@@ -436,11 +440,11 @@ def test__get_stake_amount_limit(mocker, default_conf) -> None:
PropertyMock(return_value=markets)
)
result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss)
expected_result = max(8, 2 * 2) * (1+0.05) / (1-abs(stoploss))
expected_result = max(8, 2 * 2) * (1 + 0.05) / (1 - abs(stoploss))
assert isclose(result, expected_result)
# With Leverage
result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, stoploss, 7.0)
assert isclose(result, expected_result/7.0)
assert isclose(result, expected_result / 7.0)
# Max
result = exchange.get_max_pair_stake_amount('ETH/BTC', 2)
assert result == 1000
@@ -450,7 +454,7 @@ def test__get_stake_amount_limit(mocker, default_conf) -> None:
assert isclose(result, expected_result)
# With Leverage
result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, -0.4, 8.0)
assert isclose(result, expected_result/8.0)
assert isclose(result, expected_result / 8.0)
# Max
result = exchange.get_max_pair_stake_amount('ETH/BTC', 2)
assert result == 1000
@@ -461,7 +465,7 @@ def test__get_stake_amount_limit(mocker, default_conf) -> None:
assert isclose(result, expected_result)
# With Leverage
result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, -1, 12.0)
assert isclose(result, expected_result/12)
assert isclose(result, expected_result / 12)
# Max
result = exchange.get_max_pair_stake_amount('ETH/BTC', 2)
assert result == 1000
@@ -489,7 +493,7 @@ def test__get_stake_amount_limit(mocker, default_conf) -> None:
)
# With Leverage, Contract size 10
result = exchange.get_min_pair_stake_amount('ETH/BTC', 2, -1, 12.0)
assert isclose(result, (expected_result/12) * 10.0)
assert isclose(result, (expected_result / 12) * 10.0)
# Max
result = exchange.get_max_pair_stake_amount('ETH/BTC', 2)
assert result == 10000
@@ -510,7 +514,7 @@ def test_get_min_pair_stake_amount_real_data(mocker, default_conf) -> None:
PropertyMock(return_value=markets)
)
result = exchange.get_min_pair_stake_amount('ETH/BTC', 0.020405, stoploss)
expected_result = max(0.0001, 0.001 * 0.020405) * (1+0.05) / (1-abs(stoploss))
expected_result = max(0.0001, 0.001 * 0.020405) * (1 + 0.05) / (1 - abs(stoploss))
assert round(result, 8) == round(expected_result, 8)
# Max
result = exchange.get_max_pair_stake_amount('ETH/BTC', 2.0)
@@ -518,12 +522,12 @@ def test_get_min_pair_stake_amount_real_data(mocker, default_conf) -> None:
# Leverage
result = exchange.get_min_pair_stake_amount('ETH/BTC', 0.020405, stoploss, 3.0)
assert round(result, 8) == round(expected_result/3, 8)
assert round(result, 8) == round(expected_result / 3, 8)
# Contract_size
markets["ETH/BTC"]["contractSize"] = 0.1
result = exchange.get_min_pair_stake_amount('ETH/BTC', 0.020405, stoploss, 3.0)
assert round(result, 8) == round((expected_result/3), 8)
assert round(result, 8) == round((expected_result / 3), 8)
# Max
result = exchange.get_max_pair_stake_amount('ETH/BTC', 12.0)
@@ -2691,9 +2695,10 @@ async def test__async_get_trade_history_time(default_conf, mocker, caplog, excha
# Monkey-patch async function
exchange._api_async.fetch_trades = MagicMock(side_effect=mock_get_trade_hist)
pair = 'ETH/BTC'
ret = await exchange._async_get_trade_history_time(pair,
since=fetch_trades_result[0]['timestamp'],
until=fetch_trades_result[-1]['timestamp']-1)
ret = await exchange._async_get_trade_history_time(
pair,
since=fetch_trades_result[0]['timestamp'],
until=fetch_trades_result[-1]['timestamp'] - 1)
assert type(ret) is tuple
assert ret[0] == pair
assert type(ret[1]) is list
@@ -2729,7 +2734,7 @@ async def test__async_get_trade_history_time_empty(default_conf, mocker, caplog,
exchange._async_fetch_trades = MagicMock(side_effect=mock_get_trade_hist)
pair = 'ETH/BTC'
ret = await exchange._async_get_trade_history_time(pair, since=trades_history[0][0],
until=trades_history[-1][0]-1)
until=trades_history[-1][0] - 1)
assert type(ret) is tuple
assert ret[0] == pair
assert type(ret[1]) is list

View File

@@ -6,7 +6,7 @@ import pytest
from freqtrade.leverage import interest
ten_mins = Decimal(1/6)
ten_mins = Decimal(1 / 6)
five_hours = Decimal(5.0)
twentyfive_hours = Decimal(25.0)

View File

@@ -190,7 +190,7 @@ def test_store_backtest_stats(testdatadir, mocker):
assert dump_mock.call_count == 3
assert isinstance(dump_mock.call_args_list[0][0][0], Path)
assert str(dump_mock.call_args_list[0][0][0]).startswith(str(testdatadir/'backtest-result'))
assert str(dump_mock.call_args_list[0][0][0]).startswith(str(testdatadir / 'backtest-result'))
dump_mock.reset_mock()
filename = testdatadir / 'testresult.json'
@@ -228,7 +228,7 @@ def test_generate_pair_metrics():
def test_generate_daily_stats(testdatadir):
filename = testdatadir / "backtest-result_new.json"
filename = testdatadir / "backtest_results/backtest-result_new.json"
bt_data = load_backtest_data(filename)
res = generate_daily_stats(bt_data)
assert isinstance(res, dict)
@@ -248,7 +248,7 @@ def test_generate_daily_stats(testdatadir):
def test_generate_trading_stats(testdatadir):
filename = testdatadir / "backtest-result_new.json"
filename = testdatadir / "backtest_results/backtest-result_new.json"
bt_data = load_backtest_data(filename)
res = generate_trading_stats(bt_data)
assert isinstance(res, dict)
@@ -332,7 +332,7 @@ def test_generate_sell_reason_stats():
def test_text_table_strategy(testdatadir):
filename = testdatadir / "backtest-result_multistrat.json"
filename = testdatadir / "backtest_results/backtest-result_multistrat.json"
bt_res_data = load_backtest_stats(filename)
bt_res_data_comparison = bt_res_data.pop('strategy_comparison')
@@ -364,7 +364,7 @@ def test_generate_edge_table():
def test_generate_periodic_breakdown_stats(testdatadir):
filename = testdatadir / "backtest-result_new.json"
filename = testdatadir / "backtest_results/backtest-result_new.json"
bt_data = load_backtest_data(filename).to_dict(orient='records')
res = generate_periodic_breakdown_stats(bt_data, 'day')
@@ -392,7 +392,7 @@ def test__get_resample_from_period():
def test_show_sorted_pairlist(testdatadir, default_conf, capsys):
filename = testdatadir / "backtest-result_new.json"
filename = testdatadir / "backtest_results/backtest-result_new.json"
bt_data = load_backtest_stats(filename)
default_conf['backtest_show_pair_list'] = True

View File

@@ -1581,6 +1581,38 @@ def test_api_backtesting(botclient, mocker, fee, caplog, tmpdir):
assert result['status_msg'] == 'Backtest reset'
def test_api_backtest_history(botclient, mocker, testdatadir):
ftbot, client = botclient
mocker.patch('freqtrade.data.btanalysis._get_backtest_files',
return_value=[
testdatadir / 'backtest_results/backtest-result_multistrat.json',
testdatadir / 'backtest_results/backtest-result_new.json'
])
rc = client_get(client, f"{BASE_URI}/backtest/history")
assert_response(rc, 502)
ftbot.config['user_data_dir'] = testdatadir
ftbot.config['runmode'] = RunMode.WEBSERVER
rc = client_get(client, f"{BASE_URI}/backtest/history")
assert_response(rc)
result = rc.json()
assert len(result) == 3
fn = result[0]['filename']
assert fn == "backtest-result_multistrat.json"
strategy = result[0]['strategy']
rc = client_get(client, f"{BASE_URI}/backtest/history/result?filename={fn}&strategy={strategy}")
assert_response(rc)
result2 = rc.json()
assert result2
assert result2['status'] == 'ended'
assert not result2['running']
assert result2['progress'] == 1
# Only one strategy loaded - even though we use multiresult
assert len(result2['backtest_result']['strategy']) == 1
assert result2['backtest_result']['strategy'][strategy]
def test_health(botclient):
ftbot, client = botclient

View File

@@ -164,7 +164,7 @@ def test_stoploss_from_absolute():
assert pytest.approx(stoploss_from_absolute(90, 100, True)) == 0
assert pytest.approx(stoploss_from_absolute(100, 100, True)) == 0
assert pytest.approx(stoploss_from_absolute(110, 100, True)) == -(1 - (110/100))
assert pytest.approx(stoploss_from_absolute(110, 100, True)) == -(1 - (110 / 100))
assert pytest.approx(stoploss_from_absolute(110, 100, True)) == 0.1
assert pytest.approx(stoploss_from_absolute(105, 100, True)) == 0.05
assert pytest.approx(stoploss_from_absolute(100, 0, True)) == 1

View File

@@ -119,7 +119,7 @@ def test_set_stop_loss_isolated_liq(fee):
assert trade.stop_loss is None
assert trade.initial_stop_loss is None
trade._set_stop_loss(0.1, (1.0/9.0))
trade._set_stop_loss(0.1, (1.0 / 9.0))
assert trade.liquidation_price == 0.09
assert trade.stop_loss == 0.1
assert trade.initial_stop_loss == 0.1
@@ -160,7 +160,7 @@ def test_set_stop_loss_isolated_liq(fee):
assert trade.stop_loss is None
assert trade.initial_stop_loss is None
trade._set_stop_loss(0.08, (1.0/9.0))
trade._set_stop_loss(0.08, (1.0 / 9.0))
assert trade.liquidation_price == 0.09
assert trade.stop_loss == 0.08
assert trade.initial_stop_loss == 0.08
@@ -171,13 +171,13 @@ def test_set_stop_loss_isolated_liq(fee):
assert trade.initial_stop_loss == 0.08
trade.set_isolated_liq(0.07)
trade._set_stop_loss(0.1, (1.0/8.0))
trade._set_stop_loss(0.1, (1.0 / 8.0))
assert trade.liquidation_price == 0.07
assert trade.stop_loss == 0.07
assert trade.initial_stop_loss == 0.08
# Stop doesn't move stop higher
trade._set_stop_loss(0.1, (1.0/9.0))
trade._set_stop_loss(0.1, (1.0 / 9.0))
assert trade.liquidation_price == 0.07
assert trade.stop_loss == 0.07
assert trade.initial_stop_loss == 0.08

View File

@@ -157,7 +157,7 @@ def test_plot_trades(testdatadir, caplog):
assert fig == fig1
assert log_has("No trades found.", caplog)
pair = "ADA/BTC"
filename = testdatadir / "backtest-result_new.json"
filename = testdatadir / "backtest_results/backtest-result_new.json"
trades = load_backtest_data(filename)
trades = trades.loc[trades['pair'] == pair]
@@ -298,7 +298,7 @@ def test_generate_plot_file(mocker, caplog):
def test_add_profit(testdatadir):
filename = testdatadir / "backtest-result_new.json"
filename = testdatadir / "backtest_results/backtest-result_new.json"
bt_data = load_backtest_data(filename)
timerange = TimeRange.parse_timerange("20180110-20180112")
@@ -318,7 +318,7 @@ def test_add_profit(testdatadir):
def test_generate_profit_graph(testdatadir):
filename = testdatadir / "backtest-result_new.json"
filename = testdatadir / "backtest_results/backtest-result_new.json"
trades = load_backtest_data(filename)
timerange = TimeRange.parse_timerange("20180110-20180112")
pairs = ["TRX/BTC", "XLM/BTC"]
@@ -456,7 +456,7 @@ def test_plot_profit(default_conf, mocker, testdatadir):
match=r"No trades found, cannot generate Profit-plot.*"):
plot_profit(default_conf)
default_conf['exportfilename'] = testdatadir / "backtest-result_new.json"
default_conf['exportfilename'] = testdatadir / "backtest_results/backtest-result_new.json"
plot_profit(default_conf)

View File

@@ -0,0 +1,10 @@
{
"StrategyTestV2": {
"run_id": "430d0271075ef327edbb23088f4db4ebe51a3dbf",
"backtest_start_time": 1648904006
},
"TestStrategy": {
"run_id": "110d0271075ef327edbb23085102b4ebe51a3d55",
"backtest_start_time": 1648904006
}
}

View File

@@ -0,0 +1,6 @@
{
"StrategyTestV3": {
"run_id": "430d0271075ef327edbb23088f4db4ebe51a3dbf",
"backtest_start_time": 1648904006
}
}