Merge branch 'freqtrade:develop' into strategy_utils
This commit is contained in:
@@ -24,7 +24,7 @@ from freqtrade.enums import RunMode
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.persistence.models import init_db
|
||||
from freqtrade.persistence.pairlock_middleware import PairLocks
|
||||
from tests.conftest import (CURRENT_TEST_STRATEGY, create_mock_trades, get_args, log_has,
|
||||
from tests.conftest import (CURRENT_TEST_STRATEGY, EXMS, create_mock_trades, get_args, log_has,
|
||||
log_has_re, patch_exchange, patched_configuration_load_config_file)
|
||||
from tests.conftest_trades import MOCK_TRADE_COUNT
|
||||
|
||||
@@ -454,7 +454,7 @@ def test_list_markets(mocker, markets_static, capsys):
|
||||
assert re.search(r"^BLK/BTC$", captured.out, re.MULTILINE)
|
||||
assert re.search(r"^LTC/USD$", captured.out, re.MULTILINE)
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.markets', PropertyMock(side_effect=ValueError))
|
||||
mocker.patch(f'{EXMS}.markets', PropertyMock(side_effect=ValueError))
|
||||
# Test --one-column
|
||||
args = [
|
||||
"list-markets",
|
||||
@@ -643,9 +643,7 @@ def test_download_data_keyboardInterrupt(mocker, markets):
|
||||
dl_mock = mocker.patch('freqtrade.commands.data_commands.refresh_backtest_ohlcv_data',
|
||||
MagicMock(side_effect=KeyboardInterrupt))
|
||||
patch_exchange(mocker)
|
||||
mocker.patch(
|
||||
'freqtrade.exchange.Exchange.markets', PropertyMock(return_value=markets)
|
||||
)
|
||||
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value=markets))
|
||||
args = [
|
||||
"download-data",
|
||||
"--exchange", "binance",
|
||||
@@ -664,9 +662,7 @@ def test_download_data_timerange(mocker, markets):
|
||||
dl_mock = mocker.patch('freqtrade.commands.data_commands.refresh_backtest_ohlcv_data',
|
||||
MagicMock(return_value=["ETH/BTC", "XRP/BTC"]))
|
||||
patch_exchange(mocker)
|
||||
mocker.patch(
|
||||
'freqtrade.exchange.Exchange.markets', PropertyMock(return_value=markets)
|
||||
)
|
||||
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value=markets))
|
||||
args = [
|
||||
"download-data",
|
||||
"--exchange", "binance",
|
||||
@@ -715,9 +711,7 @@ def test_download_data_no_markets(mocker, caplog):
|
||||
dl_mock = mocker.patch('freqtrade.commands.data_commands.refresh_backtest_ohlcv_data',
|
||||
MagicMock(return_value=["ETH/BTC", "XRP/BTC"]))
|
||||
patch_exchange(mocker, id='binance')
|
||||
mocker.patch(
|
||||
'freqtrade.exchange.Exchange.markets', PropertyMock(return_value={})
|
||||
)
|
||||
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value={}))
|
||||
args = [
|
||||
"download-data",
|
||||
"--exchange", "binance",
|
||||
@@ -733,9 +727,7 @@ def test_download_data_no_exchange(mocker, caplog):
|
||||
mocker.patch('freqtrade.commands.data_commands.refresh_backtest_ohlcv_data',
|
||||
MagicMock(return_value=["ETH/BTC", "XRP/BTC"]))
|
||||
patch_exchange(mocker)
|
||||
mocker.patch(
|
||||
'freqtrade.exchange.Exchange.markets', PropertyMock(return_value={})
|
||||
)
|
||||
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value={}))
|
||||
args = [
|
||||
"download-data",
|
||||
]
|
||||
@@ -751,9 +743,7 @@ def test_download_data_no_pairs(mocker):
|
||||
mocker.patch('freqtrade.commands.data_commands.refresh_backtest_ohlcv_data',
|
||||
MagicMock(return_value=["ETH/BTC", "XRP/BTC"]))
|
||||
patch_exchange(mocker)
|
||||
mocker.patch(
|
||||
'freqtrade.exchange.Exchange.markets', PropertyMock(return_value={})
|
||||
)
|
||||
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value={}))
|
||||
args = [
|
||||
"download-data",
|
||||
"--exchange",
|
||||
@@ -771,9 +761,7 @@ def test_download_data_all_pairs(mocker, markets):
|
||||
dl_mock = mocker.patch('freqtrade.commands.data_commands.refresh_backtest_ohlcv_data',
|
||||
MagicMock(return_value=["ETH/BTC", "XRP/BTC"]))
|
||||
patch_exchange(mocker)
|
||||
mocker.patch(
|
||||
'freqtrade.exchange.Exchange.markets', PropertyMock(return_value=markets)
|
||||
)
|
||||
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value=markets))
|
||||
args = [
|
||||
"download-data",
|
||||
"--exchange",
|
||||
@@ -810,9 +798,7 @@ def test_download_data_trades(mocker, caplog):
|
||||
convert_mock = mocker.patch('freqtrade.commands.data_commands.convert_trades_to_ohlcv',
|
||||
MagicMock(return_value=[]))
|
||||
patch_exchange(mocker)
|
||||
mocker.patch(
|
||||
'freqtrade.exchange.Exchange.markets', PropertyMock(return_value={})
|
||||
)
|
||||
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value={}))
|
||||
args = [
|
||||
"download-data",
|
||||
"--exchange", "kraken",
|
||||
@@ -843,9 +829,7 @@ def test_download_data_trades(mocker, caplog):
|
||||
|
||||
def test_download_data_data_invalid(mocker):
|
||||
patch_exchange(mocker, id="kraken")
|
||||
mocker.patch(
|
||||
'freqtrade.exchange.Exchange.markets', PropertyMock(return_value={})
|
||||
)
|
||||
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value={}))
|
||||
args = [
|
||||
"download-data",
|
||||
"--exchange", "kraken",
|
||||
@@ -862,9 +846,7 @@ def test_start_convert_trades(mocker, caplog):
|
||||
convert_mock = mocker.patch('freqtrade.commands.data_commands.convert_trades_to_ohlcv',
|
||||
MagicMock(return_value=[]))
|
||||
patch_exchange(mocker)
|
||||
mocker.patch(
|
||||
'freqtrade.exchange.Exchange.markets', PropertyMock(return_value={})
|
||||
)
|
||||
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value={}))
|
||||
args = [
|
||||
"trades-to-ohlcv",
|
||||
"--exchange", "kraken",
|
||||
@@ -971,7 +953,7 @@ def test_start_list_freqAI_models(capsys):
|
||||
|
||||
def test_start_test_pairlist(mocker, caplog, tickers, default_conf, capsys):
|
||||
patch_exchange(mocker, mock_markets=True)
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
mocker.patch.multiple(EXMS,
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
get_tickers=tickers,
|
||||
)
|
||||
|
@@ -40,6 +40,7 @@ np.seterr(all='raise')
|
||||
|
||||
CURRENT_TEST_STRATEGY = 'StrategyTestV3'
|
||||
TRADE_SIDES = ('long', 'short')
|
||||
EXMS = 'freqtrade.exchange.exchange.Exchange'
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
@@ -145,22 +146,21 @@ def patch_exchange(
|
||||
mock_markets=True,
|
||||
mock_supported_modes=True
|
||||
) -> None:
|
||||
mocker.patch('freqtrade.exchange.Exchange._load_async_markets', MagicMock(return_value={}))
|
||||
mocker.patch('freqtrade.exchange.Exchange.validate_config', MagicMock())
|
||||
mocker.patch('freqtrade.exchange.Exchange.validate_timeframes', MagicMock())
|
||||
mocker.patch('freqtrade.exchange.Exchange.id', PropertyMock(return_value=id))
|
||||
mocker.patch('freqtrade.exchange.Exchange.name', PropertyMock(return_value=id.title()))
|
||||
mocker.patch('freqtrade.exchange.Exchange.precisionMode', PropertyMock(return_value=2))
|
||||
mocker.patch(f'{EXMS}._load_async_markets', return_value={})
|
||||
mocker.patch(f'{EXMS}.validate_config', MagicMock())
|
||||
mocker.patch(f'{EXMS}.validate_timeframes', MagicMock())
|
||||
mocker.patch(f'{EXMS}.id', PropertyMock(return_value=id))
|
||||
mocker.patch(f'{EXMS}.name', PropertyMock(return_value=id.title()))
|
||||
mocker.patch(f'{EXMS}.precisionMode', PropertyMock(return_value=2))
|
||||
|
||||
if mock_markets:
|
||||
if isinstance(mock_markets, bool):
|
||||
mock_markets = get_markets()
|
||||
mocker.patch('freqtrade.exchange.Exchange.markets',
|
||||
PropertyMock(return_value=mock_markets))
|
||||
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value=mock_markets))
|
||||
|
||||
if mock_supported_modes:
|
||||
mocker.patch(
|
||||
f'freqtrade.exchange.{id.capitalize()}._supported_trading_mode_margin_pairs',
|
||||
f'freqtrade.exchange.{id}.{id.capitalize()}._supported_trading_mode_margin_pairs',
|
||||
PropertyMock(return_value=[
|
||||
(TradingMode.MARGIN, MarginMode.CROSS),
|
||||
(TradingMode.MARGIN, MarginMode.ISOLATED),
|
||||
@@ -170,10 +170,10 @@ def patch_exchange(
|
||||
)
|
||||
|
||||
if api_mock:
|
||||
mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock(return_value=api_mock))
|
||||
mocker.patch(f'{EXMS}._init_ccxt', return_value=api_mock)
|
||||
else:
|
||||
mocker.patch('freqtrade.exchange.Exchange._init_ccxt', MagicMock())
|
||||
mocker.patch('freqtrade.exchange.Exchange.timeframes', PropertyMock(
|
||||
mocker.patch(f'{EXMS}._init_ccxt', MagicMock())
|
||||
mocker.patch(f'{EXMS}.timeframes', PropertyMock(
|
||||
return_value=['5m', '15m', '1h', '1d']))
|
||||
|
||||
|
||||
@@ -2573,7 +2573,7 @@ def import_fails() -> None:
|
||||
realimport = builtins.__import__
|
||||
|
||||
def mockedimport(name, *args, **kwargs):
|
||||
if name in ["filelock", 'systemd.journal', 'uvloop']:
|
||||
if name in ["filelock", 'cysystemd.journal', 'uvloop']:
|
||||
raise ImportError(f"No module named '{name}'")
|
||||
return realimport(name, *args, **kwargs)
|
||||
|
||||
|
@@ -8,7 +8,7 @@ from freqtrade.data.dataprovider import DataProvider
|
||||
from freqtrade.enums import CandleType, RunMode
|
||||
from freqtrade.exceptions import ExchangeError, OperationalException
|
||||
from freqtrade.plugins.pairlistmanager import PairListManager
|
||||
from tests.conftest import generate_test_data, get_patched_exchange
|
||||
from tests.conftest import EXMS, generate_test_data, get_patched_exchange
|
||||
|
||||
|
||||
@pytest.mark.parametrize('candle_type', [
|
||||
@@ -223,7 +223,7 @@ def test_emit_df(mocker, default_conf, ohlcv_history):
|
||||
|
||||
def test_refresh(mocker, default_conf):
|
||||
refresh_mock = MagicMock()
|
||||
mocker.patch("freqtrade.exchange.Exchange.refresh_latest_ohlcv", refresh_mock)
|
||||
mocker.patch(f"{EXMS}.refresh_latest_ohlcv", refresh_mock)
|
||||
|
||||
exchange = get_patched_exchange(mocker, default_conf, id="binance")
|
||||
timeframe = default_conf["timeframe"]
|
||||
@@ -281,7 +281,7 @@ def test_market(mocker, default_conf, markets):
|
||||
|
||||
def test_ticker(mocker, default_conf, tickers):
|
||||
ticker_mock = MagicMock(return_value=tickers()['ETH/BTC'])
|
||||
mocker.patch("freqtrade.exchange.Exchange.fetch_ticker", ticker_mock)
|
||||
mocker.patch(f"{EXMS}.fetch_ticker", ticker_mock)
|
||||
exchange = get_patched_exchange(mocker, default_conf)
|
||||
dp = DataProvider(default_conf, exchange)
|
||||
res = dp.ticker('ETH/BTC')
|
||||
@@ -290,7 +290,7 @@ def test_ticker(mocker, default_conf, tickers):
|
||||
assert res['symbol'] == 'ETH/BTC'
|
||||
|
||||
ticker_mock = MagicMock(side_effect=ExchangeError('Pair not found'))
|
||||
mocker.patch("freqtrade.exchange.Exchange.fetch_ticker", ticker_mock)
|
||||
mocker.patch(f"{EXMS}.fetch_ticker", ticker_mock)
|
||||
exchange = get_patched_exchange(mocker, default_conf)
|
||||
dp = DataProvider(default_conf, exchange)
|
||||
res = dp.ticker('UNITTEST/BTC')
|
||||
@@ -301,7 +301,7 @@ def test_current_whitelist(mocker, default_conf, tickers):
|
||||
# patch default conf to volumepairlist
|
||||
default_conf['pairlists'][0] = {'method': 'VolumePairList', "number_assets": 5}
|
||||
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
mocker.patch.multiple(EXMS,
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
get_tickers=tickers)
|
||||
exchange = get_patched_exchange(mocker, default_conf)
|
||||
|
0
tests/data/test_entryexitanalysis.py
Executable file → Normal file
0
tests/data/test_entryexitanalysis.py
Executable file → Normal file
@@ -26,7 +26,7 @@ from freqtrade.enums import CandleType
|
||||
from freqtrade.exchange import timeframe_to_minutes
|
||||
from freqtrade.misc import file_dump_json
|
||||
from freqtrade.resolvers import StrategyResolver
|
||||
from tests.conftest import (CURRENT_TEST_STRATEGY, get_patched_exchange, log_has, log_has_re,
|
||||
from tests.conftest import (CURRENT_TEST_STRATEGY, EXMS, get_patched_exchange, log_has, log_has_re,
|
||||
patch_exchange)
|
||||
|
||||
|
||||
@@ -66,7 +66,7 @@ def test_load_data_7min_timeframe(caplog, testdatadir) -> None:
|
||||
|
||||
|
||||
def test_load_data_1min_timeframe(ohlcv_history, mocker, caplog, testdatadir) -> None:
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', return_value=ohlcv_history)
|
||||
mocker.patch(f'{EXMS}.get_historic_ohlcv', return_value=ohlcv_history)
|
||||
file = testdatadir / 'UNITTEST_BTC-1m.json'
|
||||
load_data(datadir=testdatadir, timeframe='1m', pairs=['UNITTEST/BTC'])
|
||||
assert file.is_file()
|
||||
@@ -77,7 +77,7 @@ def test_load_data_1min_timeframe(ohlcv_history, mocker, caplog, testdatadir) ->
|
||||
|
||||
|
||||
def test_load_data_mark(ohlcv_history, mocker, caplog, testdatadir) -> None:
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', return_value=ohlcv_history)
|
||||
mocker.patch(f'{EXMS}.get_historic_ohlcv', return_value=ohlcv_history)
|
||||
file = testdatadir / 'futures/UNITTEST_USDT_USDT-1h-mark.json'
|
||||
load_data(datadir=testdatadir, timeframe='1h', pairs=['UNITTEST/BTC'], candle_type='mark')
|
||||
assert file.is_file()
|
||||
@@ -109,7 +109,7 @@ def test_load_data_with_new_pair_1min(ohlcv_history_list, mocker, caplog,
|
||||
Test load_pair_history() with 1 min timeframe
|
||||
"""
|
||||
tmpdir1 = Path(tmpdir)
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', return_value=ohlcv_history_list)
|
||||
mocker.patch(f'{EXMS}.get_historic_ohlcv', return_value=ohlcv_history_list)
|
||||
exchange = get_patched_exchange(mocker, default_conf)
|
||||
file = tmpdir1 / 'MEME_BTC-1m.json'
|
||||
|
||||
@@ -191,7 +191,7 @@ def test_load_cached_data_for_updating(mocker, testdatadir) -> None:
|
||||
|
||||
test_data = None
|
||||
test_filename = testdatadir.joinpath('UNITTEST_BTC-1m.json')
|
||||
with open(test_filename, "rt") as file:
|
||||
with test_filename.open("rt") as file:
|
||||
test_data = json.load(file)
|
||||
|
||||
test_data_df = ohlcv_to_dataframe(test_data, '1m', 'UNITTEST/BTC',
|
||||
@@ -277,7 +277,7 @@ def test_download_pair_history(
|
||||
subdir,
|
||||
file_tail
|
||||
) -> None:
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', return_value=ohlcv_history_list)
|
||||
mocker.patch(f'{EXMS}.get_historic_ohlcv', return_value=ohlcv_history_list)
|
||||
exchange = get_patched_exchange(mocker, default_conf)
|
||||
tmpdir1 = Path(tmpdir)
|
||||
file1_1 = tmpdir1 / f'{subdir}MEME_BTC-1m{file_tail}.json'
|
||||
@@ -328,7 +328,7 @@ def test_download_pair_history2(mocker, default_conf, testdatadir) -> None:
|
||||
json_dump_mock = mocker.patch(
|
||||
'freqtrade.data.history.jsondatahandler.JsonDataHandler.ohlcv_store',
|
||||
return_value=None)
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', return_value=tick)
|
||||
mocker.patch(f'{EXMS}.get_historic_ohlcv', return_value=tick)
|
||||
exchange = get_patched_exchange(mocker, default_conf)
|
||||
_download_pair_history(datadir=testdatadir, exchange=exchange, pair="UNITTEST/BTC",
|
||||
timeframe='1m', candle_type='spot')
|
||||
@@ -340,7 +340,7 @@ def test_download_pair_history2(mocker, default_conf, testdatadir) -> None:
|
||||
|
||||
|
||||
def test_download_backtesting_data_exception(mocker, caplog, default_conf, tmpdir) -> None:
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv',
|
||||
mocker.patch(f'{EXMS}.get_historic_ohlcv',
|
||||
side_effect=Exception('File Error'))
|
||||
tmpdir1 = Path(tmpdir)
|
||||
exchange = get_patched_exchange(mocker, default_conf)
|
||||
@@ -506,9 +506,7 @@ def test_refresh_backtest_ohlcv_data(
|
||||
mocker, default_conf, markets, caplog, testdatadir, trademode, callcount):
|
||||
dl_mock = mocker.patch('freqtrade.data.history.history_utils._download_pair_history',
|
||||
MagicMock())
|
||||
mocker.patch(
|
||||
'freqtrade.exchange.Exchange.markets', PropertyMock(return_value=markets)
|
||||
)
|
||||
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value=markets))
|
||||
mocker.patch.object(Path, "exists", MagicMock(return_value=True))
|
||||
mocker.patch.object(Path, "unlink", MagicMock())
|
||||
|
||||
@@ -531,9 +529,7 @@ def test_download_data_no_markets(mocker, default_conf, caplog, testdatadir):
|
||||
MagicMock())
|
||||
|
||||
ex = get_patched_exchange(mocker, default_conf)
|
||||
mocker.patch(
|
||||
'freqtrade.exchange.Exchange.markets', PropertyMock(return_value={})
|
||||
)
|
||||
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value={}))
|
||||
timerange = TimeRange.parse_timerange("20190101-20190102")
|
||||
unav_pairs = refresh_backtest_ohlcv_data(exchange=ex, pairs=["BTT/BTC", "LTC/USDT"],
|
||||
timeframes=["1m", "5m"],
|
||||
@@ -551,9 +547,7 @@ def test_download_data_no_markets(mocker, default_conf, caplog, testdatadir):
|
||||
def test_refresh_backtest_trades_data(mocker, default_conf, markets, caplog, testdatadir):
|
||||
dl_mock = mocker.patch('freqtrade.data.history.history_utils._download_trades_history',
|
||||
MagicMock())
|
||||
mocker.patch(
|
||||
'freqtrade.exchange.Exchange.markets', PropertyMock(return_value=markets)
|
||||
)
|
||||
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value=markets))
|
||||
mocker.patch.object(Path, "exists", MagicMock(return_value=True))
|
||||
mocker.patch.object(Path, "unlink", MagicMock())
|
||||
|
||||
@@ -577,8 +571,7 @@ def test_download_trades_history(trades_history, mocker, default_conf, testdatad
|
||||
tmpdir) -> None:
|
||||
tmpdir1 = Path(tmpdir)
|
||||
ght_mock = MagicMock(side_effect=lambda pair, *args, **kwargs: (pair, trades_history))
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_historic_trades',
|
||||
ght_mock)
|
||||
mocker.patch(f'{EXMS}.get_historic_trades', ght_mock)
|
||||
exchange = get_patched_exchange(mocker, default_conf)
|
||||
file1 = tmpdir1 / 'ETH_BTC-trades.json.gz'
|
||||
data_handler = get_datahandler(tmpdir1, data_format='jsongz')
|
||||
@@ -604,8 +597,7 @@ def test_download_trades_history(trades_history, mocker, default_conf, testdatad
|
||||
|
||||
file1.unlink()
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_historic_trades',
|
||||
MagicMock(side_effect=ValueError))
|
||||
mocker.patch(f'{EXMS}.get_historic_trades', MagicMock(side_effect=ValueError))
|
||||
|
||||
assert not _download_trades_history(data_handler=data_handler, exchange=exchange,
|
||||
pair='ETH/BTC')
|
||||
@@ -615,8 +607,7 @@ def test_download_trades_history(trades_history, mocker, default_conf, testdatad
|
||||
copyfile(testdatadir / file2.name, file2)
|
||||
|
||||
ght_mock.reset_mock()
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_historic_trades',
|
||||
ght_mock)
|
||||
mocker.patch(f'{EXMS}.get_historic_trades', ght_mock)
|
||||
# Since before first start date
|
||||
since_time = int(trades_history[0][0] // 1000) - 500
|
||||
timerange = TimeRange('date', None, since_time, 0)
|
||||
|
@@ -14,7 +14,7 @@ from freqtrade.data.converter import ohlcv_to_dataframe
|
||||
from freqtrade.edge import Edge, PairInfo
|
||||
from freqtrade.enums import ExitType
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from tests.conftest import get_patched_freqtradebot, log_has
|
||||
from tests.conftest import EXMS, get_patched_freqtradebot, log_has
|
||||
from tests.optimize import (BTContainer, BTrade, _build_backtest_dataframe,
|
||||
_get_frame_time_from_offset)
|
||||
|
||||
@@ -261,7 +261,7 @@ def mocked_load_data(datadir, pairs=[], timeframe='0m',
|
||||
|
||||
def test_edge_process_downloaded_data(mocker, edge_conf):
|
||||
freqtrade = get_patched_freqtradebot(mocker, edge_conf)
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', MagicMock(return_value=0.001))
|
||||
mocker.patch(f'{EXMS}.get_fee', MagicMock(return_value=0.001))
|
||||
mocker.patch('freqtrade.edge.edge_positioning.refresh_data', MagicMock())
|
||||
mocker.patch('freqtrade.edge.edge_positioning.load_data', mocked_load_data)
|
||||
edge = Edge(edge_conf, freqtrade.exchange, freqtrade.strategy)
|
||||
@@ -273,7 +273,7 @@ def test_edge_process_downloaded_data(mocker, edge_conf):
|
||||
|
||||
def test_edge_process_no_data(mocker, edge_conf, caplog):
|
||||
freqtrade = get_patched_freqtradebot(mocker, edge_conf)
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', MagicMock(return_value=0.001))
|
||||
mocker.patch(f'{EXMS}.get_fee', MagicMock(return_value=0.001))
|
||||
mocker.patch('freqtrade.edge.edge_positioning.refresh_data', MagicMock())
|
||||
mocker.patch('freqtrade.edge.edge_positioning.load_data', MagicMock(return_value={}))
|
||||
edge = Edge(edge_conf, freqtrade.exchange, freqtrade.strategy)
|
||||
@@ -286,7 +286,7 @@ def test_edge_process_no_data(mocker, edge_conf, caplog):
|
||||
|
||||
def test_edge_process_no_trades(mocker, edge_conf, caplog):
|
||||
freqtrade = get_patched_freqtradebot(mocker, edge_conf)
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', return_value=0.001)
|
||||
mocker.patch(f'{EXMS}.get_fee', return_value=0.001)
|
||||
mocker.patch('freqtrade.edge.edge_positioning.refresh_data', )
|
||||
mocker.patch('freqtrade.edge.edge_positioning.load_data', mocked_load_data)
|
||||
# Return empty
|
||||
@@ -303,7 +303,7 @@ def test_edge_process_no_pairs(mocker, edge_conf, caplog):
|
||||
mocker.patch('freqtrade.freqtradebot.validate_config_consistency')
|
||||
|
||||
freqtrade = get_patched_freqtradebot(mocker, edge_conf)
|
||||
fee_mock = mocker.patch('freqtrade.exchange.Exchange.get_fee', return_value=0.001)
|
||||
fee_mock = mocker.patch(f'{EXMS}.get_fee', return_value=0.001)
|
||||
mocker.patch('freqtrade.edge.edge_positioning.refresh_data')
|
||||
mocker.patch('freqtrade.edge.edge_positioning.load_data', mocked_load_data)
|
||||
# Return empty
|
||||
@@ -319,7 +319,7 @@ def test_edge_process_no_pairs(mocker, edge_conf, caplog):
|
||||
|
||||
def test_edge_init_error(mocker, edge_conf,):
|
||||
edge_conf['stake_amount'] = 0.5
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', MagicMock(return_value=0.001))
|
||||
mocker.patch(f'{EXMS}.get_fee', MagicMock(return_value=0.001))
|
||||
with pytest.raises(OperationalException, match='Edge works only with unlimited stake amount'):
|
||||
get_patched_freqtradebot(mocker, edge_conf)
|
||||
|
||||
|
@@ -7,7 +7,7 @@ import pytest
|
||||
|
||||
from freqtrade.enums import CandleType, MarginMode, TradingMode
|
||||
from freqtrade.exceptions import DependencyException, InvalidOrderException, OperationalException
|
||||
from tests.conftest import get_mock_coro, get_patched_exchange, log_has_re
|
||||
from tests.conftest import EXMS, get_mock_coro, get_patched_exchange, log_has_re
|
||||
from tests.exchange.test_exchange import ccxt_exceptionhandlers
|
||||
|
||||
|
||||
@@ -34,8 +34,8 @@ def test_create_stoploss_order_binance(default_conf, mocker, limitratio, expecte
|
||||
default_conf['dry_run'] = False
|
||||
default_conf['margin_mode'] = MarginMode.ISOLATED
|
||||
default_conf['trading_mode'] = trademode
|
||||
mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y)
|
||||
mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.amount_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.price_to_precision', lambda s, x, y: y)
|
||||
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance')
|
||||
|
||||
@@ -113,8 +113,8 @@ def test_create_stoploss_order_dry_run_binance(default_conf, mocker):
|
||||
api_mock = MagicMock()
|
||||
order_type = 'stop_loss_limit'
|
||||
default_conf['dry_run'] = True
|
||||
mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y)
|
||||
mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.amount_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.price_to_precision', lambda s, x, y: y)
|
||||
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance')
|
||||
|
||||
@@ -600,7 +600,7 @@ def test_get_maintenance_ratio_and_amt_binance(
|
||||
mm_ratio,
|
||||
amt,
|
||||
):
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', return_value=True)
|
||||
mocker.patch(f'{EXMS}.exchange_has', return_value=True)
|
||||
exchange = get_patched_exchange(mocker, default_conf, id="binance")
|
||||
exchange._leverage_tiers = leverage_tiers
|
||||
(result_ratio, result_amt) = exchange.get_maintenance_ratio_and_amt(pair, nominal_value)
|
||||
|
@@ -1,7 +1,7 @@
|
||||
from datetime import datetime
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from tests.conftest import get_patched_exchange
|
||||
from tests.conftest import EXMS, get_patched_exchange
|
||||
|
||||
|
||||
def test_get_trades_for_order(default_conf, mocker):
|
||||
@@ -9,7 +9,7 @@ def test_get_trades_for_order(default_conf, mocker):
|
||||
order_id = 'ABCD-ABCD'
|
||||
since = datetime(2018, 5, 5, 0, 0, 0)
|
||||
default_conf["dry_run"] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', return_value=True)
|
||||
mocker.patch(f'{EXMS}.exchange_has', return_value=True)
|
||||
api_mock = MagicMock()
|
||||
|
||||
api_mock.fetch_my_trades = MagicMock(return_value=[{'id': 'TTR67E-3PFBD-76IISV',
|
||||
|
@@ -1,3 +1,4 @@
|
||||
from datetime import datetime, timezone
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
from freqtrade.enums.marginmode import MarginMode
|
||||
@@ -55,3 +56,19 @@ async def test_bybit_fetch_funding_rate(default_conf, mocker):
|
||||
kwargs = api_mock.fetch_funding_rate_history.call_args_list[0][1]
|
||||
assert kwargs['params'] == {'until': since_ms_end}
|
||||
assert kwargs['since'] == since_ms
|
||||
|
||||
|
||||
def test_bybit_get_funding_fees(default_conf, mocker):
|
||||
now = datetime.now(timezone.utc)
|
||||
exchange = get_patched_exchange(mocker, default_conf, id='bybit')
|
||||
exchange._fetch_and_calculate_funding_fees = MagicMock()
|
||||
exchange.get_funding_fees('BTC/USDT:USDT', 1, False, now)
|
||||
assert exchange._fetch_and_calculate_funding_fees.call_count == 0
|
||||
|
||||
default_conf['trading_mode'] = 'futures'
|
||||
default_conf['margin_mode'] = 'isolated'
|
||||
exchange = get_patched_exchange(mocker, default_conf, id='bybit')
|
||||
exchange._fetch_and_calculate_funding_fees = MagicMock()
|
||||
exchange.get_funding_fees('BTC/USDT:USDT', 1, False, now)
|
||||
|
||||
assert exchange._fetch_and_calculate_funding_fees.call_count == 1
|
||||
|
@@ -17,7 +17,7 @@ from freqtrade.enums import CandleType
|
||||
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_prev_date
|
||||
from freqtrade.exchange.exchange import Exchange, timeframe_to_msecs
|
||||
from freqtrade.resolvers.exchange_resolver import ExchangeResolver
|
||||
from tests.conftest import get_default_conf_usdt
|
||||
from tests.conftest import EXMS, get_default_conf_usdt
|
||||
|
||||
|
||||
EXCHANGE_FIXTURE_TYPE = Tuple[Exchange, str]
|
||||
@@ -309,7 +309,7 @@ def exchange(request, exchange_conf):
|
||||
|
||||
@pytest.fixture(params=EXCHANGES, scope="class")
|
||||
def exchange_futures(request, exchange_conf, class_mocker):
|
||||
if not EXCHANGES[request.param].get('futures') is True:
|
||||
if EXCHANGES[request.param].get('futures') is not True:
|
||||
yield None, request.param
|
||||
else:
|
||||
exchange_conf = set_test_proxy(
|
||||
@@ -322,13 +322,12 @@ def exchange_futures(request, exchange_conf, class_mocker):
|
||||
|
||||
class_mocker.patch(
|
||||
'freqtrade.exchange.binance.Binance.fill_leverage_tiers')
|
||||
class_mocker.patch('freqtrade.exchange.exchange.Exchange.fetch_trading_fees')
|
||||
class_mocker.patch(f'{EXMS}.fetch_trading_fees')
|
||||
class_mocker.patch('freqtrade.exchange.okx.Okx.additional_exchange_init')
|
||||
class_mocker.patch('freqtrade.exchange.binance.Binance.additional_exchange_init')
|
||||
class_mocker.patch('freqtrade.exchange.bybit.Bybit.additional_exchange_init')
|
||||
class_mocker.patch('freqtrade.exchange.exchange.Exchange.load_cached_leverage_tiers',
|
||||
return_value=None)
|
||||
class_mocker.patch('freqtrade.exchange.exchange.Exchange.cache_leverage_tiers')
|
||||
class_mocker.patch(f'{EXMS}.load_cached_leverage_tiers', return_value=None)
|
||||
class_mocker.patch(f'{EXMS}.cache_leverage_tiers')
|
||||
|
||||
exchange = ExchangeResolver.load_exchange(
|
||||
request.param, exchange_conf, validate=True, load_leverage_tiers=True)
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -7,18 +7,18 @@ from freqtrade.enums import MarginMode, TradingMode
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.exchange import Gate
|
||||
from freqtrade.resolvers.exchange_resolver import ExchangeResolver
|
||||
from tests.conftest import get_patched_exchange
|
||||
from tests.conftest import EXMS, get_patched_exchange
|
||||
|
||||
|
||||
def test_validate_order_types_gate(default_conf, mocker):
|
||||
default_conf['exchange']['name'] = 'gate'
|
||||
mocker.patch('freqtrade.exchange.Exchange._init_ccxt')
|
||||
mocker.patch('freqtrade.exchange.Exchange._load_markets', return_value={})
|
||||
mocker.patch('freqtrade.exchange.Exchange.validate_pairs')
|
||||
mocker.patch('freqtrade.exchange.Exchange.validate_timeframes')
|
||||
mocker.patch('freqtrade.exchange.Exchange.validate_stakecurrency')
|
||||
mocker.patch('freqtrade.exchange.Exchange.validate_pricing')
|
||||
mocker.patch('freqtrade.exchange.Exchange.name', 'Gate')
|
||||
mocker.patch(f'{EXMS}._init_ccxt')
|
||||
mocker.patch(f'{EXMS}._load_markets', return_value={})
|
||||
mocker.patch(f'{EXMS}.validate_pairs')
|
||||
mocker.patch(f'{EXMS}.validate_timeframes')
|
||||
mocker.patch(f'{EXMS}.validate_stakecurrency')
|
||||
mocker.patch(f'{EXMS}.validate_pricing')
|
||||
mocker.patch(f'{EXMS}.name', 'Gate')
|
||||
exch = ExchangeResolver.load_exchange('gate', default_conf, True)
|
||||
assert isinstance(exch, Gate)
|
||||
|
||||
@@ -105,7 +105,7 @@ def test_stoploss_adjust_gate(mocker, default_conf, sl1, sl2, sl3, side):
|
||||
('maker', 0.0, 0.0),
|
||||
])
|
||||
def test_fetch_my_trades_gate(mocker, default_conf, takerormaker, rate, cost):
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', return_value=True)
|
||||
mocker.patch(f'{EXMS}.exchange_has', return_value=True)
|
||||
tick = {'ETH/USDT:USDT': {
|
||||
'info': {'user_id': '',
|
||||
'taker_fee': '0.0018',
|
||||
|
@@ -5,7 +5,7 @@ import ccxt
|
||||
import pytest
|
||||
|
||||
from freqtrade.exceptions import DependencyException, InvalidOrderException, OperationalException
|
||||
from tests.conftest import get_patched_exchange
|
||||
from tests.conftest import EXMS, get_patched_exchange
|
||||
from tests.exchange.test_exchange import ccxt_exceptionhandlers
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ def test_create_stoploss_order_huobi(default_conf, mocker, limitratio, expected,
|
||||
}
|
||||
})
|
||||
default_conf['dry_run'] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y)
|
||||
mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.amount_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.price_to_precision', lambda s, x, y: y)
|
||||
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'huobi')
|
||||
|
||||
@@ -79,8 +79,8 @@ def test_create_stoploss_order_dry_run_huobi(default_conf, mocker):
|
||||
api_mock = MagicMock()
|
||||
order_type = 'stop-limit'
|
||||
default_conf['dry_run'] = True
|
||||
mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y)
|
||||
mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.amount_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.price_to_precision', lambda s, x, y: y)
|
||||
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'huobi')
|
||||
|
||||
|
@@ -5,7 +5,7 @@ import ccxt
|
||||
import pytest
|
||||
|
||||
from freqtrade.exceptions import DependencyException, InvalidOrderException
|
||||
from tests.conftest import get_patched_exchange
|
||||
from tests.conftest import EXMS, get_patched_exchange
|
||||
from tests.exchange.test_exchange import ccxt_exceptionhandlers
|
||||
|
||||
|
||||
@@ -28,8 +28,8 @@ def test_buy_kraken_trading_agreement(default_conf, mocker):
|
||||
})
|
||||
default_conf['dry_run'] = False
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y)
|
||||
mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.amount_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.price_to_precision', lambda s, x, y: y)
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock, id="kraken")
|
||||
|
||||
order = exchange.create_order(
|
||||
@@ -68,8 +68,8 @@ def test_sell_kraken_trading_agreement(default_conf, mocker):
|
||||
})
|
||||
default_conf['dry_run'] = False
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y)
|
||||
mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.amount_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.price_to_precision', lambda s, x, y: y)
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock, id="kraken")
|
||||
|
||||
order = exchange.create_order(pair='ETH/BTC', ordertype=order_type,
|
||||
@@ -191,8 +191,8 @@ def test_create_stoploss_order_kraken(default_conf, mocker, ordertype, side, adj
|
||||
})
|
||||
|
||||
default_conf['dry_run'] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y)
|
||||
mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.amount_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.price_to_precision', lambda s, x, y: y)
|
||||
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kraken')
|
||||
|
||||
@@ -262,8 +262,8 @@ def test_create_stoploss_order_kraken(default_conf, mocker, ordertype, side, adj
|
||||
def test_create_stoploss_order_dry_run_kraken(default_conf, mocker, side):
|
||||
api_mock = MagicMock()
|
||||
default_conf['dry_run'] = True
|
||||
mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y)
|
||||
mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.amount_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.price_to_precision', lambda s, x, y: y)
|
||||
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kraken')
|
||||
|
||||
|
@@ -5,7 +5,7 @@ import ccxt
|
||||
import pytest
|
||||
|
||||
from freqtrade.exceptions import DependencyException, InvalidOrderException, OperationalException
|
||||
from tests.conftest import get_patched_exchange
|
||||
from tests.conftest import EXMS, get_patched_exchange
|
||||
from tests.exchange.test_exchange import ccxt_exceptionhandlers
|
||||
|
||||
|
||||
@@ -26,8 +26,8 @@ def test_create_stoploss_order_kucoin(default_conf, mocker, limitratio, expected
|
||||
}
|
||||
})
|
||||
default_conf['dry_run'] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y)
|
||||
mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.amount_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.price_to_precision', lambda s, x, y: y)
|
||||
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kucoin')
|
||||
if order_type == 'limit':
|
||||
@@ -87,8 +87,8 @@ def test_stoploss_order_dry_run_kucoin(default_conf, mocker):
|
||||
api_mock = MagicMock()
|
||||
order_type = 'market'
|
||||
default_conf['dry_run'] = True
|
||||
mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y)
|
||||
mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.amount_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.price_to_precision', lambda s, x, y: y)
|
||||
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kucoin')
|
||||
|
||||
@@ -125,3 +125,45 @@ def test_stoploss_adjust_kucoin(mocker, default_conf):
|
||||
# Test with invalid order case
|
||||
order['stopPrice'] = None
|
||||
assert exchange.stoploss_adjust(1501, order, 'sell')
|
||||
|
||||
|
||||
@pytest.mark.parametrize("side", ["buy", "sell"])
|
||||
@pytest.mark.parametrize("ordertype,rate", [
|
||||
("market", None),
|
||||
("market", 200),
|
||||
("limit", 200),
|
||||
("stop_loss_limit", 200)
|
||||
])
|
||||
def test_kucoin_create_order(default_conf, mocker, side, ordertype, rate):
|
||||
api_mock = MagicMock()
|
||||
order_id = 'test_prod_{}_{}'.format(side, randint(0, 10 ** 6))
|
||||
api_mock.create_order = MagicMock(return_value={
|
||||
'id': order_id,
|
||||
'info': {
|
||||
'foo': 'bar'
|
||||
},
|
||||
'symbol': 'XRP/USDT',
|
||||
'amount': 1
|
||||
})
|
||||
default_conf['dry_run'] = False
|
||||
mocker.patch(f'{EXMS}.amount_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.price_to_precision', lambda s, x, y: y)
|
||||
exchange = get_patched_exchange(mocker, default_conf, api_mock, id='kucoin')
|
||||
exchange._set_leverage = MagicMock()
|
||||
exchange.set_margin_mode = MagicMock()
|
||||
|
||||
order = exchange.create_order(
|
||||
pair='XRP/USDT',
|
||||
ordertype=ordertype,
|
||||
side=side,
|
||||
amount=1,
|
||||
rate=rate,
|
||||
leverage=1.0
|
||||
)
|
||||
|
||||
assert 'id' in order
|
||||
assert 'info' in order
|
||||
assert order['id'] == order_id
|
||||
assert order['amount'] == 1
|
||||
# Status must be faked to open for kucoin.
|
||||
assert order['status'] == 'open'
|
||||
|
@@ -46,7 +46,7 @@ def test_get_maintenance_ratio_and_amt_okx(
|
||||
default_conf['margin_mode'] = 'isolated'
|
||||
default_conf['dry_run'] = False
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Okx',
|
||||
'freqtrade.exchange.okx.Okx',
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
load_leverage_tiers=MagicMock(return_value={
|
||||
'ETH/USDT:USDT': [
|
||||
|
@@ -27,7 +27,7 @@ def freqai_conf(default_conf, tmpdir):
|
||||
"timerange": "20180110-20180115",
|
||||
"freqai": {
|
||||
"enabled": True,
|
||||
"purge_old_models": True,
|
||||
"purge_old_models": 2,
|
||||
"train_period_days": 2,
|
||||
"backtest_period_days": 10,
|
||||
"live_retrain_hours": 0,
|
||||
@@ -46,6 +46,8 @@ def freqai_conf(default_conf, tmpdir):
|
||||
"use_SVM_to_remove_outliers": True,
|
||||
"stratify_training_data": 0,
|
||||
"indicator_periods_candles": [10],
|
||||
"shuffle_after_split": False,
|
||||
"buffer_train_data_candles": 0
|
||||
},
|
||||
"data_split_parameters": {"test_size": 0.33, "shuffle": False},
|
||||
"model_training_parameters": {"n_estimators": 100},
|
||||
|
@@ -35,8 +35,8 @@ def test_freqai_backtest_start_backtest_list(freqai_conf, mocker, testdatadir, c
|
||||
args = get_args(args)
|
||||
bt_config = setup_optimize_configuration(args, RunMode.BACKTEST)
|
||||
Backtesting(bt_config)
|
||||
assert log_has_re('Using --strategy-list with FreqAI REQUIRES all strategies to have identical '
|
||||
'populate_any_indicators.', caplog)
|
||||
assert log_has_re('Using --strategy-list with FreqAI REQUIRES all strategies to have identical',
|
||||
caplog)
|
||||
Backtesting.cleanup()
|
||||
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
import platform
|
||||
import shutil
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
@@ -13,10 +14,14 @@ from freqtrade.freqai.utils import download_all_data_for_training, get_required_
|
||||
from freqtrade.optimize.backtesting import Backtesting
|
||||
from freqtrade.persistence import Trade
|
||||
from freqtrade.plugins.pairlistmanager import PairListManager
|
||||
from tests.conftest import create_mock_trades, get_patched_exchange, log_has_re
|
||||
from tests.conftest import EXMS, create_mock_trades, get_patched_exchange, log_has_re
|
||||
from tests.freqai.conftest import get_patched_freqai_strategy, make_rl_config
|
||||
|
||||
|
||||
def is_py11() -> bool:
|
||||
return sys.version_info >= (3, 11)
|
||||
|
||||
|
||||
def is_arm() -> bool:
|
||||
machine = platform.machine()
|
||||
return "arm" in machine or "aarch64" in machine
|
||||
@@ -27,25 +32,32 @@ def is_mac() -> bool:
|
||||
return "Darwin" in machine
|
||||
|
||||
|
||||
@pytest.mark.parametrize('model, pca, dbscan, float32, can_short', [
|
||||
('LightGBMRegressor', True, False, True, True),
|
||||
('XGBoostRegressor', False, True, False, True),
|
||||
('XGBoostRFRegressor', False, False, False, True),
|
||||
('CatboostRegressor', False, False, False, True),
|
||||
('ReinforcementLearner', False, True, False, True),
|
||||
('ReinforcementLearner_multiproc', False, False, False, True),
|
||||
('ReinforcementLearner_test_3ac', False, False, False, False),
|
||||
('ReinforcementLearner_test_3ac', False, False, False, True),
|
||||
('ReinforcementLearner_test_4ac', False, False, False, True)
|
||||
])
|
||||
def test_extract_data_and_train_model_Standard(mocker, freqai_conf, model, pca,
|
||||
dbscan, float32, can_short):
|
||||
if is_arm() and model == 'CatboostRegressor':
|
||||
def can_run_model(model: str) -> None:
|
||||
if (is_arm() or is_py11()) and "Catboost" in model:
|
||||
pytest.skip("CatBoost is not supported on ARM")
|
||||
|
||||
if is_mac() and not is_arm() and 'Reinforcement' in model:
|
||||
pytest.skip("Reinforcement learning module not available on intel based Mac OS")
|
||||
|
||||
if is_py11() and 'Reinforcement' in model:
|
||||
pytest.skip("Reinforcement learning currently not available on python 3.11.")
|
||||
|
||||
|
||||
@pytest.mark.parametrize('model, pca, dbscan, float32, can_short, shuffle, buffer', [
|
||||
('LightGBMRegressor', True, False, True, True, False, 0),
|
||||
('XGBoostRegressor', False, True, False, True, False, 10),
|
||||
('XGBoostRFRegressor', False, False, False, True, False, 0),
|
||||
('CatboostRegressor', False, False, False, True, True, 0),
|
||||
('ReinforcementLearner', False, True, False, True, False, 0),
|
||||
('ReinforcementLearner_multiproc', False, False, False, True, False, 0),
|
||||
('ReinforcementLearner_test_3ac', False, False, False, False, False, 0),
|
||||
('ReinforcementLearner_test_3ac', False, False, False, True, False, 0),
|
||||
('ReinforcementLearner_test_4ac', False, False, False, True, False, 0)
|
||||
])
|
||||
def test_extract_data_and_train_model_Standard(mocker, freqai_conf, model, pca,
|
||||
dbscan, float32, can_short, shuffle, buffer):
|
||||
|
||||
can_run_model(model)
|
||||
model_save_ext = 'joblib'
|
||||
freqai_conf.update({"freqaimodel": model})
|
||||
freqai_conf.update({"timerange": "20180110-20180130"})
|
||||
@@ -53,6 +65,8 @@ def test_extract_data_and_train_model_Standard(mocker, freqai_conf, model, pca,
|
||||
freqai_conf['freqai']['feature_parameters'].update({"principal_component_analysis": pca})
|
||||
freqai_conf['freqai']['feature_parameters'].update({"use_DBSCAN_to_remove_outliers": dbscan})
|
||||
freqai_conf.update({"reduce_df_footprint": float32})
|
||||
freqai_conf['freqai']['feature_parameters'].update({"shuffle_after_split": shuffle})
|
||||
freqai_conf['freqai']['feature_parameters'].update({"buffer_train_data_candles": buffer})
|
||||
|
||||
if 'ReinforcementLearner' in model:
|
||||
model_save_ext = 'zip'
|
||||
@@ -114,7 +128,7 @@ def test_extract_data_and_train_model_Standard(mocker, freqai_conf, model, pca,
|
||||
('CatboostClassifierMultiTarget', "freqai_test_multimodel_classifier_strat")
|
||||
])
|
||||
def test_extract_data_and_train_model_MultiTargets(mocker, freqai_conf, model, strat):
|
||||
if is_arm() and 'Catboost' in model:
|
||||
if (is_arm() or is_py11()) and 'Catboost' in model:
|
||||
pytest.skip("CatBoost is not supported on ARM")
|
||||
|
||||
freqai_conf.update({"timerange": "20180110-20180130"})
|
||||
@@ -156,7 +170,7 @@ def test_extract_data_and_train_model_MultiTargets(mocker, freqai_conf, model, s
|
||||
'XGBoostRFClassifier',
|
||||
])
|
||||
def test_extract_data_and_train_model_Classifiers(mocker, freqai_conf, model):
|
||||
if is_arm() and model == 'CatboostClassifier':
|
||||
if (is_arm() or is_py11()) and model == 'CatboostClassifier':
|
||||
pytest.skip("CatBoost is not supported on ARM")
|
||||
|
||||
freqai_conf.update({"freqaimodel": model})
|
||||
@@ -203,13 +217,11 @@ def test_extract_data_and_train_model_Classifiers(mocker, freqai_conf, model):
|
||||
],
|
||||
)
|
||||
def test_start_backtesting(mocker, freqai_conf, model, num_files, strat, caplog):
|
||||
can_run_model(model)
|
||||
|
||||
freqai_conf.get("freqai", {}).update({"save_backtest_models": True})
|
||||
freqai_conf['runmode'] = RunMode.BACKTEST
|
||||
if is_arm() and "Catboost" in model:
|
||||
pytest.skip("CatBoost is not supported on ARM")
|
||||
|
||||
if is_mac() and 'Reinforcement' in model:
|
||||
pytest.skip("Reinforcement learning module not available on intel based Mac OS")
|
||||
Trade.use_db = False
|
||||
|
||||
freqai_conf.update({"freqaimodel": model})
|
||||
@@ -506,6 +518,8 @@ def test_get_state_info(mocker, freqai_conf, dp_exists, caplog, tickers):
|
||||
|
||||
if is_mac():
|
||||
pytest.skip("Reinforcement learning module not available on intel based Mac OS")
|
||||
if is_py11():
|
||||
pytest.skip("Reinforcement learning currently not available on python 3.11.")
|
||||
|
||||
freqai_conf.update({"freqaimodel": "ReinforcementLearner"})
|
||||
freqai_conf.update({"timerange": "20180110-20180130"})
|
||||
@@ -517,7 +531,7 @@ def test_get_state_info(mocker, freqai_conf, dp_exists, caplog, tickers):
|
||||
strategy = get_patched_freqai_strategy(mocker, freqai_conf)
|
||||
exchange = get_patched_exchange(mocker, freqai_conf)
|
||||
ticker_mock = MagicMock(return_value=tickers()['ETH/BTC'])
|
||||
mocker.patch("freqtrade.exchange.Exchange.fetch_ticker", ticker_mock)
|
||||
mocker.patch(f"{EXMS}.fetch_ticker", ticker_mock)
|
||||
strategy.dp = DataProvider(freqai_conf, exchange)
|
||||
|
||||
if not dp_exists:
|
||||
|
@@ -8,7 +8,7 @@ from freqtrade.data.history import get_timerange
|
||||
from freqtrade.enums import ExitType
|
||||
from freqtrade.optimize.backtesting import Backtesting
|
||||
from freqtrade.persistence.trade_model import LocalTrade
|
||||
from tests.conftest import patch_exchange
|
||||
from tests.conftest import EXMS, patch_exchange
|
||||
from tests.optimize import (BTContainer, BTrade, _build_backtest_dataframe,
|
||||
_get_frame_time_from_offset, tests_timeframe)
|
||||
|
||||
@@ -921,10 +921,10 @@ def test_backtest_results(default_conf, fee, mocker, caplog, data: BTContainer)
|
||||
default_conf["use_exit_signal"] = data.use_exit_signal
|
||||
default_conf["max_open_trades"] = 10
|
||||
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_fee", return_value=0.0)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
mocker.patch("freqtrade.exchange.Binance.get_max_leverage", return_value=100)
|
||||
mocker.patch(f"{EXMS}.get_fee", return_value=0.0)
|
||||
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('freqtrade.exchange.binance.Binance.get_max_leverage', return_value=100)
|
||||
patch_exchange(mocker)
|
||||
frame = _build_backtest_dataframe(data.data)
|
||||
backtesting = Backtesting(default_conf)
|
||||
|
@@ -26,8 +26,8 @@ from freqtrade.optimize.backtest_caching import get_strategy_run_id
|
||||
from freqtrade.optimize.backtesting import Backtesting
|
||||
from freqtrade.persistence import LocalTrade, Trade
|
||||
from freqtrade.resolvers import StrategyResolver
|
||||
from tests.conftest import (CURRENT_TEST_STRATEGY, get_args, log_has, log_has_re, patch_exchange,
|
||||
patched_configuration_load_config_file)
|
||||
from tests.conftest import (CURRENT_TEST_STRATEGY, EXMS, get_args, log_has, log_has_re,
|
||||
patch_exchange, patched_configuration_load_config_file)
|
||||
|
||||
|
||||
ORDER_TYPES = [
|
||||
@@ -245,7 +245,7 @@ def test_setup_optimize_configuration_stake_amount(mocker, default_conf, caplog)
|
||||
|
||||
def test_start(mocker, fee, default_conf, caplog) -> None:
|
||||
start_mock = MagicMock()
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch(f'{EXMS}.get_fee', fee)
|
||||
patch_exchange(mocker)
|
||||
mocker.patch('freqtrade.optimize.backtesting.Backtesting.start', start_mock)
|
||||
patched_configuration_load_config_file(mocker, default_conf)
|
||||
@@ -269,7 +269,7 @@ def test_backtesting_init(mocker, default_conf, order_types) -> None:
|
||||
"""
|
||||
default_conf["order_types"] = order_types
|
||||
patch_exchange(mocker)
|
||||
get_fee = mocker.patch('freqtrade.exchange.Exchange.get_fee', MagicMock(return_value=0.5))
|
||||
get_fee = mocker.patch(f'{EXMS}.get_fee', MagicMock(return_value=0.5))
|
||||
backtesting = Backtesting(default_conf)
|
||||
backtesting._set_strategy(backtesting.strategylist[0])
|
||||
assert backtesting.config == default_conf
|
||||
@@ -290,7 +290,7 @@ def test_backtesting_init_no_timeframe(mocker, default_conf, caplog) -> None:
|
||||
default_conf['strategy_list'] = [CURRENT_TEST_STRATEGY,
|
||||
'HyperoptableStrategy']
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', MagicMock(return_value=0.5))
|
||||
mocker.patch(f'{EXMS}.get_fee', MagicMock(return_value=0.5))
|
||||
with pytest.raises(OperationalException,
|
||||
match=r"Timeframe needs to be set in either configuration"):
|
||||
Backtesting(default_conf)
|
||||
@@ -300,7 +300,7 @@ def test_data_with_fee(default_conf, mocker) -> None:
|
||||
patch_exchange(mocker)
|
||||
default_conf['fee'] = 0.1234
|
||||
|
||||
fee_mock = mocker.patch('freqtrade.exchange.Exchange.get_fee', MagicMock(return_value=0.5))
|
||||
fee_mock = mocker.patch(f'{EXMS}.get_fee', MagicMock(return_value=0.5))
|
||||
backtesting = Backtesting(default_conf)
|
||||
backtesting._set_strategy(backtesting.strategylist[0])
|
||||
assert backtesting.fee == 0.1234
|
||||
@@ -404,7 +404,7 @@ def test_backtesting_start_no_data(default_conf, mocker, caplog, testdatadir) ->
|
||||
|
||||
|
||||
def test_backtesting_no_pair_left(default_conf, mocker, caplog, testdatadir) -> None:
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
|
||||
mocker.patch(f'{EXMS}.exchange_has', MagicMock(return_value=True))
|
||||
mocker.patch('freqtrade.data.history.history_utils.load_pair_history',
|
||||
MagicMock(return_value=pd.DataFrame()))
|
||||
mocker.patch('freqtrade.data.history.get_timerange', get_timerange)
|
||||
@@ -436,9 +436,9 @@ def test_backtesting_no_pair_left(default_conf, mocker, caplog, testdatadir) ->
|
||||
|
||||
|
||||
def test_backtesting_pairlist_list(default_conf, mocker, caplog, testdatadir, tickers) -> None:
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_tickers', tickers)
|
||||
mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y)
|
||||
mocker.patch(f'{EXMS}.exchange_has', MagicMock(return_value=True))
|
||||
mocker.patch(f'{EXMS}.get_tickers', tickers)
|
||||
mocker.patch(f'{EXMS}.price_to_precision', lambda s, x, y: y)
|
||||
mocker.patch('freqtrade.data.history.get_timerange', get_timerange)
|
||||
patch_exchange(mocker)
|
||||
mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest')
|
||||
@@ -474,9 +474,9 @@ def test_backtesting_pairlist_list(default_conf, mocker, caplog, testdatadir, ti
|
||||
|
||||
def test_backtest__enter_trade(default_conf, fee, mocker) -> None:
|
||||
default_conf['use_exit_signal'] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
mocker.patch(f'{EXMS}.get_fee', fee)
|
||||
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'))
|
||||
patch_exchange(mocker)
|
||||
default_conf['stake_amount'] = 'unlimited'
|
||||
default_conf['max_open_trades'] = 2
|
||||
@@ -525,7 +525,7 @@ def test_backtest__enter_trade(default_conf, fee, mocker) -> None:
|
||||
assert trade.stake_amount == 495
|
||||
assert trade.is_short is True
|
||||
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=300.0)
|
||||
mocker.patch(f"{EXMS}.get_max_pair_stake_amount", return_value=300.0)
|
||||
trade = backtesting._enter_trade(pair, row=row, direction='long')
|
||||
assert trade
|
||||
assert trade.stake_amount == 300.0
|
||||
@@ -533,10 +533,10 @@ def test_backtest__enter_trade(default_conf, fee, mocker) -> None:
|
||||
|
||||
def test_backtest__enter_trade_futures(default_conf_usdt, fee, mocker) -> None:
|
||||
default_conf_usdt['use_exit_signal'] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_leverage", return_value=100)
|
||||
mocker.patch(f'{EXMS}.get_fee', fee)
|
||||
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_leverage", return_value=100)
|
||||
mocker.patch("freqtrade.optimize.backtesting.price_to_precision", lambda p, *args: p)
|
||||
patch_exchange(mocker)
|
||||
default_conf_usdt['stake_amount'] = 300
|
||||
@@ -564,7 +564,7 @@ def test_backtest__enter_trade_futures(default_conf_usdt, fee, mocker) -> None:
|
||||
]
|
||||
|
||||
backtesting.strategy.leverage = MagicMock(return_value=5.0)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_maintenance_ratio_and_amt",
|
||||
mocker.patch(f"{EXMS}.get_maintenance_ratio_and_amt",
|
||||
return_value=(0.01, 0.01))
|
||||
|
||||
# leverage = 5
|
||||
@@ -601,7 +601,7 @@ def test_backtest__enter_trade_futures(default_conf_usdt, fee, mocker) -> None:
|
||||
assert pytest.approx(trade.liquidation_price) == 0.11787191
|
||||
|
||||
# Stake-amount too high!
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=600.0)
|
||||
mocker.patch(f"{EXMS}.get_min_pair_stake_amount", return_value=600.0)
|
||||
|
||||
trade = backtesting._enter_trade(pair, row=row, direction='long')
|
||||
assert trade is None
|
||||
@@ -616,9 +616,9 @@ def test_backtest__enter_trade_futures(default_conf_usdt, fee, mocker) -> None:
|
||||
|
||||
def test_backtest__check_trade_exit(default_conf, fee, mocker) -> None:
|
||||
default_conf['use_exit_signal'] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
mocker.patch(f'{EXMS}.get_fee', fee)
|
||||
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'))
|
||||
patch_exchange(mocker)
|
||||
default_conf['timeframe_detail'] = '1m'
|
||||
default_conf['max_open_trades'] = 2
|
||||
@@ -681,9 +681,9 @@ def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None:
|
||||
default_conf['use_exit_signal'] = False
|
||||
default_conf['max_open_trades'] = 10
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
mocker.patch(f'{EXMS}.get_fee', fee)
|
||||
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'))
|
||||
patch_exchange(mocker)
|
||||
backtesting = Backtesting(default_conf)
|
||||
backtesting._set_strategy(backtesting.strategylist[0])
|
||||
@@ -766,9 +766,9 @@ def test_backtest_one(default_conf, fee, mocker, testdatadir) -> None:
|
||||
@pytest.mark.parametrize('use_detail', [True, False])
|
||||
def test_backtest_one_detail(default_conf_usdt, fee, mocker, testdatadir, use_detail) -> None:
|
||||
default_conf_usdt['use_exit_signal'] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
mocker.patch(f'{EXMS}.get_fee', fee)
|
||||
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'))
|
||||
if use_detail:
|
||||
default_conf_usdt['timeframe_detail'] = '1m'
|
||||
patch_exchange(mocker)
|
||||
@@ -854,12 +854,12 @@ def test_backtest_one_detail_futures(
|
||||
default_conf_usdt['margin_mode'] = 'isolated'
|
||||
default_conf_usdt['candle_type_def'] = CandleType.FUTURES
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
mocker.patch(f'{EXMS}.get_fee', fee)
|
||||
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('freqtrade.plugins.pairlistmanager.PairListManager.whitelist',
|
||||
PropertyMock(return_value=['XRP/USDT:USDT']))
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_maintenance_ratio_and_amt",
|
||||
mocker.patch(f"{EXMS}.get_maintenance_ratio_and_amt",
|
||||
return_value=(0.01, 0.01))
|
||||
default_conf_usdt['timeframe'] = '1h'
|
||||
if use_detail:
|
||||
@@ -945,12 +945,12 @@ def test_backtest_one_detail_futures_funding_fees(
|
||||
default_conf_usdt['minimal_roi'] = {'0': 1}
|
||||
default_conf_usdt['dry_run_wallet'] = 100000
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
mocker.patch(f'{EXMS}.get_fee', fee)
|
||||
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('freqtrade.plugins.pairlistmanager.PairListManager.whitelist',
|
||||
PropertyMock(return_value=['XRP/USDT:USDT']))
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_maintenance_ratio_and_amt",
|
||||
mocker.patch(f"{EXMS}.get_maintenance_ratio_and_amt",
|
||||
return_value=(0.01, 0.01))
|
||||
default_conf_usdt['timeframe'] = '1h'
|
||||
if use_detail:
|
||||
@@ -1010,9 +1010,9 @@ def test_backtest_timedout_entry_orders(default_conf, fee, mocker, testdatadir)
|
||||
default_conf['startup_candle_count'] = 0
|
||||
# Cancel unfilled order after 4 minutes on 5m timeframe.
|
||||
default_conf["unfilledtimeout"] = {"entry": 4}
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
mocker.patch(f'{EXMS}.get_fee', fee)
|
||||
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'))
|
||||
patch_exchange(mocker)
|
||||
default_conf['max_open_trades'] = 1
|
||||
backtesting = Backtesting(default_conf)
|
||||
@@ -1035,9 +1035,9 @@ def test_backtest_timedout_entry_orders(default_conf, fee, mocker, testdatadir)
|
||||
def test_backtest_1min_timeframe(default_conf, fee, mocker, testdatadir) -> None:
|
||||
default_conf['use_exit_signal'] = False
|
||||
default_conf['max_open_trades'] = 1
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
mocker.patch(f'{EXMS}.get_fee', fee)
|
||||
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'))
|
||||
patch_exchange(mocker)
|
||||
backtesting = Backtesting(default_conf)
|
||||
backtesting._set_strategy(backtesting.strategylist[0])
|
||||
@@ -1061,9 +1061,9 @@ def test_backtest_trim_no_data_left(default_conf, fee, mocker, testdatadir) -> N
|
||||
default_conf['use_exit_signal'] = False
|
||||
default_conf['max_open_trades'] = 10
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
mocker.patch(f'{EXMS}.get_fee', fee)
|
||||
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'))
|
||||
patch_exchange(mocker)
|
||||
backtesting = Backtesting(default_conf)
|
||||
backtesting._set_strategy(backtesting.strategylist[0])
|
||||
@@ -1105,9 +1105,9 @@ def test_processed(default_conf, mocker, testdatadir) -> None:
|
||||
def test_backtest_dataprovider_analyzed_df(default_conf, fee, mocker, testdatadir) -> None:
|
||||
default_conf['use_exit_signal'] = False
|
||||
default_conf['max_open_trades'] = 10
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=100000)
|
||||
mocker.patch(f'{EXMS}.get_fee', fee)
|
||||
mocker.patch(f"{EXMS}.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch(f"{EXMS}.get_max_pair_stake_amount", return_value=100000)
|
||||
patch_exchange(mocker)
|
||||
backtesting = Backtesting(default_conf)
|
||||
backtesting._set_strategy(backtesting.strategylist[0])
|
||||
@@ -1155,9 +1155,9 @@ def test_backtest_pricecontours_protections(default_conf, fee, mocker, testdatad
|
||||
default_conf['enable_protections'] = True
|
||||
default_conf['timeframe'] = '1m'
|
||||
default_conf['max_open_trades'] = 1
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
mocker.patch(f'{EXMS}.get_fee', fee)
|
||||
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'))
|
||||
tests = [
|
||||
['sine', 9],
|
||||
['raise', 10],
|
||||
@@ -1203,9 +1203,9 @@ def test_backtest_pricecontours(default_conf, fee, mocker, testdatadir,
|
||||
default_conf['protections'] = protections
|
||||
default_conf['enable_protections'] = True
|
||||
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
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_fee', fee)
|
||||
# While entry-signals are unrealistic, running backtesting
|
||||
# over and over again should not cause different results
|
||||
|
||||
@@ -1262,9 +1262,9 @@ def test_backtest_only_sell(mocker, default_conf, testdatadir):
|
||||
|
||||
|
||||
def test_backtest_alternate_buy_sell(default_conf, fee, mocker, testdatadir):
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
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_fee', fee)
|
||||
default_conf['max_open_trades'] = 10
|
||||
backtest_conf = _make_backtest_conf(mocker, conf=default_conf,
|
||||
pair='UNITTEST/BTC', datadir=testdatadir)
|
||||
@@ -1310,9 +1310,9 @@ def test_backtest_multi_pair(default_conf, fee, mocker, tres, pair, testdatadir)
|
||||
dataframe['exit_short'] = 0
|
||||
return dataframe
|
||||
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
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_fee', fee)
|
||||
patch_exchange(mocker)
|
||||
|
||||
pairs = ['ADA/BTC', 'DASH/BTC', 'ETH/BTC', 'LTC/BTC', 'NXT/BTC']
|
||||
|
@@ -12,17 +12,17 @@ from freqtrade.data import history
|
||||
from freqtrade.data.history import get_timerange
|
||||
from freqtrade.enums import ExitType
|
||||
from freqtrade.optimize.backtesting import Backtesting
|
||||
from tests.conftest import patch_exchange
|
||||
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('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
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("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=0.00001)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
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'))
|
||||
patch_exchange(mocker)
|
||||
default_conf.update({
|
||||
"stake_amount": 100.0,
|
||||
@@ -99,10 +99,10 @@ def test_backtest_position_adjustment(default_conf, fee, mocker, testdatadir) ->
|
||||
])
|
||||
def test_backtest_position_adjustment_detailed(default_conf, fee, mocker, leverage) -> None:
|
||||
default_conf['use_exit_signal'] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_min_pair_stake_amount", return_value=10)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_pair_stake_amount", return_value=float('inf'))
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_leverage", return_value=10)
|
||||
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_leverage", return_value=10)
|
||||
|
||||
patch_exchange(mocker)
|
||||
default_conf.update({
|
||||
|
@@ -6,7 +6,7 @@ from unittest.mock import MagicMock
|
||||
from freqtrade.commands.optimize_commands import setup_optimize_configuration, start_edge
|
||||
from freqtrade.enums import RunMode
|
||||
from freqtrade.optimize.edge_cli import EdgeCli
|
||||
from tests.conftest import (CURRENT_TEST_STRATEGY, get_args, log_has, patch_exchange,
|
||||
from tests.conftest import (CURRENT_TEST_STRATEGY, EXMS, get_args, log_has, patch_exchange,
|
||||
patched_configuration_load_config_file)
|
||||
|
||||
|
||||
@@ -71,7 +71,7 @@ def test_setup_edge_configuration_with_arguments(mocker, edge_conf, caplog) -> N
|
||||
|
||||
def test_start(mocker, fee, edge_conf, caplog) -> None:
|
||||
start_mock = MagicMock()
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch(f'{EXMS}.get_fee', fee)
|
||||
patch_exchange(mocker)
|
||||
mocker.patch('freqtrade.optimize.edge_cli.EdgeCli.start', start_mock)
|
||||
patched_configuration_load_config_file(mocker, edge_conf)
|
||||
@@ -101,7 +101,7 @@ def test_edge_init_fee(mocker, edge_conf) -> None:
|
||||
patch_exchange(mocker)
|
||||
edge_conf['fee'] = 0.1234
|
||||
edge_conf['stake_amount'] = 20
|
||||
fee_mock = mocker.patch('freqtrade.exchange.Exchange.get_fee', MagicMock(return_value=0.5))
|
||||
fee_mock = mocker.patch(f'{EXMS}.get_fee', return_value=0.5)
|
||||
edge_cli = EdgeCli(edge_conf)
|
||||
assert edge_cli.edge.fee == 0.1234
|
||||
assert fee_mock.call_count == 0
|
||||
|
@@ -20,7 +20,7 @@ from freqtrade.optimize.hyperopt_tools import HyperoptTools
|
||||
from freqtrade.optimize.optimize_reports import generate_strategy_stats
|
||||
from freqtrade.optimize.space import SKDecimal
|
||||
from freqtrade.strategy import IntParameter
|
||||
from tests.conftest import (CURRENT_TEST_STRATEGY, get_args, get_markets, log_has, log_has_re,
|
||||
from tests.conftest import (CURRENT_TEST_STRATEGY, EXMS, get_args, get_markets, log_has, log_has_re,
|
||||
patch_exchange, patched_configuration_load_config_file)
|
||||
|
||||
|
||||
@@ -859,7 +859,7 @@ def test_simplified_interface_failed(mocker, hyperopt_conf, space) -> None:
|
||||
|
||||
def test_in_strategy_auto_hyperopt(mocker, hyperopt_conf, tmpdir, fee) -> None:
|
||||
patch_exchange(mocker)
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch(f'{EXMS}.get_fee', fee)
|
||||
(Path(tmpdir) / 'hyperopt_results').mkdir(parents=True)
|
||||
# No hyperopt needed
|
||||
hyperopt_conf.update({
|
||||
@@ -897,10 +897,10 @@ def test_in_strategy_auto_hyperopt(mocker, hyperopt_conf, tmpdir, fee) -> None:
|
||||
|
||||
|
||||
def test_in_strategy_auto_hyperopt_with_parallel(mocker, hyperopt_conf, tmpdir, fee) -> None:
|
||||
mocker.patch('freqtrade.exchange.Exchange.validate_config', MagicMock())
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch('freqtrade.exchange.Exchange._load_markets')
|
||||
mocker.patch('freqtrade.exchange.Exchange.markets',
|
||||
mocker.patch(f'{EXMS}.validate_config', MagicMock())
|
||||
mocker.patch(f'{EXMS}.get_fee', fee)
|
||||
mocker.patch(f'{EXMS}._load_markets')
|
||||
mocker.patch(f'{EXMS}.markets',
|
||||
PropertyMock(return_value=get_markets()))
|
||||
(Path(tmpdir) / 'hyperopt_results').mkdir(parents=True)
|
||||
# No hyperopt needed
|
||||
@@ -938,7 +938,7 @@ def test_in_strategy_auto_hyperopt_with_parallel(mocker, hyperopt_conf, tmpdir,
|
||||
|
||||
def test_in_strategy_auto_hyperopt_per_epoch(mocker, hyperopt_conf, tmpdir, fee) -> None:
|
||||
patch_exchange(mocker)
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch(f'{EXMS}.get_fee', fee)
|
||||
(Path(tmpdir) / 'hyperopt_results').mkdir(parents=True)
|
||||
|
||||
hyperopt_conf.update({
|
||||
@@ -996,7 +996,7 @@ def test_stake_amount_unlimited_max_open_trades(mocker, hyperopt_conf, tmpdir, f
|
||||
# This test is to ensure that unlimited max_open_trades are ignored for the backtesting
|
||||
# if we have an unlimited stake amount
|
||||
patch_exchange(mocker)
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch(f'{EXMS}.get_fee', fee)
|
||||
(Path(tmpdir) / 'hyperopt_results').mkdir(parents=True)
|
||||
hyperopt_conf.update({
|
||||
'strategy': 'HyperoptableStrategy',
|
||||
@@ -1024,7 +1024,7 @@ def test_max_open_trades_dump(mocker, hyperopt_conf, tmpdir, fee, capsys) -> Non
|
||||
# This test is to ensure that after hyperopting, max_open_trades is never
|
||||
# saved as inf in the output json params
|
||||
patch_exchange(mocker)
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch(f'{EXMS}.get_fee', fee)
|
||||
(Path(tmpdir) / 'hyperopt_results').mkdir(parents=True)
|
||||
hyperopt_conf.update({
|
||||
'strategy': 'HyperoptableStrategy',
|
||||
@@ -1070,7 +1070,7 @@ def test_max_open_trades_consistency(mocker, hyperopt_conf, tmpdir, fee) -> None
|
||||
# This test is to ensure that max_open_trades is the same across all functions needing it
|
||||
# after it has been changed from the hyperopt
|
||||
patch_exchange(mocker)
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', return_value=0)
|
||||
mocker.patch(f'{EXMS}.get_fee', return_value=0)
|
||||
|
||||
(Path(tmpdir) / 'hyperopt_results').mkdir(parents=True)
|
||||
hyperopt_conf.update({
|
||||
|
@@ -255,7 +255,7 @@ def test_write_read_backtest_candles(tmpdir):
|
||||
|
||||
# test directory exporting
|
||||
stored_file = store_backtest_signal_candles(Path(tmpdir), candle_dict, '2022_01_01_15_05_13')
|
||||
scp = open(stored_file, "rb")
|
||||
scp = stored_file.open("rb")
|
||||
pickled_signal_candles = joblib.load(scp)
|
||||
scp.close()
|
||||
|
||||
@@ -269,7 +269,7 @@ def test_write_read_backtest_candles(tmpdir):
|
||||
# test file exporting
|
||||
filename = Path(tmpdir / 'testresult')
|
||||
stored_file = store_backtest_signal_candles(filename, candle_dict, '2022_01_01_15_05_13')
|
||||
scp = open(stored_file, "rb")
|
||||
scp = stored_file.open("rb")
|
||||
pickled_signal_candles = joblib.load(scp)
|
||||
scp.close()
|
||||
|
||||
|
@@ -2440,6 +2440,7 @@ def test_select_filled_orders(fee):
|
||||
def test_order_to_ccxt(limit_buy_order_open):
|
||||
|
||||
order = Order.parse_from_ccxt_object(limit_buy_order_open, 'mocked', 'buy')
|
||||
order.ft_trade_id = 1
|
||||
order.query.session.add(order)
|
||||
Order.query.session.commit()
|
||||
|
||||
|
@@ -18,8 +18,8 @@ from freqtrade.persistence import Trade
|
||||
from freqtrade.plugins.pairlist.pairlist_helpers import dynamic_expand_pairlist, expand_pairlist
|
||||
from freqtrade.plugins.pairlistmanager import PairListManager
|
||||
from freqtrade.resolvers import PairListResolver
|
||||
from tests.conftest import (create_mock_trades_usdt, get_patched_exchange, get_patched_freqtradebot,
|
||||
log_has, log_has_re, num_log_has)
|
||||
from tests.conftest import (EXMS, create_mock_trades_usdt, get_patched_exchange,
|
||||
get_patched_freqtradebot, log_has, log_has_re, num_log_has)
|
||||
|
||||
|
||||
# Exclude RemotePairList from tests.
|
||||
@@ -116,7 +116,7 @@ def static_pl_conf(whitelist_conf):
|
||||
|
||||
|
||||
def test_log_cached(mocker, static_pl_conf, markets, tickers):
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
mocker.patch.multiple(EXMS,
|
||||
markets=PropertyMock(return_value=markets),
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
get_tickers=tickers
|
||||
@@ -139,7 +139,7 @@ def test_log_cached(mocker, static_pl_conf, markets, tickers):
|
||||
|
||||
def test_load_pairlist_noexist(mocker, markets, default_conf):
|
||||
freqtrade = get_patched_freqtradebot(mocker, default_conf)
|
||||
mocker.patch('freqtrade.exchange.Exchange.markets', PropertyMock(return_value=markets))
|
||||
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value=markets))
|
||||
plm = PairListManager(freqtrade.exchange, default_conf, MagicMock())
|
||||
with pytest.raises(OperationalException,
|
||||
match=r"Impossible to load Pairlist 'NonexistingPairList'. "
|
||||
@@ -150,7 +150,7 @@ def test_load_pairlist_noexist(mocker, markets, default_conf):
|
||||
|
||||
def test_load_pairlist_verify_multi(mocker, markets_static, default_conf):
|
||||
freqtrade = get_patched_freqtradebot(mocker, default_conf)
|
||||
mocker.patch('freqtrade.exchange.Exchange.markets', PropertyMock(return_value=markets_static))
|
||||
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value=markets_static))
|
||||
plm = PairListManager(freqtrade.exchange, default_conf, MagicMock())
|
||||
# Call different versions one after the other, should always consider what was passed in
|
||||
# and have no side-effects (therefore the same check multiple times)
|
||||
@@ -166,7 +166,7 @@ def test_refresh_market_pair_not_in_whitelist(mocker, markets, static_pl_conf):
|
||||
|
||||
freqtrade = get_patched_freqtradebot(mocker, static_pl_conf)
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.markets', PropertyMock(return_value=markets))
|
||||
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value=markets))
|
||||
freqtrade.pairlists.refresh_pairlist()
|
||||
# List ordered by BaseVolume
|
||||
whitelist = ['ETH/BTC', 'TKN/BTC']
|
||||
@@ -180,7 +180,7 @@ def test_refresh_market_pair_not_in_whitelist(mocker, markets, static_pl_conf):
|
||||
def test_refresh_static_pairlist(mocker, markets, static_pl_conf):
|
||||
freqtrade = get_patched_freqtradebot(mocker, static_pl_conf)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
markets=PropertyMock(return_value=markets),
|
||||
)
|
||||
@@ -204,7 +204,7 @@ def test_refresh_static_pairlist_noexist(mocker, markets, static_pl_conf, pairs,
|
||||
static_pl_conf['exchange']['pair_whitelist'] += pairs
|
||||
freqtrade = get_patched_freqtradebot(mocker, static_pl_conf)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
markets=PropertyMock(return_value=markets),
|
||||
)
|
||||
@@ -221,7 +221,7 @@ def test_invalid_blacklist(mocker, markets, static_pl_conf, caplog):
|
||||
static_pl_conf['exchange']['pair_blacklist'] = ['*/BTC']
|
||||
freqtrade = get_patched_freqtradebot(mocker, static_pl_conf)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
markets=PropertyMock(return_value=markets),
|
||||
)
|
||||
@@ -237,7 +237,7 @@ def test_remove_logs_for_pairs_already_in_blacklist(mocker, markets, static_pl_c
|
||||
logger = logging.getLogger(__name__)
|
||||
freqtrade = get_patched_freqtradebot(mocker, static_pl_conf)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
markets=PropertyMock(return_value=markets),
|
||||
)
|
||||
@@ -264,14 +264,14 @@ def test_remove_logs_for_pairs_already_in_blacklist(mocker, markets, static_pl_c
|
||||
def test_refresh_pairlist_dynamic(mocker, shitcoinmarkets, tickers, whitelist_conf):
|
||||
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
get_tickers=tickers,
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
)
|
||||
freqtrade = get_patched_freqtradebot(mocker, whitelist_conf)
|
||||
# Remock markets with shitcoinmarkets since get_patched_freqtradebot uses the markets fixture
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
markets=PropertyMock(return_value=shitcoinmarkets),
|
||||
)
|
||||
# argument: use the whitelist dynamically by exchange-volume
|
||||
@@ -291,7 +291,7 @@ def test_refresh_pairlist_dynamic_2(mocker, shitcoinmarkets, tickers, whitelist_
|
||||
tickers_dict = tickers()
|
||||
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
)
|
||||
# Remove caching of ticker data to emulate changing volume by the time of second call
|
||||
@@ -302,7 +302,7 @@ def test_refresh_pairlist_dynamic_2(mocker, shitcoinmarkets, tickers, whitelist_
|
||||
freqtrade = get_patched_freqtradebot(mocker, whitelist_conf_2)
|
||||
# Remock markets with shitcoinmarkets since get_patched_freqtradebot uses the markets fixture
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
markets=PropertyMock(return_value=shitcoinmarkets),
|
||||
)
|
||||
|
||||
@@ -320,11 +320,11 @@ def test_refresh_pairlist_dynamic_2(mocker, shitcoinmarkets, tickers, whitelist_
|
||||
|
||||
def test_VolumePairList_refresh_empty(mocker, markets_empty, whitelist_conf):
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
)
|
||||
freqtrade = get_patched_freqtradebot(mocker, whitelist_conf)
|
||||
mocker.patch('freqtrade.exchange.Exchange.markets', PropertyMock(return_value=markets_empty))
|
||||
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value=markets_empty))
|
||||
|
||||
# argument: use the whitelist dynamically by exchange-volume
|
||||
whitelist = []
|
||||
@@ -523,15 +523,15 @@ def test_VolumePairList_whitelist_gen(mocker, whitelist_conf, shitcoinmarkets, t
|
||||
('HOT/BTC', '1d', CandleType.SPOT): ohlcv_history_high_vola,
|
||||
}
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
|
||||
mocker.patch(f'{EXMS}.exchange_has', MagicMock(return_value=True))
|
||||
|
||||
freqtrade = get_patched_freqtradebot(mocker, whitelist_conf)
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
mocker.patch.multiple(EXMS,
|
||||
get_tickers=tickers,
|
||||
markets=PropertyMock(return_value=shitcoinmarkets)
|
||||
)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
refresh_latest_ohlcv=MagicMock(return_value=ohlcv_data),
|
||||
)
|
||||
|
||||
@@ -649,7 +649,7 @@ def test_VolumePairList_range(mocker, whitelist_conf, shitcoinmarkets, tickers,
|
||||
('HOT/BTC', '1d', CandleType.SPOT): ohlcv_history_high_volume,
|
||||
}
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
|
||||
mocker.patch(f'{EXMS}.exchange_has', MagicMock(return_value=True))
|
||||
|
||||
if volumefilter_result == 'default_refresh_too_short':
|
||||
with pytest.raises(OperationalException,
|
||||
@@ -675,7 +675,7 @@ def test_VolumePairList_range(mocker, whitelist_conf, shitcoinmarkets, tickers,
|
||||
else:
|
||||
freqtrade = get_patched_freqtradebot(mocker, whitelist_conf)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
get_tickers=tickers,
|
||||
markets=PropertyMock(return_value=shitcoinmarkets)
|
||||
)
|
||||
@@ -687,7 +687,7 @@ def test_VolumePairList_range(mocker, whitelist_conf, shitcoinmarkets, tickers,
|
||||
ohlcv_data = []
|
||||
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
refresh_latest_ohlcv=MagicMock(return_value=ohlcv_data),
|
||||
)
|
||||
|
||||
@@ -702,7 +702,7 @@ def test_PrecisionFilter_error(mocker, whitelist_conf) -> None:
|
||||
whitelist_conf['pairlists'] = [{"method": "StaticPairList"}, {"method": "PrecisionFilter"}]
|
||||
del whitelist_conf['stoploss']
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
|
||||
mocker.patch(f'{EXMS}.exchange_has', MagicMock(return_value=True))
|
||||
|
||||
with pytest.raises(OperationalException,
|
||||
match=r"PrecisionFilter can only work with stoploss defined\..*"):
|
||||
@@ -713,7 +713,7 @@ def test_PerformanceFilter_error(mocker, whitelist_conf, caplog) -> None:
|
||||
whitelist_conf['pairlists'] = [{"method": "StaticPairList"}, {"method": "PerformanceFilter"}]
|
||||
if hasattr(Trade, 'query'):
|
||||
del Trade.query
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
|
||||
mocker.patch(f'{EXMS}.exchange_has', MagicMock(return_value=True))
|
||||
exchange = get_patched_exchange(mocker, whitelist_conf)
|
||||
pm = PairListManager(exchange, whitelist_conf, MagicMock())
|
||||
pm.refresh_pairlist()
|
||||
@@ -755,7 +755,7 @@ def test_PerformanceFilter_lookback(mocker, default_conf_usdt, fee, caplog) -> N
|
||||
{"method": "StaticPairList"},
|
||||
{"method": "PerformanceFilter", "minutes": 60, "min_profit": 0.01}
|
||||
]
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
|
||||
mocker.patch(f'{EXMS}.exchange_has', MagicMock(return_value=True))
|
||||
exchange = get_patched_exchange(mocker, default_conf_usdt)
|
||||
pm = PairListManager(exchange, default_conf_usdt)
|
||||
pm.refresh_pairlist()
|
||||
@@ -781,7 +781,7 @@ def test_PerformanceFilter_keep_mid_order(mocker, default_conf_usdt, fee, caplog
|
||||
{"method": "StaticPairList", "allow_inactive": True},
|
||||
{"method": "PerformanceFilter", "minutes": 60, }
|
||||
]
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', return_value=True)
|
||||
mocker.patch(f'{EXMS}.exchange_has', return_value=True)
|
||||
exchange = get_patched_exchange(mocker, default_conf_usdt)
|
||||
pm = PairListManager(exchange, default_conf_usdt)
|
||||
pm.refresh_pairlist()
|
||||
@@ -806,7 +806,7 @@ def test_PerformanceFilter_keep_mid_order(mocker, default_conf_usdt, fee, caplog
|
||||
def test_gen_pair_whitelist_not_supported(mocker, default_conf, tickers) -> None:
|
||||
default_conf['pairlists'] = [{'method': 'VolumePairList', 'number_assets': 10}]
|
||||
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
mocker.patch.multiple(EXMS,
|
||||
get_tickers=tickers,
|
||||
exchange_has=MagicMock(return_value=False),
|
||||
)
|
||||
@@ -819,7 +819,7 @@ def test_gen_pair_whitelist_not_supported(mocker, default_conf, tickers) -> None
|
||||
def test_pair_whitelist_not_supported_Spread(mocker, default_conf, tickers) -> None:
|
||||
default_conf['pairlists'] = [{'method': 'StaticPairList'}, {'method': 'SpreadFilter'}]
|
||||
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
mocker.patch.multiple(EXMS,
|
||||
get_tickers=tickers,
|
||||
exchange_has=MagicMock(return_value=False),
|
||||
)
|
||||
@@ -832,7 +832,7 @@ def test_pair_whitelist_not_supported_Spread(mocker, default_conf, tickers) -> N
|
||||
@pytest.mark.parametrize("pairlist", TESTABLE_PAIRLISTS)
|
||||
def test_pairlist_class(mocker, whitelist_conf, markets, pairlist):
|
||||
whitelist_conf['pairlists'][0]['method'] = pairlist
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
mocker.patch.multiple(EXMS,
|
||||
markets=PropertyMock(return_value=markets),
|
||||
exchange_has=MagicMock(return_value=True)
|
||||
)
|
||||
@@ -861,7 +861,7 @@ def test_pairlist_class(mocker, whitelist_conf, markets, pairlist):
|
||||
def test__whitelist_for_active_markets(mocker, whitelist_conf, markets, pairlist, whitelist, caplog,
|
||||
log_message, tickers):
|
||||
whitelist_conf['pairlists'][0]['method'] = pairlist
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
mocker.patch.multiple(EXMS,
|
||||
markets=PropertyMock(return_value=markets),
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
get_tickers=tickers
|
||||
@@ -881,10 +881,10 @@ def test__whitelist_for_active_markets(mocker, whitelist_conf, markets, pairlist
|
||||
def test__whitelist_for_active_markets_empty(mocker, whitelist_conf, pairlist, tickers):
|
||||
whitelist_conf['pairlists'][0]['method'] = pairlist
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', return_value=True)
|
||||
mocker.patch(f'{EXMS}.exchange_has', return_value=True)
|
||||
|
||||
freqtrade = get_patched_freqtradebot(mocker, whitelist_conf)
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
mocker.patch.multiple(EXMS,
|
||||
markets=PropertyMock(return_value=None),
|
||||
get_tickers=tickers
|
||||
)
|
||||
@@ -897,7 +897,7 @@ def test__whitelist_for_active_markets_empty(mocker, whitelist_conf, pairlist, t
|
||||
def test_volumepairlist_invalid_sortvalue(mocker, whitelist_conf):
|
||||
whitelist_conf['pairlists'][0].update({"sort_key": "asdf"})
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
|
||||
mocker.patch(f'{EXMS}.exchange_has', MagicMock(return_value=True))
|
||||
with pytest.raises(OperationalException,
|
||||
match=r"key asdf not in .*"):
|
||||
get_patched_freqtradebot(mocker, whitelist_conf)
|
||||
@@ -905,7 +905,7 @@ def test_volumepairlist_invalid_sortvalue(mocker, whitelist_conf):
|
||||
|
||||
def test_volumepairlist_caching(mocker, markets, whitelist_conf, tickers):
|
||||
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
mocker.patch.multiple(EXMS,
|
||||
markets=PropertyMock(return_value=markets),
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
get_tickers=tickers
|
||||
@@ -925,7 +925,7 @@ def test_agefilter_min_days_listed_too_small(mocker, default_conf, markets, tick
|
||||
default_conf['pairlists'] = [{'method': 'VolumePairList', 'number_assets': 10},
|
||||
{'method': 'AgeFilter', 'min_days_listed': -1}]
|
||||
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
mocker.patch.multiple(EXMS,
|
||||
markets=PropertyMock(return_value=markets),
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
get_tickers=tickers
|
||||
@@ -941,7 +941,7 @@ def test_agefilter_max_days_lower_than_min_days(mocker, default_conf, markets, t
|
||||
{'method': 'AgeFilter', 'min_days_listed': 3,
|
||||
"max_days_listed": 2}]
|
||||
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
mocker.patch.multiple(EXMS,
|
||||
markets=PropertyMock(return_value=markets),
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
get_tickers=tickers
|
||||
@@ -956,7 +956,7 @@ def test_agefilter_min_days_listed_too_large(mocker, default_conf, markets, tick
|
||||
default_conf['pairlists'] = [{'method': 'VolumePairList', 'number_assets': 10},
|
||||
{'method': 'AgeFilter', 'min_days_listed': 99999}]
|
||||
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
mocker.patch.multiple(EXMS,
|
||||
markets=PropertyMock(return_value=markets),
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
get_tickers=tickers
|
||||
@@ -976,7 +976,7 @@ def test_agefilter_caching(mocker, markets, whitelist_conf_agefilter, tickers, o
|
||||
('LTC/BTC', '1d', CandleType.SPOT): ohlcv_history,
|
||||
}
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
markets=PropertyMock(return_value=markets),
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
get_tickers=tickers,
|
||||
@@ -1000,14 +1000,14 @@ def test_agefilter_caching(mocker, markets, whitelist_conf_agefilter, tickers, o
|
||||
('LTC/BTC', '1d', CandleType.SPOT): ohlcv_history,
|
||||
('XRP/BTC', '1d', CandleType.SPOT): ohlcv_history.iloc[[0]],
|
||||
}
|
||||
mocker.patch('freqtrade.exchange.Exchange.refresh_latest_ohlcv', return_value=ohlcv_data)
|
||||
mocker.patch(f'{EXMS}.refresh_latest_ohlcv', return_value=ohlcv_data)
|
||||
freqtrade.pairlists.refresh_pairlist()
|
||||
assert len(freqtrade.pairlists.whitelist) == 3
|
||||
assert freqtrade.exchange.refresh_latest_ohlcv.call_count == 1
|
||||
|
||||
# Move to next day
|
||||
t.move_to("2021-09-02 01:00:00 +00:00")
|
||||
mocker.patch('freqtrade.exchange.Exchange.refresh_latest_ohlcv', return_value=ohlcv_data)
|
||||
mocker.patch(f'{EXMS}.refresh_latest_ohlcv', return_value=ohlcv_data)
|
||||
freqtrade.pairlists.refresh_pairlist()
|
||||
assert len(freqtrade.pairlists.whitelist) == 3
|
||||
assert freqtrade.exchange.refresh_latest_ohlcv.call_count == 1
|
||||
@@ -1021,7 +1021,7 @@ def test_agefilter_caching(mocker, markets, whitelist_conf_agefilter, tickers, o
|
||||
('LTC/BTC', '1d', CandleType.SPOT): ohlcv_history,
|
||||
('XRP/BTC', '1d', CandleType.SPOT): ohlcv_history,
|
||||
}
|
||||
mocker.patch('freqtrade.exchange.Exchange.refresh_latest_ohlcv', return_value=ohlcv_data)
|
||||
mocker.patch(f'{EXMS}.refresh_latest_ohlcv', return_value=ohlcv_data)
|
||||
freqtrade.pairlists.refresh_pairlist()
|
||||
assert len(freqtrade.pairlists.whitelist) == 4
|
||||
# Called once (only for XRP/BTC)
|
||||
@@ -1033,7 +1033,7 @@ def test_OffsetFilter_error(mocker, whitelist_conf) -> None:
|
||||
[{"method": "StaticPairList"}, {"method": "OffsetFilter", "offset": -1}]
|
||||
)
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
|
||||
mocker.patch(f'{EXMS}.exchange_has', MagicMock(return_value=True))
|
||||
|
||||
with pytest.raises(OperationalException,
|
||||
match=r'OffsetFilter requires offset to be >= 0'):
|
||||
@@ -1044,7 +1044,7 @@ def test_rangestabilityfilter_checks(mocker, default_conf, markets, tickers):
|
||||
default_conf['pairlists'] = [{'method': 'VolumePairList', 'number_assets': 10},
|
||||
{'method': 'RangeStabilityFilter', 'lookback_days': 99999}]
|
||||
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
mocker.patch.multiple(EXMS,
|
||||
markets=PropertyMock(return_value=markets),
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
get_tickers=tickers
|
||||
@@ -1074,7 +1074,7 @@ def test_rangestabilityfilter_caching(mocker, markets, default_conf, tickers, oh
|
||||
'min_rate_of_change': min_rate_of_change,
|
||||
"max_rate_of_change": max_rate_of_change}]
|
||||
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
mocker.patch.multiple(EXMS,
|
||||
markets=PropertyMock(return_value=markets),
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
get_tickers=tickers
|
||||
@@ -1088,7 +1088,7 @@ def test_rangestabilityfilter_caching(mocker, markets, default_conf, tickers, oh
|
||||
('BLK/BTC', '1d', CandleType.SPOT): ohlcv_history,
|
||||
}
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
refresh_latest_ohlcv=MagicMock(return_value=ohlcv_data),
|
||||
)
|
||||
|
||||
@@ -1109,7 +1109,7 @@ def test_spreadfilter_invalid_data(mocker, default_conf, markets, tickers, caplo
|
||||
default_conf['pairlists'] = [{'method': 'VolumePairList', 'number_assets': 10},
|
||||
{'method': 'SpreadFilter', 'max_spread_ratio': 0.1}]
|
||||
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
mocker.patch.multiple(EXMS,
|
||||
markets=PropertyMock(return_value=markets),
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
get_tickers=tickers
|
||||
@@ -1123,7 +1123,7 @@ def test_spreadfilter_invalid_data(mocker, default_conf, markets, tickers, caplo
|
||||
tickers.return_value['ETH/BTC']['ask'] = 0.0
|
||||
del tickers.return_value['TKN/BTC']
|
||||
del tickers.return_value['LTC/BTC']
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange', get_tickers=tickers)
|
||||
mocker.patch.multiple(EXMS, get_tickers=tickers)
|
||||
|
||||
ftbot.pairlists.refresh_pairlist()
|
||||
assert log_has_re(r'Removed .* invalid ticker data.*', caplog)
|
||||
@@ -1197,7 +1197,7 @@ def test_spreadfilter_invalid_data(mocker, default_conf, markets, tickers, caplo
|
||||
])
|
||||
def test_pricefilter_desc(mocker, whitelist_conf, markets, pairlistconfig,
|
||||
desc_expected, exception_expected):
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
mocker.patch.multiple(EXMS,
|
||||
markets=PropertyMock(return_value=markets),
|
||||
exchange_has=MagicMock(return_value=True)
|
||||
)
|
||||
@@ -1214,7 +1214,7 @@ def test_pricefilter_desc(mocker, whitelist_conf, markets, pairlistconfig,
|
||||
|
||||
|
||||
def test_pairlistmanager_no_pairlist(mocker, whitelist_conf):
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
|
||||
mocker.patch(f'{EXMS}.exchange_has', MagicMock(return_value=True))
|
||||
|
||||
whitelist_conf['pairlists'] = []
|
||||
|
||||
@@ -1266,14 +1266,14 @@ def test_performance_filter(mocker, whitelist_conf, pairlists, pair_allowlist, o
|
||||
allowlist_conf['pairlists'] = pairlists
|
||||
allowlist_conf['exchange']['pair_whitelist'] = pair_allowlist
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
|
||||
mocker.patch(f'{EXMS}.exchange_has', MagicMock(return_value=True))
|
||||
|
||||
freqtrade = get_patched_freqtradebot(mocker, allowlist_conf)
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
mocker.patch.multiple(EXMS,
|
||||
get_tickers=tickers,
|
||||
markets=PropertyMock(return_value=markets)
|
||||
)
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
mocker.patch.multiple(EXMS,
|
||||
get_historic_ohlcv=MagicMock(return_value=ohlcv_history_list),
|
||||
)
|
||||
mocker.patch.multiple('freqtrade.persistence.Trade',
|
||||
@@ -1371,7 +1371,7 @@ def test_expand_pairlist_keep_invalid(wildcardlist, pairs, expected):
|
||||
|
||||
|
||||
def test_ProducerPairlist_no_emc(mocker, whitelist_conf):
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
|
||||
mocker.patch(f'{EXMS}.exchange_has', MagicMock(return_value=True))
|
||||
|
||||
whitelist_conf['pairlists'] = [
|
||||
{
|
||||
@@ -1388,8 +1388,8 @@ def test_ProducerPairlist_no_emc(mocker, whitelist_conf):
|
||||
|
||||
|
||||
def test_ProducerPairlist(mocker, whitelist_conf, markets):
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
|
||||
mocker.patch.multiple('freqtrade.exchange.Exchange',
|
||||
mocker.patch(f'{EXMS}.exchange_has', MagicMock(return_value=True))
|
||||
mocker.patch.multiple(EXMS,
|
||||
markets=PropertyMock(return_value=markets),
|
||||
exchange_has=MagicMock(return_value=True),
|
||||
)
|
||||
|
@@ -1,6 +1,3 @@
|
||||
# pragma pylint: disable=missing-docstring, C0103
|
||||
# pragma pylint: disable=invalid-sequence-index, invalid-name, too-many-arguments
|
||||
|
||||
from copy import deepcopy
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from unittest.mock import ANY, MagicMock, PropertyMock
|
||||
@@ -15,19 +12,10 @@ from freqtrade.persistence import Trade
|
||||
from freqtrade.persistence.pairlock_middleware import PairLocks
|
||||
from freqtrade.rpc import RPC, RPCException
|
||||
from freqtrade.rpc.fiat_convert import CryptoToFiatConverter
|
||||
from tests.conftest import (create_mock_trades, create_mock_trades_usdt, get_patched_freqtradebot,
|
||||
patch_get_signal)
|
||||
from tests.conftest import (EXMS, create_mock_trades, create_mock_trades_usdt,
|
||||
get_patched_freqtradebot, patch_get_signal)
|
||||
|
||||
|
||||
# Functions for recurrent object patching
|
||||
def prec_satoshi(a, b) -> float:
|
||||
"""
|
||||
:return: True if A and B differs less than one satoshi.
|
||||
"""
|
||||
return abs(a - b) < 0.00000001
|
||||
|
||||
|
||||
# Unit tests
|
||||
def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
|
||||
gen_response = {
|
||||
'trade_id': 1,
|
||||
@@ -68,9 +56,6 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
|
||||
'close_profit': None,
|
||||
'close_profit_pct': None,
|
||||
'close_profit_abs': None,
|
||||
'current_profit': -0.00408133,
|
||||
'current_profit_pct': -0.41,
|
||||
'current_profit_abs': -4.09e-06,
|
||||
'profit_ratio': -0.00408133,
|
||||
'profit_pct': -0.41,
|
||||
'profit_abs': -4.09e-06,
|
||||
@@ -91,6 +76,8 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
|
||||
'stoploss_entry_dist_ratio': -0.10376381,
|
||||
'open_order': None,
|
||||
'realized_profit': 0.0,
|
||||
'total_profit_abs': -4.09e-06,
|
||||
'total_profit_fiat': ANY,
|
||||
'exchange': 'binance',
|
||||
'leverage': 1.0,
|
||||
'interest_rate': 0.0,
|
||||
@@ -109,7 +96,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
|
||||
}
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
_dry_is_price_crossed=MagicMock(side_effect=[False, True]),
|
||||
@@ -134,9 +121,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
|
||||
'profit_ratio': 0.0,
|
||||
'profit_pct': 0.0,
|
||||
'profit_abs': 0.0,
|
||||
'current_profit': 0.0,
|
||||
'current_profit_pct': 0.0,
|
||||
'current_profit_abs': 0.0,
|
||||
'total_profit_abs': 0.0,
|
||||
'stop_loss_abs': 0.0,
|
||||
'stop_loss_pct': None,
|
||||
'stop_loss_ratio': None,
|
||||
@@ -184,10 +169,10 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
|
||||
response = deepcopy(gen_response)
|
||||
assert results[0] == response
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_rate',
|
||||
mocker.patch(f'{EXMS}.get_rate',
|
||||
MagicMock(side_effect=ExchangeError("Pair 'ETH/BTC' not available")))
|
||||
results = rpc._rpc_trade_status()
|
||||
assert isnan(results[0]['current_profit'])
|
||||
assert isnan(results[0]['profit_ratio'])
|
||||
assert isnan(results[0]['current_rate'])
|
||||
response_norate = deepcopy(gen_response)
|
||||
# Update elements that are NaN when no rate is available.
|
||||
@@ -198,9 +183,7 @@ def test_rpc_trade_status(default_conf, ticker, fee, mocker) -> None:
|
||||
'profit_ratio': ANY,
|
||||
'profit_pct': ANY,
|
||||
'profit_abs': ANY,
|
||||
'current_profit_abs': ANY,
|
||||
'current_profit': ANY,
|
||||
'current_profit_pct': ANY,
|
||||
'total_profit_abs': ANY,
|
||||
'current_rate': ANY,
|
||||
})
|
||||
assert results[0] == response_norate
|
||||
@@ -214,7 +197,7 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None:
|
||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
)
|
||||
@@ -226,7 +209,7 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None:
|
||||
freqtradebot.state = State.RUNNING
|
||||
with pytest.raises(RPCException, match=r'.*no active trade*'):
|
||||
rpc._rpc_status_table(default_conf['stake_currency'], 'USD')
|
||||
mocker.patch('freqtrade.exchange.Exchange._dry_is_price_crossed', return_value=False)
|
||||
mocker.patch(f'{EXMS}._dry_is_price_crossed', return_value=False)
|
||||
freqtradebot.enter_positions()
|
||||
|
||||
result, headers, fiat_profit_sum = rpc._rpc_status_table(default_conf['stake_currency'], 'USD')
|
||||
@@ -237,7 +220,7 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None:
|
||||
assert '0.00' == result[0][3]
|
||||
assert isnan(fiat_profit_sum)
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange._dry_is_price_crossed', return_value=True)
|
||||
mocker.patch(f'{EXMS}._dry_is_price_crossed', return_value=True)
|
||||
freqtradebot.process()
|
||||
|
||||
result, headers, fiat_profit_sum = rpc._rpc_status_table(default_conf['stake_currency'], 'USD')
|
||||
@@ -248,7 +231,7 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None:
|
||||
assert '-0.41%' == result[0][3]
|
||||
assert isnan(fiat_profit_sum)
|
||||
|
||||
# Test with fiatconvert
|
||||
# Test with fiat convert
|
||||
rpc._fiat_converter = CryptoToFiatConverter()
|
||||
result, headers, fiat_profit_sum = rpc._rpc_status_table(default_conf['stake_currency'], 'USD')
|
||||
assert "Since" in headers
|
||||
@@ -268,7 +251,7 @@ def test_rpc_status_table(default_conf, ticker, fee, mocker) -> None:
|
||||
# 3 on top of the initial one.
|
||||
assert result[0][4] == '1/4'
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_rate',
|
||||
mocker.patch(f'{EXMS}.get_rate',
|
||||
MagicMock(side_effect=ExchangeError("Pair 'ETH/BTC' not available")))
|
||||
result, headers, fiat_profit_sum = rpc._rpc_status_table(default_conf['stake_currency'], 'USD')
|
||||
assert 'instantly' == result[0][2]
|
||||
@@ -281,7 +264,7 @@ def test__rpc_timeunit_profit(default_conf_usdt, ticker, fee,
|
||||
limit_buy_order, limit_sell_order, markets, mocker) -> None:
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
markets=PropertyMock(return_value=markets)
|
||||
@@ -322,7 +305,7 @@ def test__rpc_timeunit_profit(default_conf_usdt, ticker, fee,
|
||||
def test_rpc_trade_history(mocker, default_conf, markets, fee, is_short):
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
markets=PropertyMock(return_value=markets)
|
||||
)
|
||||
|
||||
@@ -350,7 +333,7 @@ def test_rpc_delete_trade(mocker, default_conf, fee, markets, caplog, is_short):
|
||||
stoploss_mock = MagicMock()
|
||||
cancel_mock = MagicMock()
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
markets=PropertyMock(return_value=markets),
|
||||
cancel_order=cancel_mock,
|
||||
cancel_stoploss_order=stoploss_mock,
|
||||
@@ -384,15 +367,13 @@ def test_rpc_delete_trade(mocker, default_conf, fee, markets, caplog, is_short):
|
||||
assert stoploss_mock.call_count == 1
|
||||
assert res['cancel_order_count'] == 2
|
||||
|
||||
stoploss_mock = mocker.patch('freqtrade.exchange.Exchange.cancel_stoploss_order',
|
||||
side_effect=InvalidOrderException)
|
||||
stoploss_mock = mocker.patch(f'{EXMS}.cancel_stoploss_order', side_effect=InvalidOrderException)
|
||||
|
||||
res = rpc._rpc_delete('3')
|
||||
assert stoploss_mock.call_count == 1
|
||||
stoploss_mock.reset_mock()
|
||||
|
||||
cancel_mock = mocker.patch('freqtrade.exchange.Exchange.cancel_order',
|
||||
side_effect=InvalidOrderException)
|
||||
cancel_mock = mocker.patch(f'{EXMS}.cancel_order', side_effect=InvalidOrderException)
|
||||
|
||||
res = rpc._rpc_delete('4')
|
||||
assert cancel_mock.call_count == 1
|
||||
@@ -403,7 +384,7 @@ def test_rpc_trade_statistics(default_conf_usdt, ticker, fee, mocker) -> None:
|
||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=1.1)
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
)
|
||||
@@ -440,7 +421,7 @@ def test_rpc_trade_statistics(default_conf_usdt, ticker, fee, mocker) -> None:
|
||||
assert stats['best_rate'] == 10.0
|
||||
|
||||
# Test non-available pair
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_rate',
|
||||
mocker.patch(f'{EXMS}.get_rate',
|
||||
MagicMock(side_effect=ExchangeError("Pair 'XRP/USDT' not available")))
|
||||
stats = rpc._rpc_trade_statistics(stake_currency, fiat_display_currency)
|
||||
assert stats['trade_count'] == 7
|
||||
@@ -474,7 +455,7 @@ def test_rpc_balance_handle_error(default_conf, mocker):
|
||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
get_balances=MagicMock(return_value=mock_balance),
|
||||
get_tickers=MagicMock(side_effect=TemporaryError('Could not load ticker due to xxx'))
|
||||
)
|
||||
@@ -537,7 +518,7 @@ def test_rpc_balance_handle(default_conf, mocker, tickers):
|
||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
validate_trading_mode_and_margin_mode=MagicMock(),
|
||||
get_balances=MagicMock(return_value=mock_balance),
|
||||
fetch_positions=MagicMock(return_value=mock_pos),
|
||||
@@ -553,8 +534,8 @@ def test_rpc_balance_handle(default_conf, mocker, tickers):
|
||||
rpc._fiat_converter = CryptoToFiatConverter()
|
||||
|
||||
result = rpc._rpc_balance(default_conf['stake_currency'], default_conf['fiat_display_currency'])
|
||||
assert prec_satoshi(result['total'], 30.30909624)
|
||||
assert prec_satoshi(result['value'], 454636.44360691)
|
||||
assert pytest.approx(result['total']) == 30.30909624
|
||||
assert pytest.approx(result['value']) == 454636.44360691
|
||||
assert tickers.call_count == 1
|
||||
assert tickers.call_args_list[0][1]['cached'] is True
|
||||
assert 'USD' == result['symbol']
|
||||
@@ -614,7 +595,7 @@ def test_rpc_balance_handle(default_conf, mocker, tickers):
|
||||
def test_rpc_start(mocker, default_conf) -> None:
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=MagicMock()
|
||||
)
|
||||
|
||||
@@ -635,7 +616,7 @@ def test_rpc_start(mocker, default_conf) -> None:
|
||||
def test_rpc_stop(mocker, default_conf) -> None:
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=MagicMock()
|
||||
)
|
||||
|
||||
@@ -657,7 +638,7 @@ def test_rpc_stop(mocker, default_conf) -> None:
|
||||
def test_rpc_stopentry(mocker, default_conf) -> None:
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=MagicMock()
|
||||
)
|
||||
|
||||
@@ -677,7 +658,7 @@ def test_rpc_force_exit(default_conf, ticker, fee, mocker) -> None:
|
||||
|
||||
cancel_order_mock = MagicMock()
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
cancel_order=cancel_order_mock,
|
||||
fetch_order=MagicMock(
|
||||
@@ -725,15 +706,14 @@ def test_rpc_force_exit(default_conf, ticker, fee, mocker) -> None:
|
||||
|
||||
freqtradebot.state = State.RUNNING
|
||||
assert cancel_order_mock.call_count == 0
|
||||
mocker.patch(
|
||||
'freqtrade.exchange.Exchange._dry_is_price_crossed', MagicMock(return_value=False))
|
||||
mocker.patch(f'{EXMS}._dry_is_price_crossed', MagicMock(return_value=False))
|
||||
freqtradebot.enter_positions()
|
||||
# make an limit-buy open trade
|
||||
trade = Trade.query.filter(Trade.id == '3').first()
|
||||
filled_amount = trade.amount / 2
|
||||
# Fetch order - it's open first, and closed after cancel_order is called.
|
||||
mocker.patch(
|
||||
'freqtrade.exchange.Exchange.fetch_order',
|
||||
f'{EXMS}.fetch_order',
|
||||
side_effect=[{
|
||||
'id': trade.orders[0].order_id,
|
||||
'status': 'open',
|
||||
@@ -755,7 +735,7 @@ def test_rpc_force_exit(default_conf, ticker, fee, mocker) -> None:
|
||||
assert pytest.approx(trade.amount) == filled_amount
|
||||
|
||||
mocker.patch(
|
||||
'freqtrade.exchange.Exchange.fetch_order',
|
||||
f'{EXMS}.fetch_order',
|
||||
return_value={
|
||||
'status': 'open',
|
||||
'type': 'limit',
|
||||
@@ -769,7 +749,7 @@ def test_rpc_force_exit(default_conf, ticker, fee, mocker) -> None:
|
||||
amount = trade.amount
|
||||
# make an limit-buy open trade, if there is no 'filled', don't sell it
|
||||
mocker.patch(
|
||||
'freqtrade.exchange.Exchange.fetch_order',
|
||||
f'{EXMS}.fetch_order',
|
||||
return_value={
|
||||
'status': 'open',
|
||||
'type': 'limit',
|
||||
@@ -787,7 +767,7 @@ def test_rpc_force_exit(default_conf, ticker, fee, mocker) -> None:
|
||||
|
||||
# make an limit-sell open trade
|
||||
mocker.patch(
|
||||
'freqtrade.exchange.Exchange.fetch_order',
|
||||
f'{EXMS}.fetch_order',
|
||||
return_value={
|
||||
'status': 'open',
|
||||
'type': 'limit',
|
||||
@@ -807,7 +787,7 @@ def test_rpc_force_exit(default_conf, ticker, fee, mocker) -> None:
|
||||
def test_performance_handle(default_conf_usdt, ticker, fee, mocker) -> None:
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
get_balances=MagicMock(return_value=ticker),
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
@@ -830,7 +810,7 @@ def test_enter_tag_performance_handle(default_conf, ticker, fee, mocker) -> None
|
||||
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
get_balances=MagicMock(return_value=ticker),
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
@@ -862,7 +842,7 @@ def test_enter_tag_performance_handle(default_conf, ticker, fee, mocker) -> None
|
||||
def test_enter_tag_performance_handle_2(mocker, default_conf, markets, fee):
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
markets=PropertyMock(return_value=markets)
|
||||
)
|
||||
|
||||
@@ -875,23 +855,23 @@ def test_enter_tag_performance_handle_2(mocker, default_conf, markets, fee):
|
||||
assert len(res) == 2
|
||||
assert res[0]['enter_tag'] == 'TEST1'
|
||||
assert res[0]['count'] == 1
|
||||
assert prec_satoshi(res[0]['profit_pct'], 0.5)
|
||||
assert pytest.approx(res[0]['profit_pct']) == 0.5
|
||||
assert res[1]['enter_tag'] == 'Other'
|
||||
assert res[1]['count'] == 1
|
||||
assert prec_satoshi(res[1]['profit_pct'], 1.0)
|
||||
assert pytest.approx(res[1]['profit_pct']) == 1.0
|
||||
|
||||
# Test for a specific pair
|
||||
res = rpc._rpc_enter_tag_performance('ETC/BTC')
|
||||
assert len(res) == 1
|
||||
assert res[0]['count'] == 1
|
||||
assert res[0]['enter_tag'] == 'TEST1'
|
||||
assert prec_satoshi(res[0]['profit_pct'], 0.5)
|
||||
assert pytest.approx(res[0]['profit_pct']) == 0.5
|
||||
|
||||
|
||||
def test_exit_reason_performance_handle(default_conf_usdt, ticker, fee, mocker) -> None:
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
get_balances=MagicMock(return_value=ticker),
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
@@ -918,7 +898,7 @@ def test_exit_reason_performance_handle(default_conf_usdt, ticker, fee, mocker)
|
||||
def test_exit_reason_performance_handle_2(mocker, default_conf, markets, fee):
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
markets=PropertyMock(return_value=markets)
|
||||
)
|
||||
|
||||
@@ -931,23 +911,23 @@ def test_exit_reason_performance_handle_2(mocker, default_conf, markets, fee):
|
||||
assert len(res) == 2
|
||||
assert res[0]['exit_reason'] == 'sell_signal'
|
||||
assert res[0]['count'] == 1
|
||||
assert prec_satoshi(res[0]['profit_pct'], 0.5)
|
||||
assert pytest.approx(res[0]['profit_pct']) == 0.5
|
||||
assert res[1]['exit_reason'] == 'roi'
|
||||
assert res[1]['count'] == 1
|
||||
assert prec_satoshi(res[1]['profit_pct'], 1.0)
|
||||
assert pytest.approx(res[1]['profit_pct']) == 1.0
|
||||
|
||||
# Test for a specific pair
|
||||
res = rpc._rpc_exit_reason_performance('ETC/BTC')
|
||||
assert len(res) == 1
|
||||
assert res[0]['count'] == 1
|
||||
assert res[0]['exit_reason'] == 'sell_signal'
|
||||
assert prec_satoshi(res[0]['profit_pct'], 0.5)
|
||||
assert pytest.approx(res[0]['profit_pct']) == 0.5
|
||||
|
||||
|
||||
def test_mix_tag_performance_handle(default_conf, ticker, fee, mocker) -> None:
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
get_balances=MagicMock(return_value=ticker),
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
@@ -971,7 +951,7 @@ def test_mix_tag_performance_handle(default_conf, ticker, fee, mocker) -> None:
|
||||
def test_mix_tag_performance_handle_2(mocker, default_conf, markets, fee):
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
markets=PropertyMock(return_value=markets)
|
||||
)
|
||||
|
||||
@@ -984,10 +964,10 @@ def test_mix_tag_performance_handle_2(mocker, default_conf, markets, fee):
|
||||
assert len(res) == 2
|
||||
assert res[0]['mix_tag'] == 'TEST1 sell_signal'
|
||||
assert res[0]['count'] == 1
|
||||
assert prec_satoshi(res[0]['profit_pct'], 0.5)
|
||||
assert pytest.approx(res[0]['profit_pct']) == 0.5
|
||||
assert res[1]['mix_tag'] == 'Other roi'
|
||||
assert res[1]['count'] == 1
|
||||
assert prec_satoshi(res[1]['profit_pct'], 1.0)
|
||||
assert pytest.approx(res[1]['profit_pct']) == 1.0
|
||||
|
||||
# Test for a specific pair
|
||||
res = rpc._rpc_mix_tag_performance('ETC/BTC')
|
||||
@@ -995,13 +975,13 @@ def test_mix_tag_performance_handle_2(mocker, default_conf, markets, fee):
|
||||
assert len(res) == 1
|
||||
assert res[0]['count'] == 1
|
||||
assert res[0]['mix_tag'] == 'TEST1 sell_signal'
|
||||
assert prec_satoshi(res[0]['profit_pct'], 0.5)
|
||||
assert pytest.approx(res[0]['profit_pct']) == 0.5
|
||||
|
||||
|
||||
def test_rpc_count(mocker, default_conf, ticker, fee) -> None:
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
get_balances=MagicMock(return_value=ticker),
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
@@ -1026,7 +1006,7 @@ def test_rpc_force_entry(mocker, default_conf, ticker, fee, limit_buy_order_open
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
buy_mm = MagicMock(return_value=limit_buy_order_open)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
get_balances=MagicMock(return_value=ticker),
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
@@ -1155,7 +1135,7 @@ def test_rpc_whitelist_dynamic(mocker, default_conf) -> None:
|
||||
default_conf['pairlists'] = [{'method': 'VolumePairList',
|
||||
'number_assets': 4,
|
||||
}]
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
|
||||
mocker.patch(f'{EXMS}.exchange_has', MagicMock(return_value=True))
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
|
||||
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||
@@ -1252,6 +1232,6 @@ def test_rpc_health(mocker, default_conf) -> None:
|
||||
|
||||
freqtradebot = get_patched_freqtradebot(mocker, default_conf)
|
||||
rpc = RPC(freqtradebot)
|
||||
result = rpc._health()
|
||||
assert result['last_process'] == '1970-01-01 00:00:00+00:00'
|
||||
assert result['last_process_ts'] == 0
|
||||
result = rpc.health()
|
||||
assert result['last_process'] is None
|
||||
assert result['last_process_ts'] is None
|
||||
|
@@ -24,7 +24,7 @@ from freqtrade.rpc import RPC
|
||||
from freqtrade.rpc.api_server import ApiServer
|
||||
from freqtrade.rpc.api_server.api_auth import create_token, get_user_from_token
|
||||
from freqtrade.rpc.api_server.uvicorn_threaded import UvicornServer
|
||||
from tests.conftest import (CURRENT_TEST_STRATEGY, create_mock_trades, get_mock_coro,
|
||||
from tests.conftest import (CURRENT_TEST_STRATEGY, EXMS, create_mock_trades, get_mock_coro,
|
||||
get_patched_freqtradebot, log_has, log_has_re, patch_get_signal)
|
||||
|
||||
|
||||
@@ -473,9 +473,9 @@ def test_api_balance(botclient, mocker, rpc_balance, tickers):
|
||||
ftbot, client = botclient
|
||||
|
||||
ftbot.config['dry_run'] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_balances', return_value=rpc_balance)
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_tickers', tickers)
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_valid_pair_combination',
|
||||
mocker.patch(f'{EXMS}.get_balances', return_value=rpc_balance)
|
||||
mocker.patch(f'{EXMS}.get_tickers', tickers)
|
||||
mocker.patch(f'{EXMS}.get_valid_pair_combination',
|
||||
side_effect=lambda a, b: f"{a}/{b}")
|
||||
ftbot.wallets.update()
|
||||
|
||||
@@ -507,7 +507,7 @@ def test_api_count(botclient, mocker, ticker, fee, markets, is_short):
|
||||
ftbot, client = botclient
|
||||
patch_get_signal(ftbot)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
get_balances=MagicMock(return_value=ticker),
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
@@ -594,7 +594,7 @@ def test_api_daily(botclient, mocker, ticker, fee, markets):
|
||||
ftbot, client = botclient
|
||||
patch_get_signal(ftbot)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
get_balances=MagicMock(return_value=ticker),
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
@@ -613,7 +613,7 @@ def test_api_trades(botclient, mocker, fee, markets, is_short):
|
||||
ftbot, client = botclient
|
||||
patch_get_signal(ftbot)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
markets=PropertyMock(return_value=markets)
|
||||
)
|
||||
rc = client_get(client, f"{BASE_URI}/trades")
|
||||
@@ -644,7 +644,7 @@ def test_api_trade_single(botclient, mocker, fee, ticker, markets, is_short):
|
||||
ftbot, client = botclient
|
||||
patch_get_signal(ftbot, enter_long=not is_short, enter_short=is_short)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
markets=PropertyMock(return_value=markets),
|
||||
fetch_ticker=ticker,
|
||||
)
|
||||
@@ -668,7 +668,7 @@ def test_api_delete_trade(botclient, mocker, fee, markets, is_short):
|
||||
stoploss_mock = MagicMock()
|
||||
cancel_mock = MagicMock()
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
markets=PropertyMock(return_value=markets),
|
||||
cancel_order=cancel_mock,
|
||||
cancel_stoploss_order=stoploss_mock,
|
||||
@@ -713,7 +713,7 @@ def test_api_delete_open_order(botclient, mocker, fee, markets, ticker, is_short
|
||||
stoploss_mock = MagicMock()
|
||||
cancel_mock = MagicMock()
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
markets=PropertyMock(return_value=markets),
|
||||
fetch_ticker=ticker,
|
||||
cancel_order=cancel_mock,
|
||||
@@ -731,15 +731,13 @@ def test_api_delete_open_order(botclient, mocker, fee, markets, ticker, is_short
|
||||
assert_response(rc, 502)
|
||||
assert 'No open order for trade_id' in rc.json()['error']
|
||||
trade = Trade.get_trades([Trade.id == 6]).first()
|
||||
mocker.patch('freqtrade.exchange.Exchange.fetch_order',
|
||||
side_effect=ExchangeError)
|
||||
mocker.patch(f'{EXMS}.fetch_order', side_effect=ExchangeError)
|
||||
rc = client_delete(client, f"{BASE_URI}/trades/6/open-order")
|
||||
assert_response(rc, 502)
|
||||
assert 'Order not found.' in rc.json()['error']
|
||||
|
||||
trade = Trade.get_trades([Trade.id == 6]).first()
|
||||
mocker.patch('freqtrade.exchange.Exchange.fetch_order',
|
||||
return_value=trade.orders[-1].to_ccxt_object())
|
||||
mocker.patch(f'{EXMS}.fetch_order', return_value=trade.orders[-1].to_ccxt_object())
|
||||
|
||||
rc = client_delete(client, f"{BASE_URI}/trades/6/open-order")
|
||||
assert_response(rc)
|
||||
@@ -782,7 +780,7 @@ def test_api_edge_disabled(botclient, mocker, ticker, fee, markets):
|
||||
ftbot, client = botclient
|
||||
patch_get_signal(ftbot)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
get_balances=MagicMock(return_value=ticker),
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
@@ -844,7 +842,7 @@ def test_api_profit(botclient, mocker, ticker, fee, markets, is_short, expected)
|
||||
ftbot, client = botclient
|
||||
patch_get_signal(ftbot)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
get_balances=MagicMock(return_value=ticker),
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
@@ -902,7 +900,7 @@ def test_api_stats(botclient, mocker, ticker, fee, markets, is_short):
|
||||
ftbot, client = botclient
|
||||
patch_get_signal(ftbot, enter_long=not is_short, enter_short=is_short)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
get_balances=MagicMock(return_value=ticker),
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
@@ -983,7 +981,7 @@ def test_api_status(botclient, mocker, ticker, fee, markets, is_short,
|
||||
ftbot, client = botclient
|
||||
patch_get_signal(ftbot)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
get_balances=MagicMock(return_value=ticker),
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
@@ -1008,13 +1006,13 @@ def test_api_status(botclient, mocker, ticker, fee, markets, is_short,
|
||||
'close_profit_pct': None,
|
||||
'close_profit_abs': None,
|
||||
'close_rate': None,
|
||||
'current_profit': ANY,
|
||||
'current_profit_pct': ANY,
|
||||
'current_profit_abs': ANY,
|
||||
'profit_ratio': ANY,
|
||||
'profit_pct': ANY,
|
||||
'profit_abs': ANY,
|
||||
'profit_fiat': ANY,
|
||||
'total_profit_abs': ANY,
|
||||
'total_profit_fiat': ANY,
|
||||
'realized_profit': 0.0,
|
||||
'current_rate': current_rate,
|
||||
'open_date': ANY,
|
||||
'open_timestamp': ANY,
|
||||
@@ -1068,7 +1066,7 @@ def test_api_status(botclient, mocker, ticker, fee, markets, is_short,
|
||||
'orders': [ANY],
|
||||
}
|
||||
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_rate',
|
||||
mocker.patch(f'{EXMS}.get_rate',
|
||||
MagicMock(side_effect=ExchangeError("Pair 'ETH/BTC' not available")))
|
||||
|
||||
rc = client_get(client, f"{BASE_URI}/status")
|
||||
@@ -1181,7 +1179,7 @@ def test_api_force_entry(botclient, mocker, fee, endpoint):
|
||||
ftbot.config['force_entry_enable'] = True
|
||||
|
||||
fbuy_mock = MagicMock(return_value=None)
|
||||
mocker.patch("freqtrade.rpc.RPC._rpc_force_entry", fbuy_mock)
|
||||
mocker.patch("freqtrade.rpc.rpc.RPC._rpc_force_entry", fbuy_mock)
|
||||
rc = client_post(client, f"{BASE_URI}/{endpoint}",
|
||||
data={"pair": "ETH/BTC"})
|
||||
assert_response(rc)
|
||||
@@ -1207,7 +1205,7 @@ def test_api_force_entry(botclient, mocker, fee, endpoint):
|
||||
strategy=CURRENT_TEST_STRATEGY,
|
||||
trading_mode=TradingMode.SPOT
|
||||
))
|
||||
mocker.patch("freqtrade.rpc.RPC._rpc_force_entry", fbuy_mock)
|
||||
mocker.patch("freqtrade.rpc.rpc.RPC._rpc_force_entry", fbuy_mock)
|
||||
|
||||
rc = client_post(client, f"{BASE_URI}/{endpoint}",
|
||||
data={"pair": "ETH/BTC"})
|
||||
@@ -1244,6 +1242,7 @@ def test_api_force_entry(botclient, mocker, fee, endpoint):
|
||||
'profit_pct': None,
|
||||
'profit_abs': None,
|
||||
'profit_fiat': None,
|
||||
'realized_profit': 0.0,
|
||||
'fee_close': 0.0025,
|
||||
'fee_close_cost': None,
|
||||
'fee_close_currency': None,
|
||||
@@ -1275,7 +1274,7 @@ def test_api_force_entry(botclient, mocker, fee, endpoint):
|
||||
def test_api_forceexit(botclient, mocker, ticker, fee, markets):
|
||||
ftbot, client = botclient
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
get_balances=MagicMock(return_value=ticker),
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
@@ -1630,7 +1629,7 @@ def test_sysinfo(botclient):
|
||||
|
||||
def test_api_backtesting(botclient, mocker, fee, caplog, tmpdir):
|
||||
ftbot, client = botclient
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_fee', fee)
|
||||
mocker.patch(f'{EXMS}.get_fee', fee)
|
||||
|
||||
rc = client_get(client, f"{BASE_URI}/backtest")
|
||||
# Backtest prevented in default mode
|
||||
@@ -1737,9 +1736,15 @@ def test_api_backtesting(botclient, mocker, fee, caplog, tmpdir):
|
||||
data['stake_amount'] = 101
|
||||
|
||||
mocker.patch('freqtrade.optimize.backtesting.Backtesting.backtest_one_strategy',
|
||||
side_effect=DependencyException())
|
||||
side_effect=DependencyException('DeadBeef'))
|
||||
rc = client_post(client, f"{BASE_URI}/backtest", data=data)
|
||||
assert log_has("Backtesting caused an error: ", caplog)
|
||||
assert log_has("Backtesting caused an error: DeadBeef", caplog)
|
||||
|
||||
rc = client_get(client, f"{BASE_URI}/backtest")
|
||||
assert_response(rc)
|
||||
result = rc.json()
|
||||
assert result['status'] == 'error'
|
||||
assert 'Backtest failed' in result['status_msg']
|
||||
|
||||
# Delete backtesting to avoid leakage since the backtest-object may stick around.
|
||||
rc = client_delete(client, f"{BASE_URI}/backtest")
|
||||
@@ -1795,8 +1800,8 @@ def test_health(botclient):
|
||||
|
||||
assert_response(rc)
|
||||
ret = rc.json()
|
||||
assert ret['last_process_ts'] == 0
|
||||
assert ret['last_process'] == '1970-01-01T00:00:00+00:00'
|
||||
assert ret["last_process_ts"] is None
|
||||
assert ret["last_process"] is None
|
||||
|
||||
|
||||
def test_api_ws_subscribe(botclient, mocker):
|
||||
|
@@ -20,7 +20,8 @@ from telegram.error import BadRequest, NetworkError, TelegramError
|
||||
from freqtrade import __version__
|
||||
from freqtrade.constants import CANCEL_REASON
|
||||
from freqtrade.edge import PairInfo
|
||||
from freqtrade.enums import ExitType, RPCMessageType, RunMode, SignalDirection, State
|
||||
from freqtrade.enums import (ExitType, MarketDirection, RPCMessageType, RunMode, SignalDirection,
|
||||
State)
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.freqtradebot import FreqtradeBot
|
||||
from freqtrade.loggers import setup_logging
|
||||
@@ -29,9 +30,9 @@ from freqtrade.persistence.models import Order
|
||||
from freqtrade.rpc import RPC
|
||||
from freqtrade.rpc.rpc import RPCException
|
||||
from freqtrade.rpc.telegram import Telegram, authorized_only
|
||||
from tests.conftest import (CURRENT_TEST_STRATEGY, create_mock_trades, create_mock_trades_usdt,
|
||||
get_patched_freqtradebot, log_has, log_has_re, patch_exchange,
|
||||
patch_get_signal, patch_whitelist)
|
||||
from tests.conftest import (CURRENT_TEST_STRATEGY, EXMS, create_mock_trades,
|
||||
create_mock_trades_usdt, get_patched_freqtradebot, log_has, log_has_re,
|
||||
patch_exchange, patch_get_signal, patch_whitelist)
|
||||
|
||||
|
||||
class DummyCls(Telegram):
|
||||
@@ -106,7 +107,7 @@ def test_telegram_init(default_conf, mocker, caplog) -> None:
|
||||
"['reload_config', 'reload_conf'], ['show_config', 'show_conf'], "
|
||||
"['stopbuy', 'stopentry'], ['whitelist'], ['blacklist'], "
|
||||
"['blacklist_delete', 'bl_delete'], "
|
||||
"['logs'], ['edge'], ['health'], ['help'], ['version']"
|
||||
"['logs'], ['edge'], ['health'], ['help'], ['version'], ['marketdir']"
|
||||
"]")
|
||||
|
||||
assert log_has(message_str, caplog)
|
||||
@@ -202,6 +203,9 @@ def test_telegram_status(default_conf, update, mocker) -> None:
|
||||
'close_profit_ratio': None,
|
||||
'profit': -0.0059,
|
||||
'profit_ratio': -0.0059,
|
||||
'profit_abs': -0.225,
|
||||
'realized_profit': 0.0,
|
||||
'total_profit_abs': -0.225,
|
||||
'initial_stop_loss_abs': 1.098e-05,
|
||||
'stop_loss_abs': 1.099e-05,
|
||||
'exit_order_status': None,
|
||||
@@ -236,7 +240,7 @@ def test_telegram_status_multi_entry(default_conf, update, mocker, fee) -> None:
|
||||
default_conf['telegram']['chat_id'] = "123"
|
||||
default_conf['position_adjustment_enable'] = True
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_order=MagicMock(return_value=None),
|
||||
get_rate=MagicMock(return_value=0.22),
|
||||
)
|
||||
@@ -275,6 +279,7 @@ def test_telegram_status_multi_entry(default_conf, update, mocker, fee) -> None:
|
||||
assert msg_mock.call_count == 4
|
||||
msg = msg_mock.call_args_list[0][0][0]
|
||||
assert re.search(r'Number of Entries.*2', msg)
|
||||
assert re.search(r'Number of Exits.*0', msg)
|
||||
assert re.search(r'Average Entry Price', msg)
|
||||
assert re.search(r'Order filled', msg)
|
||||
assert re.search(r'Close Date:', msg) is None
|
||||
@@ -288,7 +293,7 @@ def test_telegram_status_closed_trade(default_conf, update, mocker, fee) -> None
|
||||
default_conf['telegram']['chat_id'] = "123"
|
||||
default_conf['position_adjustment_enable'] = True
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_order=MagicMock(return_value=None),
|
||||
get_rate=MagicMock(return_value=0.22),
|
||||
)
|
||||
@@ -310,7 +315,7 @@ def test_telegram_status_closed_trade(default_conf, update, mocker, fee) -> None
|
||||
def test_status_handle(default_conf, update, ticker, fee, mocker) -> None:
|
||||
default_conf['max_open_trades'] = 3
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
_dry_is_price_crossed=MagicMock(return_value=True),
|
||||
@@ -387,7 +392,7 @@ def test_status_handle(default_conf, update, ticker, fee, mocker) -> None:
|
||||
|
||||
def test_status_table_handle(default_conf, update, ticker, fee, mocker) -> None:
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
)
|
||||
@@ -432,7 +437,7 @@ def test_daily_handle(default_conf_usdt, update, ticker, fee, mocker, time_machi
|
||||
return_value=1.1
|
||||
)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
)
|
||||
@@ -487,7 +492,7 @@ def test_daily_handle(default_conf_usdt, update, ticker, fee, mocker, time_machi
|
||||
|
||||
def test_daily_wrong_input(default_conf, update, ticker, mocker) -> None:
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker
|
||||
)
|
||||
|
||||
@@ -521,7 +526,7 @@ def test_weekly_handle(default_conf_usdt, update, ticker, fee, mocker, time_mach
|
||||
return_value=1.1
|
||||
)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
)
|
||||
@@ -591,7 +596,7 @@ def test_monthly_handle(default_conf_usdt, update, ticker, fee, mocker, time_mac
|
||||
return_value=1.1
|
||||
)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
)
|
||||
@@ -672,7 +677,7 @@ def test_profit_handle(default_conf_usdt, update, ticker_usdt, ticker_sell_up, f
|
||||
limit_sell_order_usdt, mocker) -> None:
|
||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=1.1)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker_usdt,
|
||||
get_fee=fee,
|
||||
)
|
||||
@@ -702,7 +707,7 @@ def test_profit_handle(default_conf_usdt, update, ticker_usdt, ticker_sell_up, f
|
||||
msg_mock.reset_mock()
|
||||
|
||||
# Update the ticker with a market going up
|
||||
mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', ticker_sell_up)
|
||||
mocker.patch(f'{EXMS}.fetch_ticker', ticker_sell_up)
|
||||
# Simulate fulfilled LIMIT_SELL order for trade
|
||||
oobj = Order.parse_from_ccxt_object(
|
||||
limit_sell_order_usdt, limit_sell_order_usdt['symbol'], 'sell')
|
||||
@@ -735,7 +740,7 @@ def test_profit_handle(default_conf_usdt, update, ticker_usdt, ticker_sell_up, f
|
||||
def test_telegram_stats(default_conf, update, ticker, fee, mocker, is_short) -> None:
|
||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
)
|
||||
@@ -760,10 +765,9 @@ def test_telegram_stats(default_conf, update, ticker, fee, mocker, is_short) ->
|
||||
|
||||
def test_telegram_balance_handle(default_conf, update, mocker, rpc_balance, tickers) -> None:
|
||||
default_conf['dry_run'] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_balances', return_value=rpc_balance)
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_tickers', tickers)
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_valid_pair_combination',
|
||||
side_effect=lambda a, b: f"{a}/{b}")
|
||||
mocker.patch(f'{EXMS}.get_balances', return_value=rpc_balance)
|
||||
mocker.patch(f'{EXMS}.get_tickers', tickers)
|
||||
mocker.patch(f'{EXMS}.get_valid_pair_combination', side_effect=lambda a, b: f"{a}/{b}")
|
||||
|
||||
telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||
patch_get_signal(freqtradebot)
|
||||
@@ -786,7 +790,7 @@ def test_telegram_balance_handle(default_conf, update, mocker, rpc_balance, tick
|
||||
|
||||
def test_balance_handle_empty_response(default_conf, update, mocker) -> None:
|
||||
default_conf['dry_run'] = False
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_balances', return_value={})
|
||||
mocker.patch(f'{EXMS}.get_balances', return_value={})
|
||||
|
||||
telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||
patch_get_signal(freqtradebot)
|
||||
@@ -799,7 +803,7 @@ def test_balance_handle_empty_response(default_conf, update, mocker) -> None:
|
||||
|
||||
|
||||
def test_balance_handle_empty_response_dry(default_conf, update, mocker) -> None:
|
||||
mocker.patch('freqtrade.exchange.Exchange.get_balances', return_value={})
|
||||
mocker.patch(f'{EXMS}.get_balances', return_value={})
|
||||
|
||||
telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||
patch_get_signal(freqtradebot)
|
||||
@@ -927,7 +931,7 @@ def test_telegram_forceexit_handle(default_conf, update, ticker, fee,
|
||||
patch_exchange(mocker)
|
||||
patch_whitelist(mocker, default_conf)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
_dry_is_price_crossed=MagicMock(return_value=True),
|
||||
@@ -945,7 +949,7 @@ def test_telegram_forceexit_handle(default_conf, update, ticker, fee,
|
||||
assert trade
|
||||
|
||||
# Increase the price and sell it
|
||||
mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', ticker_sell_up)
|
||||
mocker.patch(f'{EXMS}.fetch_ticker', ticker_sell_up)
|
||||
|
||||
# /forceexit 1
|
||||
context = MagicMock()
|
||||
@@ -996,7 +1000,7 @@ def test_telegram_force_exit_down_handle(default_conf, update, ticker, fee,
|
||||
patch_whitelist(mocker, default_conf)
|
||||
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
_dry_is_price_crossed=MagicMock(return_value=True),
|
||||
@@ -1012,7 +1016,7 @@ def test_telegram_force_exit_down_handle(default_conf, update, ticker, fee,
|
||||
|
||||
# Decrease the price and sell it
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker_sell_down
|
||||
)
|
||||
|
||||
@@ -1067,7 +1071,7 @@ def test_forceexit_all_handle(default_conf, update, ticker, fee, mocker) -> None
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram._init', MagicMock())
|
||||
patch_whitelist(mocker, default_conf)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
_dry_is_price_crossed=MagicMock(return_value=True),
|
||||
@@ -1152,7 +1156,7 @@ def test_forceexit_handle_invalid(default_conf, update, mocker) -> None:
|
||||
def test_force_exit_no_pair(default_conf, update, ticker, fee, mocker) -> None:
|
||||
default_conf['max_open_trades'] = 4
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
_dry_is_price_crossed=MagicMock(return_value=True),
|
||||
@@ -1206,7 +1210,7 @@ def test_force_enter_handle(default_conf, update, mocker) -> None:
|
||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
||||
|
||||
fbuy_mock = MagicMock(return_value=None)
|
||||
mocker.patch('freqtrade.rpc.RPC._rpc_force_entry', fbuy_mock)
|
||||
mocker.patch('freqtrade.rpc.rpc.RPC._rpc_force_entry', fbuy_mock)
|
||||
|
||||
telegram, freqtradebot, _ = get_telegram_testobject(mocker, default_conf)
|
||||
patch_get_signal(freqtradebot)
|
||||
@@ -1223,7 +1227,7 @@ def test_force_enter_handle(default_conf, update, mocker) -> None:
|
||||
|
||||
# Reset and retry with specified price
|
||||
fbuy_mock = MagicMock(return_value=None)
|
||||
mocker.patch('freqtrade.rpc.RPC._rpc_force_entry', fbuy_mock)
|
||||
mocker.patch('freqtrade.rpc.rpc.RPC._rpc_force_entry', fbuy_mock)
|
||||
# /forcelong ETH/BTC 0.055
|
||||
context = MagicMock()
|
||||
context.args = ["ETH/BTC", "0.055"]
|
||||
@@ -1252,7 +1256,7 @@ def test_force_enter_no_pair(default_conf, update, mocker) -> None:
|
||||
mocker.patch('freqtrade.rpc.rpc.CryptoToFiatConverter._find_price', return_value=15000.0)
|
||||
|
||||
fbuy_mock = MagicMock(return_value=None)
|
||||
mocker.patch('freqtrade.rpc.RPC._rpc_force_entry', fbuy_mock)
|
||||
mocker.patch('freqtrade.rpc.rpc.RPC._rpc_force_entry', fbuy_mock)
|
||||
|
||||
telegram, freqtradebot, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||
|
||||
@@ -1279,7 +1283,7 @@ def test_force_enter_no_pair(default_conf, update, mocker) -> None:
|
||||
def test_telegram_performance_handle(default_conf_usdt, update, ticker, fee, mocker) -> None:
|
||||
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
)
|
||||
@@ -1297,7 +1301,7 @@ def test_telegram_performance_handle(default_conf_usdt, update, ticker, fee, moc
|
||||
def test_telegram_entry_tag_performance_handle(
|
||||
default_conf_usdt, update, ticker, fee, mocker) -> None:
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
)
|
||||
@@ -1328,7 +1332,7 @@ def test_telegram_entry_tag_performance_handle(
|
||||
def test_telegram_exit_reason_performance_handle(default_conf_usdt, update, ticker, fee,
|
||||
mocker) -> None:
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
)
|
||||
@@ -1359,7 +1363,7 @@ def test_telegram_exit_reason_performance_handle(default_conf_usdt, update, tick
|
||||
def test_telegram_mix_tag_performance_handle(default_conf_usdt, update, ticker, fee,
|
||||
mocker) -> None:
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
)
|
||||
@@ -1391,7 +1395,7 @@ def test_telegram_mix_tag_performance_handle(default_conf_usdt, update, ticker,
|
||||
|
||||
def test_count_handle(default_conf, update, ticker, fee, mocker) -> None:
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
)
|
||||
@@ -1420,7 +1424,7 @@ def test_count_handle(default_conf, update, ticker, fee, mocker) -> None:
|
||||
|
||||
def test_telegram_lock_handle(default_conf, update, ticker, fee, mocker) -> None:
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
)
|
||||
@@ -1488,7 +1492,7 @@ def test_whitelist_static(default_conf, update, mocker) -> None:
|
||||
|
||||
|
||||
def test_whitelist_dynamic(default_conf, update, mocker) -> None:
|
||||
mocker.patch('freqtrade.exchange.Exchange.exchange_has', MagicMock(return_value=True))
|
||||
mocker.patch(f'{EXMS}.exchange_has', return_value=True)
|
||||
default_conf['pairlists'] = [{'method': 'VolumePairList',
|
||||
'number_assets': 4
|
||||
}]
|
||||
@@ -1682,7 +1686,7 @@ def test_telegram_delete_trade(mocker, update, default_conf, fee, is_short):
|
||||
def test_telegram_delete_open_order(mocker, update, default_conf, fee, is_short, ticker):
|
||||
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
)
|
||||
telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||
@@ -1703,8 +1707,7 @@ def test_telegram_delete_open_order(mocker, update, default_conf, fee, is_short,
|
||||
msg_mock.reset_mock()
|
||||
|
||||
trade = Trade.get_trades([Trade.id == 6]).first()
|
||||
mocker.patch('freqtrade.exchange.Exchange.fetch_order',
|
||||
return_value=trade.orders[-1].to_ccxt_object())
|
||||
mocker.patch(f'{EXMS}.fetch_order', return_value=trade.orders[-1].to_ccxt_object())
|
||||
context = MagicMock()
|
||||
context.args = [6]
|
||||
telegram._cancel_open_order(update=update, context=context)
|
||||
@@ -2394,3 +2397,15 @@ def test__send_msg_keyboard(default_conf, mocker, caplog) -> None:
|
||||
assert log_has("using custom keyboard from config.json: "
|
||||
"[['/daily', '/stats', '/balance', '/profit', '/profit 5'], ['/count', "
|
||||
"'/start', '/reload_config', '/help']]", caplog)
|
||||
|
||||
|
||||
def test_change_market_direction(default_conf, mocker, update) -> None:
|
||||
telegram, _, msg_mock = get_telegram_testobject(mocker, default_conf)
|
||||
assert telegram._rpc._freqtrade.strategy.market_direction == MarketDirection.NONE
|
||||
context = MagicMock()
|
||||
context.args = ["long"]
|
||||
telegram._changemarketdir(update, context)
|
||||
assert telegram._rpc._freqtrade.strategy.market_direction == MarketDirection.LONG
|
||||
context = MagicMock()
|
||||
context.args = ["invalid"]
|
||||
assert telegram._rpc._freqtrade.strategy.market_direction == MarketDirection.LONG
|
||||
|
@@ -356,6 +356,14 @@ def test_exception_send_msg(default_conf, mocker, caplog):
|
||||
}
|
||||
webhook.send_msg(msg)
|
||||
|
||||
# Test no failure for not implemented but known messagetypes
|
||||
for e in RPCMessageType:
|
||||
msg = {
|
||||
'type': e,
|
||||
'status': 'whatever'
|
||||
}
|
||||
webhook.send_msg(msg)
|
||||
|
||||
|
||||
def test__send_msg(default_conf, mocker, caplog):
|
||||
default_conf["webhook"] = get_webhook_dict()
|
||||
|
@@ -7,6 +7,7 @@ from datetime import datetime
|
||||
|
||||
from pandas import DataFrame
|
||||
|
||||
from freqtrade.persistence.trade_model import Order
|
||||
from freqtrade.strategy.interface import IStrategy
|
||||
|
||||
|
||||
@@ -35,7 +36,7 @@ class TestStrategyImplementBuyTimeout(TestStrategyNoImplementSell):
|
||||
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
return super().populate_exit_trend(dataframe, metadata)
|
||||
|
||||
def check_buy_timeout(self, pair: str, trade, order: dict,
|
||||
def check_buy_timeout(self, pair: str, trade, order: Order,
|
||||
current_time: datetime, **kwargs) -> bool:
|
||||
return False
|
||||
|
||||
@@ -44,6 +45,6 @@ class TestStrategyImplementSellTimeout(TestStrategyNoImplementSell):
|
||||
def populate_exit_trend(self, dataframe: DataFrame, metadata: dict) -> DataFrame:
|
||||
return super().populate_exit_trend(dataframe, metadata)
|
||||
|
||||
def check_sell_timeout(self, pair: str, trade, order: dict,
|
||||
def check_sell_timeout(self, pair: str, trade, order: Order,
|
||||
current_time: datetime, **kwargs) -> bool:
|
||||
return False
|
||||
|
@@ -197,7 +197,7 @@ class StrategyTestV3(IStrategy):
|
||||
|
||||
if current_profit < -0.0075:
|
||||
orders = trade.select_filled_orders(trade.entry_side)
|
||||
return round(orders[0].cost, 0)
|
||||
return round(orders[0].safe_cost, 0)
|
||||
|
||||
return None
|
||||
|
||||
|
@@ -214,12 +214,12 @@ def test_ignore_expired_candle(default_conf):
|
||||
|
||||
current_time = latest_date + timedelta(seconds=30 + 300)
|
||||
|
||||
assert not strategy.ignore_expired_candle(
|
||||
assert strategy.ignore_expired_candle(
|
||||
latest_date=latest_date,
|
||||
current_time=current_time,
|
||||
timeframe_seconds=300,
|
||||
enter=True
|
||||
) is True
|
||||
) is not True
|
||||
|
||||
|
||||
def test_assert_df_raise(mocker, caplog, ohlcv_history):
|
||||
@@ -291,18 +291,6 @@ def test_advise_all_indicators(default_conf, testdatadir) -> None:
|
||||
assert len(processed['UNITTEST/BTC']) == 103
|
||||
|
||||
|
||||
def test_populate_any_indicators(default_conf, testdatadir) -> None:
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
|
||||
timerange = TimeRange.parse_timerange('1510694220-1510700340')
|
||||
data = load_data(testdatadir, '1m', ['UNITTEST/BTC'], timerange=timerange,
|
||||
fill_up_missing=True)
|
||||
processed = strategy.populate_any_indicators('UNITTEST/BTC', data, '5m')
|
||||
assert processed == data
|
||||
assert id(processed) == id(data)
|
||||
assert len(processed['UNITTEST/BTC']) == 103
|
||||
|
||||
|
||||
def test_freqai_not_initialized(default_conf) -> None:
|
||||
strategy = StrategyResolver.load_strategy(default_conf)
|
||||
strategy.ft_bot_start()
|
||||
|
@@ -119,53 +119,54 @@ def test_merge_informative_pair_suffix_append_timeframe():
|
||||
merge_informative_pair(data, informative, '15m', '1h', suffix="suf")
|
||||
|
||||
|
||||
def test_stoploss_from_open():
|
||||
@pytest.mark.parametrize("side,profitrange", [
|
||||
# profit range for long is [-1, inf] while for shorts is [-inf, 1]
|
||||
("long", [-0.99, 2, 30]),
|
||||
("short", [-2.0, 0.99, 30]),
|
||||
])
|
||||
def test_stoploss_from_open(side, profitrange):
|
||||
open_price_ranges = [
|
||||
[0.01, 1.00, 30],
|
||||
[1, 100, 30],
|
||||
[100, 10000, 30],
|
||||
]
|
||||
# profit range for long is [-1, inf] while for shorts is [-inf, 1]
|
||||
current_profit_range_dict = {'long': [-0.99, 2, 30], 'short': [-2.0, 0.99, 30]}
|
||||
desired_stop_range = [-0.50, 0.50, 30]
|
||||
|
||||
for side, current_profit_range in current_profit_range_dict.items():
|
||||
for open_range in open_price_ranges:
|
||||
for open_price in np.linspace(*open_range):
|
||||
for desired_stop in np.linspace(*desired_stop_range):
|
||||
for open_range in open_price_ranges:
|
||||
for open_price in np.linspace(*open_range):
|
||||
for desired_stop in np.linspace(-0.50, 0.50, 30):
|
||||
|
||||
if side == 'long':
|
||||
# -1 is not a valid current_profit, should return 1
|
||||
assert stoploss_from_open(desired_stop, -1) == 1
|
||||
else:
|
||||
# 1 is not a valid current_profit for shorts, should return 1
|
||||
assert stoploss_from_open(desired_stop, 1, True) == 1
|
||||
|
||||
for current_profit in np.linspace(*profitrange):
|
||||
if side == 'long':
|
||||
# -1 is not a valid current_profit, should return 1
|
||||
assert stoploss_from_open(desired_stop, -1) == 1
|
||||
current_price = open_price * (1 + current_profit)
|
||||
expected_stop_price = open_price * (1 + desired_stop)
|
||||
stoploss = stoploss_from_open(desired_stop, current_profit)
|
||||
stop_price = current_price * (1 - stoploss)
|
||||
else:
|
||||
# 1 is not a valid current_profit for shorts, should return 1
|
||||
assert stoploss_from_open(desired_stop, 1, True) == 1
|
||||
current_price = open_price * (1 - current_profit)
|
||||
expected_stop_price = open_price * (1 - desired_stop)
|
||||
stoploss = stoploss_from_open(desired_stop, current_profit, True)
|
||||
stop_price = current_price * (1 + stoploss)
|
||||
|
||||
for current_profit in np.linspace(*current_profit_range):
|
||||
if side == 'long':
|
||||
current_price = open_price * (1 + current_profit)
|
||||
expected_stop_price = open_price * (1 + desired_stop)
|
||||
stoploss = stoploss_from_open(desired_stop, current_profit)
|
||||
stop_price = current_price * (1 - stoploss)
|
||||
else:
|
||||
current_price = open_price * (1 - current_profit)
|
||||
expected_stop_price = open_price * (1 - desired_stop)
|
||||
stoploss = stoploss_from_open(desired_stop, current_profit, True)
|
||||
stop_price = current_price * (1 + stoploss)
|
||||
assert stoploss >= 0
|
||||
# Technically the formula can yield values greater than 1 for shorts
|
||||
# eventhough it doesn't make sense because the position would be liquidated
|
||||
if side == 'long':
|
||||
assert stoploss <= 1
|
||||
|
||||
assert stoploss >= 0
|
||||
# Technically the formula can yield values greater than 1 for shorts
|
||||
# eventhough it doesn't make sense because the position would be liquidated
|
||||
if side == 'long':
|
||||
assert stoploss <= 1
|
||||
|
||||
# there is no correct answer if the expected stop price is above
|
||||
# the current price
|
||||
if ((side == 'long' and expected_stop_price > current_price)
|
||||
or (side == 'short' and expected_stop_price < current_price)):
|
||||
assert stoploss == 0
|
||||
else:
|
||||
assert pytest.approx(stop_price) == expected_stop_price
|
||||
# there is no correct answer if the expected stop price is above
|
||||
# the current price
|
||||
if ((side == 'long' and expected_stop_price > current_price)
|
||||
or (side == 'short' and expected_stop_price < current_price)):
|
||||
assert stoploss == 0
|
||||
else:
|
||||
assert pytest.approx(stop_price) == expected_stop_price
|
||||
|
||||
|
||||
def test_stoploss_from_absolute():
|
||||
|
@@ -59,7 +59,7 @@ def test_load_config_incorrect_stake_amount(default_conf) -> None:
|
||||
def test_load_config_file(default_conf, mocker, caplog) -> None:
|
||||
del default_conf['user_data_dir']
|
||||
default_conf['datadir'] = str(default_conf['datadir'])
|
||||
file_mock = mocker.patch('freqtrade.configuration.load_config.open', mocker.mock_open(
|
||||
file_mock = mocker.patch('freqtrade.configuration.load_config.Path.open', mocker.mock_open(
|
||||
read_data=json.dumps(default_conf)
|
||||
))
|
||||
|
||||
@@ -73,7 +73,8 @@ def test_load_config_file_error(default_conf, mocker, caplog) -> None:
|
||||
default_conf['datadir'] = str(default_conf['datadir'])
|
||||
filedata = json.dumps(default_conf).replace(
|
||||
'"stake_amount": 0.001,', '"stake_amount": .001,')
|
||||
mocker.patch('freqtrade.configuration.load_config.open', mocker.mock_open(read_data=filedata))
|
||||
mocker.patch('freqtrade.configuration.load_config.Path.open',
|
||||
mocker.mock_open(read_data=filedata))
|
||||
mocker.patch.object(Path, "read_text", MagicMock(return_value=filedata))
|
||||
|
||||
with pytest.raises(OperationalException, match=r".*Please verify the following segment.*"):
|
||||
@@ -272,7 +273,7 @@ def test_load_config_max_open_trades_minus_one(default_conf, mocker, caplog) ->
|
||||
|
||||
def test_load_config_file_exception(mocker) -> None:
|
||||
mocker.patch(
|
||||
'freqtrade.configuration.configuration.open',
|
||||
'freqtrade.configuration.configuration.Path.open',
|
||||
MagicMock(side_effect=FileNotFoundError('File not found'))
|
||||
)
|
||||
|
||||
@@ -701,15 +702,16 @@ def test_set_loggers_journald(mocker):
|
||||
'logfile': 'journald',
|
||||
}
|
||||
|
||||
setup_logging_pre()
|
||||
setup_logging(config)
|
||||
assert len(logger.handlers) == 2
|
||||
assert len(logger.handlers) == 3
|
||||
assert [x for x in logger.handlers if type(x).__name__ == "JournaldLogHandler"]
|
||||
assert [x for x in logger.handlers if type(x) == logging.StreamHandler]
|
||||
# reset handlers to not break pytest
|
||||
logger.handlers = orig_handlers
|
||||
|
||||
|
||||
def test_set_loggers_journald_importerror(mocker, import_fails):
|
||||
def test_set_loggers_journald_importerror(import_fails):
|
||||
logger = logging.getLogger()
|
||||
orig_handlers = logger.handlers
|
||||
logger.handlers = []
|
||||
@@ -718,7 +720,7 @@ def test_set_loggers_journald_importerror(mocker, import_fails):
|
||||
'logfile': 'journald',
|
||||
}
|
||||
with pytest.raises(OperationalException,
|
||||
match=r'You need the systemd python package.*'):
|
||||
match=r'You need the cysystemd python package.*'):
|
||||
setup_logging(config)
|
||||
logger.handlers = orig_handlers
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@ from freqtrade.enums import ExitCheckTuple, ExitType, TradingMode
|
||||
from freqtrade.persistence import Trade
|
||||
from freqtrade.persistence.models import Order
|
||||
from freqtrade.rpc.rpc import RPC
|
||||
from tests.conftest import get_patched_freqtradebot, log_has_re, patch_get_signal
|
||||
from tests.conftest import EXMS, get_patched_freqtradebot, log_has_re, patch_get_signal
|
||||
|
||||
|
||||
def test_may_execute_exit_stoploss_on_exchange_multi(default_conf, ticker, fee,
|
||||
@@ -56,9 +56,9 @@ def test_may_execute_exit_stoploss_on_exchange_multi(default_conf, ticker, fee,
|
||||
[ExitCheckTuple(exit_type=ExitType.EXIT_SIGNAL)]]
|
||||
)
|
||||
cancel_order_mock = MagicMock()
|
||||
mocker.patch('freqtrade.exchange.Binance.create_stoploss', stoploss)
|
||||
mocker.patch('freqtrade.exchange.binance.Binance.create_stoploss', stoploss)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
amount_to_precision=lambda s, x, y: y,
|
||||
@@ -147,7 +147,7 @@ def test_forcebuy_last_unlimited(default_conf, ticker, fee, mocker, balance_rati
|
||||
default_conf['telegram']['enabled'] = True
|
||||
mocker.patch('freqtrade.rpc.telegram.Telegram', MagicMock())
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
get_fee=fee,
|
||||
amount_to_precision=lambda s, x, y: y,
|
||||
@@ -217,7 +217,7 @@ def test_dca_buying(default_conf_usdt, ticker_usdt, fee, mocker) -> None:
|
||||
|
||||
freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker_usdt,
|
||||
get_fee=fee,
|
||||
)
|
||||
@@ -239,7 +239,7 @@ def test_dca_buying(default_conf_usdt, ticker_usdt, fee, mocker) -> None:
|
||||
# Reduce bid amount
|
||||
ticker_usdt_modif = ticker_usdt.return_value
|
||||
ticker_usdt_modif['bid'] = ticker_usdt_modif['bid'] * 0.995
|
||||
mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', return_value=ticker_usdt_modif)
|
||||
mocker.patch(f'{EXMS}.fetch_ticker', return_value=ticker_usdt_modif)
|
||||
|
||||
# additional buy order
|
||||
freqtrade.process()
|
||||
@@ -286,7 +286,7 @@ def test_dca_short(default_conf_usdt, ticker_usdt, fee, mocker) -> None:
|
||||
|
||||
freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker_usdt,
|
||||
get_fee=fee,
|
||||
amount_to_precision=lambda s, x, y: round(y, 4),
|
||||
@@ -311,7 +311,7 @@ def test_dca_short(default_conf_usdt, ticker_usdt, fee, mocker) -> None:
|
||||
# Reduce bid amount
|
||||
ticker_usdt_modif = ticker_usdt.return_value
|
||||
ticker_usdt_modif['ask'] = ticker_usdt_modif['ask'] * 1.004
|
||||
mocker.patch('freqtrade.exchange.Exchange.fetch_ticker', return_value=ticker_usdt_modif)
|
||||
mocker.patch(f'{EXMS}.fetch_ticker', return_value=ticker_usdt_modif)
|
||||
|
||||
# additional buy order
|
||||
freqtrade.process()
|
||||
@@ -361,16 +361,16 @@ def test_dca_order_adjust(default_conf_usdt, ticker_usdt, leverage, fee, mocker)
|
||||
|
||||
freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt)
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker_usdt,
|
||||
get_fee=fee,
|
||||
amount_to_precision=lambda s, x, y: y,
|
||||
price_to_precision=lambda s, x, y: y,
|
||||
)
|
||||
mocker.patch('freqtrade.exchange.Exchange._dry_is_price_crossed', return_value=False)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_leverage", return_value=10)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_funding_fees", return_value=0)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_maintenance_ratio_and_amt", return_value=(0, 0))
|
||||
mocker.patch(f'{EXMS}._dry_is_price_crossed', return_value=False)
|
||||
mocker.patch(f"{EXMS}.get_max_leverage", return_value=10)
|
||||
mocker.patch(f"{EXMS}.get_funding_fees", return_value=0)
|
||||
mocker.patch(f"{EXMS}.get_maintenance_ratio_and_amt", return_value=(0, 0))
|
||||
|
||||
patch_get_signal(freqtrade)
|
||||
freqtrade.strategy.custom_entry_price = lambda **kwargs: ticker_usdt['ask'] * 0.96
|
||||
@@ -413,7 +413,7 @@ def test_dca_order_adjust(default_conf_usdt, ticker_usdt, leverage, fee, mocker)
|
||||
assert trade.initial_stop_loss_pct is None
|
||||
|
||||
# Fill order
|
||||
mocker.patch('freqtrade.exchange.Exchange._dry_is_price_crossed', return_value=True)
|
||||
mocker.patch(f'{EXMS}._dry_is_price_crossed', return_value=True)
|
||||
freqtrade.process()
|
||||
trade = Trade.get_trades().first()
|
||||
assert len(trade.orders) == 2
|
||||
@@ -428,7 +428,7 @@ def test_dca_order_adjust(default_conf_usdt, ticker_usdt, leverage, fee, mocker)
|
||||
|
||||
# 2nd order - not filling
|
||||
freqtrade.strategy.adjust_trade_position = MagicMock(return_value=120)
|
||||
mocker.patch('freqtrade.exchange.Exchange._dry_is_price_crossed', return_value=False)
|
||||
mocker.patch(f'{EXMS}._dry_is_price_crossed', return_value=False)
|
||||
|
||||
freqtrade.process()
|
||||
trade = Trade.get_trades().first()
|
||||
@@ -452,7 +452,7 @@ def test_dca_order_adjust(default_conf_usdt, ticker_usdt, leverage, fee, mocker)
|
||||
|
||||
# Fill DCA order
|
||||
freqtrade.strategy.adjust_trade_position = MagicMock(return_value=None)
|
||||
mocker.patch('freqtrade.exchange.Exchange._dry_is_price_crossed', return_value=True)
|
||||
mocker.patch(f'{EXMS}._dry_is_price_crossed', return_value=True)
|
||||
freqtrade.strategy.adjust_entry_price = MagicMock(side_effect=ValueError)
|
||||
|
||||
freqtrade.process()
|
||||
@@ -477,14 +477,14 @@ def test_dca_exiting(default_conf_usdt, ticker_usdt, fee, mocker, caplog, levera
|
||||
freqtrade = get_patched_freqtradebot(mocker, default_conf_usdt)
|
||||
freqtrade.trading_mode = TradingMode.FUTURES
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker_usdt,
|
||||
get_fee=fee,
|
||||
amount_to_precision=lambda s, x, y: y,
|
||||
price_to_precision=lambda s, x, y: y,
|
||||
get_min_pair_stake_amount=MagicMock(return_value=10),
|
||||
)
|
||||
mocker.patch("freqtrade.exchange.Exchange.get_max_leverage", return_value=10)
|
||||
mocker.patch(f"{EXMS}.get_max_leverage", return_value=10)
|
||||
|
||||
patch_get_signal(freqtrade)
|
||||
freqtrade.strategy.leverage = MagicMock(return_value=leverage)
|
||||
@@ -532,8 +532,7 @@ def test_dca_exiting(default_conf_usdt, ticker_usdt, fee, mocker, caplog, levera
|
||||
assert trade.is_open
|
||||
|
||||
# use amount that would trunc to 0.0 once selling
|
||||
mocker.patch("freqtrade.exchange.Exchange.amount_to_contract_precision",
|
||||
lambda s, p, v: round(v, 1))
|
||||
mocker.patch(f"{EXMS}.amount_to_contract_precision", lambda s, p, v: round(v, 1))
|
||||
freqtrade.strategy.adjust_trade_position = MagicMock(return_value=-0.01)
|
||||
freqtrade.process()
|
||||
trade = Trade.get_trades().first()
|
||||
|
@@ -46,7 +46,7 @@ def test_shorten_date() -> None:
|
||||
|
||||
|
||||
def test_file_dump_json(mocker) -> None:
|
||||
file_open = mocker.patch('freqtrade.misc.open', MagicMock())
|
||||
file_open = mocker.patch('freqtrade.misc.Path.open', MagicMock())
|
||||
json_dump = mocker.patch('rapidjson.dump', MagicMock())
|
||||
file_dump_json(Path('somefile'), [1, 2, 3])
|
||||
assert file_open.call_count == 1
|
||||
|
@@ -6,13 +6,13 @@ import pytest
|
||||
|
||||
from freqtrade.constants import UNLIMITED_STAKE_AMOUNT
|
||||
from freqtrade.exceptions import DependencyException
|
||||
from tests.conftest import create_mock_trades, get_patched_freqtradebot, patch_wallet
|
||||
from tests.conftest import EXMS, create_mock_trades, get_patched_freqtradebot, patch_wallet
|
||||
|
||||
|
||||
def test_sync_wallet_at_boot(mocker, default_conf):
|
||||
default_conf['dry_run'] = False
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
get_balances=MagicMock(return_value={
|
||||
"BNT": {
|
||||
"free": 1.0,
|
||||
@@ -45,7 +45,7 @@ def test_sync_wallet_at_boot(mocker, default_conf):
|
||||
assert 'USDT' in freqtrade.wallets._wallets
|
||||
assert freqtrade.wallets._last_wallet_refresh > 0
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
get_balances=MagicMock(return_value={
|
||||
"BNT": {
|
||||
"free": 1.2,
|
||||
@@ -87,7 +87,7 @@ def test_sync_wallet_at_boot(mocker, default_conf):
|
||||
def test_sync_wallet_missing_data(mocker, default_conf):
|
||||
default_conf['dry_run'] = False
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
get_balances=MagicMock(return_value={
|
||||
"BNT": {
|
||||
"free": 1.0,
|
||||
@@ -136,7 +136,7 @@ def test_get_trade_stake_amount_unlimited_amount(default_conf, ticker, balance_r
|
||||
result1, result2, limit_buy_order_open,
|
||||
fee, mocker) -> None:
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
fetch_ticker=ticker,
|
||||
create_order=MagicMock(return_value=limit_buy_order_open),
|
||||
get_fee=fee
|
||||
@@ -312,7 +312,7 @@ def test_sync_wallet_futures_live(mocker, default_conf):
|
||||
}
|
||||
]
|
||||
mocker.patch.multiple(
|
||||
'freqtrade.exchange.Exchange',
|
||||
EXMS,
|
||||
get_balances=MagicMock(return_value={
|
||||
"USDT": {
|
||||
"free": 900,
|
||||
|
@@ -8,11 +8,11 @@ import time_machine
|
||||
from freqtrade.data.dataprovider import DataProvider
|
||||
from freqtrade.enums import State
|
||||
from freqtrade.worker import Worker
|
||||
from tests.conftest import get_patched_worker, log_has, log_has_re
|
||||
from tests.conftest import EXMS, get_patched_worker, log_has, log_has_re
|
||||
|
||||
|
||||
def test_worker_state(mocker, default_conf, markets) -> None:
|
||||
mocker.patch('freqtrade.exchange.Exchange.markets', PropertyMock(return_value=markets))
|
||||
mocker.patch(f'{EXMS}.markets', PropertyMock(return_value=markets))
|
||||
worker = get_patched_worker(mocker, default_conf)
|
||||
assert worker.freqtrade.state is State.RUNNING
|
||||
|
||||
|
Reference in New Issue
Block a user