Merge remote-tracking branch 'upstream/develop' into feature/fetch-public-trades

This commit is contained in:
Joe Schr
2024-03-04 16:27:53 +01:00
40 changed files with 490 additions and 421 deletions
+2 -7
View File
@@ -820,12 +820,6 @@ def test_download_data_trades(mocker):
"--trading-mode", "futures",
"--dl-trades"
]
pargs = get_args(args)
pargs['config'] = None
start_download_data(pargs)
assert dl_mock.call_args[1]['timerange'].starttype == "date"
assert dl_mock.call_count == 2
assert convert_mock.call_count == 2
def test_download_data_data_invalid(mocker):
@@ -843,10 +837,11 @@ def test_download_data_data_invalid(mocker):
start_download_data(pargs)
def test_start_convert_trades(mocker, caplog):
def test_start_convert_trades(mocker):
convert_mock = mocker.patch('freqtrade.commands.data_commands.convert_trades_to_ohlcv',
MagicMock(return_value=[]))
patch_exchange(mocker)
mocker.patch(f'{EXMS}.get_markets')
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value={}))
args = [
"trades-to-ohlcv",
+5 -5
View File
@@ -142,8 +142,8 @@ def generate_trades_history(n_rows, start_date: Optional[datetime] = None, days=
return df
def generate_test_data(timeframe: str, size: int, start: str = '2020-07-05'):
np.random.seed(42)
def generate_test_data(timeframe: str, size: int, start: str = '2020-07-05', random_seed=42):
np.random.seed(random_seed)
base = np.random.normal(20, 2, size=size)
if timeframe == '1y':
@@ -174,10 +174,10 @@ def generate_test_data(timeframe: str, size: int, start: str = '2020-07-05'):
return df
def generate_test_data_raw(timeframe: str, size: int, start: str = '2020-07-05'):
def generate_test_data_raw(timeframe: str, size: int, start: str = '2020-07-05', random_seed=42):
""" Generates data in the ohlcv format used by ccxt """
df = generate_test_data(timeframe, size, start)
df['date'] = df.loc[:, 'date'].view(np.int64) // 1000 // 1000
df = generate_test_data(timeframe, size, start, random_seed)
df['date'] = df.loc[:, 'date'].astype(np.int64) // 1000 // 1000
return list(list(x) for x in zip(*(df[x].values.tolist() for x in df.columns)))
+6 -2
View File
@@ -542,7 +542,9 @@ def test_convert_trades_to_ohlcv(testdatadir, tmp_path, caplog):
convert_trades_to_ohlcv([pair], timeframes=['1m', '5m'],
data_format_trades='jsongz',
datadir=tmp_path, timerange=tr, erase=True)
datadir=tmp_path, timerange=tr, erase=True,
data_format_ohlcv='feather',
candle_type=CandleType.SPOT)
assert log_has("Deleting existing data for pair XRP/ETH, interval 1m.", caplog)
# Load new data
@@ -556,5 +558,7 @@ def test_convert_trades_to_ohlcv(testdatadir, tmp_path, caplog):
convert_trades_to_ohlcv(['NoDatapair'], timeframes=['1m', '5m'],
data_format_trades='jsongz',
datadir=tmp_path, timerange=tr, erase=True)
datadir=tmp_path, timerange=tr, erase=True,
data_format_ohlcv='feather',
candle_type=CandleType.SPOT)
assert log_has(msg, caplog)
+12 -12
View File
@@ -261,11 +261,11 @@ def test_datahandler_trades_not_supported(datahandler, testdatadir, ):
def test_jsondatahandler_trades_load(testdatadir, caplog):
dh = JsonGzDataHandler(testdatadir)
logmsg = "Old trades format detected - converting"
dh.trades_load('XRP/ETH')
dh.trades_load('XRP/ETH', TradingMode.SPOT)
assert not log_has(logmsg, caplog)
# Test conversation is happening
dh.trades_load('XRP/OLD')
dh.trades_load('XRP/OLD', TradingMode.SPOT)
assert log_has(logmsg, caplog)
@@ -300,16 +300,16 @@ def test_datahandler_trades_get_pairs(testdatadir, datahandler, expected):
def test_hdf5datahandler_trades_load(testdatadir):
dh = get_datahandler(testdatadir, 'hdf5')
trades = dh.trades_load('XRP/ETH')
trades = dh.trades_load('XRP/ETH', TradingMode.SPOT)
assert isinstance(trades, DataFrame)
trades1 = dh.trades_load('UNITTEST/NONEXIST')
trades1 = dh.trades_load('UNITTEST/NONEXIST', TradingMode.SPOT)
assert isinstance(trades1, DataFrame)
assert trades1.empty
# data goes from 2019-10-11 - 2019-10-13
timerange = TimeRange.parse_timerange('20191011-20191012')
trades2 = dh._trades_load('XRP/ETH', timerange)
trades2 = dh._trades_load('XRP/ETH', TradingMode.SPOT, timerange)
assert len(trades) > len(trades2)
# Check that ID is None (If it's nan, it's wrong)
assert trades2.iloc[0]['type'] is None
@@ -451,13 +451,13 @@ def test_hdf5datahandler_ohlcv_purge(mocker, testdatadir):
@pytest.mark.parametrize('datahandler', ['jsongz', 'hdf5', 'feather', 'parquet'])
def test_datahandler_trades_load(testdatadir, datahandler):
dh = get_datahandler(testdatadir, datahandler)
trades = dh.trades_load('XRP/ETH')
trades = dh.trades_load('XRP/ETH', TradingMode.SPOT)
assert isinstance(trades, DataFrame)
assert trades.iloc[0]['timestamp'] == 1570752011620
assert trades.iloc[0]['date'] == Timestamp('2019-10-11 00:00:11.620000+0000')
assert trades.iloc[-1]['cost'] == 0.1986231
trades1 = dh.trades_load('UNITTEST/NONEXIST')
trades1 = dh.trades_load('UNITTEST/NONEXIST', TradingMode.SPOT)
assert isinstance(trades, DataFrame)
assert trades1.empty
@@ -465,15 +465,15 @@ def test_datahandler_trades_load(testdatadir, datahandler):
@pytest.mark.parametrize('datahandler', ['jsongz', 'hdf5', 'feather', 'parquet'])
def test_datahandler_trades_store(testdatadir, tmp_path, datahandler):
dh = get_datahandler(testdatadir, datahandler)
trades = dh.trades_load('XRP/ETH')
trades = dh.trades_load('XRP/ETH', TradingMode.SPOT)
dh1 = get_datahandler(tmp_path, datahandler)
dh1.trades_store('XRP/NEW', trades)
dh1.trades_store('XRP/NEW', trades, TradingMode.SPOT)
file = tmp_path / f'XRP_NEW-trades.{dh1._get_file_extension()}'
assert file.is_file()
# Load trades back
trades_new = dh1.trades_load('XRP/NEW')
trades_new = dh1.trades_load('XRP/NEW', TradingMode.SPOT)
assert_frame_equal(trades, trades_new, check_exact=True)
assert len(trades_new) == len(trades)
@@ -483,11 +483,11 @@ def test_datahandler_trades_purge(mocker, testdatadir, datahandler):
mocker.patch.object(Path, "exists", MagicMock(return_value=False))
unlinkmock = mocker.patch.object(Path, "unlink", MagicMock())
dh = get_datahandler(testdatadir, datahandler)
assert not dh.trades_purge('UNITTEST/NONEXIST')
assert not dh.trades_purge('UNITTEST/NONEXIST', TradingMode.SPOT)
assert unlinkmock.call_count == 0
mocker.patch.object(Path, "exists", MagicMock(return_value=True))
assert dh.trades_purge('UNITTEST/NONEXIST')
assert dh.trades_purge('UNITTEST/NONEXIST', TradingMode.SPOT)
assert unlinkmock.call_count == 1
-5
View File
@@ -78,11 +78,6 @@ def test_download_data_main_trades(mocker):
"trading_mode": "futures",
})
download_data_main(config)
assert dl_mock.call_args[1]['timerange'].starttype == "date"
assert dl_mock.call_count == 2
assert convert_mock.call_count == 2
def test_download_data_main_data_invalid(mocker):
patch_exchange(mocker, id="kraken")
+22 -18
View File
@@ -23,7 +23,7 @@ from freqtrade.data.history.history_utils import (_download_pair_history, _downl
validate_backtest_data)
from freqtrade.data.history.idatahandler import get_datahandler
from freqtrade.data.history.jsondatahandler import JsonDataHandler, JsonGzDataHandler
from freqtrade.enums import CandleType
from freqtrade.enums import CandleType, TradingMode
from freqtrade.exchange import timeframe_to_minutes
from freqtrade.misc import file_dump_json
from freqtrade.resolvers import StrategyResolver
@@ -168,20 +168,21 @@ def test_json_pair_data_filename(pair, timeframe, expected_result, candle_type):
assert fn == Path(expected_result + '.gz')
@pytest.mark.parametrize("pair,expected_result", [
("ETH/BTC", 'freqtrade/hello/world/ETH_BTC-trades.json'),
("Fabric Token/ETH", 'freqtrade/hello/world/Fabric_Token_ETH-trades.json'),
("ETHH20", 'freqtrade/hello/world/ETHH20-trades.json'),
(".XBTBON2H", 'freqtrade/hello/world/_XBTBON2H-trades.json'),
("ETHUSD.d", 'freqtrade/hello/world/ETHUSD_d-trades.json'),
("ACC_OLD_BTC", 'freqtrade/hello/world/ACC_OLD_BTC-trades.json'),
@pytest.mark.parametrize("pair,trading_mode,expected_result", [
("ETH/BTC", '', 'freqtrade/hello/world/ETH_BTC-trades.json'),
("ETH/USDT:USDT", 'futures', 'freqtrade/hello/world/futures/ETH_USDT_USDT-trades.json'),
("Fabric Token/ETH", '', 'freqtrade/hello/world/Fabric_Token_ETH-trades.json'),
("ETHH20", '', 'freqtrade/hello/world/ETHH20-trades.json'),
(".XBTBON2H", '', 'freqtrade/hello/world/_XBTBON2H-trades.json'),
("ETHUSD.d", '', 'freqtrade/hello/world/ETHUSD_d-trades.json'),
("ACC_OLD_BTC", '', 'freqtrade/hello/world/ACC_OLD_BTC-trades.json'),
])
def test_json_pair_trades_filename(pair, expected_result):
fn = JsonDataHandler._pair_trades_filename(Path('freqtrade/hello/world'), pair)
def test_json_pair_trades_filename(pair, trading_mode, expected_result):
fn = JsonDataHandler._pair_trades_filename(Path('freqtrade/hello/world'), pair, trading_mode)
assert isinstance(fn, Path)
assert fn == Path(expected_result)
fn = JsonGzDataHandler._pair_trades_filename(Path('freqtrade/hello/world'), pair)
fn = JsonGzDataHandler._pair_trades_filename(Path('freqtrade/hello/world'), pair, trading_mode)
assert isinstance(fn, Path)
assert fn == Path(expected_result + '.gz')
@@ -559,7 +560,8 @@ def test_refresh_backtest_trades_data(mocker, default_conf, markets, caplog, tes
unavailable_pairs = refresh_backtest_trades_data(exchange=ex,
pairs=["ETH/BTC", "XRP/BTC", "XRP/ETH"],
datadir=testdatadir,
timerange=timerange, erase=True
timerange=timerange, erase=True,
trading_mode=TradingMode.SPOT,
)
assert dl_mock.call_count == 2
@@ -584,7 +586,7 @@ def test_download_trades_history(trades_history, mocker, default_conf, testdatad
assert not file1.is_file()
assert _download_trades_history(data_handler=data_handler, exchange=exchange,
pair='ETH/BTC')
pair='ETH/BTC', trading_mode=TradingMode.SPOT)
assert log_has("Current Amount of trades: 0", caplog)
assert log_has("New Amount of trades: 6", caplog)
assert ght_mock.call_count == 1
@@ -597,8 +599,9 @@ def test_download_trades_history(trades_history, mocker, default_conf, testdatad
since_time = int(trades_history[-3][0] // 1000)
since_time2 = int(trades_history[-1][0] // 1000)
timerange = TimeRange('date', None, since_time, 0)
assert _download_trades_history(data_handler=data_handler, exchange=exchange,
pair='ETH/BTC', timerange=timerange)
assert _download_trades_history(
data_handler=data_handler, exchange=exchange, pair='ETH/BTC',
timerange=timerange, trading_mode=TradingMode.SPOT)
assert ght_mock.call_count == 1
# Check this in seconds - since we had to convert to seconds above too.
@@ -611,7 +614,7 @@ def test_download_trades_history(trades_history, mocker, default_conf, testdatad
caplog.clear()
assert not _download_trades_history(data_handler=data_handler, exchange=exchange,
pair='ETH/BTC')
pair='ETH/BTC', trading_mode=TradingMode.SPOT)
assert log_has_re('Failed to download and store historic trades for pair: "ETH/BTC".*', caplog)
file2 = tmp_path / 'XRP_ETH-trades.json.gz'
@@ -623,8 +626,9 @@ def test_download_trades_history(trades_history, mocker, default_conf, testdatad
since_time = int(trades_history[0][0] // 1000) - 500
timerange = TimeRange('date', None, since_time, 0)
assert _download_trades_history(data_handler=data_handler, exchange=exchange,
pair='XRP/ETH', timerange=timerange)
assert _download_trades_history(
data_handler=data_handler, exchange=exchange, pair='XRP/ETH',
timerange=timerange, trading_mode=TradingMode.SPOT)
assert ght_mock.call_count == 1
+2 -1
View File
@@ -6,6 +6,7 @@ import pytest
from freqtrade.data.converter.trade_converter_kraken import import_kraken_trades_from_csv
from freqtrade.data.history.idatahandler import get_datahandler
from freqtrade.enums import TradingMode
from freqtrade.exceptions import OperationalException
from tests.conftest import EXMS, log_has, log_has_re, patch_exchange
@@ -40,7 +41,7 @@ def test_import_kraken_trades_from_csv(testdatadir, tmp_path, caplog, default_co
assert dstfile.is_file()
dh = get_datahandler(tmp_path, 'feather')
trades = dh.trades_load('BCH_EUR')
trades = dh.trades_load('BCH_EUR', TradingMode.SPOT)
assert len(trades) == 340
assert trades['date'].min().to_pydatetime() == datetime(2023, 1, 1, 0, 3, 56,
+10 -2
View File
@@ -7,6 +7,7 @@ from unittest.mock import MagicMock, Mock, PropertyMock, patch
import ccxt
import pytest
from numpy import NaN
from pandas import DataFrame
from freqtrade.enums import CandleType, MarginMode, RunMode, TradingMode
@@ -4203,6 +4204,7 @@ def test_get_max_leverage_from_margin(default_conf, mocker, pair, nominal_value,
(10, 0.0001, 2.0, 1.0, 0.002, 0.002),
(10, 0.0002, 2.0, 0.01, 0.004, 0.00004),
(10, 0.0002, 2.5, None, 0.005, None),
(10, 0.0002, NaN, None, 0.0, None),
])
def test_calculate_funding_fees(
default_conf,
@@ -4312,8 +4314,8 @@ def test_combine_funding_and_mark(
assert len(df) == 1
# Empty funding rates
funding_rates = DataFrame([], columns=['date', 'open'])
df = exchange.combine_funding_and_mark(funding_rates, mark_rates, futures_funding_rate)
funding_rates2 = DataFrame([], columns=['date', 'open'])
df = exchange.combine_funding_and_mark(funding_rates2, mark_rates, futures_funding_rate)
if futures_funding_rate is not None:
assert len(df) == 3
assert df.iloc[0]['open_fund'] == futures_funding_rate
@@ -4322,6 +4324,12 @@ def test_combine_funding_and_mark(
else:
assert len(df) == 0
# Empty mark candles
mark_candles = DataFrame([], columns=['date', 'open'])
df = exchange.combine_funding_and_mark(funding_rates, mark_candles, futures_funding_rate)
assert len(df) == 0
@pytest.mark.parametrize('exchange,rate_start,rate_end,d1,d2,amount,expected_fees', [
('binance', 0, 2, "2021-09-01 01:00:00", "2021-09-01 04:00:00", 30.0, 0.0),
@@ -57,28 +57,30 @@ def test_backtest_position_adjustment(default_conf, fee, mocker, testdatadir) ->
),
'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.10401764894444211, 0.10302485],
'close_rate': [0.10453904066847439, 0.103541],
'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.09272236],
'initial_stop_loss_abs': [0.0940005, 0.092722365],
'initial_stop_loss_ratio': [-0.1, -0.1],
'stop_loss_abs': [0.0940005, 0.09272236],
'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.1038888],
'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': [1517265300000, 1517285400000],
'close_timestamp': [1517263200000, 1517285400000],
})
pd.testing.assert_frame_equal(results.drop(columns=['orders']), expected)
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
+1 -1
View File
@@ -498,7 +498,7 @@ def test__get_resample_from_period():
assert _get_resample_from_period('day') == '1d'
assert _get_resample_from_period('week') == '1W-MON'
assert _get_resample_from_period('month') == '1M'
assert _get_resample_from_period('month') == '1ME'
with pytest.raises(ValueError, match=r"Period noooo is not supported."):
_get_resample_from_period('noooo')
+106 -1
View File
@@ -19,7 +19,7 @@ from freqtrade.plugins.pairlist.pairlist_helpers import dynamic_expand_pairlist,
from freqtrade.plugins.pairlistmanager import PairListManager
from freqtrade.resolvers import PairListResolver
from freqtrade.util.datetime_helpers import dt_now
from tests.conftest import (EXMS, create_mock_trades_usdt, get_patched_exchange,
from tests.conftest import (EXMS, create_mock_trades_usdt, generate_test_data, get_patched_exchange,
get_patched_freqtradebot, log_has, log_has_re, num_log_has)
@@ -748,6 +748,104 @@ def test_PerformanceFilter_error(mocker, whitelist_conf, caplog) -> None:
assert log_has("PerformanceFilter is not available in this mode.", caplog)
def test_VolatilityFilter_error(mocker, whitelist_conf) -> None:
volatility_filter = {"method": "VolatilityFilter", "lookback_days": -1}
whitelist_conf['pairlists'] = [{"method": "StaticPairList"}, volatility_filter]
mocker.patch(f'{EXMS}.exchange_has', MagicMock(return_value=True))
exchange_mock = MagicMock()
exchange_mock.ohlcv_candle_limit = MagicMock(return_value=1000)
with pytest.raises(OperationalException,
match=r"VolatilityFilter requires lookback_days to be >= 1*"):
PairListManager(exchange_mock, whitelist_conf, MagicMock())
volatility_filter = {"method": "VolatilityFilter", "lookback_days": 2000}
whitelist_conf['pairlists'] = [{"method": "StaticPairList"}, volatility_filter]
with pytest.raises(OperationalException,
match=r"VolatilityFilter requires lookback_days to not exceed exchange max"):
PairListManager(exchange_mock, whitelist_conf, MagicMock())
volatility_filter = {"method": "VolatilityFilter", "sort_direction": "Random"}
whitelist_conf['pairlists'] = [{"method": "StaticPairList"}, volatility_filter]
with pytest.raises(OperationalException,
match=r"VolatilityFilter requires sort_direction to be either "
r"None .*'asc'.*'desc'"):
PairListManager(exchange_mock, whitelist_conf, MagicMock())
@pytest.mark.parametrize('pairlist,expected_pairlist', [
({"method": "VolatilityFilter", "sort_direction": "asc"},
['XRP/BTC', 'ETH/BTC', 'LTC/BTC', 'TKN/BTC']),
({"method": "VolatilityFilter", "sort_direction": "desc"},
['TKN/BTC', 'LTC/BTC', 'ETH/BTC', 'XRP/BTC']),
({"method": "VolatilityFilter", "sort_direction": "desc", 'min_volatility': 0.4},
['TKN/BTC', 'LTC/BTC', 'ETH/BTC']),
({"method": "VolatilityFilter", "sort_direction": "asc", 'min_volatility': 0.4},
['ETH/BTC', 'LTC/BTC', 'TKN/BTC']),
({"method": "VolatilityFilter", "sort_direction": "desc", 'max_volatility': 0.5},
['LTC/BTC', 'ETH/BTC', 'XRP/BTC']),
({"method": "VolatilityFilter", "sort_direction": "asc", 'max_volatility': 0.5},
['XRP/BTC', 'ETH/BTC', 'LTC/BTC']),
({"method": "RangeStabilityFilter", "sort_direction": "asc"},
['ETH/BTC', 'XRP/BTC', 'LTC/BTC', 'TKN/BTC']),
({"method": "RangeStabilityFilter", "sort_direction": "desc"},
['TKN/BTC', 'LTC/BTC', 'XRP/BTC', 'ETH/BTC']),
({"method": "RangeStabilityFilter", "sort_direction": "asc", 'min_rate_of_change': 0.4},
['XRP/BTC', 'LTC/BTC', 'TKN/BTC']),
({"method": "RangeStabilityFilter", "sort_direction": "desc", 'min_rate_of_change': 0.4},
['TKN/BTC', 'LTC/BTC', 'XRP/BTC']),
])
def test_VolatilityFilter_RangeStabilityFilter_sort(
mocker, whitelist_conf, tickers, time_machine, pairlist, expected_pairlist) -> None:
whitelist_conf['pairlists'] = [
{'method': 'VolumePairList', 'number_assets': 10},
pairlist
]
df1 = generate_test_data('1d', 10, '2022-01-05 00:00:00+00:00', random_seed=42)
df2 = generate_test_data('1d', 10, '2022-01-05 00:00:00+00:00', random_seed=2)
df3 = generate_test_data('1d', 10, '2022-01-05 00:00:00+00:00', random_seed=3)
df4 = generate_test_data('1d', 10, '2022-01-05 00:00:00+00:00', random_seed=4)
df5 = generate_test_data('1d', 10, '2022-01-05 00:00:00+00:00', random_seed=5)
df6 = generate_test_data('1d', 10, '2022-01-05 00:00:00+00:00', random_seed=6)
assert not df1.equals(df2)
time_machine.move_to('2022-01-15 00:00:00+00:00')
ohlcv_data = {
('ETH/BTC', '1d', CandleType.SPOT): df1,
('TKN/BTC', '1d', CandleType.SPOT): df2,
('LTC/BTC', '1d', CandleType.SPOT): df3,
('XRP/BTC', '1d', CandleType.SPOT): df4,
('HOT/BTC', '1d', CandleType.SPOT): df5,
('BLK/BTC', '1d', CandleType.SPOT): df6,
}
ohlcv_mock = MagicMock(return_value=ohlcv_data)
mocker.patch.multiple(
EXMS,
exchange_has=MagicMock(return_value=True),
refresh_latest_ohlcv=ohlcv_mock,
get_tickers=tickers
)
exchange = get_patched_exchange(mocker, whitelist_conf)
exchange.ohlcv_candle_limit = MagicMock(return_value=1000)
plm = PairListManager(exchange, whitelist_conf, MagicMock())
assert exchange.ohlcv_candle_limit.call_count == 2
plm.refresh_pairlist()
assert ohlcv_mock.call_count == 1
assert exchange.ohlcv_candle_limit.call_count == 2
assert plm.whitelist == expected_pairlist
plm.refresh_pairlist()
assert exchange.ohlcv_candle_limit.call_count == 2
assert ohlcv_mock.call_count == 1
def test_ShuffleFilter_init(mocker, whitelist_conf, caplog) -> None:
whitelist_conf['pairlists'] = [
{"method": "StaticPairList"},
@@ -1095,6 +1193,13 @@ def test_rangestabilityfilter_checks(mocker, default_conf, markets, tickers):
match='RangeStabilityFilter requires lookback_days to be >= 1'):
get_patched_freqtradebot(mocker, default_conf)
default_conf['pairlists'] = [{'method': 'VolumePairList', 'number_assets': 10},
{'method': 'RangeStabilityFilter', 'sort_direction': 'something'}]
with pytest.raises(OperationalException,
match='RangeStabilityFilter requires sort_direction to be either None.*'):
get_patched_freqtradebot(mocker, default_conf)
@pytest.mark.parametrize('min_rate_of_change,max_rate_of_change,expected_length', [
(0.01, 0.99, 5),
+9 -9
View File
@@ -1022,22 +1022,22 @@ def test_auto_hyperopt_interface_loadparams(default_conf, mocker, caplog):
@pytest.mark.parametrize('function,raises', [
('populate_entry_trend', True),
('populate_entry_trend', False),
('advise_entry', False),
('populate_exit_trend', True),
('populate_exit_trend', False),
('advise_exit', False),
])
def test_pandas_warning_direct(ohlcv_history, function, raises):
def test_pandas_warning_direct(ohlcv_history, function, raises, recwarn):
df = _STRATEGY.populate_indicators(ohlcv_history, {'pair': 'ETH/BTC'})
if raises:
with pytest.warns(FutureWarning):
# Test for Future warning
# FutureWarning: Setting an item of incompatible dtype is
# deprecated and will raise in a future error of pandas
# https://github.com/pandas-dev/pandas/issues/56503
getattr(_STRATEGY, function)(df, {'pair': 'ETH/BTC'})
assert len(recwarn) == 1
# https://github.com/pandas-dev/pandas/issues/56503
# Fixed in 2.2.x
getattr(_STRATEGY, function)(df, {'pair': 'ETH/BTC'})
else:
assert len(recwarn) == 0
getattr(_STRATEGY, function)(df, {'pair': 'ETH/BTC'})