Fix liquidation price tier calculation

closes #7294
This commit is contained in:
Matthias
2022-08-26 20:04:36 +02:00
parent 753d1b2aad
commit 01126c43f7
5 changed files with 40 additions and 26 deletions

View File

@@ -137,23 +137,27 @@ class Binance(Exchange):
pair: str,
open_rate: float, # Entry price of position
is_short: bool,
position: float, # Absolute value of position size
amount: float,
stake_amount: float,
wallet_balance: float, # Or margin balance
mm_ex_1: float = 0.0, # (Binance) Cross only
upnl_ex_1: float = 0.0, # (Binance) Cross only
) -> Optional[float]:
"""
Important: Must be fetching data from cached values as this is used by backtesting!
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 open_rate: Entry price of position
:param is_short: True if the trade is a short, false otherwise
:param position: Absolute value of position size (in base currency)
:param wallet_balance: (WB)
:param amount: Absolute value of position size incl. leverage (in base currency)
:param stake_amount: Stake amount - Collateral in settle currency.
:param trading_mode: SPOT, MARGIN, FUTURES, etc.
:param margin_mode: Either ISOLATED or CROSS
:param wallet_balance: Amount of margin_mode in the wallet being used to trade
Cross-Margin Mode: crossWalletBalance
Isolated-Margin Mode: isolatedWalletBalance
:param maintenance_amt:
# * Only required for Cross
:param mm_ex_1: (TMM)
@@ -165,12 +169,11 @@ class Binance(Exchange):
"""
side_1 = -1 if is_short else 1
position = abs(position)
cross_vars = upnl_ex_1 - mm_ex_1 if self.margin_mode == MarginMode.CROSS else 0.0
# mm_ratio: Binance's formula specifies maintenance margin rate which is mm_ratio * 100%
# maintenance_amt: (CUM) Maintenance Amount of position
mm_ratio, maintenance_amt = self.get_maintenance_ratio_and_amt(pair, position)
mm_ratio, maintenance_amt = self.get_maintenance_ratio_and_amt(pair, stake_amount)
if (maintenance_amt is None):
raise OperationalException(
@@ -182,9 +185,9 @@ class Binance(Exchange):
return (
(
(wallet_balance + cross_vars + maintenance_amt) -
(side_1 * position * open_rate)
(side_1 * amount * open_rate)
) / (
(position * mm_ratio) - (side_1 * position)
(amount * mm_ratio) - (side_1 * amount)
)
)
else:

View File

@@ -2437,6 +2437,7 @@ class Exchange:
pair: str,
open_rate: float,
amount: float, # quote currency, includes leverage
stake_amount: float,
leverage: float,
is_short: bool
) -> Optional[float]:
@@ -2446,13 +2447,13 @@ class Exchange:
elif (
self.trading_mode == TradingMode.FUTURES
):
wallet_balance = (amount * open_rate) / leverage
isolated_liq = self.get_or_calculate_liquidation_price(
pair=pair,
open_rate=open_rate,
is_short=is_short,
position=amount,
wallet_balance=wallet_balance,
amount=amount,
stake_amount=stake_amount,
wallet_balance=stake_amount, # In isolated mode, stake-amount = wallet size
mm_ex_1=0.0,
upnl_ex_1=0.0,
)
@@ -2627,14 +2628,14 @@ class Exchange:
# Dry-run
open_rate: float, # Entry price of position
is_short: bool,
position: float, # Absolute value of position size
amount: float, # Absolute value of position size
stake_amount: float,
wallet_balance: float, # Or margin balance
mm_ex_1: float = 0.0, # (Binance) Cross only
upnl_ex_1: float = 0.0, # (Binance) Cross only
) -> Optional[float]:
"""
Set's the margin mode on the exchange to cross or isolated for a specific pair
:param pair: base/quote currency pair (e.g. "ADA/USDT")
"""
if self.trading_mode == TradingMode.SPOT:
return None
@@ -2648,7 +2649,8 @@ class Exchange:
pair=pair,
open_rate=open_rate,
is_short=is_short,
position=position,
amount=amount,
stake_amount=stake_amount,
wallet_balance=wallet_balance,
mm_ex_1=mm_ex_1,
upnl_ex_1=upnl_ex_1
@@ -2677,22 +2679,24 @@ class Exchange:
pair: str,
open_rate: float, # Entry price of position
is_short: bool,
position: float, # Absolute value of position size
amount: float,
stake_amount: float,
wallet_balance: float, # Or margin balance
mm_ex_1: float = 0.0, # (Binance) Cross only
upnl_ex_1: float = 0.0, # (Binance) Cross only
) -> Optional[float]:
"""
Important: Must be fetching data from cached values as this is used by backtesting!
PERPETUAL:
gateio: https://www.gate.io/help/futures/perpetual/22160/calculation-of-liquidation-price
okex: https://www.okex.com/support/hc/en-us/articles/
360053909592-VI-Introduction-to-the-isolated-mode-of-Single-Multi-currency-Portfolio-margin
Important: Must be fetching data from cached values as this is used by backtesting!
:param exchange_name:
:param open_rate: Entry price of position
:param is_short: True if the trade is a short, false otherwise
:param position: Absolute value of position size incl. leverage (in base currency)
:param amount: Absolute value of position size incl. leverage (in base currency)
:param stake_amount: Stake amount - Collateral in settle currency.
:param trading_mode: SPOT, MARGIN, FUTURES, etc.
:param margin_mode: Either ISOLATED or CROSS
:param wallet_balance: Amount of margin_mode in the wallet being used to trade
@@ -2706,7 +2710,7 @@ class Exchange:
market = self.markets[pair]
taker_fee_rate = market['taker']
mm_ratio, _ = self.get_maintenance_ratio_and_amt(pair, position)
mm_ratio, _ = self.get_maintenance_ratio_and_amt(pair, stake_amount)
if self.trading_mode == TradingMode.FUTURES and self.margin_mode == MarginMode.ISOLATED:
@@ -2714,7 +2718,7 @@ class Exchange:
raise OperationalException(
"Freqtrade does not yet support inverse contracts")
value = wallet_balance / position
value = wallet_balance / amount
mm_ratio_taker = (mm_ratio + taker_fee_rate)
if is_short: