bybit: Initial implementation liquidation calculation
This commit is contained in:
parent
93ce963e9b
commit
31745a9dc2
@ -3,6 +3,7 @@ import logging
|
||||
from typing import Any, Dict, List, Optional, Tuple
|
||||
|
||||
from freqtrade.enums import MarginMode, TradingMode
|
||||
from freqtrade.exceptions import OperationalException
|
||||
from freqtrade.exchange import Exchange
|
||||
from freqtrade.exchange.exchange_utils import timeframe_to_msecs
|
||||
|
||||
@ -80,3 +81,65 @@ class Bybit(Exchange):
|
||||
# Convert funding rate to candle pattern
|
||||
data = [[x['timestamp'], x['fundingRate'], 0, 0, 0, 0] for x in data]
|
||||
return data
|
||||
|
||||
def dry_run_liquidation_price(
|
||||
self,
|
||||
pair: str,
|
||||
open_rate: float, # Entry price of position
|
||||
is_short: bool,
|
||||
amount: float,
|
||||
stake_amount: float,
|
||||
leverage: 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:
|
||||
bybit:
|
||||
https://www.bybithelp.com/HelpCenterKnowledge/bybitHC_Article?language=en_US&id=000001067
|
||||
|
||||
Long:
|
||||
Liquidation Price = (
|
||||
Entry Price * (1 - Initial Margin Rate + Maintenance Margin Rate)
|
||||
- Extra Margin Added/ Contract)
|
||||
Short:
|
||||
Liquidation Price = (
|
||||
Entry Price * (1 + Initial Margin Rate - Maintenance Margin Rate)
|
||||
+ Extra Margin Added/ Contract)
|
||||
|
||||
Implementation Note: Extra margin is currently not used.
|
||||
|
||||
:param pair: Pair to calculate liquidation price for
|
||||
:param open_rate: Entry price of position
|
||||
:param is_short: True if the trade is a short, false otherwise
|
||||
:param amount: Absolute value of position size incl. leverage (in base currency)
|
||||
:param stake_amount: Stake amount - Collateral in settle currency.
|
||||
:param leverage: Leverage used for this position.
|
||||
: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
|
||||
"""
|
||||
|
||||
market = self.markets[pair]
|
||||
mm_ratio, _ = self.get_maintenance_ratio_and_amt(pair, stake_amount)
|
||||
|
||||
if self.trading_mode == TradingMode.FUTURES and self.margin_mode == MarginMode.ISOLATED:
|
||||
|
||||
if market['inverse']:
|
||||
raise OperationalException(
|
||||
"Freqtrade does not yet support inverse contracts")
|
||||
initial_margin_rate = 1 / leverage
|
||||
|
||||
# See docstring - ignores extra margin!
|
||||
if is_short:
|
||||
return open_rate * (1 + initial_margin_rate - mm_ratio)
|
||||
else:
|
||||
return open_rate * (1 - initial_margin_rate + mm_ratio)
|
||||
|
||||
else:
|
||||
raise OperationalException(
|
||||
"Freqtrade only supports isolated futures for leverage trading")
|
||||
|
@ -5115,7 +5115,7 @@ def test_get_liquidation_price1(mocker, default_conf):
|
||||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize('liquidation_buffer', [0.0, 0.05])
|
||||
@pytest.mark.parametrize('liquidation_buffer', [0.0])
|
||||
@pytest.mark.parametrize(
|
||||
"is_short,trading_mode,exchange_name,margin_mode,leverage,open_rate,amount,expected_liq", [
|
||||
(False, 'spot', 'binance', '', 5.0, 10.0, 1.0, None),
|
||||
@ -5144,6 +5144,16 @@ def test_get_liquidation_price1(mocker, default_conf):
|
||||
(False, 'futures', 'gateio', 'isolated', 5.0, 10.0, 1.0, 8.085708510208207),
|
||||
(False, 'futures', 'gateio', 'isolated', 3.0, 10.0, 1.0, 6.738090425173506),
|
||||
(False, 'futures', 'okx', 'isolated', 3.0, 10.0, 1.0, 6.738090425173506),
|
||||
# bybit, long
|
||||
(False, 'futures', 'bybit', 'isolated', 1.0, 10.0, 1.0, 0.1),
|
||||
(False, 'futures', 'bybit', 'isolated', 3.0, 10.0, 1.0, 6.7666666),
|
||||
(False, 'futures', 'bybit', 'isolated', 5.0, 10.0, 1.0, 8.1),
|
||||
(False, 'futures', 'bybit', 'isolated', 10.0, 10.0, 1.0, 9.1),
|
||||
# bybit, short
|
||||
(True, 'futures', 'bybit', 'isolated', 1.0, 10.0, 1.0, 19.9),
|
||||
(True, 'futures', 'bybit', 'isolated', 3.0, 10.0, 1.0, 13.233333),
|
||||
(True, 'futures', 'bybit', 'isolated', 5.0, 10.0, 1.0, 11.9),
|
||||
(True, 'futures', 'bybit', 'isolated', 10.0, 10.0, 1.0, 10.9),
|
||||
]
|
||||
)
|
||||
def test_get_liquidation_price(
|
||||
|
Loading…
Reference in New Issue
Block a user