ruff format: Update a few test files

This commit is contained in:
Matthias
2024-05-12 15:29:14 +02:00
parent baa15f6ed6
commit 7090950db6
13 changed files with 1629 additions and 1283 deletions

View File

@@ -9,13 +9,14 @@ from freqtrade.util.datetime_helpers import dt_utc
tests_start_time = dt_utc(2018, 10, 3)
tests_timeframe = '1h'
tests_timeframe = "1h"
class BTrade(NamedTuple):
"""
Minimalistic Trade result used for functional backtesting
"""
exit_reason: ExitType
open_tick: int
close_tick: int
@@ -27,6 +28,7 @@ class BTContainer(NamedTuple):
"""
Minimal BacktestContainer defining Backtest inputs and results.
"""
data: List[List[float]]
stop_loss: float
roi: Dict[str, float]
@@ -51,22 +53,32 @@ def _get_frame_time_from_offset(offset):
def _build_backtest_dataframe(data):
columns = ['date', 'open', 'high', 'low', 'close', 'volume', 'enter_long', 'exit_long',
'enter_short', 'exit_short']
columns = [
"date",
"open",
"high",
"low",
"close",
"volume",
"enter_long",
"exit_long",
"enter_short",
"exit_short",
]
if len(data[0]) == 8:
# No short columns
data = [d + [0, 0] for d in data]
columns = columns + ['enter_tag'] if len(data[0]) == 11 else columns
columns = columns + ["enter_tag"] if len(data[0]) == 11 else columns
frame = DataFrame.from_records(data, columns=columns)
frame['date'] = frame['date'].apply(_get_frame_time_from_offset)
frame["date"] = frame["date"].apply(_get_frame_time_from_offset)
# Ensure floats are in place
for column in ['open', 'high', 'low', 'close', 'volume']:
frame[column] = frame[column].astype('float64')
for column in ["open", "high", "low", "close", "volume"]:
frame[column] = frame[column].astype("float64")
# Ensure all candles make kindof sense
assert all(frame['low'] <= frame['close'])
assert all(frame['low'] <= frame['open'])
assert all(frame['high'] >= frame['close'])
assert all(frame['high'] >= frame['open'])
assert all(frame["low"] <= frame["close"])
assert all(frame["low"] <= frame["open"])
assert all(frame["high"] >= frame["close"])
assert all(frame["high"] >= frame["open"])
return frame

View File

