implemented binance.get_maintenance_ratio_and_amt
This commit is contained in:
parent
ba5fc21d84
commit
69a6223ca0
@ -163,11 +163,10 @@ class Binance(Exchange):
|
|||||||
if pair not in self._leverage_brackets:
|
if pair not in self._leverage_brackets:
|
||||||
return 1.0
|
return 1.0
|
||||||
pair_brackets = self._leverage_brackets[pair]
|
pair_brackets = self._leverage_brackets[pair]
|
||||||
max_lev = 1.0
|
for [notional_floor, mm_ratio, _] in reversed(pair_brackets):
|
||||||
for [notional_floor, maint_margin_ratio] in pair_brackets:
|
|
||||||
if nominal_value >= notional_floor:
|
if nominal_value >= notional_floor:
|
||||||
max_lev = 1/maint_margin_ratio
|
return 1/mm_ratio
|
||||||
return max_lev
|
return 1.0
|
||||||
|
|
||||||
@retrier
|
@retrier
|
||||||
def _set_leverage(
|
def _set_leverage(
|
||||||
@ -227,3 +226,114 @@ class Binance(Exchange):
|
|||||||
:return: The cutoff open time for when a funding fee is charged
|
:return: The cutoff open time for when a funding fee is charged
|
||||||
"""
|
"""
|
||||||
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: Optional[str],
|
||||||
|
nominal_value: Optional[float]
|
||||||
|
):
|
||||||
|
'''
|
||||||
|
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
|
||||||
|
https://www.binance.com/en/support/faq/b3c689c1f50a44cabb3a84e663b81d93
|
||||||
|
'''
|
||||||
|
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 liquidation_price_helper(
|
||||||
|
self,
|
||||||
|
open_rate: float, # Entry price of position
|
||||||
|
is_short: bool,
|
||||||
|
leverage: float,
|
||||||
|
trading_mode: TradingMode,
|
||||||
|
mm_ratio: float,
|
||||||
|
collateral: Collateral,
|
||||||
|
maintenance_amt: Optional[float] = None, # (Binance)
|
||||||
|
position: Optional[float] = None, # (Binance and Gateio) Absolute value of position size
|
||||||
|
wallet_balance: Optional[float] = None, # (Binance and Gateio)
|
||||||
|
taker_fee_rate: Optional[float] = None, # (Gateio & Okex)
|
||||||
|
liability: Optional[float] = None, # (Okex)
|
||||||
|
interest: Optional[float] = None, # (Okex)
|
||||||
|
position_assets: Optional[float] = None, # * (Okex) Might be same as position
|
||||||
|
mm_ex_1: Optional[float] = 0.0, # (Binance) Cross only
|
||||||
|
upnl_ex_1: Optional[float] = 0.0, # (Binance) Cross only
|
||||||
|
) -> Optional[float]:
|
||||||
|
"""
|
||||||
|
MARGIN: https://www.binance.com/en/support/faq/f6b010588e55413aa58b7d63ee0125ed
|
||||||
|
PERPETUAL: https://www.binance.com/en/support/faq/b3c689c1f50a44cabb3a84e663b81d93
|
||||||
|
|
||||||
|
:param exchange_name:
|
||||||
|
:param open_rate: (EP1) Entry price of position
|
||||||
|
:param is_short: True if the trade is a short, false otherwise
|
||||||
|
:param leverage: The amount of leverage on the trade
|
||||||
|
:param trading_mode: SPOT, MARGIN, FUTURES, etc.
|
||||||
|
:param position: Absolute value of position size (in base currency)
|
||||||
|
:param mm_ratio: (MMR)
|
||||||
|
# Binance's formula specifies maintenance margin rate which is mm_ratio * 100%
|
||||||
|
:param collateral: Either ISOLATED or CROSS
|
||||||
|
:param maintenance_amt: (CUM) Maintenance Amount of position
|
||||||
|
:param wallet_balance: (WB)
|
||||||
|
Cross-Margin Mode: crossWalletBalance
|
||||||
|
Isolated-Margin Mode: isolatedWalletBalance
|
||||||
|
:param position: Absolute value of position size (in base currency)
|
||||||
|
|
||||||
|
# * Not required by Binance
|
||||||
|
:param taker_fee_rate:
|
||||||
|
:param liability:
|
||||||
|
:param interest:
|
||||||
|
:param position_assets:
|
||||||
|
|
||||||
|
# * Only required for Cross
|
||||||
|
:param mm_ex_1: (TMM)
|
||||||
|
Cross-Margin Mode: Maintenance Margin of all other contracts, excluding Contract 1
|
||||||
|
Isolated-Margin Mode: 0
|
||||||
|
:param upnl_ex_1: (UPNL)
|
||||||
|
Cross-Margin Mode: Unrealized PNL of all other contracts, excluding Contract 1.
|
||||||
|
Isolated-Margin Mode: 0
|
||||||
|
"""
|
||||||
|
if trading_mode == TradingMode.SPOT:
|
||||||
|
return None
|
||||||
|
|
||||||
|
if not collateral:
|
||||||
|
raise OperationalException(
|
||||||
|
"Parameter collateral is required by liquidation_price when trading_mode is "
|
||||||
|
f"{trading_mode}"
|
||||||
|
)
|
||||||
|
if (
|
||||||
|
(wallet_balance is None or maintenance_amt is None or position is None) or
|
||||||
|
(collateral == Collateral.CROSS and (mm_ex_1 is None or upnl_ex_1 is None))
|
||||||
|
):
|
||||||
|
required_params = "wallet_balance, maintenance_amt, position"
|
||||||
|
if collateral == Collateral.CROSS:
|
||||||
|
required_params += ", mm_ex_1, upnl_ex_1"
|
||||||
|
raise OperationalException(
|
||||||
|
f"Parameters {required_params} are required by Binance.liquidation_price"
|
||||||
|
f"for {collateral.name} {trading_mode.name}"
|
||||||
|
)
|
||||||
|
|
||||||
|
side_1 = -1 if is_short else 1
|
||||||
|
position = abs(position)
|
||||||
|
cross_vars = upnl_ex_1 - mm_ex_1 if collateral == Collateral.CROSS else 0.0 # type: ignore
|
||||||
|
|
||||||
|
if trading_mode == TradingMode.FUTURES:
|
||||||
|
return (
|
||||||
|
(
|
||||||
|
(wallet_balance + cross_vars + maintenance_amt) -
|
||||||
|
(side_1 * position * open_rate)
|
||||||
|
) / (
|
||||||
|
(position * mm_ratio) - (side_1 * position)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
raise OperationalException(
|
||||||
|
f"Binance does not support {collateral.value} Mode {trading_mode.value} trading ")
|
||||||
|
@ -2003,8 +2003,11 @@ class Exchange:
|
|||||||
except ccxt.BaseError as e:
|
except ccxt.BaseError as e:
|
||||||
raise OperationalException(e) from e
|
raise OperationalException(e) from e
|
||||||
|
|
||||||
@retrier
|
def get_maintenance_ratio_and_amt(
|
||||||
def get_mm_amt_rate(self, pair: str, amount: float):
|
self,
|
||||||
|
pair: Optional[str],
|
||||||
|
nominal_value: Optional[float]
|
||||||
|
):
|
||||||
'''
|
'''
|
||||||
:return: The maintenance amount, and maintenance margin rate
|
:return: The maintenance amount, and maintenance margin rate
|
||||||
'''
|
'''
|
||||||
|
@ -616,7 +616,7 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
# open_rate=open_rate,
|
# open_rate=open_rate,
|
||||||
# is_short=is_short
|
# is_short=is_short
|
||||||
# )
|
# )
|
||||||
maintenance_amt, mm_rate = self.exchange.get_mm_amt_rate(pair, amount)
|
mm_ratio, maintenance_amt = self.exchange.get_maintenance_ratio_and_amt(pair, amount)
|
||||||
|
|
||||||
if self.collateral_type == Collateral.ISOLATED:
|
if self.collateral_type == Collateral.ISOLATED:
|
||||||
if self.config['dry_run']:
|
if self.config['dry_run']:
|
||||||
@ -630,9 +630,9 @@ class FreqtradeBot(LoggingMixin):
|
|||||||
mm_ex_1=0.0,
|
mm_ex_1=0.0,
|
||||||
upnl_ex_1=0.0,
|
upnl_ex_1=0.0,
|
||||||
position=amount * open_rate,
|
position=amount * open_rate,
|
||||||
wallet_balance=amount/leverage, # TODO-lev: Is this correct?
|
wallet_balance=amount/leverage, # TODO: Update for cross
|
||||||
maintenance_amt=maintenance_amt,
|
maintenance_amt=maintenance_amt,
|
||||||
mm_rate=mm_rate,
|
mm_ratio=mm_ratio,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
isolated_liq = self.exchange.get_liquidation_price(pair)
|
isolated_liq = self.exchange.get_liquidation_price(pair)
|
||||||
|
@ -35,12 +35,12 @@ def liquidation_price(
|
|||||||
'''
|
'''
|
||||||
wallet_balance
|
wallet_balance
|
||||||
In Cross margin mode, WB is crossWalletBalance
|
In Cross margin mode, WB is crossWalletBalance
|
||||||
In Isolated margin mode, WB is isolatedWalletBalance of the isolated position,
|
In Isolated margin mode, WB is isolatedWalletBalance of the isolated position,
|
||||||
TMM=0, UPNL=0, substitute the position quantity, MMR, cum into the formula to calculate.
|
TMM=0, UPNL=0, substitute the position quantity, MMR, cum into the formula to calculate.
|
||||||
Under the cross margin mode, the same ticker/symbol,
|
Under the cross margin mode, the same ticker/symbol,
|
||||||
both long and short position share the same liquidation price except in the isolated mode.
|
both long and short position share the same liquidation price except in the isolated mode.
|
||||||
Under the isolated mode, each isolated position will have different liquidation prices depending
|
Under the isolated mode, each isolated position will have different liquidation prices
|
||||||
on the margin allocated to the positions.
|
depending on the margin allocated to the positions.
|
||||||
position
|
position
|
||||||
Absolute value of position size (in base currency)
|
Absolute value of position size (in base currency)
|
||||||
|
|
||||||
|
@ -368,7 +368,7 @@ class LocalTrade():
|
|||||||
wallet_balance: Optional[float] = None,
|
wallet_balance: Optional[float] = None,
|
||||||
current_price: Optional[float] = None,
|
current_price: Optional[float] = None,
|
||||||
maintenance_amt: Optional[float] = None,
|
maintenance_amt: Optional[float] = None,
|
||||||
mm_rate: Optional[float] = None,
|
mm_ratio: Optional[float] = None,
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
Method you should use to set self.liquidation price.
|
Method you should use to set self.liquidation price.
|
||||||
@ -380,6 +380,16 @@ class LocalTrade():
|
|||||||
"wallet balance must be passed to LocalTrade.set_isolated_liq when param"
|
"wallet balance must be passed to LocalTrade.set_isolated_liq when param"
|
||||||
"isolated_liq is None"
|
"isolated_liq is None"
|
||||||
)
|
)
|
||||||
|
if (
|
||||||
|
mm_ratio is None or
|
||||||
|
wallet_balance is None or
|
||||||
|
current_price is None or
|
||||||
|
maintenance_amt is None
|
||||||
|
):
|
||||||
|
raise OperationalException(
|
||||||
|
'mm_ratio, wallet_balance, current_price and maintenance_amt '
|
||||||
|
'required in set_isolated_liq when isolated_liq is None'
|
||||||
|
)
|
||||||
isolated_liq = liquidation_price(
|
isolated_liq = liquidation_price(
|
||||||
exchange_name=self.exchange,
|
exchange_name=self.exchange,
|
||||||
open_rate=self.open_rate,
|
open_rate=self.open_rate,
|
||||||
@ -390,9 +400,9 @@ class LocalTrade():
|
|||||||
mm_ex_1=0.0,
|
mm_ex_1=0.0,
|
||||||
upnl_ex_1=0.0,
|
upnl_ex_1=0.0,
|
||||||
position=self.amount * current_price,
|
position=self.amount * current_price,
|
||||||
wallet_balance=self.amount / self.leverage, # TODO-lev: Is this correct?
|
wallet_balance=self.amount / self.leverage, # TODO: Update for cross
|
||||||
maintenance_amt=maintenance_amt,
|
maintenance_amt=maintenance_amt,
|
||||||
mm_rate=mm_rate,
|
mm_ratio=mm_ratio,
|
||||||
|
|
||||||
)
|
)
|
||||||
if isolated_liq is None:
|
if isolated_liq is None:
|
||||||
|
@ -173,30 +173,32 @@ def test_stoploss_adjust_binance(mocker, default_conf, sl1, sl2, sl3, side):
|
|||||||
def test_get_max_leverage_binance(default_conf, mocker, pair, nominal_value, max_lev):
|
def test_get_max_leverage_binance(default_conf, mocker, pair, nominal_value, max_lev):
|
||||||
exchange = get_patched_exchange(mocker, default_conf, id="binance")
|
exchange = get_patched_exchange(mocker, default_conf, id="binance")
|
||||||
exchange._leverage_brackets = {
|
exchange._leverage_brackets = {
|
||||||
'BNB/BUSD': [[0.0, 0.025],
|
'BNB/BUSD': [[0.0, 0.025, 0.0],
|
||||||
[100000.0, 0.05],
|
[100000.0, 0.05, 2500.0],
|
||||||
[500000.0, 0.1],
|
[500000.0, 0.1, 27500.0],
|
||||||
[1000000.0, 0.15],
|
[1000000.0, 0.15, 77499.99999999999],
|
||||||
[2000000.0, 0.25],
|
[2000000.0, 0.25, 277500.0],
|
||||||
[5000000.0, 0.5]],
|
[5000000.0, 0.5, 1527500.0]],
|
||||||
'BNB/USDT': [[0.0, 0.0065],
|
'BNB/USDT': [[0.0, 0.0065, 0.0],
|
||||||
[10000.0, 0.01],
|
[10000.0, 0.01, 35.00000000000001],
|
||||||
[50000.0, 0.02],
|
[50000.0, 0.02, 535.0],
|
||||||
[250000.0, 0.05],
|
[250000.0, 0.05, 8035.000000000001],
|
||||||
[1000000.0, 0.1],
|
[1000000.0, 0.1, 58035.0],
|
||||||
[2000000.0, 0.125],
|
[2000000.0, 0.125, 108034.99999999999],
|
||||||
[5000000.0, 0.15],
|
[5000000.0, 0.15, 233034.99999999994],
|
||||||
[10000000.0, 0.25]],
|
[10000000.0, 0.25, 1233035.0]],
|
||||||
'BTC/USDT': [[0.0, 0.004],
|
'BTC/USDT': [[0.0, 0.004, 0.0],
|
||||||
[50000.0, 0.005],
|
[50000.0, 0.005, 50.0],
|
||||||
[250000.0, 0.01],
|
[250000.0, 0.01, 1300.0],
|
||||||
[1000000.0, 0.025],
|
[1000000.0, 0.025, 16300.000000000002],
|
||||||
[5000000.0, 0.05],
|
[5000000.0, 0.05, 141300.0],
|
||||||
[20000000.0, 0.1],
|
[20000000.0, 0.1, 1141300.0],
|
||||||
[50000000.0, 0.125],
|
[50000000.0, 0.125, 2391300.0],
|
||||||
[100000000.0, 0.15],
|
[100000000.0, 0.15, 4891300.0],
|
||||||
[200000000.0, 0.25],
|
[200000000.0, 0.25, 24891300.0],
|
||||||
[300000000.0, 0.5]],
|
[300000000.0, 0.5, 99891300.0]
|
||||||
|
]
|
||||||
|
|
||||||
}
|
}
|
||||||
assert exchange.get_max_leverage(pair, nominal_value) == max_lev
|
assert exchange.get_max_leverage(pair, nominal_value) == max_lev
|
||||||
|
|
||||||
@ -235,28 +237,28 @@ 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],
|
'ADA/BUSD': [[0.0, 0.025, 0.0],
|
||||||
[100000.0, 0.05],
|
[100000.0, 0.05, 2500.0],
|
||||||
[500000.0, 0.1],
|
[500000.0, 0.1, 27500.0],
|
||||||
[1000000.0, 0.15],
|
[1000000.0, 0.15, 77499.99999999999],
|
||||||
[2000000.0, 0.25],
|
[2000000.0, 0.25, 277500.0],
|
||||||
[5000000.0, 0.5]],
|
[5000000.0, 0.5, 1827500.0]],
|
||||||
'BTC/USDT': [[0.0, 0.004],
|
'BTC/USDT': [[0.0, 0.004, 0.0],
|
||||||
[50000.0, 0.005],
|
[50000.0, 0.005, 50.0],
|
||||||
[250000.0, 0.01],
|
[250000.0, 0.01, 1300.0],
|
||||||
[1000000.0, 0.025],
|
[1000000.0, 0.025, 16300.000000000002],
|
||||||
[5000000.0, 0.05],
|
[5000000.0, 0.05, 141300.0],
|
||||||
[20000000.0, 0.1],
|
[20000000.0, 0.1, 1141300.0],
|
||||||
[50000000.0, 0.125],
|
[50000000.0, 0.125, 2391300.0],
|
||||||
[100000000.0, 0.15],
|
[100000000.0, 0.15, 4891300.0],
|
||||||
[200000000.0, 0.25],
|
[200000000.0, 0.25, 24891300.0],
|
||||||
[300000000.0, 0.5]],
|
[300000000.0, 0.5, 99891300.0]],
|
||||||
"ZEC/USDT": [[0.0, 0.01],
|
"ZEC/USDT": [[0.0, 0.01, 0.0],
|
||||||
[5000.0, 0.025],
|
[5000.0, 0.025, 75.0],
|
||||||
[25000.0, 0.05],
|
[25000.0, 0.05, 700.0],
|
||||||
[100000.0, 0.1],
|
[100000.0, 0.1, 5700.0],
|
||||||
[250000.0, 0.125],
|
[250000.0, 0.125, 11949.999999999998],
|
||||||
[1000000.0, 0.5]],
|
[1000000.0, 0.5, 386950.0]]
|
||||||
}
|
}
|
||||||
|
|
||||||
api_mock = MagicMock()
|
api_mock = MagicMock()
|
||||||
@ -389,3 +391,49 @@ def test__ccxt_config(default_conf, mocker, trading_mode, collateral, config):
|
|||||||
default_conf['collateral'] = collateral
|
default_conf['collateral'] = collateral
|
||||||
exchange = get_patched_exchange(mocker, default_conf, id="binance")
|
exchange = get_patched_exchange(mocker, default_conf, id="binance")
|
||||||
assert exchange._ccxt_config == config
|
assert exchange._ccxt_config == config
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('pair,nominal_value,mm_ratio,amt', [
|
||||||
|
("BNB/BUSD", 0.0, 0.025, 0),
|
||||||
|
("BNB/USDT", 100.0, 0.0065, 0),
|
||||||
|
("BTC/USDT", 170.30, 0.004, 0),
|
||||||
|
("BNB/BUSD", 999999.9, 0.1, 0),
|
||||||
|
("BNB/USDT", 5000000.0, 0.5, 0),
|
||||||
|
("BTC/USDT", 300000000.1, 0.5, 0),
|
||||||
|
])
|
||||||
|
def test_get_maintenance_ratio_and_amt_binance(
|
||||||
|
default_conf,
|
||||||
|
mocker,
|
||||||
|
pair,
|
||||||
|
nominal_value,
|
||||||
|
mm_ratio,
|
||||||
|
amt
|
||||||
|
):
|
||||||
|
exchange = get_patched_exchange(mocker, default_conf, id="binance")
|
||||||
|
exchange._leverage_brackets = {
|
||||||
|
'BNB/BUSD': [[0.0, 0.025],
|
||||||
|
[100000.0, 0.05],
|
||||||
|
[500000.0, 0.1],
|
||||||
|
[1000000.0, 0.15],
|
||||||
|
[2000000.0, 0.25],
|
||||||
|
[5000000.0, 0.5]],
|
||||||
|
'BNB/USDT': [[0.0, 0.0065],
|
||||||
|
[10000.0, 0.01],
|
||||||
|
[50000.0, 0.02],
|
||||||
|
[250000.0, 0.05],
|
||||||
|
[1000000.0, 0.1],
|
||||||
|
[2000000.0, 0.125],
|
||||||
|
[5000000.0, 0.15],
|
||||||
|
[10000000.0, 0.25]],
|
||||||
|
'BTC/USDT': [[0.0, 0.004],
|
||||||
|
[50000.0, 0.005],
|
||||||
|
[250000.0, 0.01],
|
||||||
|
[1000000.0, 0.025],
|
||||||
|
[5000000.0, 0.05],
|
||||||
|
[20000000.0, 0.1],
|
||||||
|
[50000000.0, 0.125],
|
||||||
|
[100000000.0, 0.15],
|
||||||
|
[200000000.0, 0.25],
|
||||||
|
[300000000.0, 0.5]],
|
||||||
|
}
|
||||||
|
assert exchange.get_max_leverage(pair, nominal_value) == max_lev
|
||||||
|
@ -90,7 +90,7 @@ def test_liquidation_price_exception_thrown(
|
|||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
'exchange_name, is_short, leverage, trading_mode, collateral, wallet_balance, '
|
'exchange_name, is_short, leverage, trading_mode, collateral, wallet_balance, '
|
||||||
'mm_ex_1, upnl_ex_1, maintenance_amt, position, open_rate, '
|
'mm_ex_1, upnl_ex_1, maintenance_amt, position, open_rate, '
|
||||||
'mm_rate, expected',
|
'mm_ratio, expected',
|
||||||
[
|
[
|
||||||
("binance", False, 1, TradingMode.FUTURES, Collateral.ISOLATED, 1535443.01, 0.0,
|
("binance", False, 1, TradingMode.FUTURES, Collateral.ISOLATED, 1535443.01, 0.0,
|
||||||
0.0, 135365.00, 3683.979, 1456.84, 0.10, 1114.78),
|
0.0, 135365.00, 3683.979, 1456.84, 0.10, 1114.78),
|
||||||
@ -103,7 +103,7 @@ def test_liquidation_price_exception_thrown(
|
|||||||
])
|
])
|
||||||
def test_liquidation_price(
|
def test_liquidation_price(
|
||||||
exchange_name, open_rate, is_short, leverage, trading_mode, collateral, wallet_balance,
|
exchange_name, open_rate, is_short, leverage, trading_mode, collateral, wallet_balance,
|
||||||
mm_ex_1, upnl_ex_1, maintenance_amt, position, mm_rate, expected
|
mm_ex_1, upnl_ex_1, maintenance_amt, position, mm_ratio, expected
|
||||||
):
|
):
|
||||||
assert isclose(round(liquidation_price(
|
assert isclose(round(liquidation_price(
|
||||||
exchange_name=exchange_name,
|
exchange_name=exchange_name,
|
||||||
@ -117,5 +117,5 @@ def test_liquidation_price(
|
|||||||
upnl_ex_1=upnl_ex_1,
|
upnl_ex_1=upnl_ex_1,
|
||||||
maintenance_amt=maintenance_amt,
|
maintenance_amt=maintenance_amt,
|
||||||
position=position,
|
position=position,
|
||||||
mm_rate=mm_rate
|
mm_ratio=mm_ratio
|
||||||
), 2), expected)
|
), 2), expected)
|
||||||
|
Loading…
Reference in New Issue
Block a user