Move leverage_prep calculations to exchange class
This commit is contained in:
		| @@ -2055,6 +2055,42 @@ class Exchange: | ||||
|         except ccxt.BaseError as e: | ||||
|             raise OperationalException(e) from e | ||||
|  | ||||
|     def leverage_prep( | ||||
|             self, | ||||
|             pair: str, | ||||
|             open_rate: float, | ||||
|             amount: float,  # quote currency, includes leverage | ||||
|             leverage: float, | ||||
|             is_short: bool | ||||
|     ) -> Tuple[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) | ||||
|         elif ( | ||||
|             self.margin_mode == MarginMode.ISOLATED and | ||||
|             self.trading_mode == TradingMode.FUTURES | ||||
|         ): | ||||
|             wallet_balance = (amount * open_rate) / leverage | ||||
|             isolated_liq = self.get_liquidation_price( | ||||
|                 pair=pair, | ||||
|                 open_rate=open_rate, | ||||
|                 is_short=is_short, | ||||
|                 position=amount, | ||||
|                 wallet_balance=wallet_balance, | ||||
|                 mm_ex_1=0.0, | ||||
|                 upnl_ex_1=0.0, | ||||
|             ) | ||||
|             return (0.0, isolated_liq) | ||||
|         else: | ||||
|             raise OperationalException( | ||||
|                 "Freqtrade only supports isolated futures for leverage trading") | ||||
|  | ||||
|     def funding_fee_cutoff(self, open_date: datetime): | ||||
|         """ | ||||
|         :param open_date: The open date for a trade | ||||
|   | ||||
| @@ -578,42 +578,6 @@ class FreqtradeBot(LoggingMixin): | ||||
|             logger.info(f"Bids to asks delta for {pair} does not satisfy condition.") | ||||
|             return False | ||||
|  | ||||
|     def leverage_prep( | ||||
|         self, | ||||
|         pair: str, | ||||
|         open_rate: float, | ||||
|         amount: float,  # quote currency, includes leverage | ||||
|         leverage: float, | ||||
|         is_short: bool | ||||
|     ) -> Tuple[float, Optional[float]]: | ||||
|  | ||||
|         # if TradingMode == TradingMode.MARGIN: | ||||
|         #     interest_rate = self.exchange.get_interest_rate( | ||||
|         #         pair=pair, | ||||
|         #         open_rate=open_rate, | ||||
|         #         is_short=is_short | ||||
|         #     ) | ||||
|         if self.trading_mode == TradingMode.SPOT: | ||||
|             return (0.0, None) | ||||
|         elif ( | ||||
|             self.margin_mode == MarginMode.ISOLATED and | ||||
|             self.trading_mode == TradingMode.FUTURES | ||||
|         ): | ||||
|             wallet_balance = (amount * open_rate)/leverage | ||||
|             isolated_liq = self.exchange.get_liquidation_price( | ||||
|                 pair=pair, | ||||
|                 open_rate=open_rate, | ||||
|                 is_short=is_short, | ||||
|                 position=amount, | ||||
|                 wallet_balance=wallet_balance, | ||||
|                 mm_ex_1=0.0, | ||||
|                 upnl_ex_1=0.0, | ||||
|             ) | ||||
|             return (0.0, isolated_liq) | ||||
|         else: | ||||
|             raise OperationalException( | ||||
|                 "Freqtrade only supports isolated futures for leverage trading") | ||||
|  | ||||
|     def execute_entry( | ||||
|         self, | ||||
|         pair: str, | ||||
| @@ -724,7 +688,7 @@ 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.leverage_prep( | ||||
|         interest_rate, isolated_liq = self.exchange.leverage_prep( | ||||
|             leverage=leverage, | ||||
|             pair=pair, | ||||
|             amount=amount, | ||||
|   | ||||
| @@ -592,42 +592,6 @@ class Backtesting: | ||||
|         else: | ||||
|             return self._get_sell_trade_entry_for_candle(trade, sell_row) | ||||
|  | ||||
|     def _leverage_prep( | ||||
|         self, | ||||
|         pair: str, | ||||
|         open_rate: float, | ||||
|         amount: float,  # quote currency, includes leverage | ||||
|         leverage: float, | ||||
|         is_short: bool | ||||
|     ) -> Tuple[float, Optional[float]]: | ||||
|  | ||||
|         # if TradingMode == TradingMode.MARGIN: | ||||
|         #     interest_rate = self.exchange.get_interest_rate( | ||||
|         #         pair=pair, | ||||
|         #         open_rate=open_rate, | ||||
|         #         is_short=is_short | ||||
|         #     ) | ||||
|         if self.trading_mode == TradingMode.SPOT: | ||||
|             return (0.0, None) | ||||
|         elif ( | ||||
|             self.margin_mode == MarginMode.ISOLATED and | ||||
|             self.trading_mode == TradingMode.FUTURES | ||||
|         ): | ||||
|             wallet_balance = (amount * open_rate)/leverage | ||||
|             isolated_liq = self.exchange.get_liquidation_price( | ||||
|                 pair=pair, | ||||
|                 open_rate=open_rate, | ||||
|                 is_short=is_short, | ||||
|                 position=amount, | ||||
|                 wallet_balance=wallet_balance, | ||||
|                 mm_ex_1=0.0, | ||||
|                 upnl_ex_1=0.0, | ||||
|             ) | ||||
|             return (0.0, isolated_liq) | ||||
|         else: | ||||
|             raise OperationalException( | ||||
|                 "Freqtrade only supports isolated futures for leverage trading") | ||||
|  | ||||
|     def _enter_trade(self, pair: str, row: Tuple, direction: str, | ||||
|                      stake_amount: Optional[float] = None, | ||||
|                      trade: Optional[LocalTrade] = None) -> Optional[LocalTrade]: | ||||
| @@ -702,7 +666,7 @@ class Backtesting: | ||||
|             self.order_id_counter += 1 | ||||
|             amount = round((stake_amount / propose_rate) * leverage, 8) | ||||
|             is_short = (direction == 'short') | ||||
|             (interest_rate, isolated_liq) = self._leverage_prep( | ||||
|             (interest_rate, isolated_liq) = self.exchange.leverage_prep( | ||||
|                 pair=pair, | ||||
|                 open_rate=propose_rate, | ||||
|                 amount=amount, | ||||
|   | ||||
| @@ -4527,3 +4527,127 @@ def test__get_params(mocker, default_conf, exchange_name): | ||||
|         time_in_force='ioc', | ||||
|         leverage=3.0, | ||||
|     ) == params2 | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('liquidation_buffer', [0.0, 0.05]) | ||||
| @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), | ||||
|         (True, 'spot', 'binance', '', 5.0,  10.0, 1.0, None), | ||||
|         (False, 'spot', 'gateio', '', 5.0,  10.0, 1.0, None), | ||||
|         (True, 'spot', 'gateio', '', 5.0,  10.0, 1.0, None), | ||||
|         (False, 'spot', 'okx', '', 5.0,  10.0, 1.0, None), | ||||
|         (True, 'spot', 'okx', '', 5.0,  10.0, 1.0, None), | ||||
|         # Binance, short | ||||
|         (True, 'futures', 'binance', 'isolated', 5.0, 10.0, 1.0, 11.89108910891089), | ||||
|         (True, 'futures', 'binance', 'isolated', 3.0, 10.0, 1.0, 13.211221122079207), | ||||
|         (True, 'futures', 'binance', 'isolated', 5.0, 8.0, 1.0, 9.514851485148514), | ||||
|         (True, 'futures', 'binance', 'isolated', 5.0, 10.0, 0.6, 12.557755775577558), | ||||
|         # Binance, long | ||||
|         (False, 'futures', 'binance', 'isolated', 5, 10, 1.0, 8.070707070707071), | ||||
|         (False, 'futures', 'binance', 'isolated', 5, 8, 1.0, 6.454545454545454), | ||||
|         (False, 'futures', 'binance', 'isolated', 3, 10, 1.0, 6.717171717171718), | ||||
|         (False, 'futures', 'binance', 'isolated', 5, 10, 0.6, 7.39057239057239), | ||||
|         # Gateio/okx, short | ||||
|         (True, 'futures', 'gateio', 'isolated', 5, 10, 1.0, 11.87413417771621), | ||||
|         (True, 'futures', 'gateio', 'isolated', 5, 10, 2.0, 11.87413417771621), | ||||
|         (True, 'futures', 'gateio', 'isolated', 3, 10, 1.0, 13.476180850346978), | ||||
|         (True, 'futures', 'gateio', 'isolated', 5, 8, 1.0, 9.499307342172967), | ||||
|         # Gateio/okx, long | ||||
|         (False, 'futures', 'gateio', 'isolated', 5.0, 10.0, 1.0, 8.085708510208207), | ||||
|         (False, 'futures', 'gateio', 'isolated', 3.0, 10.0, 1.0, 6.738090425173506), | ||||
|         # (True, 'futures', 'okx', 'isolated', 11.87413417771621), | ||||
|         # (False, 'futures', 'okx', 'isolated', 8.085708510208207), | ||||
|     ] | ||||
| ) | ||||
| def test_leverage_prep( | ||||
|     mocker, | ||||
|     default_conf_usdt, | ||||
|     is_short, | ||||
|     trading_mode, | ||||
|     exchange_name, | ||||
|     margin_mode, | ||||
|     leverage, | ||||
|     open_rate, | ||||
|     amount, | ||||
|     expected_liq, | ||||
|     liquidation_buffer, | ||||
| ): | ||||
|     """ | ||||
|     position = 0.2 * 5 | ||||
|     wb: wallet balance (stake_amount if isolated) | ||||
|     cum_b: maintenance amount | ||||
|     side_1: -1 if is_short else 1 | ||||
|     ep1: entry price | ||||
|     mmr_b: maintenance margin ratio | ||||
|  | ||||
|     Binance, Short | ||||
|     leverage = 5, open_rate = 10, amount = 1.0 | ||||
|         ((wb + cum_b) - (side_1 * position * ep1)) / ((position * mmr_b) - (side_1 * position)) | ||||
|         ((2 + 0.01) - ((-1) * 1 * 10)) / ((1 * 0.01) - ((-1) * 1)) = 11.89108910891089 | ||||
|     leverage = 3, open_rate = 10, amount = 1.0 | ||||
|         ((3.3333333333 + 0.01) - ((-1) * 1.0 * 10)) / ((1.0 * 0.01) - ((-1) * 1.0)) = 13.2112211220 | ||||
|     leverage = 5, open_rate = 8, amount = 1.0 | ||||
|         ((1.6 + 0.01) - ((-1) * 1 * 8)) / ((1 * 0.01) - ((-1) * 1)) = 9.514851485148514 | ||||
|     leverage = 5, open_rate = 10, amount = 0.6 | ||||
|         ((1.6 + 0.01) - ((-1) * 0.6 * 10)) / ((0.6 * 0.01) - ((-1) * 0.6)) = 12.557755775577558 | ||||
|  | ||||
|     Binance, Long | ||||
|     leverage = 5, open_rate = 10, amount = 1.0 | ||||
|         ((wb + cum_b) - (side_1 * position * ep1)) / ((position * mmr_b) - (side_1 * position)) | ||||
|         ((2 + 0.01) - (1 * 1 * 10)) / ((1 * 0.01) - (1 * 1)) = 8.070707070707071 | ||||
|     leverage = 5, open_rate = 8, amount = 1.0 | ||||
|         ((1.6 + 0.01) - (1 * 1 * 8)) / ((1 * 0.01) - (1 * 1)) = 6.454545454545454 | ||||
|     leverage = 3, open_rate = 10, amount = 1.0 | ||||
|         ((2 + 0.01) - (1 * 0.6 * 10)) / ((0.6 * 0.01) - (1 * 0.6)) = 6.717171717171718 | ||||
|     leverage = 5, open_rate = 10, amount = 0.6 | ||||
|         ((1.6 + 0.01) - (1 * 0.6 * 10)) / ((0.6 * 0.01) - (1 * 0.6)) = 7.39057239057239 | ||||
|  | ||||
|     Gateio/Okx, Short | ||||
|     leverage = 5, open_rate = 10, amount = 1.0 | ||||
|         (open_rate + (wallet_balance / position)) / (1 + (mm_ratio + taker_fee_rate)) | ||||
|         (10 + (2 / 1.0)) / (1 + (0.01 + 0.0006)) = 11.87413417771621 | ||||
|     leverage = 5, open_rate = 10, amount = 2.0 | ||||
|         (10 + (4 / 2.0)) / (1 + (0.01 + 0.0006)) = 11.87413417771621 | ||||
|     leverage = 3, open_rate = 10, amount = 1.0 | ||||
|         (10 + (3.3333333333333 / 1.0)) / (1 - (0.01 + 0.0006)) = 13.476180850346978 | ||||
|     leverage = 5, open_rate = 8, amount = 1.0 | ||||
|         (8 + (1.6 / 1.0)) / (1 + (0.01 + 0.0006)) = 9.499307342172967 | ||||
|  | ||||
|     Gateio/Okx, Long | ||||
|     leverage = 5, open_rate = 10, amount = 1.0 | ||||
|         (open_rate - (wallet_balance / position)) / (1 - (mm_ratio + taker_fee_rate)) | ||||
|         (10 - (2 / 1)) / (1 - (0.01 + 0.0006)) = 8.085708510208207 | ||||
|     leverage = 5, open_rate = 10, amount = 2.0 | ||||
|         (10 - (4 / 2.0)) / (1 + (0.01 + 0.0006)) = 7.916089451810806 | ||||
|     leverage = 3, open_rate = 10, amount = 1.0 | ||||
|         (10 - (3.333333333333333333 / 1.0)) / (1 - (0.01 + 0.0006)) = 6.738090425173506 | ||||
|     leverage = 5, open_rate = 8, amount = 1.0 | ||||
|         (8 - (1.6 / 1.0)) / (1 + (0.01 + 0.0006)) = 6.332871561448645 | ||||
|     """ | ||||
|     default_conf_usdt['liquidation_buffer'] = liquidation_buffer | ||||
|     default_conf_usdt['trading_mode'] = trading_mode | ||||
|     default_conf_usdt['exchange']['name'] = exchange_name | ||||
|     default_conf_usdt['margin_mode'] = margin_mode | ||||
|     mocker.patch('freqtrade.exchange.Gateio.validate_ordertypes') | ||||
|     exchange = get_patched_exchange(mocker, default_conf_usdt) | ||||
|  | ||||
|     exchange.get_maintenance_ratio_and_amt = MagicMock(return_value=(0.01, 0.01)) | ||||
|     exchange.name = exchange_name | ||||
|     # default_conf_usdt.update({ | ||||
|     #     "dry_run": False, | ||||
|     # }) | ||||
|     (interest, liq) = exchange.leverage_prep( | ||||
|         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: | ||||
|         buffer_amount = liquidation_buffer * abs(open_rate - expected_liq) | ||||
|         expected_liq = expected_liq - buffer_amount if is_short else expected_liq + buffer_amount | ||||
|         isclose(expected_liq, liq) | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
| import random | ||||
| from copy import deepcopy | ||||
| from datetime import datetime, timedelta, timezone | ||||
| from math import isclose | ||||
| from pathlib import Path | ||||
| from unittest.mock import MagicMock, PropertyMock | ||||
|  | ||||
| @@ -10,7 +11,6 @@ import numpy as np | ||||
| import pandas as pd | ||||
| import pytest | ||||
| from arrow import Arrow | ||||
| from math import isclose | ||||
|  | ||||
| from freqtrade import constants | ||||
| from freqtrade.commands.optimize_commands import setup_optimize_configuration, start_backtesting | ||||
|   | ||||
| @@ -4839,132 +4839,6 @@ def test_get_valid_price(mocker, default_conf_usdt) -> None: | ||||
|     assert valid_price_at_min_alwd < proposed_price | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('liquidation_buffer', [0.0, 0.05]) | ||||
| @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), | ||||
|         (True, 'spot', 'binance', '', 5.0,  10.0, 1.0, None), | ||||
|         (False, 'spot', 'gateio', '', 5.0,  10.0, 1.0, None), | ||||
|         (True, 'spot', 'gateio', '', 5.0,  10.0, 1.0, None), | ||||
|         (False, 'spot', 'okx', '', 5.0,  10.0, 1.0, None), | ||||
|         (True, 'spot', 'okx', '', 5.0,  10.0, 1.0, None), | ||||
|         # Binance, short | ||||
|         (True, 'futures', 'binance', 'isolated', 5.0, 10.0, 1.0, 11.89108910891089), | ||||
|         (True, 'futures', 'binance', 'isolated', 3.0, 10.0, 1.0, 13.211221122079207), | ||||
|         (True, 'futures', 'binance', 'isolated', 5.0, 8.0, 1.0, 9.514851485148514), | ||||
|         (True, 'futures', 'binance', 'isolated', 5.0, 10.0, 0.6, 12.557755775577558), | ||||
|         # Binance, long | ||||
|         (False, 'futures', 'binance', 'isolated', 5, 10, 1.0, 8.070707070707071), | ||||
|         (False, 'futures', 'binance', 'isolated', 5, 8, 1.0, 6.454545454545454), | ||||
|         (False, 'futures', 'binance', 'isolated', 3, 10, 1.0, 6.717171717171718), | ||||
|         (False, 'futures', 'binance', 'isolated', 5, 10, 0.6, 7.39057239057239), | ||||
|         # Gateio/okx, short | ||||
|         (True, 'futures', 'gateio', 'isolated', 5, 10, 1.0, 11.87413417771621), | ||||
|         (True, 'futures', 'gateio', 'isolated', 5, 10, 2.0, 11.87413417771621), | ||||
|         (True, 'futures', 'gateio', 'isolated', 3, 10, 1.0, 13.476180850346978), | ||||
|         (True, 'futures', 'gateio', 'isolated', 5, 8, 1.0, 9.499307342172967), | ||||
|         # Gateio/okx, long | ||||
|         (False, 'futures', 'gateio', 'isolated', 5.0, 10.0, 1.0, 8.085708510208207), | ||||
|         (False, 'futures', 'gateio', 'isolated', 3.0, 10.0, 1.0, 6.738090425173506), | ||||
|         # (True, 'futures', 'okx', 'isolated', 11.87413417771621), | ||||
|         # (False, 'futures', 'okx', 'isolated', 8.085708510208207), | ||||
|     ] | ||||
| ) | ||||
| def test_leverage_prep( | ||||
|     mocker, | ||||
|     default_conf_usdt, | ||||
|     is_short, | ||||
|     trading_mode, | ||||
|     exchange_name, | ||||
|     margin_mode, | ||||
|     leverage, | ||||
|     open_rate, | ||||
|     amount, | ||||
|     expected_liq, | ||||
|     liquidation_buffer, | ||||
| ): | ||||
|     """ | ||||
|     position = 0.2 * 5 | ||||
|     wb: wallet balance (stake_amount if isolated) | ||||
|     cum_b: maintenance amount | ||||
|     side_1: -1 if is_short else 1 | ||||
|     ep1: entry price | ||||
|     mmr_b: maintenance margin ratio | ||||
|  | ||||
|     Binance, Short | ||||
|     leverage = 5, open_rate = 10, amount = 1.0 | ||||
|         ((wb + cum_b) - (side_1 * position * ep1)) / ((position * mmr_b) - (side_1 * position)) | ||||
|         ((2 + 0.01) - ((-1) * 1 * 10)) / ((1 * 0.01) - ((-1) * 1)) = 11.89108910891089 | ||||
|     leverage = 3, open_rate = 10, amount = 1.0 | ||||
|         ((3.3333333333 + 0.01) - ((-1) * 1.0 * 10)) / ((1.0 * 0.01) - ((-1) * 1.0)) = 13.2112211220 | ||||
|     leverage = 5, open_rate = 8, amount = 1.0 | ||||
|         ((1.6 + 0.01) - ((-1) * 1 * 8)) / ((1 * 0.01) - ((-1) * 1)) = 9.514851485148514 | ||||
|     leverage = 5, open_rate = 10, amount = 0.6 | ||||
|         ((1.6 + 0.01) - ((-1) * 0.6 * 10)) / ((0.6 * 0.01) - ((-1) * 0.6)) = 12.557755775577558 | ||||
|  | ||||
|     Binance, Long | ||||
|     leverage = 5, open_rate = 10, amount = 1.0 | ||||
|         ((wb + cum_b) - (side_1 * position * ep1)) / ((position * mmr_b) - (side_1 * position)) | ||||
|         ((2 + 0.01) - (1 * 1 * 10)) / ((1 * 0.01) - (1 * 1)) = 8.070707070707071 | ||||
|     leverage = 5, open_rate = 8, amount = 1.0 | ||||
|         ((1.6 + 0.01) - (1 * 1 * 8)) / ((1 * 0.01) - (1 * 1)) = 6.454545454545454 | ||||
|     leverage = 3, open_rate = 10, amount = 1.0 | ||||
|         ((2 + 0.01) - (1 * 0.6 * 10)) / ((0.6 * 0.01) - (1 * 0.6)) = 6.717171717171718 | ||||
|     leverage = 5, open_rate = 10, amount = 0.6 | ||||
|         ((1.6 + 0.01) - (1 * 0.6 * 10)) / ((0.6 * 0.01) - (1 * 0.6)) = 7.39057239057239 | ||||
|  | ||||
|     Gateio/Okx, Short | ||||
|     leverage = 5, open_rate = 10, amount = 1.0 | ||||
|         (open_rate + (wallet_balance / position)) / (1 + (mm_ratio + taker_fee_rate)) | ||||
|         (10 + (2 / 1.0)) / (1 + (0.01 + 0.0006)) = 11.87413417771621 | ||||
|     leverage = 5, open_rate = 10, amount = 2.0 | ||||
|         (10 + (4 / 2.0)) / (1 + (0.01 + 0.0006)) = 11.87413417771621 | ||||
|     leverage = 3, open_rate = 10, amount = 1.0 | ||||
|         (10 + (3.3333333333333 / 1.0)) / (1 - (0.01 + 0.0006)) = 13.476180850346978 | ||||
|     leverage = 5, open_rate = 8, amount = 1.0 | ||||
|         (8 + (1.6 / 1.0)) / (1 + (0.01 + 0.0006)) = 9.499307342172967 | ||||
|  | ||||
|     Gateio/Okx, Long | ||||
|     leverage = 5, open_rate = 10, amount = 1.0 | ||||
|         (open_rate - (wallet_balance / position)) / (1 - (mm_ratio + taker_fee_rate)) | ||||
|         (10 - (2 / 1)) / (1 - (0.01 + 0.0006)) = 8.085708510208207 | ||||
|     leverage = 5, open_rate = 10, amount = 2.0 | ||||
|         (10 - (4 / 2.0)) / (1 + (0.01 + 0.0006)) = 7.916089451810806 | ||||
|     leverage = 3, open_rate = 10, amount = 1.0 | ||||
|         (10 - (3.333333333333333333 / 1.0)) / (1 - (0.01 + 0.0006)) = 6.738090425173506 | ||||
|     leverage = 5, open_rate = 8, amount = 1.0 | ||||
|         (8 - (1.6 / 1.0)) / (1 + (0.01 + 0.0006)) = 6.332871561448645 | ||||
|     """ | ||||
|     default_conf_usdt['liquidation_buffer'] = liquidation_buffer | ||||
|     default_conf_usdt['trading_mode'] = trading_mode | ||||
|     default_conf_usdt['exchange']['name'] = exchange_name | ||||
|     default_conf_usdt['margin_mode'] = margin_mode | ||||
|     mocker.patch('freqtrade.exchange.Gateio.validate_ordertypes') | ||||
|     patch_RPCManager(mocker) | ||||
|     patch_exchange(mocker, id=exchange_name) | ||||
|     freqtrade = FreqtradeBot(default_conf_usdt) | ||||
|  | ||||
|     freqtrade.exchange.get_maintenance_ratio_and_amt = MagicMock(return_value=(0.01, 0.01)) | ||||
|     freqtrade.exchange.name = exchange_name | ||||
|     # default_conf_usdt.update({ | ||||
|     #     "dry_run": False, | ||||
|     # }) | ||||
|     (interest, liq) = freqtrade.leverage_prep( | ||||
|         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: | ||||
|         buffer_amount = liquidation_buffer * abs(open_rate - expected_liq) | ||||
|         expected_liq = expected_liq - buffer_amount if is_short else expected_liq + buffer_amount | ||||
|         isclose(expected_liq, liq) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('trading_mode,calls,t1,t2', [ | ||||
|     ('spot', 0, "2021-09-01 00:00:00", "2021-09-01 08:00:00"), | ||||
|     ('margin', 0, "2021-09-01 00:00:00", "2021-09-01 08:00:00"), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user