@@ -11,21 +11,23 @@ from freqtrade.optimize.hyperopt import Hyperopt
from tests.conftest import patch_exchange
@pytest.fixture(scope='function')
@pytest.fixture(scope="function")
def hyperopt_conf(default_conf):
hyperconf = deepcopy(default_conf)
hyperconf.update({
'datadir': Path(default_conf['datadir']),
'runmode': RunMode.HYPEROPT,
'strategy': 'HyperoptableStrategy',
'hyperopt_loss': 'ShortTradeDurHyperOptLoss',
'hyperopt_path': str(Path(__file__).parent / 'hyperopts'),
'epochs': 1,
'timerange': None,
'spaces': ['default'],
'hyperopt_jobs': 1,
'hyperopt_min_trades': 1,
})
hyperconf.update(
{
"datadir": Path(default_conf["datadir"]),
"runmode": RunMode.HYPEROPT,
"strategy": "HyperoptableStrategy",
"hyperopt_loss": "ShortTradeDurHyperOptLoss",
"hyperopt_path": str(Path(__file__).parent / "hyperopts"),
"epochs": 1,
"timerange": None,
"spaces": ["default"],
"hyperopt_jobs": 1,
"hyperopt_min_trades": 1,
}
)
return hyperconf
@@ -36,32 +38,29 @@ def backtesting_cleanup():
Backtesting.cleanup()
@pytest.fixture(scope='function')
@pytest.fixture(scope="function")
def hyperopt(hyperopt_conf, mocker):
patch_exchange(mocker)
return Hyperopt(hyperopt_conf)
@pytest.fixture(scope='function')
@pytest.fixture(scope="function")
def hyperopt_results():
return pd.DataFrame(
{
'pair': ['ETH/USDT', 'ETH/USDT', 'ETH/USDT', 'ETH/USDT'],
'profit_ratio': [-0.1, 0.2, -0.12, 0.3],
'profit_abs': [-0.2, 0.4, -0.21, 0.6],
'trade_duration': [10, 30, 10, 10],
'amount': [0.1, 0.1, 0.1, 0.1],
'exit_reason': [ExitType.STOP_LOSS, ExitType.ROI, ExitType.STOP_LOSS, ExitType.ROI],
'open_date':
[
"pair": ["ETH/USDT", "ETH/USDT", "ETH/USDT", "ETH/USDT"],
"profit_ratio": [-0.1, 0.2, -0.12, 0.3],
"profit_abs": [-0.2, 0.4, -0.21, 0.6],
"trade_duration": [10, 30, 10, 10],
"amount": [0.1, 0.1, 0.1, 0.1],
"exit_reason": [ExitType.STOP_LOSS, ExitType.ROI, ExitType.STOP_LOSS, ExitType.ROI],
"open_date": [
datetime(2019, 1, 1, 9, 15, 0),
datetime(2019, 1, 2, 8, 55, 0),
datetime(2019, 1, 3, 9, 15, 0),
datetime(2019, 1, 4, 9, 15, 0),
],
'close_date':
[
"close_date": [
datetime(2019, 1, 1, 9, 25, 0),
datetime(2019, 1, 2, 9, 25, 0),
datetime(2019, 1, 3, 9, 25, 0),

File diff suppressed because it is too large Load Diff

View File

@@ -16,25 +16,26 @@ from tests.conftest import EXMS, patch_exchange
def test_backtest_position_adjustment(default_conf, fee, mocker, testdatadir) -> None:
default_conf['use_exit_signal'] = False
default_conf['max_open_trades'] = 10
mocker.patch(f'{EXMS}.get_fee', fee)
mocker.patch('freqtrade.optimize.backtesting.amount_to_contract_precision',
lambda x, *args, **kwargs: round(x, 8))
default_conf["use_exit_signal"] = False
default_conf["max_open_trades"] = 10
mocker.patch(f"{EXMS}.get_fee", fee)
mocker.patch(
"freqtrade.optimize.backtesting.amount_to_contract_precision",
lambda x, *args, **kwargs: round(x, 8),
)
mocker.patch(f"{EXMS}.get_min_pair_stake_amount", return_value=0.00001)
mocker.patch(f"{EXMS}.get_max_pair_stake_amount", return_value=float('inf'))
mocker.patch(f"{EXMS}.get_max_pair_stake_amount", return_value=float("inf"))
patch_exchange(mocker)
default_conf.update({
"stake_amount": 100.0,
"dry_run_wallet": 1000.0,
"strategy": "StrategyTestV3"
})
default_conf.update(
{"stake_amount": 100.0, "dry_run_wallet": 1000.0, "strategy": "StrategyTestV3"}
)
backtesting = Backtesting(default_conf)
backtesting._set_strategy(backtesting.strategylist[0])
pair = 'UNITTEST/BTC'
timerange = TimeRange('date', None, 1517227800, 0)
data = history.load_data(datadir=testdatadir, timeframe='5m', pairs=['UNITTEST/BTC'],
timerange=timerange)
pair = "UNITTEST/BTC"
timerange = TimeRange("date", None, 1517227800, 0)
data = history.load_data(
datadir=testdatadir, timeframe="5m", pairs=["UNITTEST/BTC"], timerange=timerange
)
backtesting.strategy.position_adjustment_enable = True
processed = backtesting.strategy.advise_all_indicators(data)
min_date, max_date = get_timerange(processed)
@@ -43,47 +44,50 @@ def test_backtest_position_adjustment(default_conf, fee, mocker, testdatadir) ->
start_date=min_date,
end_date=max_date,
)
results = result['results']
results = result["results"]
assert not results.empty
assert len(results) == 2
expected = pd.DataFrame(
{'pair': [pair, pair],
'stake_amount': [500.0, 100.0],
'max_stake_amount': [500.0, 100],
'amount': [4806.87657523, 970.63960782],
'open_date': pd.to_datetime([dt_utc(2018, 1, 29, 18, 40, 0),
dt_utc(2018, 1, 30, 3, 30, 0)], utc=True
),
'close_date': pd.to_datetime([dt_utc(2018, 1, 29, 22, 00, 0),
dt_utc(2018, 1, 30, 4, 10, 0)], utc=True),
'open_rate': [0.10401764891917063, 0.10302485],
'close_rate': [0.10453904064307624, 0.10354126528822055],
'fee_open': [0.0025, 0.0025],
'fee_close': [0.0025, 0.0025],
'trade_duration': [200, 40],
'profit_ratio': [0.0, 0.0],
'profit_abs': [0.0, 0.0],
'exit_reason': [ExitType.ROI.value, ExitType.ROI.value],
'initial_stop_loss_abs': [0.0940005, 0.092722365],
'initial_stop_loss_ratio': [-0.1, -0.1],
'stop_loss_abs': [0.0940005, 0.092722365],
'stop_loss_ratio': [-0.1, -0.1],
'min_rate': [0.10370188, 0.10300000000000001],
'max_rate': [0.10481985, 0.10388887000000001],
'is_open': [False, False],
'enter_tag': ['', ''],
'leverage': [1.0, 1.0],
'is_short': [False, False],
'open_timestamp': [1517251200000, 1517283000000],
'close_timestamp': [1517263200000, 1517285400000],
})
results_no = results.drop(columns=['orders'])
{
"pair": [pair, pair],
"stake_amount": [500.0, 100.0],
"max_stake_amount": [500.0, 100],
"amount": [4806.87657523, 970.63960782],
"open_date": pd.to_datetime(
[dt_utc(2018, 1, 29, 18, 40, 0), dt_utc(2018, 1, 30, 3, 30, 0)], utc=True
),
"close_date": pd.to_datetime(
[dt_utc(2018, 1, 29, 22, 00, 0), dt_utc(2018, 1, 30, 4, 10, 0)], utc=True
),
"open_rate": [0.10401764891917063, 0.10302485],
"close_rate": [0.10453904064307624, 0.10354126528822055],
"fee_open": [0.0025, 0.0025],
"fee_close": [0.0025, 0.0025],
"trade_duration": [200, 40],
"profit_ratio": [0.0, 0.0],
"profit_abs": [0.0, 0.0],
"exit_reason": [ExitType.ROI.value, ExitType.ROI.value],
"initial_stop_loss_abs": [0.0940005, 0.092722365],
"initial_stop_loss_ratio": [-0.1, -0.1],
"stop_loss_abs": [0.0940005, 0.092722365],
"stop_loss_ratio": [-0.1, -0.1],
"min_rate": [0.10370188, 0.10300000000000001],
"max_rate": [0.10481985, 0.10388887000000001],
"is_open": [False, False],
"enter_tag": ["", ""],
"leverage": [1.0, 1.0],
"is_short": [False, False],
"open_timestamp": [1517251200000, 1517283000000],
"close_timestamp": [1517263200000, 1517285400000],
}
)
results_no = results.drop(columns=["orders"])
pd.testing.assert_frame_equal(results_no, expected, check_exact=True)
data_pair = processed[pair]
assert len(results.iloc[0]['orders']) == 6
assert len(results.iloc[1]['orders']) == 2
assert len(results.iloc[0]["orders"]) == 6
assert len(results.iloc[1]["orders"]) == 2
for _, t in results.iterrows():
ln = data_pair.loc[data_pair["date"] == t["open_date"]]
@@ -91,65 +95,65 @@ def test_backtest_position_adjustment(default_conf, fee, mocker, testdatadir) ->
assert ln is not None
# check close trade rate aligns to close rate or is between high and low
ln = data_pair.loc[data_pair["date"] == t["close_date"]]
assert (round(ln.iloc[0]["open"], 6) == round(t["close_rate"], 6) or
round(ln.iloc[0]["low"], 6) < round(
t["close_rate"], 6) < round(ln.iloc[0]["high"], 6))
assert round(ln.iloc[0]["open"], 6) == round(t["close_rate"], 6) or round(
ln.iloc[0]["low"], 6
) < round(t["close_rate"], 6) < round(ln.iloc[0]["high"], 6)
@pytest.mark.parametrize('leverage', [
1, 2
])
@pytest.mark.parametrize("leverage", [1, 2])
def test_backtest_position_adjustment_detailed(default_conf, fee, mocker, leverage) -> None:
default_conf['use_exit_signal'] = False
mocker.patch(f'{EXMS}.get_fee', fee)
default_conf["use_exit_signal"] = False
mocker.patch(f"{EXMS}.get_fee", fee)
mocker.patch(f"{EXMS}.get_min_pair_stake_amount", return_value=10)
mocker.patch(f"{EXMS}.get_max_pair_stake_amount", return_value=float('inf'))
mocker.patch(f"{EXMS}.get_max_pair_stake_amount", return_value=float("inf"))
mocker.patch(f"{EXMS}.get_max_leverage", return_value=10)
mocker.patch(f"{EXMS}.get_maintenance_ratio_and_amt", return_value=(0.1, 0.1))
mocker.patch('freqtrade.optimize.backtesting.Backtesting._run_funding_fees')
mocker.patch("freqtrade.optimize.backtesting.Backtesting._run_funding_fees")
patch_exchange(mocker)
default_conf.update({
"stake_amount": 100.0,
"dry_run_wallet": 1000.0,
"strategy": "StrategyTestV3",
"trading_mode": "futures",
"margin_mode": "isolated",
})
default_conf['pairlists'] = [{'method': 'StaticPairList', 'allow_inactive': True}]
default_conf.update(
{
"stake_amount": 100.0,
"dry_run_wallet": 1000.0,
"strategy": "StrategyTestV3",
"trading_mode": "futures",
"margin_mode": "isolated",
}
)
default_conf["pairlists"] = [{"method": "StaticPairList", "allow_inactive": True}]
backtesting = Backtesting(default_conf)
backtesting._can_short = True
backtesting._set_strategy(backtesting.strategylist[0])
pair = 'XRP/USDT:USDT'
pair = "XRP/USDT:USDT"
row_enter = [
pd.Timestamp(year=2020, month=1, day=1, hour=4, minute=0),
2.1, # Open
2.2, # High
1.9, # Low
2.1, # Close
1, # enter_long
0, # exit_long
0, # enter_short
0, # exit_short
'', # enter_tag
'', # exit_tag
]
pd.Timestamp(year=2020, month=1, day=1, hour=4, minute=0),
2.1, # Open
2.2, # High
1.9, # Low
2.1, # Close
1, # enter_long
0, # exit_long
0, # enter_short
0, # exit_short
"", # enter_tag
"", # exit_tag
]
# Exit row - with slightly different values
row_exit = [
pd.Timestamp(year=2020, month=1, day=1, hour=5, minute=0),
2.2, # Open
2.3, # High
2.0, # Low
2.2, # Close
1, # enter_long
0, # exit_long
0, # enter_short
0, # exit_short
'', # enter_tag
'', # exit_tag
]
pd.Timestamp(year=2020, month=1, day=1, hour=5, minute=0),
2.2, # Open
2.3, # High
2.0, # Low
2.2, # Close
1, # enter_long
0, # exit_long
0, # enter_short
0, # exit_short
"", # enter_tag
"", # exit_tag
]
backtesting.strategy.leverage = MagicMock(return_value=leverage)
trade = backtesting._enter_trade(pair, row=row_enter, direction='long')
trade = backtesting._enter_trade(pair, row=row_enter, direction="long")
current_time = row_enter[0].to_pydatetime()
assert trade
assert pytest.approx(trade.stake_amount) == 100.0
@@ -164,7 +168,7 @@ def test_backtest_position_adjustment_detailed(default_conf, fee, mocker, levera
assert pytest.approx(trade.amount) == 47.61904762 * leverage
assert len(trade.orders) == 1
# Increase position by 100
backtesting.strategy.adjust_trade_position = MagicMock(return_value=(100, 'PartIncrease'))
backtesting.strategy.adjust_trade_position = MagicMock(return_value=(100, "PartIncrease"))
trade = backtesting._get_adjust_trade_entry_for_candle(trade, row_enter, current_time)
@@ -173,7 +177,7 @@ def test_backtest_position_adjustment_detailed(default_conf, fee, mocker, levera
assert pytest.approx(trade.stake_amount) == 200.0
assert pytest.approx(trade.amount) == 95.23809524 * leverage
assert len(trade.orders) == 2
assert trade.orders[-1].ft_order_tag == 'PartIncrease'
assert trade.orders[-1].ft_order_tag == "PartIncrease"
assert pytest.approx(trade.liquidation_price) == liq_price
# Reduce by more than amount - no change to trade.
@@ -190,14 +194,14 @@ def test_backtest_position_adjustment_detailed(default_conf, fee, mocker, levera
assert pytest.approx(trade.liquidation_price) == liq_price
# Reduce position by 50
backtesting.strategy.adjust_trade_position = MagicMock(return_value=(-100, 'partDecrease'))
backtesting.strategy.adjust_trade_position = MagicMock(return_value=(-100, "partDecrease"))
trade = backtesting._get_adjust_trade_entry_for_candle(trade, row_exit, current_time)
assert trade
assert pytest.approx(trade.stake_amount) == 100.0
assert pytest.approx(trade.amount) == 47.61904762 * leverage
assert len(trade.orders) == 3
assert trade.orders[-1].ft_order_tag == 'partDecrease'
assert trade.orders[-1].ft_order_tag == "partDecrease"
assert trade.nr_of_successful_entries == 2
assert trade.nr_of_successful_exits == 1
assert pytest.approx(trade.liquidation_price) == liq_price