moved get_maintenance_ratio_and_amt to base.exchange. Wrote get_leverage_tiers. Added mmr_key to exchange._ft_has
This commit is contained in:
parent
ee5f05208e
commit
a5aba4813d
@ -169,11 +169,11 @@ class Binance(Exchange):
|
|||||||
+ amt
|
+ amt
|
||||||
) if old_ratio else 0.0
|
) if old_ratio else 0.0
|
||||||
old_ratio = mm_ratio
|
old_ratio = mm_ratio
|
||||||
brackets.append([
|
brackets.append((
|
||||||
float(notional_floor),
|
float(notional_floor),
|
||||||
float(mm_ratio),
|
float(mm_ratio),
|
||||||
amt,
|
amt,
|
||||||
])
|
))
|
||||||
self._leverage_brackets[pair] = brackets
|
self._leverage_brackets[pair] = brackets
|
||||||
except ccxt.DDoSProtection as e:
|
except ccxt.DDoSProtection as e:
|
||||||
raise DDosProtection(e) from e
|
raise DDosProtection(e) from e
|
||||||
@ -272,34 +272,6 @@ class Binance(Exchange):
|
|||||||
"""
|
"""
|
||||||
return open_date.minute > 0 or (open_date.minute == 0 and open_date.second > 15)
|
return open_date.minute > 0 or (open_date.minute == 0 and open_date.second > 15)
|
||||||
|
|
||||||
def get_maintenance_ratio_and_amt(
|
|
||||||
self,
|
|
||||||
pair: str,
|
|
||||||
nominal_value: Optional[float] = 0.0,
|
|
||||||
) -> Tuple[float, Optional[float]]:
|
|
||||||
"""
|
|
||||||
Formula: https://www.binance.com/en/support/faq/b3c689c1f50a44cabb3a84e663b81d93
|
|
||||||
|
|
||||||
Maintenance amt = Floor of Position Bracket on Level n *
|
|
||||||
difference between
|
|
||||||
Maintenance Margin Rate on Level n and
|
|
||||||
Maintenance Margin Rate on Level n-1)
|
|
||||||
+ Maintenance Amount on Level n-1
|
|
||||||
:return: The maintenance margin ratio and maintenance amount
|
|
||||||
"""
|
|
||||||
if nominal_value is None:
|
|
||||||
raise OperationalException(
|
|
||||||
"nominal value is required for binance.get_maintenance_ratio_and_amt")
|
|
||||||
if pair not in self._leverage_brackets:
|
|
||||||
raise InvalidOrderException(f"Cannot calculate liquidation price for {pair}")
|
|
||||||
pair_brackets = self._leverage_brackets[pair]
|
|
||||||
for [notional_floor, mm_ratio, amt] in reversed(pair_brackets):
|
|
||||||
if nominal_value >= notional_floor:
|
|
||||||
return (mm_ratio, amt)
|
|
||||||
raise OperationalException("nominal value can not be lower than 0")
|
|
||||||
# The lowest notional_floor for any pair in loadLeverageBrackets is always 0 because it
|
|
||||||
# describes the min amount for a bracket, and the lowest bracket will always go down to 0
|
|
||||||
|
|
||||||
def dry_run_liquidation_price(
|
def dry_run_liquidation_price(
|
||||||
self,
|
self,
|
||||||
pair: str,
|
pair: str,
|
||||||
|
@ -73,7 +73,8 @@ class Exchange:
|
|||||||
"l2_limit_range_required": True, # Allow Empty L2 limit (kucoin)
|
"l2_limit_range_required": True, # Allow Empty L2 limit (kucoin)
|
||||||
"mark_ohlcv_price": "mark",
|
"mark_ohlcv_price": "mark",
|
||||||
"mark_ohlcv_timeframe": "8h",
|
"mark_ohlcv_timeframe": "8h",
|
||||||
"ccxt_futures_name": "swap"
|
"ccxt_futures_name": "swap",
|
||||||
|
"mmr_key": None,
|
||||||
}
|
}
|
||||||
_ft_has: Dict = {}
|
_ft_has: Dict = {}
|
||||||
|
|
||||||
@ -90,7 +91,7 @@ class Exchange:
|
|||||||
self._api: ccxt.Exchange = None
|
self._api: ccxt.Exchange = None
|
||||||
self._api_async: ccxt_async.Exchange = None
|
self._api_async: ccxt_async.Exchange = None
|
||||||
self._markets: Dict = {}
|
self._markets: Dict = {}
|
||||||
self._leverage_brackets: Dict[str, List[List[float]]] = {}
|
self._leverage_brackets: Dict[str, List[Tuple[float, float, Optional(float)]]] = {}
|
||||||
self.loop = asyncio.new_event_loop()
|
self.loop = asyncio.new_event_loop()
|
||||||
asyncio.set_event_loop(self.loop)
|
asyncio.set_event_loop(self.loop)
|
||||||
|
|
||||||
@ -2099,16 +2100,6 @@ class Exchange:
|
|||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_maintenance_ratio_and_amt(
|
|
||||||
self,
|
|
||||||
pair: str,
|
|
||||||
nominal_value: Optional[float] = 0.0,
|
|
||||||
) -> Tuple[float, Optional[float]]:
|
|
||||||
"""
|
|
||||||
:return: The maintenance margin ratio and maintenance amount
|
|
||||||
"""
|
|
||||||
raise OperationalException(self.name + ' does not support leverage futures trading')
|
|
||||||
|
|
||||||
def dry_run_liquidation_price(
|
def dry_run_liquidation_price(
|
||||||
self,
|
self,
|
||||||
pair: str,
|
pair: str,
|
||||||
@ -2161,6 +2152,59 @@ class Exchange:
|
|||||||
raise OperationalException(
|
raise OperationalException(
|
||||||
"Freqtrade only supports isolated futures for leverage trading")
|
"Freqtrade only supports isolated futures for leverage trading")
|
||||||
|
|
||||||
|
def get_leverage_tiers(self, pair: str):
|
||||||
|
# When exchanges can load all their leverage brackets at once in the constructor
|
||||||
|
# then this method does nothing, it should only be implemented when the leverage
|
||||||
|
# brackets requires per symbol fetching to avoid excess api calls
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_maintenance_ratio_and_amt(
|
||||||
|
self,
|
||||||
|
pair: str,
|
||||||
|
nominal_value: Optional[float] = 0.0,
|
||||||
|
) -> Tuple[float, Optional[float]]:
|
||||||
|
"""
|
||||||
|
:param pair: Market symbol
|
||||||
|
:param nominal_value: The total trade amount in quote currency including leverage
|
||||||
|
maintenance amount only on Binance
|
||||||
|
:return: (maintenance margin ratio, maintenance amount)
|
||||||
|
"""
|
||||||
|
if nominal_value is None:
|
||||||
|
raise OperationalException(
|
||||||
|
f"nominal value is required for {self.name}.get_maintenance_ratio_and_amt"
|
||||||
|
)
|
||||||
|
if self._api.has['fetchLeverageTiers']:
|
||||||
|
if pair not in self._leverage_brackets:
|
||||||
|
# Used when fetchLeverageTiers cannot fetch all symbols at once
|
||||||
|
tiers = self.get_leverage_tiers(pair)
|
||||||
|
if not bool(tiers):
|
||||||
|
raise InvalidOrderException(f"Cannot calculate liquidation price for {pair}")
|
||||||
|
else:
|
||||||
|
self._leverage_brackets[pair] = []
|
||||||
|
for tier in tiers[pair]:
|
||||||
|
self._leverage_brackets[pair].append((
|
||||||
|
tier['notionalFloor'],
|
||||||
|
tier['maintenanceMarginRatio'],
|
||||||
|
None,
|
||||||
|
))
|
||||||
|
pair_brackets = self._leverage_brackets[pair]
|
||||||
|
for (notional_floor, mm_ratio, amt) in reversed(pair_brackets):
|
||||||
|
if nominal_value >= notional_floor:
|
||||||
|
return (mm_ratio, amt)
|
||||||
|
raise OperationalException("nominal value can not be lower than 0")
|
||||||
|
# The lowest notional_floor for any pair in loadLeverageBrackets is always 0 because it
|
||||||
|
# describes the min amt for a bracket, and the lowest bracket will always go down to 0
|
||||||
|
else:
|
||||||
|
info = self.markets[pair]['info']
|
||||||
|
mmr_key = self._ft_has['mmr_key']
|
||||||
|
if mmr_key and mmr_key in info:
|
||||||
|
return (float(info[mmr_key]), None)
|
||||||
|
else:
|
||||||
|
raise OperationalException(
|
||||||
|
f"Cannot fetch maintenance margin. Dry-run for freqtrade {self.trading_mode}"
|
||||||
|
f"is not available for {self.name}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def is_exchange_known_ccxt(exchange_name: str, ccxt_module: CcxtModuleType = None) -> bool:
|
def is_exchange_known_ccxt(exchange_name: str, ccxt_module: CcxtModuleType = None) -> bool:
|
||||||
return exchange_name in ccxt_exchanges(ccxt_module)
|
return exchange_name in ccxt_exchanges(ccxt_module)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
""" Gate.io exchange subclass """
|
""" Gate.io exchange subclass """
|
||||||
import logging
|
import logging
|
||||||
from typing import Dict, List, Optional, Tuple
|
from typing import Dict, List, Tuple
|
||||||
|
|
||||||
from freqtrade.enums import MarginMode, TradingMode
|
from freqtrade.enums import MarginMode, TradingMode
|
||||||
from freqtrade.exceptions import OperationalException
|
from freqtrade.exceptions import OperationalException
|
||||||
@ -23,6 +23,7 @@ class Gateio(Exchange):
|
|||||||
_ft_has: Dict = {
|
_ft_has: Dict = {
|
||||||
"ohlcv_candle_limit": 1000,
|
"ohlcv_candle_limit": 1000,
|
||||||
"ohlcv_volume_currency": "quote",
|
"ohlcv_volume_currency": "quote",
|
||||||
|
"mmr_key": "maintenance_rate",
|
||||||
}
|
}
|
||||||
|
|
||||||
_headers = {'X-Gate-Channel-Id': 'freqtrade'}
|
_headers = {'X-Gate-Channel-Id': 'freqtrade'}
|
||||||
@ -40,14 +41,3 @@ class Gateio(Exchange):
|
|||||||
if any(v == 'market' for k, v in order_types.items()):
|
if any(v == 'market' for k, v in order_types.items()):
|
||||||
raise OperationalException(
|
raise OperationalException(
|
||||||
f'Exchange {self.name} does not support market orders.')
|
f'Exchange {self.name} does not support market orders.')
|
||||||
|
|
||||||
def get_maintenance_ratio_and_amt(
|
|
||||||
self,
|
|
||||||
pair: str,
|
|
||||||
nominal_value: Optional[float] = 0.0,
|
|
||||||
) -> Tuple[float, Optional[float]]:
|
|
||||||
"""
|
|
||||||
:return: The maintenance margin ratio and maintenance amount
|
|
||||||
"""
|
|
||||||
info = self.markets[pair]['info']
|
|
||||||
return (float(info['maintenance_rate']), None)
|
|
||||||
|
@ -25,7 +25,7 @@ class Okx(Exchange):
|
|||||||
# TradingMode.SPOT always supported and not required in this list
|
# TradingMode.SPOT always supported and not required in this list
|
||||||
# (TradingMode.MARGIN, MarginMode.CROSS),
|
# (TradingMode.MARGIN, MarginMode.CROSS),
|
||||||
# (TradingMode.FUTURES, MarginMode.CROSS),
|
# (TradingMode.FUTURES, MarginMode.CROSS),
|
||||||
# (TradingMode.FUTURES, MarginMode.ISOLATED)
|
(TradingMode.FUTURES, MarginMode.ISOLATED),
|
||||||
]
|
]
|
||||||
|
|
||||||
def _lev_prep(
|
def _lev_prep(
|
||||||
@ -46,3 +46,6 @@ class Okx(Exchange):
|
|||||||
"mgnMode": self.margin_mode.value,
|
"mgnMode": self.margin_mode.value,
|
||||||
"posSide": "long" if side == "buy" else "short",
|
"posSide": "long" if side == "buy" else "short",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
def get_leverage_tiers(self, pair: str):
|
||||||
|
return self._api.fetch_leverage_tiers(pair)
|
||||||
|
@ -210,13 +210,16 @@ def test_get_max_leverage_binance(default_conf, mocker, pair, stake_amount, max_
|
|||||||
def test_fill_leverage_brackets_binance(default_conf, mocker):
|
def test_fill_leverage_brackets_binance(default_conf, mocker):
|
||||||
api_mock = MagicMock()
|
api_mock = MagicMock()
|
||||||
api_mock.load_leverage_brackets = MagicMock(return_value={
|
api_mock.load_leverage_brackets = MagicMock(return_value={
|
||||||
'ADA/BUSD': [[0.0, 0.025],
|
'ADA/BUSD': [
|
||||||
|
[0.0, 0.025],
|
||||||
[100000.0, 0.05],
|
[100000.0, 0.05],
|
||||||
[500000.0, 0.1],
|
[500000.0, 0.1],
|
||||||
[1000000.0, 0.15],
|
[1000000.0, 0.15],
|
||||||
[2000000.0, 0.25],
|
[2000000.0, 0.25],
|
||||||
[5000000.0, 0.5]],
|
[5000000.0, 0.5],
|
||||||
'BTC/USDT': [[0.0, 0.004],
|
],
|
||||||
|
'BTC/USDT': [
|
||||||
|
[0.0, 0.004],
|
||||||
[50000.0, 0.005],
|
[50000.0, 0.005],
|
||||||
[250000.0, 0.01],
|
[250000.0, 0.01],
|
||||||
[1000000.0, 0.025],
|
[1000000.0, 0.025],
|
||||||
@ -225,13 +228,16 @@ def test_fill_leverage_brackets_binance(default_conf, mocker):
|
|||||||
[50000000.0, 0.125],
|
[50000000.0, 0.125],
|
||||||
[100000000.0, 0.15],
|
[100000000.0, 0.15],
|
||||||
[200000000.0, 0.25],
|
[200000000.0, 0.25],
|
||||||
[300000000.0, 0.5]],
|
[300000000.0, 0.5],
|
||||||
"ZEC/USDT": [[0.0, 0.01],
|
],
|
||||||
|
"ZEC/USDT": [
|
||||||
|
[0.0, 0.01],
|
||||||
[5000.0, 0.025],
|
[5000.0, 0.025],
|
||||||
[25000.0, 0.05],
|
[25000.0, 0.05],
|
||||||
[100000.0, 0.1],
|
[100000.0, 0.1],
|
||||||
[250000.0, 0.125],
|
[250000.0, 0.125],
|
||||||
[1000000.0, 0.5]],
|
[1000000.0, 0.5],
|
||||||
|
],
|
||||||
|
|
||||||
})
|
})
|
||||||
default_conf['dry_run'] = False
|
default_conf['dry_run'] = False
|
||||||
@ -241,28 +247,34 @@ def test_fill_leverage_brackets_binance(default_conf, mocker):
|
|||||||
exchange.fill_leverage_brackets()
|
exchange.fill_leverage_brackets()
|
||||||
|
|
||||||
assert exchange._leverage_brackets == {
|
assert exchange._leverage_brackets == {
|
||||||
'ADA/BUSD': [[0.0, 0.025, 0.0],
|
'ADA/BUSD': [
|
||||||
[100000.0, 0.05, 2500.0],
|
(0.0, 0.025, 0.0),
|
||||||
[500000.0, 0.1, 27500.0],
|
(100000.0, 0.05, 2500.0),
|
||||||
[1000000.0, 0.15, 77499.99999999999],
|
(500000.0, 0.1, 27500.0),
|
||||||
[2000000.0, 0.25, 277500.0],
|
(1000000.0, 0.15, 77499.99999999999),
|
||||||
[5000000.0, 0.5, 1527500.0]],
|
(2000000.0, 0.25, 277500.0),
|
||||||
'BTC/USDT': [[0.0, 0.004, 0.0],
|
(5000000.0, 0.5, 1527500.0),
|
||||||
[50000.0, 0.005, 50.0],
|
],
|
||||||
[250000.0, 0.01, 1300.0],
|
'BTC/USDT': [
|
||||||
[1000000.0, 0.025, 16300.000000000002],
|
(0.0, 0.004, 0.0),
|
||||||
[5000000.0, 0.05, 141300.0],
|
(50000.0, 0.005, 50.0),
|
||||||
[20000000.0, 0.1, 1141300.0],
|
(250000.0, 0.01, 1300.0),
|
||||||
[50000000.0, 0.125, 2391300.0],
|
(1000000.0, 0.025, 16300.000000000002),
|
||||||
[100000000.0, 0.15, 4891300.0],
|
(5000000.0, 0.05, 141300.0),
|
||||||
[200000000.0, 0.25, 24891300.0],
|
(20000000.0, 0.1, 1141300.0),
|
||||||
[300000000.0, 0.5, 99891300.0]],
|
(50000000.0, 0.125, 2391300.0),
|
||||||
"ZEC/USDT": [[0.0, 0.01, 0.0],
|
(100000000.0, 0.15, 4891300.0),
|
||||||
[5000.0, 0.025, 75.0],
|
(200000000.0, 0.25, 24891300.0),
|
||||||
[25000.0, 0.05, 700.0],
|
(300000000.0, 0.5, 99891300.0),
|
||||||
[100000.0, 0.1, 5700.0],
|
],
|
||||||
[250000.0, 0.125, 11949.999999999998],
|
"ZEC/USDT": [
|
||||||
[1000000.0, 0.5, 386950.0]]
|
(0.0, 0.01, 0.0),
|
||||||
|
(5000.0, 0.025, 75.0),
|
||||||
|
(25000.0, 0.05, 700.0),
|
||||||
|
(100000.0, 0.1, 5700.0),
|
||||||
|
(250000.0, 0.125, 11949.999999999998),
|
||||||
|
(1000000.0, 0.5, 386950.0),
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
api_mock = MagicMock()
|
api_mock = MagicMock()
|
||||||
@ -288,37 +300,37 @@ def test_fill_leverage_brackets_binance_dryrun(default_conf, mocker):
|
|||||||
|
|
||||||
leverage_brackets = {
|
leverage_brackets = {
|
||||||
"1000SHIB/USDT": [
|
"1000SHIB/USDT": [
|
||||||
[0.0, 0.01, 0.0],
|
(0.0, 0.01, 0.0),
|
||||||
[5000.0, 0.025, 75.0],
|
(5000.0, 0.025, 75.0),
|
||||||
[25000.0, 0.05, 700.0],
|
(25000.0, 0.05, 700.0),
|
||||||
[100000.0, 0.1, 5700.0],
|
(100000.0, 0.1, 5700.0),
|
||||||
[250000.0, 0.125, 11949.999999999998],
|
(250000.0, 0.125, 11949.999999999998),
|
||||||
[1000000.0, 0.5, 386950.0],
|
(1000000.0, 0.5, 386950.0),
|
||||||
],
|
],
|
||||||
"1INCH/USDT": [
|
"1INCH/USDT": [
|
||||||
[0.0, 0.012, 0.0],
|
(0.0, 0.012, 0.0),
|
||||||
[5000.0, 0.025, 65.0],
|
(5000.0, 0.025, 65.0),
|
||||||
[25000.0, 0.05, 690.0],
|
(25000.0, 0.05, 690.0),
|
||||||
[100000.0, 0.1, 5690.0],
|
(100000.0, 0.1, 5690.0),
|
||||||
[250000.0, 0.125, 11939.999999999998],
|
(250000.0, 0.125, 11939.999999999998),
|
||||||
[1000000.0, 0.5, 386940.0],
|
(1000000.0, 0.5, 386940.0),
|
||||||
],
|
],
|
||||||
"AAVE/USDT": [
|
"AAVE/USDT": [
|
||||||
[0.0, 0.01, 0.0],
|
(0.0, 0.01, 0.0),
|
||||||
[50000.0, 0.02, 500.0],
|
(50000.0, 0.02, 500.0),
|
||||||
[250000.0, 0.05, 8000.000000000001],
|
(250000.0, 0.05, 8000.000000000001),
|
||||||
[1000000.0, 0.1, 58000.0],
|
(1000000.0, 0.1, 58000.0),
|
||||||
[2000000.0, 0.125, 107999.99999999999],
|
(2000000.0, 0.125, 107999.99999999999),
|
||||||
[5000000.0, 0.1665, 315500.00000000006],
|
(5000000.0, 0.1665, 315500.00000000006),
|
||||||
[10000000.0, 0.25, 1150500.0],
|
(10000000.0, 0.25, 1150500.0),
|
||||||
],
|
],
|
||||||
"ADA/BUSD": [
|
"ADA/BUSD": [
|
||||||
[0.0, 0.025, 0.0],
|
(0.0, 0.025, 0.0),
|
||||||
[100000.0, 0.05, 2500.0],
|
(100000.0, 0.05, 2500.0),
|
||||||
[500000.0, 0.1, 27500.0],
|
(500000.0, 0.1, 27500.0),
|
||||||
[1000000.0, 0.15, 77499.99999999999],
|
(1000000.0, 0.15, 77499.99999999999),
|
||||||
[2000000.0, 0.25, 277500.0],
|
(2000000.0, 0.25, 277500.0),
|
||||||
[5000000.0, 0.5, 1527500.0],
|
(5000000.0, 0.5, 1527500.0),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,6 +37,7 @@ def test_validate_order_types_gateio(default_conf, mocker):
|
|||||||
])
|
])
|
||||||
def test_get_maintenance_ratio_and_amt_gateio(default_conf, mocker, pair, mm_ratio):
|
def test_get_maintenance_ratio_and_amt_gateio(default_conf, mocker, pair, mm_ratio):
|
||||||
api_mock = MagicMock()
|
api_mock = MagicMock()
|
||||||
|
type(api_mock).has = PropertyMock(return_value={'fetchLeverageTiers': False})
|
||||||
exchange = get_patched_exchange(mocker, default_conf, api_mock, id="gateio")
|
exchange = get_patched_exchange(mocker, default_conf, api_mock, id="gateio")
|
||||||
mocker.patch(
|
mocker.patch(
|
||||||
'freqtrade.exchange.Exchange.markets',
|
'freqtrade.exchange.Exchange.markets',
|
||||||
|
@ -722,8 +722,8 @@ def test_process_informative_pairs_added(default_conf_usdt, ticker_usdt, mocker)
|
|||||||
(False, 'futures', 'binance', 'isolated', 0.05, 8.167171717171717),
|
(False, 'futures', 'binance', 'isolated', 0.05, 8.167171717171717),
|
||||||
(True, 'futures', 'gateio', 'isolated', 0.05, 11.7804274688304),
|
(True, 'futures', 'gateio', 'isolated', 0.05, 11.7804274688304),
|
||||||
(False, 'futures', 'gateio', 'isolated', 0.05, 8.181423084697796),
|
(False, 'futures', 'gateio', 'isolated', 0.05, 8.181423084697796),
|
||||||
# (True, 'futures', 'okex', 'isolated', 11.87413417771621),
|
(True, 'futures', 'okex', 'isolated', 11.87413417771621),
|
||||||
# (False, 'futures', 'okex', 'isolated', 8.085708510208207),
|
(False, 'futures', 'okex', 'isolated', 8.085708510208207),
|
||||||
])
|
])
|
||||||
def test_execute_entry(mocker, default_conf_usdt, fee, limit_order,
|
def test_execute_entry(mocker, default_conf_usdt, fee, limit_order,
|
||||||
limit_order_open, is_short, trading_mode,
|
limit_order_open, is_short, trading_mode,
|
||||||
@ -778,7 +778,8 @@ def test_execute_entry(mocker, default_conf_usdt, fee, limit_order,
|
|||||||
get_min_pair_stake_amount=MagicMock(return_value=1),
|
get_min_pair_stake_amount=MagicMock(return_value=1),
|
||||||
get_fee=fee,
|
get_fee=fee,
|
||||||
get_funding_fees=MagicMock(return_value=0),
|
get_funding_fees=MagicMock(return_value=0),
|
||||||
name=exchange_name
|
name=exchange_name,
|
||||||
|
get_maintenance_ratio_and_amt=MagicMock(return_value=(0.01, 0.01)),
|
||||||
)
|
)
|
||||||
pair = 'ETH/USDT'
|
pair = 'ETH/USDT'
|
||||||
|
|
||||||
@ -922,7 +923,6 @@ def test_execute_entry(mocker, default_conf_usdt, fee, limit_order,
|
|||||||
assert trade.open_rate_requested == 10
|
assert trade.open_rate_requested == 10
|
||||||
|
|
||||||
# In case of custom entry price not float type
|
# In case of custom entry price not float type
|
||||||
freqtrade.exchange.get_maintenance_ratio_and_amt = MagicMock(return_value=(0.01, 0.01))
|
|
||||||
freqtrade.exchange.name = exchange_name
|
freqtrade.exchange.name = exchange_name
|
||||||
order['status'] = 'open'
|
order['status'] = 'open'
|
||||||
order['id'] = '5568'
|
order['id'] = '5568'
|
||||||
|
Loading…
Reference in New Issue
Block a user