def test_fetch_stoploss_order(default_conf, mocker): default_conf['dry_run'] = True order = MagicMock() order.myid = 123 exchange = get_patched_exchange(mocker, default_conf, id='ftx') exchange._dry_run_open_orders['X'] = order assert exchange.fetch_stoploss_order('X', 'TKN/BTC').myid == 123 with pytest.raises(InvalidOrderException, match=r'Tried to get an invalid dry-run-order.*'): exchange.fetch_stoploss_order('Y', 'TKN/BTC') default_conf['dry_run'] = False api_mock = MagicMock() api_mock.fetch_orders = MagicMock(return_value=[{'id': 'X', 'status': '456'}]) exchange = get_patched_exchange(mocker, default_conf, api_mock, id='ftx') assert exchange.fetch_stoploss_order('X', 'TKN/BTC')['status'] == '456' api_mock.fetch_orders = MagicMock(return_value=[{'id': 'Y', 'status': '456'}]) exchange = get_patched_exchange(mocker, default_conf, api_mock, id='ftx') with pytest.raises(InvalidOrderException, match=r"Could not get stoploss order for id X"): exchange.fetch_stoploss_order('X', 'TKN/BTC')['status'] with pytest.raises(InvalidOrderException): api_mock.fetch_orders = MagicMock(side_effect=ccxt.InvalidOrder("Order not found")) exchange = get_patched_exchange(mocker, default_conf, api_mock, id='ftx') exchange.fetch_stoploss_order(order_id='_', pair='TKN/BTC') assert api_mock.fetch_orders.call_count == 1 ccxt_exceptionhandlers(mocker, default_conf, api_mock, 'ftx', 'fetch_stoploss_order', 'fetch_orders', retries=API_FETCH_ORDER_RETRY_COUNT + 1, order_id='_', pair='TKN/BTC')
def test_fetch_stoploss_order_ftx(default_conf, mocker, limit_sell_order, limit_buy_order): default_conf['dry_run'] = True order = MagicMock() order.myid = 123 exchange = get_patched_exchange(mocker, default_conf, id='ftx') exchange._dry_run_open_orders['X'] = order assert exchange.fetch_stoploss_order('X', 'TKN/BTC').myid == 123 with pytest.raises(InvalidOrderException, match=r'Tried to get an invalid dry-run-order.*'): exchange.fetch_stoploss_order('Y', 'TKN/BTC') default_conf['dry_run'] = False api_mock = MagicMock() api_mock.fetch_orders = MagicMock(return_value=[{'id': 'X', 'status': '456'}]) exchange = get_patched_exchange(mocker, default_conf, api_mock, id='ftx') assert exchange.fetch_stoploss_order('X', 'TKN/BTC')['status'] == '456' api_mock.fetch_orders = MagicMock(return_value=[{'id': 'Y', 'status': '456'}]) exchange = get_patched_exchange(mocker, default_conf, api_mock, id='ftx') with pytest.raises(InvalidOrderException, match=r"Could not get stoploss order for id X"): exchange.fetch_stoploss_order('X', 'TKN/BTC')['status'] # stoploss Limit order api_mock.fetch_orders = MagicMock(return_value=[ {'id': 'X', 'status': 'closed', 'info': { 'orderId': 'mocked_limit_sell', }}]) api_mock.fetch_order = MagicMock(return_value=limit_sell_order) # No orderId field - no call to fetch_order resp = exchange.fetch_stoploss_order('X', 'TKN/BTC') assert resp assert api_mock.fetch_order.call_count == 1 assert resp['id_stop'] == 'mocked_limit_sell' assert resp['id'] == 'X' assert resp['type'] == 'stop' assert resp['status_stop'] == 'triggered' # Stoploss market order # Contains no new Order, but "average" instead order = {'id': 'X', 'status': 'closed', 'info': {'orderId': None}, 'average': 0.254} api_mock.fetch_orders = MagicMock(return_value=[order]) api_mock.fetch_order.reset_mock() resp = exchange.fetch_stoploss_order('X', 'TKN/BTC') assert resp # fetch_order not called (no regular order ID) assert api_mock.fetch_order.call_count == 0 assert order == order with pytest.raises(InvalidOrderException): api_mock.fetch_orders = MagicMock(side_effect=ccxt.InvalidOrder("Order not found")) exchange = get_patched_exchange(mocker, default_conf, api_mock, id='ftx') exchange.fetch_stoploss_order(order_id='_', pair='TKN/BTC') assert api_mock.fetch_orders.call_count == 1 ccxt_exceptionhandlers(mocker, default_conf, api_mock, 'ftx', 'fetch_stoploss_order', 'fetch_orders', retries=API_FETCH_ORDER_RETRY_COUNT + 1, order_id='_', pair='TKN/BTC')
def test_stoploss_order_kraken(default_conf, mocker): api_mock = MagicMock() order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6)) order_type = 'stop-loss' api_mock.create_order = MagicMock(return_value={ 'id': order_id, 'info': { 'foo': 'bar' } }) 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) exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kraken') # stoploss_on_exchange_limit_ratio is irrelevant for kraken market orders order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=190, order_types={'stoploss_on_exchange_limit_ratio': 1.05}) assert api_mock.create_order.call_count == 1 api_mock.create_order.reset_mock() order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) assert 'id' in order assert 'info' in order assert order['id'] == order_id assert api_mock.create_order.call_args_list[0][1]['symbol'] == 'ETH/BTC' assert api_mock.create_order.call_args_list[0][1]['type'] == order_type assert api_mock.create_order.call_args_list[0][1]['side'] == 'sell' assert api_mock.create_order.call_args_list[0][1]['amount'] == 1 assert api_mock.create_order.call_args_list[0][1]['price'] == 220 assert api_mock.create_order.call_args_list[0][1]['params'] == {'trading_agreement': 'agree'} # test exception handling with pytest.raises(DependencyException): api_mock.create_order = MagicMock(side_effect=ccxt.InsufficientFunds("0 balance")) exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kraken') exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) with pytest.raises(InvalidOrderException): api_mock.create_order = MagicMock( side_effect=ccxt.InvalidOrder("kraken Order would trigger immediately.")) exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kraken') exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) with pytest.raises(TemporaryError): api_mock.create_order = MagicMock(side_effect=ccxt.NetworkError("No connection")) exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kraken') exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) with pytest.raises(OperationalException, match=r".*DeadBeef.*"): api_mock.create_order = MagicMock(side_effect=ccxt.BaseError("DeadBeef")) exchange = get_patched_exchange(mocker, default_conf, api_mock, 'kraken') exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={})
def test_stoploss_order_binance(default_conf, mocker, limitratio, expected): api_mock = MagicMock() order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6)) order_type = 'stop_loss_limit' api_mock.create_order = MagicMock(return_value={ 'id': order_id, 'info': { 'foo': 'bar' } }) 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) exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance') with pytest.raises(OperationalException): order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=190, order_types={'stoploss_on_exchange_limit_ratio': 1.05}) api_mock.create_order.reset_mock() order_types = {} if limitratio is None else {'stoploss_on_exchange_limit_ratio': limitratio} order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types=order_types) assert 'id' in order assert 'info' in order assert order['id'] == order_id assert api_mock.create_order.call_args_list[0][1]['symbol'] == 'ETH/BTC' assert api_mock.create_order.call_args_list[0][1]['type'] == order_type assert api_mock.create_order.call_args_list[0][1]['side'] == 'sell' assert api_mock.create_order.call_args_list[0][1]['amount'] == 1 # Price should be 1% below stopprice assert api_mock.create_order.call_args_list[0][1]['price'] == expected assert api_mock.create_order.call_args_list[0][1]['params'] == {'stopPrice': 220} # test exception handling with pytest.raises(DependencyException): api_mock.create_order = MagicMock(side_effect=ccxt.InsufficientFunds("0 balance")) exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance') exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) with pytest.raises(InvalidOrderException): api_mock.create_order = MagicMock( side_effect=ccxt.InvalidOrder("binance Order would trigger immediately.")) exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance') exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) ccxt_exceptionhandlers(mocker, default_conf, api_mock, "binance", "stoploss", "create_order", retries=1, pair='ETH/BTC', amount=1, stop_price=220, order_types={})
def test_stoploss_order_dry_run_ftx(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) exchange = get_patched_exchange(mocker, default_conf, api_mock, 'ftx') api_mock.create_order.reset_mock() order = exchange.stoploss( pair='ETH/BTC', amount=1, stop_price=220, order_types={}, side=side, leverage=1.0 ) assert 'id' in order assert 'info' in order assert 'type' in order assert order['type'] == STOPLOSS_ORDERTYPE assert order['price'] == 220 assert order['amount'] == 1
def test_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) exchange = get_patched_exchange(mocker, default_conf, api_mock, 'huobi') with pytest.raises(OperationalException): order = exchange.stoploss( pair='ETH/BTC', amount=1, stop_price=190, order_types={'stoploss_on_exchange_limit_ratio': 1.05}) api_mock.create_order.reset_mock() order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={}) assert 'id' in order assert 'info' in order assert 'type' in order assert order['type'] == order_type assert order['price'] == 220 assert order['amount'] == 1
def test_get_signal_handles_exceptions(mocker, default_conf): exchange = get_patched_exchange(mocker, default_conf) mocker.patch.object( _STRATEGY, 'analyze_ticker', side_effect=Exception('invalid ticker history ') ) assert _STRATEGY.get_signal(exchange, 'ETH/BTC', '5m') == (False, False)
def test_download_pair_history2(mocker, default_conf, testdatadir) -> None: tick = [[ 1509836520000, 0.00162008, 0.00162008, 0.00162008, 0.00162008, 108.14853839 ], [1509836580000, 0.00161, 0.00161, 0.00161, 0.00161, 82.390199]] 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) exchange = get_patched_exchange(mocker, default_conf) _download_pair_history(datadir=testdatadir, exchange=exchange, pair="UNITTEST/BTC", timeframe='1m', candle_type='spot') _download_pair_history(datadir=testdatadir, exchange=exchange, pair="UNITTEST/BTC", timeframe='3m', candle_type='spot') _download_pair_history(datadir=testdatadir, exchange=exchange, pair="UNITTEST/USDT", timeframe='1h', candle_type='mark') assert json_dump_mock.call_count == 3
async def test__async_get_historic_ohlcv_binance(default_conf, mocker, caplog): ohlcv = [ [ int((datetime.now(timezone.utc).timestamp() - 1000) * 1000), 1, # open 2, # high 3, # low 4, # close 5, # volume (in quote currency) ] ] exchange = get_patched_exchange(mocker, default_conf, id='binance') # Monkey-patch async function exchange._api_async.fetch_ohlcv = get_mock_coro(ohlcv) pair = 'ETH/BTC' res = await exchange._async_get_historic_ohlcv(pair, "5m", 1500000000000, is_new_pair=False) # Call with very old timestamp - causes tons of requests assert exchange._api_async.fetch_ohlcv.call_count > 400 # assert res == ohlcv exchange._api_async.fetch_ohlcv.reset_mock() res = await exchange._async_get_historic_ohlcv(pair, "5m", 1500000000000, is_new_pair=True) # Called twice - one "init" call - and one to get the actual data. assert exchange._api_async.fetch_ohlcv.call_count == 2 assert res == ohlcv assert log_has_re(r"Candle-data for ETH/BTC available starting with .*", caplog)
def test_get_pair_dataframe(mocker, default_conf, ohlcv_history): default_conf["runmode"] = RunMode.DRY_RUN timeframe = default_conf["timeframe"] exchange = get_patched_exchange(mocker, default_conf) exchange._klines[("XRP/BTC", timeframe)] = ohlcv_history exchange._klines[("UNITTEST/BTC", timeframe)] = ohlcv_history dp = DataProvider(default_conf, exchange) assert dp.runmode == RunMode.DRY_RUN assert ohlcv_history.equals(dp.get_pair_dataframe("UNITTEST/BTC", timeframe)) assert isinstance(dp.get_pair_dataframe("UNITTEST/BTC", timeframe), DataFrame) assert dp.get_pair_dataframe("UNITTEST/BTC", timeframe) is not ohlcv_history assert not dp.get_pair_dataframe("UNITTEST/BTC", timeframe).empty assert dp.get_pair_dataframe("NONESENSE/AAA", timeframe).empty # Test with and without parameter assert dp.get_pair_dataframe("UNITTEST/BTC", timeframe)\ .equals(dp.get_pair_dataframe("UNITTEST/BTC")) default_conf["runmode"] = RunMode.LIVE dp = DataProvider(default_conf, exchange) assert dp.runmode == RunMode.LIVE assert isinstance(dp.get_pair_dataframe("UNITTEST/BTC", timeframe), DataFrame) assert dp.get_pair_dataframe("NONESENSE/AAA", timeframe).empty historymock = MagicMock(return_value=ohlcv_history) mocker.patch("freqtrade.data.dataprovider.load_pair_history", historymock) default_conf["runmode"] = RunMode.BACKTEST dp = DataProvider(default_conf, exchange) assert dp.runmode == RunMode.BACKTEST assert isinstance(dp.get_pair_dataframe("UNITTEST/BTC", timeframe), DataFrame)
def test_download_trades_history(trades_history, mocker, default_conf, testdatadir, caplog) -> None: ght_mock = MagicMock( side_effect=lambda pair, *args, **kwargs: (pair, trades_history)) mocker.patch('freqtrade.exchange.Exchange.get_historic_trades', ght_mock) exchange = get_patched_exchange(mocker, default_conf) file1 = testdatadir / 'ETH_BTC-trades.json.gz' _backup_file(file1) assert not file1.is_file() assert _download_trades_history(datadir=testdatadir, exchange=exchange, pair='ETH/BTC') assert log_has("New Amount of trades: 5", caplog) assert file1.is_file() # clean files freshly downloaded _clean_test_file(file1) mocker.patch('freqtrade.exchange.Exchange.get_historic_trades', MagicMock(side_effect=ValueError)) assert not _download_trades_history( datadir=testdatadir, exchange=exchange, pair='ETH/BTC') assert log_has_re( 'Failed to download historic trades for pair: "ETH/BTC".*', caplog)
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', exchange_has=MagicMock(return_value=True), get_tickers=tickers) exchange = get_patched_exchange(mocker, default_conf) pairlist = PairListManager(exchange, default_conf) dp = DataProvider(default_conf, exchange, pairlist) # Simulate volumepairs from exchange. pairlist.refresh_pairlist() assert dp.current_whitelist() == pairlist._whitelist # The identity of the 2 lists should not be identical, but a copy assert dp.current_whitelist() is not pairlist._whitelist with pytest.raises(OperationalException): dp = DataProvider(default_conf, exchange) dp.current_whitelist()
def test_download_backtesting_data_exception(ticker_history, mocker, caplog, default_conf, testdatadir) -> None: mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', side_effect=Exception('File Error')) exchange = get_patched_exchange(mocker, default_conf) file1_1 = os.path.join(os.path.dirname(__file__), '..', 'testdata', 'MEME_BTC-1m.json') file1_5 = os.path.join(os.path.dirname(__file__), '..', 'testdata', 'MEME_BTC-5m.json') _backup_file(file1_1) _backup_file(file1_5) assert not download_pair_history(datadir=testdatadir, exchange=exchange, pair='MEME/BTC', ticker_interval='1m') # clean files freshly downloaded _clean_test_file(file1_1) _clean_test_file(file1_5) assert log_has( 'Failed to download history data for pair: "MEME/BTC", interval: 1m. ' 'Error: File Error', caplog)
def test_ticker(mocker, default_conf, tickers): ticker_mock = MagicMock(return_value=tickers()['ETH/BTC']) mocker.patch("freqtrade.exchange.Exchange.fetch_ticker", ticker_mock) exchange = get_patched_exchange(mocker, default_conf) dp = DataProvider(default_conf, exchange) res = dp.ticker('ETH/BTC') assert type(res) is dict assert 'symbol' in res assert res['symbol'] == 'ETH/BTC' ticker_mock = MagicMock(side_effect=ExchangeError('Pair not found')) mocker.patch("freqtrade.exchange.Exchange.fetch_ticker", ticker_mock) exchange = get_patched_exchange(mocker, default_conf) dp = DataProvider(default_conf, exchange) res = dp.ticker('UNITTEST/BTC') assert res == {}
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.object(Path, "exists", MagicMock(return_value=True)) mocker.patch.object(Path, "unlink", MagicMock()) ex = get_patched_exchange(mocker, default_conf) timerange = TimeRange.parse_timerange("20190101-20190102") unavailable_pairs = refresh_backtest_trades_data( exchange=ex, pairs=["ETH/BTC", "XRP/BTC", "XRP/ETH"], datadir=testdatadir, timerange=timerange, erase=True) assert dl_mock.call_count == 2 assert dl_mock.call_args[1]['timerange'].starttype == 'date' assert log_has("Downloading trades for pair ETH/BTC.", caplog) assert unavailable_pairs == ["XRP/ETH"] assert log_has("Skipping pair XRP/ETH...", caplog)
def test_ohlcv(mocker, default_conf, ohlcv_history): default_conf["runmode"] = RunMode.DRY_RUN timeframe = default_conf["timeframe"] exchange = get_patched_exchange(mocker, default_conf) exchange._klines[("XRP/BTC", timeframe)] = ohlcv_history exchange._klines[("UNITTEST/BTC", timeframe)] = ohlcv_history dp = DataProvider(default_conf, exchange) assert dp.runmode == RunMode.DRY_RUN assert ohlcv_history.equals(dp.ohlcv("UNITTEST/BTC", timeframe)) assert isinstance(dp.ohlcv("UNITTEST/BTC", timeframe), DataFrame) assert dp.ohlcv("UNITTEST/BTC", timeframe) is not ohlcv_history assert dp.ohlcv("UNITTEST/BTC", timeframe, copy=False) is ohlcv_history assert not dp.ohlcv("UNITTEST/BTC", timeframe).empty assert dp.ohlcv("NONESENSE/AAA", timeframe).empty # Test with and without parameter assert dp.ohlcv("UNITTEST/BTC", timeframe).equals(dp.ohlcv("UNITTEST/BTC")) default_conf["runmode"] = RunMode.LIVE dp = DataProvider(default_conf, exchange) assert dp.runmode == RunMode.LIVE assert isinstance(dp.ohlcv("UNITTEST/BTC", timeframe), DataFrame) default_conf["runmode"] = RunMode.BACKTEST dp = DataProvider(default_conf, exchange) assert dp.runmode == RunMode.BACKTEST assert dp.ohlcv("UNITTEST/BTC", timeframe).empty
def test_load_data_with_new_pair_1min(ticker_history_list, mocker, caplog, default_conf, testdatadir) -> None: """ Test load_pair_history() with 1 min ticker """ mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', return_value=ticker_history_list) exchange = get_patched_exchange(mocker, default_conf) file = testdatadir / 'MEME_BTC-1m.json' _backup_file(file) # do not download a new pair if refresh_pairs isn't set load_pair_history(datadir=testdatadir, timeframe='1m', pair='MEME/BTC') assert not file.is_file() assert log_has( 'No history data for pair: "MEME/BTC", timeframe: 1m. ' 'Use `freqtrade download-data` to download the data', caplog) # download a new pair if refresh_pairs is set refresh_data(datadir=testdatadir, timeframe='1m', pairs=['MEME/BTC'], exchange=exchange) load_pair_history(datadir=testdatadir, timeframe='1m', pair='MEME/BTC') assert file.is_file() assert log_has_re( 'Download history data for pair: "MEME/BTC", timeframe: 1m ' 'and store in .*', caplog) _clean_test_file(file)
def test_buy_kraken_trading_agreement(default_conf, mocker): api_mock = MagicMock() order_id = 'test_prod_buy_{}'.format(randint(0, 10 ** 6)) order_type = 'limit' time_in_force = 'ioc' api_mock.options = {} api_mock.create_order = MagicMock(return_value={ 'id': order_id, 'info': { 'foo': 'bar' } }) default_conf['dry_run'] = False mocker.patch('freqtrade.exchange.Exchange.symbol_amount_prec', lambda s, x, y: y) mocker.patch('freqtrade.exchange.Exchange.symbol_price_prec', lambda s, x, y: y) exchange = get_patched_exchange(mocker, default_conf, api_mock, id="kraken") order = exchange.buy(pair='ETH/BTC', ordertype=order_type, amount=1, rate=200, time_in_force=time_in_force) assert 'id' in order assert 'info' in order assert order['id'] == order_id assert api_mock.create_order.call_args[0][0] == 'ETH/BTC' assert api_mock.create_order.call_args[0][1] == order_type assert api_mock.create_order.call_args[0][2] == 'buy' assert api_mock.create_order.call_args[0][3] == 1 assert api_mock.create_order.call_args[0][4] == 200 assert api_mock.create_order.call_args[0][5] == {'timeInForce': 'ioc', 'trading_agreement': 'agree'}
def test_stoploss_limit_order_dry_run(default_conf, mocker): api_mock = MagicMock() order_type = 'stop_loss_limit' default_conf['dry_run'] = True mocker.patch('freqtrade.exchange.Exchange.symbol_amount_prec', lambda s, x, y: y) mocker.patch('freqtrade.exchange.Exchange.symbol_price_prec', lambda s, x, y: y) exchange = get_patched_exchange(mocker, default_conf, api_mock, 'binance') with pytest.raises(OperationalException): order = exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=190, rate=200) api_mock.create_order.reset_mock() order = exchange.stoploss_limit(pair='ETH/BTC', amount=1, stop_price=220, rate=200) assert 'id' in order assert 'info' in order assert 'type' in order assert order['type'] == order_type assert order['price'] == 220 assert order['amount'] == 1
def test_init(default_conf, mocker) -> None: exchange = get_patched_exchange(mocker, default_conf) assert {} == history.load_data(datadir='', exchange=exchange, pairs=[], refresh_pairs=True, timeframe=default_conf['ticker_interval'])
def test_sell_kraken_trading_agreement(default_conf, mocker): api_mock = MagicMock() order_id = 'test_prod_sell_{}'.format(randint(0, 10 ** 6)) order_type = 'market' api_mock.options = {} api_mock.create_order = MagicMock(return_value={ 'id': order_id, 'info': { 'foo': 'bar' } }) 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) exchange = get_patched_exchange(mocker, default_conf, api_mock, id="kraken") order = exchange.sell(pair='ETH/BTC', ordertype=order_type, amount=1, rate=200) assert 'id' in order assert 'info' in order assert order['id'] == order_id assert api_mock.create_order.call_args[0][0] == 'ETH/BTC' assert api_mock.create_order.call_args[0][1] == order_type assert api_mock.create_order.call_args[0][2] == 'sell' assert api_mock.create_order.call_args[0][3] == 1 assert api_mock.create_order.call_args[0][4] is None assert api_mock.create_order.call_args[0][5] == {'trading_agreement': 'agree'}
def test_historic_ohlcv_dataformat(mocker, default_conf, ohlcv_history): hdf5loadmock = MagicMock(return_value=ohlcv_history) jsonloadmock = MagicMock(return_value=ohlcv_history) mocker.patch( "freqtrade.data.history.hdf5datahandler.HDF5DataHandler._ohlcv_load", hdf5loadmock) mocker.patch( "freqtrade.data.history.jsondatahandler.JsonDataHandler._ohlcv_load", jsonloadmock) default_conf["runmode"] = RunMode.BACKTEST exchange = get_patched_exchange(mocker, default_conf) dp = DataProvider(default_conf, exchange) data = dp.historic_ohlcv("UNITTEST/BTC", "5m") assert isinstance(data, DataFrame) hdf5loadmock.assert_not_called() jsonloadmock.assert_called_once() # Switching to dataformat hdf5 hdf5loadmock.reset_mock() jsonloadmock.reset_mock() default_conf["dataformat_ohlcv"] = "hdf5" dp = DataProvider(default_conf, exchange) data = dp.historic_ohlcv("UNITTEST/BTC", "5m") assert isinstance(data, DataFrame) hdf5loadmock.assert_called_once() jsonloadmock.assert_not_called()
def test_refresh(mocker, default_conf, ohlcv_history): refresh_mock = MagicMock() mocker.patch("freqtrade.exchange.Exchange.refresh_latest_ohlcv", refresh_mock) exchange = get_patched_exchange(mocker, default_conf, id="binance") timeframe = default_conf["timeframe"] pairs = [("XRP/BTC", timeframe), ("UNITTEST/BTC", timeframe)] pairs_non_trad = [("ETH/USDT", timeframe), ("BTC/TUSD", "1h")] dp = DataProvider(default_conf, exchange) dp.refresh(pairs) assert refresh_mock.call_count == 1 assert len(refresh_mock.call_args[0]) == 1 assert len(refresh_mock.call_args[0][0]) == len(pairs) assert refresh_mock.call_args[0][0] == pairs refresh_mock.reset_mock() dp.refresh(pairs, pairs_non_trad) assert refresh_mock.call_count == 1 assert len(refresh_mock.call_args[0]) == 1 assert len( refresh_mock.call_args[0][0]) == len(pairs) + len(pairs_non_trad) assert refresh_mock.call_args[0][0] == pairs + pairs_non_trad
def test_download_trades_history(trades_history, mocker, default_conf, testdatadir, caplog) -> None: ght_mock = MagicMock(side_effect=lambda pair, *args, **kwargs: (pair, trades_history)) mocker.patch('freqtrade.exchange.Exchange.get_historic_trades', ght_mock) exchange = get_patched_exchange(mocker, default_conf) file1 = testdatadir / 'ETH_BTC-trades.json.gz' data_handler = get_datahandler(testdatadir, data_format='jsongz') _backup_file(file1) assert not file1.is_file() assert _download_trades_history(data_handler=data_handler, exchange=exchange, pair='ETH/BTC') assert log_has("New Amount of trades: 5", caplog) assert file1.is_file() ght_mock.reset_mock() since_time = int(trades_history[-3][0] // 1000) since_time2 = int(trades_history[-1][0] // 1000) timerange = TimeRange('date', None, since_time, 0) assert _download_trades_history(data_handler=data_handler, exchange=exchange, pair='ETH/BTC', timerange=timerange) assert ght_mock.call_count == 1 # Check this in seconds - since we had to convert to seconds above too. assert int(ght_mock.call_args_list[0][1]['since'] // 1000) == since_time2 - 5 assert ght_mock.call_args_list[0][1]['from_id'] is not None # clean files freshly downloaded _clean_test_file(file1) mocker.patch('freqtrade.exchange.Exchange.get_historic_trades', MagicMock(side_effect=ValueError)) assert not _download_trades_history(data_handler=data_handler, exchange=exchange, pair='ETH/BTC') assert log_has_re('Failed to download historic trades for pair: "ETH/BTC".*', caplog) file2 = testdatadir / 'XRP_ETH-trades.json.gz' _backup_file(file2, True) ght_mock.reset_mock() mocker.patch('freqtrade.exchange.Exchange.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) assert _download_trades_history(data_handler=data_handler, exchange=exchange, pair='XRP/ETH', timerange=timerange) assert ght_mock.call_count == 1 assert int(ght_mock.call_args_list[0][1]['since'] // 1000) == since_time assert ght_mock.call_args_list[0][1]['from_id'] is None assert log_has_re(r'Start earlier than available data. Redownloading trades for.*', caplog) _clean_test_file(file2)
def test_stoploss_adjust_gateio(mocker, default_conf): exchange = get_patched_exchange(mocker, default_conf, id='gateio') order = { 'price': 1500, 'stopPrice': 1500, } assert exchange.stoploss_adjust(1501, order) assert not exchange.stoploss_adjust(1499, order)
def test_stoploss_adjust_gateio(mocker, default_conf, sl1, sl2, sl3, side): exchange = get_patched_exchange(mocker, default_conf, id='gateio') order = { 'price': 1500, 'stopPrice': 1500, } assert exchange.stoploss_adjust(sl1, order, side) assert not exchange.stoploss_adjust(sl2, order, side)
def test_init_with_refresh(default_conf, mocker) -> None: exchange = get_patched_exchange(mocker, default_conf) refresh_data(datadir='', pairs=[], timeframe=default_conf['ticker_interval'], exchange=exchange) assert {} == load_data(datadir='', pairs=[], timeframe=default_conf['ticker_interval'])
def test_get_max_pair_stake_amount_okx(default_conf, mocker, leverage_tiers): exchange = get_patched_exchange(mocker, default_conf, id="okx") assert exchange.get_max_pair_stake_amount('BNB/BUSD', 1.0) == float('inf') default_conf['trading_mode'] = 'futures' default_conf['margin_mode'] = 'isolated' exchange = get_patched_exchange(mocker, default_conf, id="okx") exchange._leverage_tiers = leverage_tiers assert exchange.get_max_pair_stake_amount('BNB/BUSD', 1.0) == 30000000 assert exchange.get_max_pair_stake_amount('BNB/USDT', 1.0) == 50000000 assert exchange.get_max_pair_stake_amount('BTC/USDT', 1.0) == 1000000000 assert exchange.get_max_pair_stake_amount('BTC/USDT', 1.0, 10.0) == 100000000 assert exchange.get_max_pair_stake_amount('TTT/USDT', 1.0) == float( 'inf') # Not in tiers
def test_available_pairs(mocker, default_conf, ohlcv_history): exchange = get_patched_exchange(mocker, default_conf) timeframe = default_conf["timeframe"] exchange._klines[("XRP/BTC", timeframe)] = ohlcv_history exchange._klines[("UNITTEST/BTC", timeframe)] = ohlcv_history dp = DataProvider(default_conf, exchange) assert len(dp.available_pairs) == 2 assert dp.available_pairs == [("XRP/BTC", timeframe), ("UNITTEST/BTC", timeframe), ]
def test_download_pair_history(ticker_history_list, mocker, default_conf, testdatadir) -> None: mocker.patch('freqtrade.exchange.Exchange.get_historic_ohlcv', return_value=ticker_history_list) exchange = get_patched_exchange(mocker, default_conf) file1_1 = os.path.join(os.path.dirname(__file__), '..', 'testdata', 'MEME_BTC-1m.json') file1_5 = os.path.join(os.path.dirname(__file__), '..', 'testdata', 'MEME_BTC-5m.json') file2_1 = os.path.join(os.path.dirname(__file__), '..', 'testdata', 'CFI_BTC-1m.json') file2_5 = os.path.join(os.path.dirname(__file__), '..', 'testdata', 'CFI_BTC-5m.json') _backup_file(file1_1) _backup_file(file1_5) _backup_file(file2_1) _backup_file(file2_5) assert os.path.isfile(file1_1) is False assert os.path.isfile(file2_1) is False assert download_pair_history(datadir=testdatadir, exchange=exchange, pair='MEME/BTC', ticker_interval='1m') assert download_pair_history(datadir=testdatadir, exchange=exchange, pair='CFI/BTC', ticker_interval='1m') assert not exchange._pairs_last_refresh_time assert os.path.isfile(file1_1) is True assert os.path.isfile(file2_1) is True # clean files freshly downloaded _clean_test_file(file1_1) _clean_test_file(file2_1) assert os.path.isfile(file1_5) is False assert os.path.isfile(file2_5) is False assert download_pair_history(datadir=testdatadir, exchange=exchange, pair='MEME/BTC', ticker_interval='5m') assert download_pair_history(datadir=testdatadir, exchange=exchange, pair='CFI/BTC', ticker_interval='5m') assert not exchange._pairs_last_refresh_time assert os.path.isfile(file1_5) is True assert os.path.isfile(file2_5) is True # clean files freshly downloaded _clean_test_file(file1_5) _clean_test_file(file2_5)