Simplify liquidation price calculation

This commit is contained in:
Matthias 2022-02-28 19:45:15 +01:00
parent ab46476e63
commit 79538368db
4 changed files with 22 additions and 19 deletions

View File

@ -2055,23 +2055,23 @@ class Exchange:
except ccxt.BaseError as e:
raise OperationalException(e) from e
def leverage_prep(
def get_interest_rate(self) -> float:
"""
Calculate interest rate - necessary for Margin trading.
"""
return 0.0
def get_liquidation_price(
self,
pair: str,
open_rate: float,
amount: float, # quote currency, includes leverage
leverage: float,
is_short: bool
) -> Tuple[float, Optional[float]]:
) -> Optional[float]:
# if TradingMode == TradingMode.MARGIN:
# interest_rate = self.get_interest_rate(
# pair=pair,
# open_rate=open_rate,
# is_short=is_short
# )
if self.trading_mode == TradingMode.SPOT:
return (0.0, None)
if self.trading_mode in (TradingMode.SPOT, TradingMode.MARGIN):
return None
elif (
self.margin_mode == MarginMode.ISOLATED and
self.trading_mode == TradingMode.FUTURES
@ -2086,7 +2086,7 @@ class Exchange:
mm_ex_1=0.0,
upnl_ex_1=0.0,
)
return (0.0, isolated_liq)
return isolated_liq
else:
raise OperationalException(
"Freqtrade only supports isolated futures for leverage trading")
@ -2231,7 +2231,7 @@ class Exchange:
return 0.0
@retrier
def get_liquidation_price(
def get_or_calculate_liquidation_price(
self,
pair: str,
# Dry-run

View File

@ -19,7 +19,7 @@ from freqtrade.edge import Edge
from freqtrade.enums import (MarginMode, RPCMessageType, RunMode, SellType, SignalDirection, State,
TradingMode)
from freqtrade.exceptions import (DependencyException, ExchangeError, InsufficientFundsError,
InvalidOrderException, OperationalException, PricingError)
InvalidOrderException, PricingError)
from freqtrade.exchange import timeframe_to_minutes, timeframe_to_seconds
from freqtrade.misc import safe_value_fallback, safe_value_fallback2
from freqtrade.mixins import LoggingMixin
@ -688,13 +688,14 @@ class FreqtradeBot(LoggingMixin):
amount = safe_value_fallback(order, 'filled', 'amount')
enter_limit_filled_price = safe_value_fallback(order, 'average', 'price')
interest_rate, isolated_liq = self.exchange.leverage_prep(
isolated_liq = self.exchange.get_liquidation_price(
leverage=leverage,
pair=pair,
amount=amount,
open_rate=enter_limit_filled_price,
is_short=is_short
)
interest_rate = self.exchange.get_interest_rate()
# Fee is applied twice because we make a LIMIT_BUY and LIMIT_SELL
fee = self.exchange.get_fee(symbol=pair, taker_or_maker='maker')

View File

@ -666,13 +666,16 @@ class Backtesting:
self.order_id_counter += 1
amount = round((stake_amount / propose_rate) * leverage, 8)
is_short = (direction == 'short')
(interest_rate, isolated_liq) = self.exchange.leverage_prep(
isolated_liq = self.exchange.get_liquidation_price(
pair=pair,
open_rate=propose_rate,
amount=amount,
leverage=leverage,
is_short=is_short,
)
# Necessary for Margin trading. Disabled until support is enabled.
# interest_rate = self.exchange.get_interest_rate()
if trade is None:
# Enter trade
self.trade_id_counter += 1
@ -694,7 +697,7 @@ class Backtesting:
is_short=is_short,
trading_mode=self.trading_mode,
leverage=leverage,
interest_rate=interest_rate,
# interest_rate=interest_rate,
orders=[],
)

View File

@ -4560,7 +4560,7 @@ def test__get_params(mocker, default_conf, exchange_name):
# (False, 'futures', 'okx', 'isolated', 8.085708510208207),
]
)
def test_leverage_prep(
def test_get_liquidation_price(
mocker,
default_conf_usdt,
is_short,
@ -4637,14 +4637,13 @@ def test_leverage_prep(
# default_conf_usdt.update({
# "dry_run": False,
# })
(interest, liq) = exchange.leverage_prep(
liq = exchange.get_liquidation_price(
pair='ETH/USDT:USDT',
open_rate=open_rate,
amount=amount,
leverage=leverage,
is_short=is_short,
)
assert interest == 0.0
if expected_liq is None:
assert liq is None
else: