cleaned up liquidation price methods
This commit is contained in:
		| @@ -277,18 +277,15 @@ class Binance(Exchange): | |||||||
|         # The lowest notional_floor for any pair in loadLeverageBrackets is always 0 because it |         # The lowest notional_floor for any pair in loadLeverageBrackets is always 0 because it | ||||||
|         # describes the min amount for a bracket, and the lowest bracket will always go down to 0 |         # describes the min amount for a bracket, and the lowest bracket will always go down to 0 | ||||||
|  |  | ||||||
|     def liquidation_price_helper( |     def liquidation_price( | ||||||
|         self, |         self, | ||||||
|         open_rate: float,   # Entry price of position |         open_rate: float,   # Entry price of position | ||||||
|         is_short: bool, |         is_short: bool, | ||||||
|         leverage: float, |  | ||||||
|         mm_ratio: float, |         mm_ratio: float, | ||||||
|         position: float,  # Absolute value of position size |         position: float,  # Absolute value of position size | ||||||
|         trading_mode: TradingMode, |         wallet_balance: float,  # Or margin balance | ||||||
|         collateral: Collateral, |  | ||||||
|         maintenance_amt: Optional[float] = None,  # (Binance) |  | ||||||
|         wallet_balance: Optional[float] = None,  # (Binance and Gateio) |  | ||||||
|         taker_fee_rate: Optional[float] = None,  # (Gateio & Okex) |         taker_fee_rate: Optional[float] = None,  # (Gateio & Okex) | ||||||
|  |         maintenance_amt: Optional[float] = None,  # (Binance) | ||||||
|         mm_ex_1: Optional[float] = 0.0,  # (Binance) Cross only |         mm_ex_1: Optional[float] = 0.0,  # (Binance) Cross only | ||||||
|         upnl_ex_1: Optional[float] = 0.0,  # (Binance) Cross only |         upnl_ex_1: Optional[float] = 0.0,  # (Binance) Cross only | ||||||
|     ) -> Optional[float]: |     ) -> Optional[float]: | ||||||
| @@ -299,19 +296,15 @@ class Binance(Exchange): | |||||||
|         :param exchange_name: |         :param exchange_name: | ||||||
|         :param open_rate: (EP1) Entry price of position |         :param open_rate: (EP1) Entry price of position | ||||||
|         :param is_short: True if the trade is a short, false otherwise |         :param is_short: True if the trade is a short, false otherwise | ||||||
|         :param leverage: The amount of leverage on the trade |  | ||||||
|         :param mm_ratio: (MMR) |         :param mm_ratio: (MMR) | ||||||
|             # Binance's formula specifies maintenance margin rate which is mm_ratio * 100% |             # Binance's formula specifies maintenance margin rate which is mm_ratio * 100% | ||||||
|         :param position: Absolute value of position size (in base currency) |         :param position: Absolute value of position size (in base currency) | ||||||
|         :param trading_mode: SPOT, MARGIN, FUTURES, etc. |  | ||||||
|         :param collateral: Either ISOLATED or CROSS |  | ||||||
|         :param maintenance_amt: (CUM) Maintenance Amount of position |         :param maintenance_amt: (CUM) Maintenance Amount of position | ||||||
|         :param wallet_balance: (WB) |         :param wallet_balance: (WB) | ||||||
|             Cross-Margin Mode: crossWalletBalance |             Cross-Margin Mode: crossWalletBalance | ||||||
|             Isolated-Margin Mode: isolatedWalletBalance |             Isolated-Margin Mode: isolatedWalletBalance | ||||||
|  |         :param taker_fee_rate:  # * Not required by Binance | ||||||
|         # * Not required by Binance |         :param maintenance_amt: | ||||||
|         :param taker_fee_rate: |  | ||||||
|  |  | ||||||
|         # * Only required for Cross |         # * Only required for Cross | ||||||
|         :param mm_ex_1: (TMM) |         :param mm_ex_1: (TMM) | ||||||
| @@ -321,31 +314,32 @@ class Binance(Exchange): | |||||||
|             Cross-Margin Mode: Unrealized PNL of all other contracts, excluding Contract 1. |             Cross-Margin Mode: Unrealized PNL of all other contracts, excluding Contract 1. | ||||||
|             Isolated-Margin Mode: 0 |             Isolated-Margin Mode: 0 | ||||||
|         """ |         """ | ||||||
|         if trading_mode == TradingMode.SPOT: |         if self.trading_mode == TradingMode.SPOT: | ||||||
|             return None |             return None | ||||||
|  |         elif (self.collateral is None): | ||||||
|  |             raise OperationalException('Binance.collateral must be set for liquidation_price') | ||||||
|  |  | ||||||
|         if not collateral: |         if (maintenance_amt is None): | ||||||
|             raise OperationalException( |             raise OperationalException( | ||||||
|                 "Parameter collateral is required by liquidation_price when trading_mode is " |                 f"Parameter maintenance_amt is required by Binance.liquidation_price" | ||||||
|                 f"{trading_mode}" |                 f"for {self.collateral.value} {self.trading_mode.value}" | ||||||
|             ) |             ) | ||||||
|         if ( |  | ||||||
|             (wallet_balance is None or maintenance_amt is None or position is None) or |         if (self.collateral == Collateral.CROSS and (mm_ex_1 is None or upnl_ex_1 is None)): | ||||||
|             (collateral == Collateral.CROSS and (mm_ex_1 is None or upnl_ex_1 is None)) |  | ||||||
|         ): |  | ||||||
|             required_params = "wallet_balance, maintenance_amt, position" |  | ||||||
|             if collateral == Collateral.CROSS: |  | ||||||
|                 required_params += ", mm_ex_1, upnl_ex_1" |  | ||||||
|             raise OperationalException( |             raise OperationalException( | ||||||
|                 f"Parameters {required_params} are required by Binance.liquidation_price" |                 f"Parameters mm_ex_1 and upnl_ex_1 are required by Binance.liquidation_price" | ||||||
|                 f"for {collateral.name} {trading_mode.name}" |                 f"for {self.collateral.value} {self.trading_mode.value}" | ||||||
|             ) |             ) | ||||||
|  |  | ||||||
|         side_1 = -1 if is_short else 1 |         side_1 = -1 if is_short else 1 | ||||||
|         position = abs(position) |         position = abs(position) | ||||||
|         cross_vars = upnl_ex_1 - mm_ex_1 if collateral == Collateral.CROSS else 0.0  # type: ignore |         cross_vars = ( | ||||||
|  |             upnl_ex_1 - mm_ex_1  # type: ignore | ||||||
|  |             if self.collateral == Collateral.CROSS else | ||||||
|  |             0.0 | ||||||
|  |         ) | ||||||
|  |  | ||||||
|         if trading_mode == TradingMode.FUTURES: |         if self.trading_mode == TradingMode.FUTURES: | ||||||
|             return ( |             return ( | ||||||
|                 ( |                 ( | ||||||
|                     (wallet_balance + cross_vars + maintenance_amt) - |                     (wallet_balance + cross_vars + maintenance_amt) - | ||||||
| @@ -356,4 +350,4 @@ class Binance(Exchange): | |||||||
|             ) |             ) | ||||||
|  |  | ||||||
|         raise OperationalException( |         raise OperationalException( | ||||||
|             f"Binance does not support {collateral.value} Mode {trading_mode.value} trading ") |             f"Binance does not support {self.collateral.value} {self.trading_mode.value} trading") | ||||||
|   | |||||||
| @@ -2018,135 +2018,62 @@ class Exchange: | |||||||
|         self, |         self, | ||||||
|         open_rate: float,   # Entry price of position |         open_rate: float,   # Entry price of position | ||||||
|         is_short: bool, |         is_short: bool, | ||||||
|         leverage: float, |  | ||||||
|         mm_ratio: float, |         mm_ratio: float, | ||||||
|         position: float,  # Absolute value of position size |         position: float,  # Absolute value of position size | ||||||
|         trading_mode: TradingMode, |         wallet_balance: float,  # Or margin balance | ||||||
|         collateral: Optional[Collateral] = Collateral.ISOLATED, |  | ||||||
|         maintenance_amt: Optional[float] = None,  # (Binance) |  | ||||||
|         wallet_balance: Optional[float] = None,  # (Binance and Gateio) |  | ||||||
|         taker_fee_rate: Optional[float] = None,  # (Gateio & Okex) |         taker_fee_rate: Optional[float] = None,  # (Gateio & Okex) | ||||||
|  |         maintenance_amt: Optional[float] = None,  # (Binance) | ||||||
|         mm_ex_1: Optional[float] = 0.0,  # (Binance) Cross only |         mm_ex_1: Optional[float] = 0.0,  # (Binance) Cross only | ||||||
|         upnl_ex_1: Optional[float] = 0.0,  # (Binance) Cross only |         upnl_ex_1: Optional[float] = 0.0,  # (Binance) Cross only | ||||||
|     ) -> Optional[float]: |     ) -> Optional[float]: | ||||||
|         """ |         """ | ||||||
|  |         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 | ||||||
|  |  | ||||||
|         :param exchange_name: |         :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 is_short: True if the trade is a short, false otherwise | ||||||
|         :param leverage: The amount of leverage on the trade |  | ||||||
|         :param mm_ratio: (MMR) |  | ||||||
|             Okex: [assets in the position - (liability +interest) * mark price] / |  | ||||||
|                 (maintenance margin + liquidation fee) |  | ||||||
|             # * Note: Binance's formula specifies maintenance margin rate which is mm_ratio * 100% |  | ||||||
|         :param position: Absolute value of position size (in base currency) |         :param position: Absolute value of position size (in base currency) | ||||||
|  |         :param mm_ratio: | ||||||
|         :param trading_mode: SPOT, MARGIN, FUTURES, etc. |         :param trading_mode: SPOT, MARGIN, FUTURES, etc. | ||||||
|         :param collateral: Either ISOLATED or CROSS |         :param collateral: Either ISOLATED or CROSS | ||||||
|  |         :param wallet_balance: Amount of collateral in the wallet being used to trade | ||||||
|         # * Binance |  | ||||||
|         :param maintenance_amt: (CUM) Maintenance Amount of position |  | ||||||
|  |  | ||||||
|         # * Binance and Gateio |  | ||||||
|         :param wallet_balance: (WB) |  | ||||||
|             Cross-Margin Mode: crossWalletBalance |             Cross-Margin Mode: crossWalletBalance | ||||||
|             Isolated-Margin Mode: isolatedWalletBalance |             Isolated-Margin Mode: isolatedWalletBalance | ||||||
|  |  | ||||||
|         # * Gateio & Okex |  | ||||||
|         :param taker_fee_rate: |         :param taker_fee_rate: | ||||||
|  |  | ||||||
|         # * Cross only (Binance) |         # * Not required by Gateio or OKX | ||||||
|         :param mm_ex_1: (TMM) |         :param maintenance_amt: | ||||||
|             Cross-Margin Mode: Maintenance Margin of all other contracts, excluding Contract 1 |         :param mm_ex_1: | ||||||
|             Isolated-Margin Mode: 0 |         :param upnl_ex_1: | ||||||
|         :param upnl_ex_1: (UPNL) |  | ||||||
|             Cross-Margin Mode: Unrealized PNL of all other contracts, excluding Contract 1. |  | ||||||
|             Isolated-Margin Mode: 0 |  | ||||||
|         """ |         """ | ||||||
|         if trading_mode == TradingMode.SPOT: |         if self.trading_mode == TradingMode.SPOT: | ||||||
|             return None |             return None | ||||||
|  |         elif (self.collateral is None): | ||||||
|  |             raise OperationalException('Binance.collateral must be set for liquidation_price') | ||||||
|  |  | ||||||
|         if not collateral: |         if (not taker_fee_rate): | ||||||
|             raise OperationalException( |             raise OperationalException( | ||||||
|                 "Parameter collateral is required by liquidation_price when trading_mode is " |                 f"Parameter taker_fee_rate is required by {self.name}.liquidation_price" | ||||||
|                 f"{trading_mode}" |  | ||||||
|             ) |             ) | ||||||
|  |  | ||||||
|         return self.liquidation_price_helper( |         if self.trading_mode == TradingMode.FUTURES and self.collateral == Collateral.ISOLATED: | ||||||
|             open_rate=open_rate, |             # if is_inverse: | ||||||
|             is_short=is_short, |             #     raise OperationalException( | ||||||
|             leverage=leverage, |             #         "Freqtrade does not support inverse contracts at the moment") | ||||||
|             mm_ratio=mm_ratio, |  | ||||||
|             position=position, |  | ||||||
|             trading_mode=trading_mode, |  | ||||||
|             collateral=collateral, |  | ||||||
|             maintenance_amt=maintenance_amt, |  | ||||||
|             wallet_balance=wallet_balance, |  | ||||||
|             taker_fee_rate=taker_fee_rate, |  | ||||||
|             mm_ex_1=mm_ex_1, |  | ||||||
|             upnl_ex_1=upnl_ex_1, |  | ||||||
|         ) |  | ||||||
|  |  | ||||||
|         def liquidation_price_helper( |             value = wallet_balance / position | ||||||
|             self, |  | ||||||
|             open_rate: float,   # Entry price of position |  | ||||||
|             is_short: bool, |  | ||||||
|             leverage: float, |  | ||||||
|             mm_ratio: float, |  | ||||||
|             position: float,  # Absolute value of position size |  | ||||||
|             wallet_balance: float,  # Or margin balance |  | ||||||
|             trading_mode: TradingMode, |  | ||||||
|             collateral: Collateral, |  | ||||||
|             taker_fee_rate: Optional[float] = None,  # (Gateio & Okex) |  | ||||||
|             maintenance_amt: Optional[float] = None,  # (Binance) |  | ||||||
|             mm_ex_1: Optional[float] = 0.0,  # (Binance) Cross only |  | ||||||
|             upnl_ex_1: Optional[float] = 0.0,  # (Binance) Cross only |  | ||||||
|         ) -> Optional[float]: |  | ||||||
|             """ |  | ||||||
|             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 |  | ||||||
|  |  | ||||||
|             :param exchange_name: |             mm_ratio_taker = (mm_ratio + taker_fee_rate) | ||||||
|             :param open_rate: Entry price of position |             if is_short: | ||||||
|             :param is_short: True if the trade is a short, false otherwise |                 return (open_rate + value) / (1 + mm_ratio_taker) | ||||||
|             :param leverage: The amount of leverage on the trade |  | ||||||
|             :param position: Absolute value of position size (in base currency) |  | ||||||
|             :param mm_ratio: |  | ||||||
|             :param trading_mode: SPOT, MARGIN, FUTURES, etc. |  | ||||||
|             :param collateral: Either ISOLATED or CROSS |  | ||||||
|             :param wallet_balance: Amount of collateral in the wallet being used to trade |  | ||||||
|                 Cross-Margin Mode: crossWalletBalance |  | ||||||
|                 Isolated-Margin Mode: isolatedWalletBalance |  | ||||||
|             :param taker_fee_rate: |  | ||||||
|  |  | ||||||
|             # * Not required by Gateio or OKX |  | ||||||
|             :param maintenance_amt: |  | ||||||
|             :param mm_ex_1: |  | ||||||
|             :param upnl_ex_1: |  | ||||||
|             """ |  | ||||||
|             if trading_mode == TradingMode.SPOT: |  | ||||||
|                 return None |  | ||||||
|  |  | ||||||
|             if (not taker_fee_rate): |  | ||||||
|                 raise OperationalException( |  | ||||||
|                     f"Parameter taker_fee_rate is required by {self.name}.liquidation_price" |  | ||||||
|                 ) |  | ||||||
|  |  | ||||||
|             if trading_mode == TradingMode.FUTURES and collateral == Collateral.ISOLATED: |  | ||||||
|                 # if is_inverse: |  | ||||||
|                 #     raise OperationalException( |  | ||||||
|                 #         "Freqtrade does not support inverse contracts at the moment") |  | ||||||
|  |  | ||||||
|                 value = wallet_balance / position |  | ||||||
|  |  | ||||||
|                 mm_ratio_taker = (mm_ratio + taker_fee_rate) |  | ||||||
|                 if is_short: |  | ||||||
|                     return (open_rate + value) / (1 + mm_ratio_taker) |  | ||||||
|                 else: |  | ||||||
|                     return (open_rate - value) / (1 - mm_ratio_taker) |  | ||||||
|             else: |             else: | ||||||
|                 raise OperationalException( |                 return (open_rate - value) / (1 - mm_ratio_taker) | ||||||
|                     f"{self.name} does not support {collateral.value} {trading_mode.value}") |         else: | ||||||
|  |             raise OperationalException( | ||||||
|  |                 f"{self.name} does not support {self.collateral.value} {self.trading_mode.value}") | ||||||
|  |  | ||||||
|  |  | ||||||
| def is_exchange_known_ccxt(exchange_name: str, ccxt_module: CcxtModuleType = None) -> bool: | def is_exchange_known_ccxt(exchange_name: str, ccxt_module: CcxtModuleType = None) -> bool: | ||||||
|   | |||||||
| @@ -1,8 +1,6 @@ | |||||||
| import logging | import logging | ||||||
| from typing import Dict, List, Optional, Tuple | from typing import Dict, List, Tuple | ||||||
|  |  | ||||||
| from freqtrade.enums import Collateral, TradingMode | from freqtrade.enums import Collateral, TradingMode | ||||||
| from freqtrade.exceptions import OperationalException |  | ||||||
| from freqtrade.exchange import Exchange | from freqtrade.exchange import Exchange | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -626,16 +626,13 @@ class FreqtradeBot(LoggingMixin): | |||||||
|                 isolated_liq = self.exchange.liquidation_price( |                 isolated_liq = self.exchange.liquidation_price( | ||||||
|                     open_rate=open_rate, |                     open_rate=open_rate, | ||||||
|                     is_short=is_short, |                     is_short=is_short, | ||||||
|                     leverage=leverage, |                     mm_ratio=mm_ratio, | ||||||
|                     trading_mode=self.trading_mode, |  | ||||||
|                     collateral=Collateral.ISOLATED, |  | ||||||
|                     mm_ex_1=0.0, |  | ||||||
|                     upnl_ex_1=0.0, |  | ||||||
|                     position=amount, |                     position=amount, | ||||||
|                     wallet_balance=(amount * open_rate)/leverage,  # TODO: Update for cross |                     wallet_balance=(amount * open_rate)/leverage,  # TODO: Update for cross | ||||||
|  |                     taker_fee_rate=taker_fee_rate, | ||||||
|                     maintenance_amt=maintenance_amt, |                     maintenance_amt=maintenance_amt, | ||||||
|                     mm_ratio=mm_ratio, |                     mm_ex_1=0.0, | ||||||
|                     taker_fee_rate=taker_fee_rate |                     upnl_ex_1=0.0, | ||||||
|                 ) |                 ) | ||||||
|             else: |             else: | ||||||
|                 isolated_liq = self.exchange.get_liquidation_price(pair) |                 isolated_liq = self.exchange.get_liquidation_price(pair) | ||||||
|   | |||||||
| @@ -3626,6 +3626,8 @@ def test_get_liquidation_price(mocker, default_conf): | |||||||
|         exchange_has=MagicMock(return_value=True), |         exchange_has=MagicMock(return_value=True), | ||||||
|     ) |     ) | ||||||
|     default_conf['dry_run'] = False |     default_conf['dry_run'] = False | ||||||
|  |     default_conf['trading_mode'] = 'futures' | ||||||
|  |     default_conf['collateral'] = 'isolated' | ||||||
|  |  | ||||||
|     exchange = get_patched_exchange(mocker, default_conf, api_mock) |     exchange = get_patched_exchange(mocker, default_conf, api_mock) | ||||||
|     liq_price = exchange.get_liquidation_price('NEAR/USDT:USDT') |     liq_price = exchange.get_liquidation_price('NEAR/USDT:USDT') | ||||||
| @@ -3973,13 +3975,13 @@ def test__amount_to_contracts( | |||||||
|  |  | ||||||
| @pytest.mark.parametrize('exchange_name,open_rate,is_short,leverage,trading_mode,collateral', [ | @pytest.mark.parametrize('exchange_name,open_rate,is_short,leverage,trading_mode,collateral', [ | ||||||
|     # Bittrex |     # Bittrex | ||||||
|     ('bittrex', "2.0", False, "3.0", spot, None), |     ('bittrex', 2.0, False, 3.0, spot, None), | ||||||
|     ('bittrex', "2.0", False, "1.0", spot, cross), |     ('bittrex', 2.0, False, 1.0, spot, cross), | ||||||
|     ('bittrex', "2.0", True, "3.0", spot, isolated), |     ('bittrex', 2.0, True, 3.0, spot, isolated), | ||||||
|     # Binance |     # Binance | ||||||
|     ('binance', "2.0", False, "3.0", spot, None), |     ('binance', 2.0, False, 3.0, spot, None), | ||||||
|     ('binance', "2.0", False, "1.0", spot, cross), |     ('binance', 2.0, False, 1.0, spot, cross), | ||||||
|     ('binance', "2.0", True, "3.0", spot, isolated), |     ('binance', 2.0, True, 3.0, spot, isolated), | ||||||
| ]) | ]) | ||||||
| def test_liquidation_price_is_none( | def test_liquidation_price_is_none( | ||||||
|     mocker, |     mocker, | ||||||
| @@ -3991,51 +3993,22 @@ def test_liquidation_price_is_none( | |||||||
|     trading_mode, |     trading_mode, | ||||||
|     collateral |     collateral | ||||||
| ): | ): | ||||||
|  |     default_conf['trading_mode'] = trading_mode | ||||||
|  |     default_conf['collateral'] = collateral | ||||||
|     exchange = get_patched_exchange(mocker, default_conf, id=exchange_name) |     exchange = get_patched_exchange(mocker, default_conf, id=exchange_name) | ||||||
|     assert exchange.liquidation_price( |     assert exchange.liquidation_price( | ||||||
|         open_rate, |         open_rate=open_rate, | ||||||
|         is_short, |         is_short=is_short, | ||||||
|         leverage, |         mm_ratio=1535443.01, | ||||||
|         trading_mode, |         position=71200.81144, | ||||||
|         collateral, |         wallet_balance=-56354.57, | ||||||
|         1535443.01, |         taker_fee_rate=0.01, | ||||||
|         71200.81144, |         maintenance_amt=3683.979, | ||||||
|         -56354.57, |         mm_ex_1=0.10, | ||||||
|         135365.00, |         upnl_ex_1=0.0 | ||||||
|         3683.979, |  | ||||||
|         0.10, |  | ||||||
|     ) is None |     ) is None | ||||||
|  |  | ||||||
|  |  | ||||||
| @pytest.mark.parametrize('exchange_name,open_rate,is_short,leverage,trading_mode,collateral', [ |  | ||||||
|     # Bittrex |  | ||||||
|     ('bittrex', "2.0", False, "3.0", margin, cross), |  | ||||||
|     ('bittrex', "2.0", False, "3.0", margin, isolated), |  | ||||||
|     ('bittrex', "2.0", False, "3.0", futures, cross), |  | ||||||
|     ('bittrex', "2.0", False, "3.0", futures, isolated), |  | ||||||
|     # Binance |  | ||||||
|     # Binance supports isolated margin, but freqtrade likely won't for a while on Binance |  | ||||||
|     ('binance', "2.0", True, "3.0", margin, isolated), |  | ||||||
|     # Kraken |  | ||||||
|     ('kraken', "2.0", True, "1.0", margin, isolated), |  | ||||||
|     ('kraken', "2.0", True, "1.0", futures, isolated), |  | ||||||
|     # FTX |  | ||||||
|     ('ftx', "2.0", True, "3.0", margin, isolated), |  | ||||||
|     ('ftx', "2.0", True, "3.0", futures, isolated), |  | ||||||
| ]) |  | ||||||
| def test_liquidation_price_exception_thrown( |  | ||||||
|     exchange_name, |  | ||||||
|     open_rate, |  | ||||||
|     is_short, |  | ||||||
|     leverage, |  | ||||||
|     trading_mode, |  | ||||||
|     collateral, |  | ||||||
|     result |  | ||||||
| ): |  | ||||||
|     # TODO-lev assert exception is thrown |  | ||||||
|     return  # Here to avoid indent error, remove when implemented |  | ||||||
|  |  | ||||||
|  |  | ||||||
| @pytest.mark.parametrize( | @pytest.mark.parametrize( | ||||||
|     'exchange_name, is_short, leverage, trading_mode, collateral, wallet_balance, ' |     'exchange_name, is_short, leverage, trading_mode, collateral, wallet_balance, ' | ||||||
|     'mm_ex_1, upnl_ex_1, maintenance_amt, position, open_rate, ' |     'mm_ex_1, upnl_ex_1, maintenance_amt, position, open_rate, ' | ||||||
| @@ -4054,13 +4027,12 @@ def test_liquidation_price( | |||||||
|     mocker, default_conf, exchange_name, open_rate, is_short, leverage, trading_mode, |     mocker, default_conf, exchange_name, open_rate, is_short, leverage, trading_mode, | ||||||
|     collateral, wallet_balance, mm_ex_1, upnl_ex_1, maintenance_amt, position, mm_ratio, expected |     collateral, wallet_balance, mm_ex_1, upnl_ex_1, maintenance_amt, position, mm_ratio, expected | ||||||
| ): | ): | ||||||
|  |     default_conf['trading_mode'] = trading_mode | ||||||
|  |     default_conf['collateral'] = collateral | ||||||
|     exchange = get_patched_exchange(mocker, default_conf, id=exchange_name) |     exchange = get_patched_exchange(mocker, default_conf, id=exchange_name) | ||||||
|     assert isclose(round(exchange.liquidation_price( |     assert isclose(round(exchange.liquidation_price( | ||||||
|         open_rate=open_rate, |         open_rate=open_rate, | ||||||
|         is_short=is_short, |         is_short=is_short, | ||||||
|         leverage=leverage, |  | ||||||
|         trading_mode=trading_mode, |  | ||||||
|         collateral=collateral, |  | ||||||
|         wallet_balance=wallet_balance, |         wallet_balance=wallet_balance, | ||||||
|         mm_ex_1=mm_ex_1, |         mm_ex_1=mm_ex_1, | ||||||
|         upnl_ex_1=upnl_ex_1, |         upnl_ex_1=upnl_ex_1, | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user