Added Formulas to Calculate Liquidation Price of Binance USDⓈ-M Futures Contracts

This commit is contained in:
Arunavo Ray 2021-08-27 11:28:12 +05:30
parent 347c7e0652
commit d343e84507
3 changed files with 140 additions and 22 deletions

View File

@ -7,3 +7,4 @@ from freqtrade.enums.selltype import SellType
from freqtrade.enums.signaltype import SignalTagType, SignalType from freqtrade.enums.signaltype import SignalTagType, SignalType
from freqtrade.enums.state import State from freqtrade.enums.state import State
from freqtrade.enums.tradingmode import TradingMode from freqtrade.enums.tradingmode import TradingMode
from freqtrade.enums.marginmode import MarginMode

View File

@ -0,0 +1,10 @@
from enum import Enum
class MarginMode(Enum):
"""
Enum to distinguish between
one-way mode or hedge mode in Futures (Cross and Isolated) or Margin Trading
"""
ONE_WAY = "one-way"
HEDGE = "hedge"

View File

@ -1,6 +1,6 @@
from typing import Optional from typing import Optional
from freqtrade.enums import Collateral, TradingMode from freqtrade.enums import Collateral, TradingMode, MarginMode
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
@ -12,7 +12,6 @@ def liquidation_price(
trading_mode: TradingMode, trading_mode: TradingMode,
collateral: Optional[Collateral] collateral: Optional[Collateral]
) -> Optional[float]: ) -> Optional[float]:
if trading_mode == TradingMode.SPOT: if trading_mode == TradingMode.SPOT:
return None return None
@ -36,60 +35,164 @@ def liquidation_price(
def exception( def exception(
exchange: str, exchange: str,
trading_mode: TradingMode, trading_mode: TradingMode,
collateral: Collateral collateral: Collateral,
margin_mode: Optional[MarginMode]
): ):
""" """
Raises an exception if exchange used doesn't support desired leverage mode Raises an exception if exchange used doesn't support desired leverage mode
:param name: Name of the exchange :param exchange: Name of the exchange
:param margin_mode: one-way or hedge
:param trading_mode: spot, margin, futures :param trading_mode: spot, margin, futures
:param collateral: cross, isolated :param collateral: cross, isolated
""" """
if not margin_mode:
raise OperationalException( raise OperationalException(
f"{exchange} does not support {collateral.value} {trading_mode.value} trading") f"{exchange} does not support {collateral.value} {trading_mode.value} trading ")
raise OperationalException(
f"{exchange} does not support {collateral.value} {margin_mode.value} Mode {trading_mode.value} trading ")
def binance( def binance(
open_rate: float, open_rate: float,
is_short: bool, is_short: bool,
leverage: float, leverage: float,
margin_mode: MarginMode,
trading_mode: TradingMode, trading_mode: TradingMode,
collateral: Collateral collateral: Collateral,
**kwargs
): ):
""" r"""
Calculates the liquidation price on Binance Calculates the liquidation price on Binance
:param name: Name of the exchange :param open_rate: open_rate
:param is_short: true or false
:param leverage: leverage in float
:param margin_mode: one-way or hedge
:param trading_mode: spot, margin, futures :param trading_mode: spot, margin, futures
:param collateral: cross, isolated :param collateral: cross, isolated
:param \**kwargs:
See below
:Keyword Arguments:
* *wallet_balance* (``float``) --
Wallet Balance is crossWalletBalance in Cross-Margin Mode
Wallet Balance is isolatedWalletBalance in Isolated Margin Mode
* *maintenance_margin_ex_1* (``float``) --
Maintenance Margin of all other contracts, excluding Contract 1.
If it is an isolated margin mode, then TMM=0
* *unrealized_pnl_ex_1* (``float``) --
Unrealized PNL of all other contracts, excluding Contract 1.
If it is an isolated margin mode, then UPNL=0
* *maintenance_amount_both* (``float``) --
Maintenance Amount of BOTH position (one-way mode)
* *maintenance_amount_long* (``float``) --
Maintenance Amount of LONG position (hedge mode)
* *maintenance_amount_short* (``float``) --
Maintenance Amount of SHORT position (hedge mode)
* *side_1_both* (``int``) --
Direction of BOTH position, 1 as long position, -1 as short position
Derived from is_short
* *position_1_both* (``float``) --
Absolute value of BOTH position size (one-way mode)
* *entry_price_1_both* (``float``) --
Entry Price of BOTH position (one-way mode)
* *position_1_long* (``float``) --
Absolute value of LONG position size (hedge mode)
* *entry_price_1_long* (``float``) --
Entry Price of LONG position (hedge mode)
* *position_1_short* (``float``) --
Absolute value of SHORT position size (hedge mode)
* *entry_price_1_short* (``float``) --
Entry Price of SHORT position (hedge mode)
* *maintenance_margin_rate_both* (``float``) --
Maintenance margin rate of BOTH position (one-way mode)
* *maintenance_margin_rate_long* (``float``) --
Maintenance margin rate of LONG position (hedge mode)
* *maintenance_margin_rate_short* (``float``) --
Maintenance margin rate of SHORT position (hedge mode)
""" """
# TODO-lev: Additional arguments, fill in formulas # TODO-lev: Additional arguments, fill in formulas
wb = kwargs.get("wallet_balance")
tmm_1 = 0.0 if collateral == Collateral.ISOLATED else kwargs.get("maintenance_margin_ex_1")
upnl_1 = 0.0 if collateral == Collateral.ISOLATED else kwargs.get("unrealized_pnl_ex_1")
cum_b = kwargs.get("maintenance_amount_both")
cum_l = kwargs.get("maintenance_amount_long")
cum_s = kwargs.get("maintenance_amount_short")
side_1_both = -1 if is_short else 1
position_1_both = abs(kwargs.get("position_1_both"))
ep1_both = kwargs.get("entry_price_1_both")
position_1_long = abs(kwargs.get("position_1_long"))
ep1_long = kwargs.get("entry_price_1_long")
position_1_short = abs(kwargs.get("position_1_short"))
ep1_short = kwargs.get("entry_price_1_short")
mmr_b = kwargs.get("maintenance_margin_rate_both")
mmr_l = kwargs.get("maintenance_margin_rate_long")
mmr_s = kwargs.get("maintenance_margin_rate_short")
if trading_mode == TradingMode.MARGIN and collateral == Collateral.CROSS: if trading_mode == TradingMode.MARGIN and collateral == Collateral.CROSS:
# TODO-lev: perform a calculation based on this formula # TODO-lev: perform a calculation based on this formula
# https://www.binance.com/en/support/faq/f6b010588e55413aa58b7d63ee0125ed # https://www.binance.com/en/support/faq/f6b010588e55413aa58b7d63ee0125ed
exception("binance", trading_mode, collateral) exception("binance", trading_mode, collateral, margin_mode)
elif trading_mode == TradingMode.FUTURES and collateral == Collateral.CROSS:
# TODO-lev: perform a calculation based on this formula
# https://www.binance.com/en/support/faq/b3c689c1f50a44cabb3a84e663b81d93
exception("binance", trading_mode, collateral)
elif trading_mode == TradingMode.FUTURES and collateral == Collateral.ISOLATED: elif trading_mode == TradingMode.FUTURES and collateral == Collateral.ISOLATED:
# TODO-lev: perform a calculation based on this formula
# https://www.binance.com/en/support/faq/b3c689c1f50a44cabb3a84e663b81d93 # https://www.binance.com/en/support/faq/b3c689c1f50a44cabb3a84e663b81d93
exception("binance", trading_mode, collateral) # Liquidation Price of USDⓈ-M Futures Contracts Isolated
if margin_mode == MarginMode.HEDGE:
exception("binance", trading_mode, collateral, margin_mode)
elif margin_mode == MarginMode.ONE_WAY:
# Isolated margin mode, then TMM=0UPNL=0
return (wb + cum_b - (side_1_both * position_1_both * ep1_both)) / (
position_1_both * mmr_b - side_1_both * position_1_both)
elif trading_mode == TradingMode.FUTURES and collateral == Collateral.CROSS:
# https://www.binance.com/en/support/faq/b3c689c1f50a44cabb3a84e663b81d93
# Liquidation Price of USDⓈ-M Futures Contracts Cross
if margin_mode == MarginMode.HEDGE:
return (wb - tmm_1 + upnl_1 + cum_l + cum_s - (position_1_long * ep1_long) + (
position_1_short * ep1_short)) / (
position_1_long * mmr_l + position_1_short * mmr_s - position_1_long + position_1_short)
elif margin_mode == MarginMode.ONE_WAY:
# Isolated margin mode, then TMM=0UPNL=0
return (wb - tmm_1 + upnl_1 + cum_b - (side_1_both * position_1_both * ep1_both)) / (
position_1_both * mmr_b - side_1_both * position_1_both)
# If nothing was returned # If nothing was returned
exception("binance", trading_mode, collateral) exception("binance", trading_mode, collateral, margin_mode)
def kraken( def kraken(
open_rate: float, open_rate: float,
is_short: bool, is_short: bool,
leverage: float, leverage: float,
margin_mode: MarginMode,
trading_mode: TradingMode, trading_mode: TradingMode,
collateral: Collateral collateral: Collateral
): ):
""" """
Calculates the liquidation price on Kraken Calculates the liquidation price on Kraken
:param name: Name of the exchange :param open_rate: open_rate
:param is_short: true or false
:param leverage: leverage in float
:param margin_mode: one-way or hedge
:param trading_mode: spot, margin, futures :param trading_mode: spot, margin, futures
:param collateral: cross, isolated :param collateral: cross, isolated
""" """
@ -101,28 +204,32 @@ def kraken(
# TODO-lev: perform a calculation based on this formula # TODO-lev: perform a calculation based on this formula
# https://support.kraken.com/hc/en-us/articles/203325763-Margin-Call-Level-and-Margin-Liquidation-Level # https://support.kraken.com/hc/en-us/articles/203325763-Margin-Call-Level-and-Margin-Liquidation-Level
elif trading_mode == TradingMode.FUTURES: elif trading_mode == TradingMode.FUTURES:
exception("kraken", trading_mode, collateral) exception("kraken", trading_mode, collateral, margin_mode)
# If nothing was returned # If nothing was returned
exception("kraken", trading_mode, collateral) exception("kraken", trading_mode, collateral, margin_mode)
def ftx( def ftx(
open_rate: float, open_rate: float,
is_short: bool, is_short: bool,
leverage: float, leverage: float,
margin_mode: MarginMode,
trading_mode: TradingMode, trading_mode: TradingMode,
collateral: Collateral collateral: Collateral
): ):
""" """
Calculates the liquidation price on FTX Calculates the liquidation price on FTX
:param name: Name of the exchange :param open_rate: open_rate
:param is_short: true or false
:param leverage: leverage in float
:param margin_mode: one-way or hedge
:param trading_mode: spot, margin, futures :param trading_mode: spot, margin, futures
:param collateral: cross, isolated :param collateral: cross, isolated
""" """
if collateral == Collateral.CROSS: if collateral == Collateral.CROSS:
# TODO-lev: Additional arguments, fill in formulas # TODO-lev: Additional arguments, fill in formulas
exception("ftx", trading_mode, collateral) exception("ftx", trading_mode, collateral, margin_mode)
# If nothing was returned # If nothing was returned
exception("ftx", trading_mode, collateral) exception("ftx", trading_mode, collateral, margin_mode)