exchange.fill_leverage_brackets/get_maintenance_ratio_and_amt docstring and type specification
This commit is contained in:
parent
b4a0611afc
commit
bb2b2211d0
@ -119,10 +119,25 @@ class Binance(Exchange):
|
|||||||
raise OperationalException(e) from e
|
raise OperationalException(e) from e
|
||||||
|
|
||||||
@retrier
|
@retrier
|
||||||
def fill_leverage_brackets(self):
|
def fill_leverage_brackets(self) -> None:
|
||||||
"""
|
"""
|
||||||
Assigns property _leverage_brackets to a dictionary of information about the leverage
|
Assigns property _leverage_brackets to a dictionary of information about the leverage
|
||||||
allowed on each pair
|
allowed on each pair
|
||||||
|
After exectution, self._leverage_brackets = {
|
||||||
|
"pair_name": [
|
||||||
|
[notional_floor, maintenenace_margin_ratio, maintenance_amt],
|
||||||
|
...
|
||||||
|
],
|
||||||
|
...
|
||||||
|
}
|
||||||
|
e.g. {
|
||||||
|
"ETH/USDT:USDT": [
|
||||||
|
[0.0, 0.01, 0.0],
|
||||||
|
[10000, 0.02, 0.01],
|
||||||
|
...
|
||||||
|
],
|
||||||
|
...
|
||||||
|
}
|
||||||
"""
|
"""
|
||||||
if self.trading_mode == TradingMode.FUTURES:
|
if self.trading_mode == TradingMode.FUTURES:
|
||||||
try:
|
try:
|
||||||
@ -136,14 +151,14 @@ class Binance(Exchange):
|
|||||||
leverage_brackets = self._api.load_leverage_brackets()
|
leverage_brackets = self._api.load_leverage_brackets()
|
||||||
|
|
||||||
for pair, brkts in leverage_brackets.items():
|
for pair, brkts in leverage_brackets.items():
|
||||||
[amt, old_ratio] = [None, None]
|
[amt, old_ratio] = [0.0, 0.0]
|
||||||
brackets = []
|
brackets = []
|
||||||
for [notional_floor, mm_ratio] in brkts:
|
for [notional_floor, mm_ratio] in brkts:
|
||||||
amt = (
|
amt = (
|
||||||
(
|
(
|
||||||
(float(notional_floor) * (float(mm_ratio)) - float(old_ratio))
|
(float(notional_floor) * (float(mm_ratio)) - float(old_ratio))
|
||||||
) + amt
|
) + amt
|
||||||
) if old_ratio else 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),
|
||||||
@ -167,6 +182,9 @@ class Binance(Exchange):
|
|||||||
"""
|
"""
|
||||||
if pair not in self._leverage_brackets:
|
if pair not in self._leverage_brackets:
|
||||||
return 1.0
|
return 1.0
|
||||||
|
if (pair is None or nominal_value is None):
|
||||||
|
raise OperationalException(
|
||||||
|
"binance.get_max_leverage requires parameters pair and nominal_value")
|
||||||
pair_brackets = self._leverage_brackets[pair]
|
pair_brackets = self._leverage_brackets[pair]
|
||||||
for [notional_floor, mm_ratio, _] in reversed(pair_brackets):
|
for [notional_floor, mm_ratio, _] in reversed(pair_brackets):
|
||||||
if nominal_value >= notional_floor:
|
if nominal_value >= notional_floor:
|
||||||
@ -236,15 +254,20 @@ class Binance(Exchange):
|
|||||||
self,
|
self,
|
||||||
pair: str,
|
pair: str,
|
||||||
nominal_value: Optional[float] = 0.0,
|
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 *
|
Maintenance amt = Floor of Position Bracket on Level n *
|
||||||
difference between
|
difference between
|
||||||
Maintenance Margin Rate on Level n and
|
Maintenance Margin Rate on Level n and
|
||||||
Maintenance Margin Rate on Level n-1)
|
Maintenance Margin Rate on Level n-1)
|
||||||
+ Maintenance Amount on Level n-1
|
+ Maintenance Amount on Level n-1
|
||||||
https://www.binance.com/en/support/faq/b3c689c1f50a44cabb3a84e663b81d93
|
: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:
|
if pair not in self._leverage_brackets:
|
||||||
raise InvalidOrderException(f"Cannot calculate liquidation price for {pair}")
|
raise InvalidOrderException(f"Cannot calculate liquidation price for {pair}")
|
||||||
pair_brackets = self._leverage_brackets[pair]
|
pair_brackets = self._leverage_brackets[pair]
|
||||||
|
@ -90,7 +90,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 = {}
|
self._leverage_brackets: Dict[str, List[List[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)
|
||||||
|
|
||||||
@ -2006,12 +2006,12 @@ class Exchange:
|
|||||||
self,
|
self,
|
||||||
pair: str,
|
pair: str,
|
||||||
nominal_value: Optional[float] = 0.0,
|
nominal_value: Optional[float] = 0.0,
|
||||||
):
|
) -> Tuple[float, Optional[float]]:
|
||||||
"""
|
"""
|
||||||
:return: The maintenance amount, and maintenance margin rate
|
:return: The maintenance margin ratio and maintenance amount
|
||||||
"""
|
"""
|
||||||
# TODO-lev: return the real amounts
|
# TODO-lev: return the real amounts
|
||||||
return 0, 0.4
|
return (0, 0.4)
|
||||||
|
|
||||||
|
|
||||||
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:
|
||||||
|
@ -45,9 +45,9 @@ class Gateio(Exchange):
|
|||||||
self,
|
self,
|
||||||
pair: str,
|
pair: str,
|
||||||
nominal_value: Optional[float] = 0.0,
|
nominal_value: Optional[float] = 0.0,
|
||||||
):
|
) -> Tuple[float, Optional[float]]:
|
||||||
|
"""
|
||||||
|
:return: The maintenance margin ratio and maintenance amount
|
||||||
|
"""
|
||||||
info = self.markets[pair]['info']
|
info = self.markets[pair]['info']
|
||||||
if 'maintenance_rate' in info:
|
return (float(info['maintenance_rate']), None)
|
||||||
return [float(info['maintenance_rate']), None]
|
|
||||||
else:
|
|
||||||
return [None, None]
|
|
||||||
|
@ -620,7 +620,9 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
if self.collateral_type == Collateral.ISOLATED:
|
if self.collateral_type == Collateral.ISOLATED:
|
||||||
if self.config['dry_run']:
|
if self.config['dry_run']:
|
||||||
mm_ratio, maintenance_amt = self.exchange.get_maintenance_ratio_and_amt(
|
mm_ratio, maintenance_amt = self.exchange.get_maintenance_ratio_and_amt(
|
||||||
pair, amount)
|
pair,
|
||||||
|
amount
|
||||||
|
)
|
||||||
taker_fee_rate = self.exchange.markets[pair]['taker']
|
taker_fee_rate = self.exchange.markets[pair]['taker']
|
||||||
isolated_liq = liquidation_price(
|
isolated_liq = liquidation_price(
|
||||||
exchange_name=self.exchange.name,
|
exchange_name=self.exchange.name,
|
||||||
@ -637,7 +639,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
mm_ratio=mm_ratio,
|
mm_ratio=mm_ratio,
|
||||||
taker_fee_rate=taker_fee_rate
|
taker_fee_rate=taker_fee_rate
|
||||||
|
|
||||||
# Okex
|
# TODO-lev: Okex parameters
|
||||||
# liability: Optional[float]=None,
|
# liability: Optional[float]=None,
|
||||||
# interest: Optional[float]=None,
|
# interest: Optional[float]=None,
|
||||||
# position_assets: Optional[float]=None, # * Might be same as position
|
# position_assets: Optional[float]=None, # * Might be same as position
|
||||||
|
@ -337,7 +337,8 @@ def kraken(
|
|||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
# ! Not Implemented
|
# ! Not Implemented
|
||||||
MARGIN: https://support.kraken.com/hc/en-us/articles/203325763-Margin-Call-Level-and-Margin-Liquidation-Level
|
MARGIN:
|
||||||
|
https://support.kraken.com/hc/en-us/articles/203325763-Margin-Call-Level-and-Margin-Liquidation-Level
|
||||||
|
|
||||||
:param open_rate: Entry price of position
|
:param open_rate: Entry price of position
|
||||||
:param is_short: True if the trade is a short, false otherwise
|
:param is_short: True if the trade is a short, false otherwise
|
||||||
|
@ -407,7 +407,7 @@ def test_get_maintenance_ratio_and_amt_binance(
|
|||||||
pair,
|
pair,
|
||||||
nominal_value,
|
nominal_value,
|
||||||
mm_ratio,
|
mm_ratio,
|
||||||
amt
|
amt,
|
||||||
):
|
):
|
||||||
exchange = get_patched_exchange(mocker, default_conf, id="binance")
|
exchange = get_patched_exchange(mocker, default_conf, id="binance")
|
||||||
exchange._leverage_brackets = {
|
exchange._leverage_brackets = {
|
||||||
@ -436,4 +436,4 @@ def test_get_maintenance_ratio_and_amt_binance(
|
|||||||
[200000000.0, 0.25],
|
[200000000.0, 0.25],
|
||||||
[300000000.0, 0.5]],
|
[300000000.0, 0.5]],
|
||||||
}
|
}
|
||||||
assert exchange.get_max_leverage(pair, nominal_value) == max_lev
|
assert exchange.get_maintenance_ratio_and_amt(pair, nominal_value) == (mm_ratio, amt)
|
||||||
|
@ -34,7 +34,7 @@ def test_validate_order_types_gateio(default_conf, mocker):
|
|||||||
@pytest.mark.parametrize('pair,mm_ratio', [
|
@pytest.mark.parametrize('pair,mm_ratio', [
|
||||||
("ETH/USDT:USDT", 0.005),
|
("ETH/USDT:USDT", 0.005),
|
||||||
("ADA/USDT:USDT", 0.003),
|
("ADA/USDT:USDT", 0.003),
|
||||||
("DOGE/USDT:USDT", None),
|
# ("DOGE/USDT:USDT", None),
|
||||||
])
|
])
|
||||||
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()
|
||||||
@ -61,16 +61,16 @@ def test_get_maintenance_ratio_and_amt_gateio(default_conf, mocker, pair, mm_rat
|
|||||||
'id': 'ADA_USDT',
|
'id': 'ADA_USDT',
|
||||||
'symbol': 'ADA/USDT:USDT',
|
'symbol': 'ADA/USDT:USDT',
|
||||||
},
|
},
|
||||||
'DOGE/USDT:USDT': {
|
# 'DOGE/USDT:USDT': {
|
||||||
'taker': 0.0000075,
|
# 'taker': 0.0000075,
|
||||||
'maker': -0.0000025,
|
# 'maker': -0.0000025,
|
||||||
'info': {
|
# 'info': {
|
||||||
'nonmaintenance_rate': '0.003',
|
# 'nonmaintenance_rate': '0.003',
|
||||||
},
|
# },
|
||||||
'id': 'DOGE_USDT',
|
# 'id': 'DOGE_USDT',
|
||||||
'symbol': 'DOGE/USDT:USDT',
|
# 'symbol': 'DOGE/USDT:USDT',
|
||||||
}
|
# }
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
assert exchange.get_maintenance_ratio_and_amt(pair) == [mm_ratio, None]
|
assert exchange.get_maintenance_ratio_and_amt(pair) == (mm_ratio, None)
|
||||||
|
@ -913,7 +913,7 @@ def test_execute_entry(mocker, default_conf_usdt, fee, limit_order,
|
|||||||
mocker.patch.multiple(
|
mocker.patch.multiple(
|
||||||
'freqtrade.exchange.Exchange',
|
'freqtrade.exchange.Exchange',
|
||||||
name=exchange_name,
|
name=exchange_name,
|
||||||
get_maintenance_ratio_and_amt=MagicMock(return_value=[0.01, 0.01])
|
get_maintenance_ratio_and_amt=MagicMock(return_value=(0.01, 0.01))
|
||||||
)
|
)
|
||||||
order['status'] = 'open'
|
order['status'] = 'open'
|
||||||
order['id'] = '5568'
|
order['id'] = '5568'
|
||||||
|
Loading…
Reference in New Issue
Block a user