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__set_leverage_binance(mocker, default_conf): api_mock = MagicMock() api_mock.set_leverage = MagicMock() type(api_mock).has = PropertyMock(return_value={'setLeverage': True}) default_conf['dry_run'] = False exchange = get_patched_exchange(mocker, default_conf, id="binance") exchange._set_leverage(3.0, trading_mode=TradingMode.MARGIN) ccxt_exceptionhandlers( mocker, default_conf, api_mock, "binance", "_set_leverage", "set_leverage", pair="XRP/USDT", leverage=5.0, trading_mode=TradingMode.FUTURES )
def test_get_balances_prod(default_conf, mocker): balance_item = { 'free': None, 'total': 10.0, 'used': 0.0 } api_mock = MagicMock() api_mock.fetch_balance = MagicMock(return_value={ '1ST': balance_item.copy(), '2ST': balance_item.copy(), '3ST': balance_item.copy(), '4ST': balance_item.copy(), }) kraken_open_orders = [{'symbol': '1ST/EUR', 'type': 'limit', 'side': 'sell', 'price': 20, 'cost': 0.0, 'amount': 1.0, 'filled': 0.0, 'average': 0.0, 'remaining': 1.0, }, {'status': 'open', 'symbol': '2ST/EUR', 'type': 'limit', 'side': 'sell', 'price': 20.0, 'cost': 0.0, 'amount': 2.0, 'filled': 0.0, 'average': 0.0, 'remaining': 2.0, }, {'status': 'open', 'symbol': '2ST/USD', 'type': 'limit', 'side': 'sell', 'price': 20.0, 'cost': 0.0, 'amount': 2.0, 'filled': 0.0, 'average': 0.0, 'remaining': 2.0, }, {'status': 'open', 'symbol': 'BTC/3ST', 'type': 'limit', 'side': 'buy', 'price': 20, 'cost': 0.0, 'amount': 3.0, 'filled': 0.0, 'average': 0.0, 'remaining': 3.0, }] api_mock.fetch_open_orders = MagicMock(return_value=kraken_open_orders) default_conf['dry_run'] = False exchange = get_patched_exchange(mocker, default_conf, api_mock, id="kraken") balances = exchange.get_balances() assert len(balances) == 4 assert balances['1ST']['free'] == 9.0 assert balances['1ST']['total'] == 10.0 assert balances['1ST']['used'] == 1.0 assert balances['2ST']['free'] == 6.0 assert balances['2ST']['total'] == 10.0 assert balances['2ST']['used'] == 4.0 assert balances['3ST']['free'] == 7.0 assert balances['3ST']['total'] == 10.0 assert balances['3ST']['used'] == 3.0 assert balances['4ST']['free'] == 10.0 assert balances['4ST']['total'] == 10.0 assert balances['4ST']['used'] == 0.0 ccxt_exceptionhandlers(mocker, default_conf, api_mock, "kraken", "get_balances", "fetch_balance")
def test_stoploss_order_kraken(default_conf, mocker, ordertype): api_mock = MagicMock() order_id = 'test_prod_buy_{}'.format(randint(0, 10**6)) 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') order = exchange.stoploss(pair='ETH/BTC', amount=1, stop_price=220, order_types={ 'stoploss': ordertype, 'stoploss_on_exchange_limit_ratio': 0.99 }) 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' if ordertype == 'limit': assert api_mock.create_order.call_args_list[0][1][ 'type'] == STOPLOSS_LIMIT_ORDERTYPE assert api_mock.create_order.call_args_list[0][1]['params'] == { 'trading_agreement': 'agree', 'price2': 217.8 } else: assert api_mock.create_order.call_args_list[0][1][ 'type'] == STOPLOSS_ORDERTYPE assert api_mock.create_order.call_args_list[0][1]['params'] == { 'trading_agreement': 'agree' } 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 # 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={}) ccxt_exceptionhandlers(mocker, default_conf, api_mock, "kraken", "stoploss", "create_order", retries=1, pair='ETH/BTC', amount=1, stop_price=220, order_types={})
def test_fill_leverage_tiers_binance(default_conf, mocker): api_mock = MagicMock() api_mock.fetch_leverage_tiers = MagicMock(return_value={ 'ADA/BUSD': [ { "tier": 1, "minNotional": 0, "maxNotional": 100000, "maintenanceMarginRate": 0.025, "maxLeverage": 20, "info": { "bracket": "1", "initialLeverage": "20", "maxNotional": "100000", "minNotional": "0", "maintMarginRatio": "0.025", "cum": "0.0" } }, { "tier": 2, "minNotional": 100000, "maxNotional": 500000, "maintenanceMarginRate": 0.05, "maxLeverage": 10, "info": { "bracket": "2", "initialLeverage": "10", "maxNotional": "500000", "minNotional": "100000", "maintMarginRatio": "0.05", "cum": "2500.0" } }, { "tier": 3, "minNotional": 500000, "maxNotional": 1000000, "maintenanceMarginRate": 0.1, "maxLeverage": 5, "info": { "bracket": "3", "initialLeverage": "5", "maxNotional": "1000000", "minNotional": "500000", "maintMarginRatio": "0.1", "cum": "27500.0" } }, { "tier": 4, "minNotional": 1000000, "maxNotional": 2000000, "maintenanceMarginRate": 0.15, "maxLeverage": 3, "info": { "bracket": "4", "initialLeverage": "3", "maxNotional": "2000000", "minNotional": "1000000", "maintMarginRatio": "0.15", "cum": "77500.0" } }, { "tier": 5, "minNotional": 2000000, "maxNotional": 5000000, "maintenanceMarginRate": 0.25, "maxLeverage": 2, "info": { "bracket": "5", "initialLeverage": "2", "maxNotional": "5000000", "minNotional": "2000000", "maintMarginRatio": "0.25", "cum": "277500.0" } }, { "tier": 6, "minNotional": 5000000, "maxNotional": 30000000, "maintenanceMarginRate": 0.5, "maxLeverage": 1, "info": { "bracket": "6", "initialLeverage": "1", "maxNotional": "30000000", "minNotional": "5000000", "maintMarginRatio": "0.5", "cum": "1527500.0" } } ], "ZEC/USDT": [ { "tier": 1, "minNotional": 0, "maxNotional": 50000, "maintenanceMarginRate": 0.01, "maxLeverage": 50, "info": { "bracket": "1", "initialLeverage": "50", "maxNotional": "50000", "minNotional": "0", "maintMarginRatio": "0.01", "cum": "0.0" } }, { "tier": 2, "minNotional": 50000, "maxNotional": 150000, "maintenanceMarginRate": 0.025, "maxLeverage": 20, "info": { "bracket": "2", "initialLeverage": "20", "maxNotional": "150000", "minNotional": "50000", "maintMarginRatio": "0.025", "cum": "750.0" } }, { "tier": 3, "minNotional": 150000, "maxNotional": 250000, "maintenanceMarginRate": 0.05, "maxLeverage": 10, "info": { "bracket": "3", "initialLeverage": "10", "maxNotional": "250000", "minNotional": "150000", "maintMarginRatio": "0.05", "cum": "4500.0" } }, { "tier": 4, "minNotional": 250000, "maxNotional": 500000, "maintenanceMarginRate": 0.1, "maxLeverage": 5, "info": { "bracket": "4", "initialLeverage": "5", "maxNotional": "500000", "minNotional": "250000", "maintMarginRatio": "0.1", "cum": "17000.0" } }, { "tier": 5, "minNotional": 500000, "maxNotional": 1000000, "maintenanceMarginRate": 0.125, "maxLeverage": 4, "info": { "bracket": "5", "initialLeverage": "4", "maxNotional": "1000000", "minNotional": "500000", "maintMarginRatio": "0.125", "cum": "29500.0" } }, { "tier": 6, "minNotional": 1000000, "maxNotional": 2000000, "maintenanceMarginRate": 0.25, "maxLeverage": 2, "info": { "bracket": "6", "initialLeverage": "2", "maxNotional": "2000000", "minNotional": "1000000", "maintMarginRatio": "0.25", "cum": "154500.0" } }, { "tier": 7, "minNotional": 2000000, "maxNotional": 30000000, "maintenanceMarginRate": 0.5, "maxLeverage": 1, "info": { "bracket": "7", "initialLeverage": "1", "maxNotional": "30000000", "minNotional": "2000000", "maintMarginRatio": "0.5", "cum": "654500.0" } } ], }) default_conf['dry_run'] = False default_conf['trading_mode'] = TradingMode.FUTURES default_conf['margin_mode'] = MarginMode.ISOLATED exchange = get_patched_exchange(mocker, default_conf, api_mock, id="binance") exchange.fill_leverage_tiers() assert exchange._leverage_tiers == { 'ADA/BUSD': [ { "min": 0, "max": 100000, "mmr": 0.025, "lev": 20, "maintAmt": 0.0 }, { "min": 100000, "max": 500000, "mmr": 0.05, "lev": 10, "maintAmt": 2500.0 }, { "min": 500000, "max": 1000000, "mmr": 0.1, "lev": 5, "maintAmt": 27500.0 }, { "min": 1000000, "max": 2000000, "mmr": 0.15, "lev": 3, "maintAmt": 77500.0 }, { "min": 2000000, "max": 5000000, "mmr": 0.25, "lev": 2, "maintAmt": 277500.0 }, { "min": 5000000, "max": 30000000, "mmr": 0.5, "lev": 1, "maintAmt": 1527500.0 } ], "ZEC/USDT": [ { 'min': 0, 'max': 50000, 'mmr': 0.01, 'lev': 50, 'maintAmt': 0.0 }, { 'min': 50000, 'max': 150000, 'mmr': 0.025, 'lev': 20, 'maintAmt': 750.0 }, { 'min': 150000, 'max': 250000, 'mmr': 0.05, 'lev': 10, 'maintAmt': 4500.0 }, { 'min': 250000, 'max': 500000, 'mmr': 0.1, 'lev': 5, 'maintAmt': 17000.0 }, { 'min': 500000, 'max': 1000000, 'mmr': 0.125, 'lev': 4, 'maintAmt': 29500.0 }, { 'min': 1000000, 'max': 2000000, 'mmr': 0.25, 'lev': 2, 'maintAmt': 154500.0 }, { 'min': 2000000, 'max': 30000000, 'mmr': 0.5, 'lev': 1, 'maintAmt': 654500.0 }, ] } api_mock = MagicMock() api_mock.load_leverage_tiers = MagicMock() type(api_mock).has = PropertyMock(return_value={'fetchLeverageTiers': True}) ccxt_exceptionhandlers( mocker, default_conf, api_mock, "binance", "fill_leverage_tiers", "fetch_leverage_tiers", )