Changed name Collateral -> MarginMode, collateral -> margin_mode, and _supported_trading_mode_margin_pairs -> _supported_trading_margin_pairs
This commit is contained in:
		| @@ -155,7 +155,7 @@ CONF_SCHEMA = { | ||||
|         'ignore_roi_if_buy_signal': {'type': 'boolean'}, | ||||
|         'ignore_buying_expired_candle_after': {'type': 'number'}, | ||||
|         'trading_mode': {'type': 'string', 'enum': TRADING_MODES}, | ||||
|         'collateral': {'type': 'string', 'enum': COLLATERAL_TYPES}, | ||||
|         'margin_mode': {'type': 'string', 'enum': COLLATERAL_TYPES}, | ||||
|         'backtest_breakdown': { | ||||
|             'type': 'array', | ||||
|             'items': {'type': 'string', 'enum': BACKTEST_BREAKDOWNS} | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| # flake8: noqa: F401 | ||||
| from freqtrade.enums.backteststate import BacktestState | ||||
| from freqtrade.enums.candletype import CandleType | ||||
| from freqtrade.enums.collateral import Collateral | ||||
| from freqtrade.enums.marginmode import MarginMode | ||||
| from freqtrade.enums.ordertypevalue import OrderTypeValues | ||||
| from freqtrade.enums.rpcmessagetype import RPCMessageType | ||||
| from freqtrade.enums.runmode import NON_UTIL_MODES, OPTIMIZE_MODES, TRADING_MODES, RunMode | ||||
|   | ||||
| @@ -1,11 +1,11 @@ | ||||
| from enum import Enum | ||||
| 
 | ||||
| 
 | ||||
| class Collateral(Enum): | ||||
| class MarginMode(Enum): | ||||
|     """ | ||||
|     Enum to distinguish between | ||||
|     cross margin/futures collateral and | ||||
|     isolated margin/futures collateral | ||||
|     cross margin/futures margin_mode and | ||||
|     isolated margin/futures margin_mode | ||||
|     """ | ||||
|     CROSS = "cross" | ||||
|     ISOLATED = "isolated" | ||||
| @@ -8,7 +8,7 @@ from typing import Dict, List, Optional, Tuple | ||||
| import arrow | ||||
| import ccxt | ||||
|  | ||||
| from freqtrade.enums import CandleType, Collateral, TradingMode | ||||
| from freqtrade.enums import CandleType, MarginMode, TradingMode | ||||
| from freqtrade.exceptions import (DDosProtection, InsufficientFundsError, InvalidOrderException, | ||||
|                                   OperationalException, TemporaryError) | ||||
| from freqtrade.exchange import Exchange | ||||
| @@ -31,11 +31,11 @@ class Binance(Exchange): | ||||
|         "ccxt_futures_name": "future" | ||||
|     } | ||||
|  | ||||
|     _supported_trading_mode_collateral_pairs: List[Tuple[TradingMode, Collateral]] = [ | ||||
|     _supported_trading_mode_margin_pairs: List[Tuple[TradingMode, MarginMode]] = [ | ||||
|         # TradingMode.SPOT always supported and not required in this list | ||||
|         # (TradingMode.MARGIN, Collateral.CROSS), | ||||
|         # (TradingMode.FUTURES, Collateral.CROSS), | ||||
|         (TradingMode.FUTURES, Collateral.ISOLATED) | ||||
|         # (TradingMode.MARGIN, MarginMode.CROSS), | ||||
|         # (TradingMode.FUTURES, MarginMode.CROSS), | ||||
|         (TradingMode.FUTURES, MarginMode.ISOLATED) | ||||
|     ] | ||||
|  | ||||
|     def stoploss_adjust(self, stop_loss: float, order: Dict, side: str) -> bool: | ||||
| @@ -177,7 +177,7 @@ class Binance(Exchange): | ||||
|         """ | ||||
|         Returns the maximum leverage that a pair can be traded at | ||||
|         :param pair: The base/quote currency pair being traded | ||||
|         :stake_amount: The total value of the traders collateral in quote currency | ||||
|         :stake_amount: The total value of the traders margin_mode in quote currency | ||||
|         """ | ||||
|         if stake_amount is None: | ||||
|             raise OperationalException('binance.get_max_leverage requires argument stake_amount') | ||||
| @@ -324,7 +324,7 @@ class Binance(Exchange): | ||||
|  | ||||
|         side_1 = -1 if is_short else 1 | ||||
|         position = abs(position) | ||||
|         cross_vars = upnl_ex_1 - mm_ex_1 if self.collateral == Collateral.CROSS else 0.0 | ||||
|         cross_vars = upnl_ex_1 - mm_ex_1 if self.margin_mode == MarginMode.CROSS else 0.0 | ||||
|  | ||||
|         # mm_ratio: Binance's formula specifies maintenance margin rate which is mm_ratio * 100% | ||||
|         # maintenance_amt: (CUM) Maintenance Amount of position | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| import logging | ||||
| from typing import Dict, List, Tuple | ||||
|  | ||||
| from freqtrade.enums import Collateral, TradingMode | ||||
| from freqtrade.enums import MarginMode, TradingMode | ||||
| from freqtrade.exchange import Exchange | ||||
|  | ||||
|  | ||||
| @@ -24,8 +24,8 @@ class Bybit(Exchange): | ||||
|         "ccxt_futures_name": "linear" | ||||
|     } | ||||
|  | ||||
|     _supported_trading_mode_collateral_pairs: List[Tuple[TradingMode, Collateral]] = [ | ||||
|     _supported_trading_mode_margin_pairs: List[Tuple[TradingMode, MarginMode]] = [ | ||||
|         # TradingMode.SPOT always supported and not required in this list | ||||
|         # (TradingMode.FUTURES, Collateral.CROSS), | ||||
|         # (TradingMode.FUTURES, Collateral.ISOLATED) | ||||
|         # (TradingMode.FUTURES, MarginMode.CROSS), | ||||
|         # (TradingMode.FUTURES, MarginMode.ISOLATED) | ||||
|     ] | ||||
|   | ||||
| @@ -22,7 +22,7 @@ from pandas import DataFrame | ||||
| from freqtrade.constants import (DEFAULT_AMOUNT_RESERVE_PERCENT, NON_OPEN_EXCHANGE_STATES, | ||||
|                                  ListPairsWithTimeframes, PairWithTimeframe) | ||||
| from freqtrade.data.converter import ohlcv_to_dataframe, trades_dict_to_list | ||||
| from freqtrade.enums import CandleType, Collateral, TradingMode | ||||
| from freqtrade.enums import CandleType, MarginMode, TradingMode | ||||
| from freqtrade.exceptions import (DDosProtection, ExchangeError, InsufficientFundsError, | ||||
|                                   InvalidOrderException, OperationalException, PricingError, | ||||
|                                   RetryableOrderError, TemporaryError) | ||||
| @@ -77,7 +77,7 @@ class Exchange: | ||||
|     } | ||||
|     _ft_has: Dict = {} | ||||
|  | ||||
|     _supported_trading_mode_collateral_pairs: List[Tuple[TradingMode, Collateral]] = [ | ||||
|     _supported_trading_mode_margin_pairs: List[Tuple[TradingMode, MarginMode]] = [ | ||||
|         # TradingMode.SPOT always supported and not required in this list | ||||
|     ] | ||||
|  | ||||
| @@ -137,9 +137,9 @@ class Exchange: | ||||
|  | ||||
|         self.trading_mode = TradingMode(config.get('trading_mode', 'spot')) | ||||
|  | ||||
|         self.collateral: Optional[Collateral] = ( | ||||
|             Collateral(config.get('collateral')) | ||||
|             if config.get('collateral') | ||||
|         self.margin_mode: Optional[MarginMode] = ( | ||||
|             MarginMode(config.get('margin_mode')) | ||||
|             if config.get('margin_mode') | ||||
|             else None | ||||
|         ) | ||||
|  | ||||
| @@ -175,7 +175,7 @@ class Exchange: | ||||
|             self.validate_order_time_in_force(config.get('order_time_in_force', {})) | ||||
|             self.required_candle_call_count = self.validate_required_startup_candles( | ||||
|                 config.get('startup_candle_count', 0), config.get('timeframe', '')) | ||||
|             self.validate_trading_mode_and_collateral(self.trading_mode, self.collateral) | ||||
|             self.validate_trading_mode_and_margin_mode(self.trading_mode, self.margin_mode) | ||||
|  | ||||
|         # Converts the interval provided in minutes in config to seconds | ||||
|         self.markets_refresh_interval: int = exchange_config.get( | ||||
| @@ -599,23 +599,23 @@ class Exchange: | ||||
|                            f"if you really need {startup_candles} candles for your strategy") | ||||
|         return required_candle_call_count | ||||
|  | ||||
|     def validate_trading_mode_and_collateral( | ||||
|     def validate_trading_mode_and_margin_mode( | ||||
|         self, | ||||
|         trading_mode: TradingMode, | ||||
|         collateral: Optional[Collateral]  # Only None when trading_mode = TradingMode.SPOT | ||||
|         margin_mode: Optional[MarginMode]  # Only None when trading_mode = TradingMode.SPOT | ||||
|     ): | ||||
|         """ | ||||
|         Checks if freqtrade can perform trades using the configured | ||||
|         trading mode(Margin, Futures) and Collateral(Cross, Isolated) | ||||
|         trading mode(Margin, Futures) and MarginMode(Cross, Isolated) | ||||
|         Throws OperationalException: | ||||
|             If the trading_mode/collateral type are not supported by freqtrade on this exchange | ||||
|             If the trading_mode/margin_mode type are not supported by freqtrade on this exchange | ||||
|         """ | ||||
|         if trading_mode != TradingMode.SPOT and ( | ||||
|             (trading_mode, collateral) not in self._supported_trading_mode_collateral_pairs | ||||
|             (trading_mode, margin_mode) not in self._supported_trading_mode_margin_pairs | ||||
|         ): | ||||
|             collateral_value = collateral and collateral.value | ||||
|             mm_value = margin_mode and margin_mode.value | ||||
|             raise OperationalException( | ||||
|                 f"Freqtrade does not support {collateral_value} {trading_mode.value} on {self.name}" | ||||
|                 f"Freqtrade does not support {mm_value} {trading_mode.value} on {self.name}" | ||||
|             ) | ||||
|  | ||||
|     def exchange_has(self, endpoint: str) -> bool: | ||||
| @@ -879,7 +879,7 @@ class Exchange: | ||||
|  | ||||
|     def _lev_prep(self, pair: str, leverage: float): | ||||
|         if self.trading_mode != TradingMode.SPOT: | ||||
|             self.set_margin_mode(pair, self.collateral) | ||||
|             self.set_margin_mode(pair, self.margin_mode) | ||||
|             self._set_leverage(leverage, pair) | ||||
|  | ||||
|     def _get_params(self, ordertype: str, leverage: float, time_in_force: str = 'gtc') -> Dict: | ||||
| @@ -1810,7 +1810,7 @@ class Exchange: | ||||
|         """ | ||||
|         Returns the maximum leverage that a pair can be traded at | ||||
|         :param pair: The base/quote currency pair being traded | ||||
|         :param nominal_value: The total value of the trade in quote currency (collateral + debt) | ||||
|         :param nominal_value: The total value of the trade in quote currency (margin_mode + debt) | ||||
|         """ | ||||
|         market = self.markets[pair] | ||||
|         if market['limits']['leverage']['max'] is not None: | ||||
| @@ -1830,7 +1830,7 @@ class Exchange: | ||||
|         have the same leverage on every trade | ||||
|         """ | ||||
|         if self._config['dry_run'] or not self.exchange_has("setLeverage"): | ||||
|             # Some exchanges only support one collateral type | ||||
|             # Some exchanges only support one margin_mode type | ||||
|             return | ||||
|  | ||||
|         try: | ||||
| @@ -1851,17 +1851,17 @@ class Exchange: | ||||
|         return open_date.minute > 0 or open_date.second > 0 | ||||
|  | ||||
|     @retrier | ||||
|     def set_margin_mode(self, pair: str, collateral: Collateral, params: dict = {}): | ||||
|     def set_margin_mode(self, pair: str, margin_mode: MarginMode, params: dict = {}): | ||||
|         """ | ||||
|         Set's the margin mode on the exchange to cross or isolated for a specific pair | ||||
|         :param pair: base/quote currency pair (e.g. "ADA/USDT") | ||||
|         """ | ||||
|         if self._config['dry_run'] or not self.exchange_has("setMarginMode"): | ||||
|             # Some exchanges only support one collateral type | ||||
|             # Some exchanges only support one margin_mode type | ||||
|             return | ||||
|  | ||||
|         try: | ||||
|             self._api.set_margin_mode(pair, collateral.value, params) | ||||
|             self._api.set_margin_mode(pair, margin_mode.value, params) | ||||
|         except ccxt.DDoSProtection as e: | ||||
|             raise DDosProtection(e) from e | ||||
|         except (ccxt.NetworkError, ccxt.ExchangeError) as e: | ||||
| @@ -2000,11 +2000,11 @@ class Exchange: | ||||
|         """ | ||||
|         if self.trading_mode == TradingMode.SPOT: | ||||
|             return None | ||||
|         elif (self.collateral is None): | ||||
|             raise OperationalException(f'{self.name}.collateral must be set for liquidation_price') | ||||
|         elif (self.trading_mode != TradingMode.FUTURES and self.collateral != Collateral.ISOLATED): | ||||
|         elif (self.margin_mode is None): | ||||
|             raise OperationalException(f'{self.name}.margin_mode must be set for liquidation_price') | ||||
|         elif (self.trading_mode != TradingMode.FUTURES and self.margin_mode != MarginMode.ISOLATED): | ||||
|             raise OperationalException( | ||||
|                 f"{self.name} does not support {self.collateral.value} {self.trading_mode.value}") | ||||
|                 f"{self.name} does not support {self.margin_mode.value} {self.trading_mode.value}") | ||||
|  | ||||
|         if self._config['dry_run'] or not self.exchange_has("fetchPositions"): | ||||
|  | ||||
| @@ -2064,8 +2064,8 @@ class Exchange: | ||||
|         :param is_short: True if the trade is a short, false otherwise | ||||
|         :param position: Absolute value of position size incl. leverage (in base currency) | ||||
|         :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 | ||||
|         :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 | ||||
|  | ||||
| @@ -2078,7 +2078,7 @@ class Exchange: | ||||
|         taker_fee_rate = market['taker'] | ||||
|         mm_ratio, _ = self.get_maintenance_ratio_and_amt(pair, position) | ||||
|  | ||||
|         if self.trading_mode == TradingMode.FUTURES and self.collateral == Collateral.ISOLATED: | ||||
|         if self.trading_mode == TradingMode.FUTURES and self.margin_mode == MarginMode.ISOLATED: | ||||
|  | ||||
|             if market['inverse']: | ||||
|                 raise OperationalException( | ||||
|   | ||||
| @@ -4,7 +4,7 @@ from typing import Any, Dict, List, Tuple | ||||
|  | ||||
| import ccxt | ||||
|  | ||||
| from freqtrade.enums import Collateral, TradingMode | ||||
| from freqtrade.enums import MarginMode, TradingMode | ||||
| from freqtrade.exceptions import (DDosProtection, InsufficientFundsError, InvalidOrderException, | ||||
|                                   OperationalException, TemporaryError) | ||||
| from freqtrade.exchange import Exchange | ||||
| @@ -25,10 +25,10 @@ class Ftx(Exchange): | ||||
|         "mark_ohlcv_timeframe": "1h", | ||||
|     } | ||||
|  | ||||
|     _supported_trading_mode_collateral_pairs: List[Tuple[TradingMode, Collateral]] = [ | ||||
|     _supported_trading_mode_margin_pairs: List[Tuple[TradingMode, MarginMode]] = [ | ||||
|         # TradingMode.SPOT always supported and not required in this list | ||||
|         # (TradingMode.MARGIN, Collateral.CROSS), | ||||
|         # (TradingMode.FUTURES, Collateral.CROSS) | ||||
|         # (TradingMode.MARGIN, MarginMode.CROSS), | ||||
|         # (TradingMode.FUTURES, MarginMode.CROSS) | ||||
|     ] | ||||
|  | ||||
|     def stoploss_adjust(self, stop_loss: float, order: Dict, side: str) -> bool: | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
| import logging | ||||
| from typing import Dict, List, Optional, Tuple | ||||
|  | ||||
| from freqtrade.enums import Collateral, TradingMode | ||||
| from freqtrade.enums import MarginMode, TradingMode | ||||
| from freqtrade.exceptions import OperationalException | ||||
| from freqtrade.exchange import Exchange | ||||
|  | ||||
| @@ -27,11 +27,11 @@ class Gateio(Exchange): | ||||
|  | ||||
|     _headers = {'X-Gate-Channel-Id': 'freqtrade'} | ||||
|  | ||||
|     _supported_trading_mode_collateral_pairs: List[Tuple[TradingMode, Collateral]] = [ | ||||
|     _supported_trading_mode_margin_pairs: List[Tuple[TradingMode, MarginMode]] = [ | ||||
|         # TradingMode.SPOT always supported and not required in this list | ||||
|         # (TradingMode.MARGIN, Collateral.CROSS), | ||||
|         # (TradingMode.FUTURES, Collateral.CROSS), | ||||
|         (TradingMode.FUTURES, Collateral.ISOLATED) | ||||
|         # (TradingMode.MARGIN, MarginMode.CROSS), | ||||
|         # (TradingMode.FUTURES, MarginMode.CROSS), | ||||
|         (TradingMode.FUTURES, MarginMode.ISOLATED) | ||||
|     ] | ||||
|  | ||||
|     def validate_ordertypes(self, order_types: Dict) -> None: | ||||
|   | ||||
| @@ -6,7 +6,7 @@ from typing import Any, Dict, List, Optional, Tuple | ||||
| import ccxt | ||||
| from pandas import DataFrame | ||||
|  | ||||
| from freqtrade.enums import Collateral, TradingMode | ||||
| from freqtrade.enums import MarginMode, TradingMode | ||||
| from freqtrade.exceptions import (DDosProtection, InsufficientFundsError, InvalidOrderException, | ||||
|                                   OperationalException, TemporaryError) | ||||
| from freqtrade.exchange import Exchange | ||||
| @@ -27,10 +27,10 @@ class Kraken(Exchange): | ||||
|         "mark_ohlcv_timeframe": "4h", | ||||
|     } | ||||
|  | ||||
|     _supported_trading_mode_collateral_pairs: List[Tuple[TradingMode, Collateral]] = [ | ||||
|     _supported_trading_mode_margin_pairs: List[Tuple[TradingMode, MarginMode]] = [ | ||||
|         # TradingMode.SPOT always supported and not required in this list | ||||
|         # (TradingMode.MARGIN, Collateral.CROSS), | ||||
|         # (TradingMode.FUTURES, Collateral.CROSS) | ||||
|         # (TradingMode.MARGIN, MarginMode.CROSS), | ||||
|         # (TradingMode.FUTURES, MarginMode.CROSS) | ||||
|     ] | ||||
|  | ||||
|     def market_is_tradable(self, market: Dict[str, Any]) -> bool: | ||||
|   | ||||
| @@ -1,7 +1,7 @@ | ||||
| import logging | ||||
| from typing import Dict, List, Tuple | ||||
|  | ||||
| from freqtrade.enums import Collateral, TradingMode | ||||
| from freqtrade.enums import MarginMode, TradingMode | ||||
| from freqtrade.exchange import Exchange | ||||
|  | ||||
|  | ||||
| @@ -20,9 +20,9 @@ class Okex(Exchange): | ||||
|         "funding_fee_timeframe": "8h", | ||||
|     } | ||||
|  | ||||
|     _supported_trading_mode_collateral_pairs: List[Tuple[TradingMode, Collateral]] = [ | ||||
|     _supported_trading_mode_margin_pairs: List[Tuple[TradingMode, MarginMode]] = [ | ||||
|         # TradingMode.SPOT always supported and not required in this list | ||||
|         # (TradingMode.MARGIN, Collateral.CROSS), | ||||
|         # (TradingMode.FUTURES, Collateral.CROSS), | ||||
|         # (TradingMode.FUTURES, Collateral.ISOLATED) | ||||
|         # (TradingMode.MARGIN, MarginMode.CROSS), | ||||
|         # (TradingMode.FUTURES, MarginMode.CROSS), | ||||
|         # (TradingMode.FUTURES, MarginMode.ISOLATED) | ||||
|     ] | ||||
|   | ||||
| @@ -16,7 +16,7 @@ from freqtrade.configuration import validate_config_consistency | ||||
| from freqtrade.data.converter import order_book_to_dataframe | ||||
| from freqtrade.data.dataprovider import DataProvider | ||||
| from freqtrade.edge import Edge | ||||
| from freqtrade.enums import (Collateral, RPCMessageType, RunMode, SellType, SignalDirection, State, | ||||
| from freqtrade.enums import (MarginMode, RPCMessageType, RunMode, SellType, SignalDirection, State, | ||||
|                              TradingMode) | ||||
| from freqtrade.exceptions import (DependencyException, ExchangeError, InsufficientFundsError, | ||||
|                                   InvalidOrderException, OperationalException, PricingError) | ||||
| @@ -105,9 +105,9 @@ class FreqtradeBot(LoggingMixin): | ||||
|  | ||||
|         self.trading_mode = TradingMode(self.config.get('trading_mode', 'spot')) | ||||
|  | ||||
|         self.collateral_type: Optional[Collateral] = None | ||||
|         if 'collateral' in self.config: | ||||
|             self.collateral_type = Collateral(self.config['collateral']) | ||||
|         self.margin_mode_type: Optional[MarginMode] = None | ||||
|         if 'margin_mode' in self.config: | ||||
|             self.margin_mode = MarginMode(self.config['margin_mode']) | ||||
|  | ||||
|         self._schedule = Scheduler() | ||||
|  | ||||
| @@ -615,7 +615,7 @@ class FreqtradeBot(LoggingMixin): | ||||
|         if self.trading_mode == TradingMode.SPOT: | ||||
|             return (0.0, None) | ||||
|         elif ( | ||||
|             self.collateral_type == Collateral.ISOLATED and | ||||
|             self.margin_mode == MarginMode.ISOLATED and | ||||
|             self.trading_mode == TradingMode.FUTURES | ||||
|         ): | ||||
|             wallet_balance = (amount * open_rate)/leverage | ||||
|   | ||||
| @@ -17,7 +17,7 @@ from freqtrade import constants | ||||
| from freqtrade.commands import Arguments | ||||
| from freqtrade.data.converter import ohlcv_to_dataframe | ||||
| from freqtrade.edge import PairInfo | ||||
| from freqtrade.enums import CandleType, Collateral, RunMode, SignalDirection, TradingMode | ||||
| from freqtrade.enums import CandleType, MarginMode, RunMode, SignalDirection, TradingMode | ||||
| from freqtrade.exchange import Exchange | ||||
| from freqtrade.freqtradebot import FreqtradeBot | ||||
| from freqtrade.persistence import LocalTrade, Trade, init_db | ||||
| @@ -115,12 +115,12 @@ def patch_exchange( | ||||
|  | ||||
|     if mock_supported_modes: | ||||
|         mocker.patch( | ||||
|             f'freqtrade.exchange.{id.capitalize()}._supported_trading_mode_collateral_pairs', | ||||
|             f'freqtrade.exchange.{id.capitalize()}._supported_trading_mode_margin_pairs', | ||||
|             PropertyMock(return_value=[ | ||||
|                 (TradingMode.MARGIN, Collateral.CROSS), | ||||
|                 (TradingMode.MARGIN, Collateral.ISOLATED), | ||||
|                 (TradingMode.FUTURES, Collateral.CROSS), | ||||
|                 (TradingMode.FUTURES, Collateral.ISOLATED) | ||||
|                 (TradingMode.MARGIN, MarginMode.CROSS), | ||||
|                 (TradingMode.MARGIN, MarginMode.ISOLATED), | ||||
|                 (TradingMode.FUTURES, MarginMode.CROSS), | ||||
|                 (TradingMode.FUTURES, MarginMode.ISOLATED) | ||||
|             ]) | ||||
|         ) | ||||
|  | ||||
|   | ||||
| @@ -5,7 +5,7 @@ from unittest.mock import MagicMock, PropertyMock | ||||
| import ccxt | ||||
| import pytest | ||||
|  | ||||
| from freqtrade.enums import Collateral, TradingMode | ||||
| from freqtrade.enums import MarginMode, TradingMode | ||||
| from freqtrade.exceptions import DependencyException, InvalidOrderException, OperationalException | ||||
| from tests.conftest import get_mock_coro, get_patched_exchange, log_has_re | ||||
| from tests.exchange.test_exchange import ccxt_exceptionhandlers | ||||
| @@ -236,7 +236,7 @@ def test_fill_leverage_brackets_binance(default_conf, mocker): | ||||
|     }) | ||||
|     default_conf['dry_run'] = False | ||||
|     default_conf['trading_mode'] = TradingMode.FUTURES | ||||
|     default_conf['collateral'] = Collateral.ISOLATED | ||||
|     default_conf['margin_mode'] = MarginMode.ISOLATED | ||||
|     exchange = get_patched_exchange(mocker, default_conf, api_mock, id="binance") | ||||
|     exchange.fill_leverage_brackets() | ||||
|  | ||||
| @@ -282,7 +282,7 @@ def test_fill_leverage_brackets_binance(default_conf, mocker): | ||||
| def test_fill_leverage_brackets_binance_dryrun(default_conf, mocker): | ||||
|     api_mock = MagicMock() | ||||
|     default_conf['trading_mode'] = TradingMode.FUTURES | ||||
|     default_conf['collateral'] = Collateral.ISOLATED | ||||
|     default_conf['margin_mode'] = MarginMode.ISOLATED | ||||
|     exchange = get_patched_exchange(mocker, default_conf, api_mock, id="binance") | ||||
|     exchange.fill_leverage_brackets() | ||||
|  | ||||
| @@ -385,14 +385,14 @@ async def test__async_get_historic_ohlcv_binance(default_conf, mocker, caplog, c | ||||
|     assert log_has_re(r"Candle-data for ETH/BTC available starting with .*", caplog) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("trading_mode,collateral,config", [ | ||||
| @pytest.mark.parametrize("trading_mode,margin_mode,config", [ | ||||
|     ("spot", "", {}), | ||||
|     ("margin", "cross", {"options": {"defaultType": "margin"}}), | ||||
|     ("futures", "isolated", {"options": {"defaultType": "future"}}), | ||||
| ]) | ||||
| def test__ccxt_config(default_conf, mocker, trading_mode, collateral, config): | ||||
| def test__ccxt_config(default_conf, mocker, trading_mode, margin_mode, config): | ||||
|     default_conf['trading_mode'] = trading_mode | ||||
|     default_conf['collateral'] = collateral | ||||
|     default_conf['margin_mode'] = margin_mode | ||||
|     exchange = get_patched_exchange(mocker, default_conf, id="binance") | ||||
|     assert exchange._ccxt_config == config | ||||
|  | ||||
|   | ||||
| @@ -104,12 +104,12 @@ def exchange_futures(request, exchange_conf, class_mocker): | ||||
|         exchange_conf = deepcopy(exchange_conf) | ||||
|         exchange_conf['exchange']['name'] = request.param | ||||
|         exchange_conf['trading_mode'] = 'futures' | ||||
|         exchange_conf['collateral'] = 'cross' | ||||
|         exchange_conf['margin_mode'] = 'cross' | ||||
|         exchange_conf['stake_currency'] = EXCHANGES[request.param]['stake_currency'] | ||||
|  | ||||
|         # TODO-lev: This mock should no longer be necessary once futures are enabled. | ||||
|         class_mocker.patch( | ||||
|             'freqtrade.exchange.exchange.Exchange.validate_trading_mode_and_collateral') | ||||
|             'freqtrade.exchange.exchange.Exchange.validate_trading_mode_and_margin_mode') | ||||
|         class_mocker.patch( | ||||
|             'freqtrade.exchange.binance.Binance.fill_leverage_brackets') | ||||
|  | ||||
|   | ||||
| @@ -11,7 +11,7 @@ import ccxt | ||||
| import pytest | ||||
| from pandas import DataFrame | ||||
|  | ||||
| from freqtrade.enums import CandleType, Collateral, TradingMode | ||||
| from freqtrade.enums import CandleType, MarginMode, TradingMode | ||||
| from freqtrade.exceptions import (DDosProtection, DependencyException, InvalidOrderException, | ||||
|                                   OperationalException, PricingError, TemporaryError) | ||||
| from freqtrade.exchange import Binance, Bittrex, Exchange, Kraken | ||||
| @@ -263,7 +263,7 @@ def test_amount_to_precision( | ||||
|     }) | ||||
|  | ||||
|     default_conf['trading_mode'] = trading_mode | ||||
|     default_conf['collateral'] = 'isolated' | ||||
|     default_conf['margin_mode'] = 'isolated' | ||||
|  | ||||
|     exchange = get_patched_exchange(mocker, default_conf, id="binance") | ||||
|     # digits counting mode | ||||
| @@ -473,7 +473,7 @@ def test_get_min_pair_stake_amount(mocker, default_conf) -> None: | ||||
|  | ||||
|     markets["ETH/BTC"]["contractSize"] = '0.01' | ||||
|     default_conf['trading_mode'] = 'futures' | ||||
|     default_conf['collateral'] = 'isolated' | ||||
|     default_conf['margin_mode'] = 'isolated' | ||||
|     exchange = get_patched_exchange(mocker, default_conf, id="binance") | ||||
|     mocker.patch( | ||||
|         'freqtrade.exchange.Exchange.markets', | ||||
| @@ -1165,7 +1165,7 @@ def test_create_order(default_conf, mocker, side, ordertype, rate, marketprice, | ||||
|         'amount': 1 | ||||
|     }) | ||||
|     default_conf['dry_run'] = False | ||||
|     default_conf['collateral'] = 'isolated' | ||||
|     default_conf['margin_mode'] = 'isolated' | ||||
|     mocker.patch('freqtrade.exchange.Exchange.amount_to_precision', lambda s, x, y: y) | ||||
|     mocker.patch('freqtrade.exchange.Exchange.price_to_precision', lambda s, x, y: y) | ||||
|     exchange = get_patched_exchange(mocker, default_conf, api_mock, id=exchange_name) | ||||
| @@ -2334,7 +2334,7 @@ async def test__async_fetch_trades(default_conf, mocker, caplog, exchange_name, | ||||
| async def test__async_fetch_trades_contract_size(default_conf, mocker, caplog, exchange_name, | ||||
|                                                  fetch_trades_result): | ||||
|     caplog.set_level(logging.DEBUG) | ||||
|     default_conf['collateral'] = 'isolated' | ||||
|     default_conf['margin_mode'] = 'isolated' | ||||
|     default_conf['trading_mode'] = 'futures' | ||||
|     exchange = get_patched_exchange(mocker, default_conf, id=exchange_name) | ||||
|     # Monkey-patch async function | ||||
| @@ -2796,7 +2796,7 @@ def test_get_trades_for_order(default_conf, mocker, exchange_name, trading_mode, | ||||
|     since = datetime(2018, 5, 5, 0, 0, 0) | ||||
|     default_conf["dry_run"] = False | ||||
|     default_conf["trading_mode"] = trading_mode | ||||
|     default_conf["collateral"] = 'isolated' | ||||
|     default_conf["margin_mode"] = 'isolated' | ||||
|     mocker.patch('freqtrade.exchange.Exchange.exchange_has', return_value=True) | ||||
|     api_mock = MagicMock() | ||||
|  | ||||
| @@ -3170,7 +3170,7 @@ def test_market_is_tradable( | ||||
|         quote, spot, margin, futures, trademode, add_dict, exchange, expected_result | ||||
| ) -> None: | ||||
|     default_conf['trading_mode'] = trademode | ||||
|     mocker.patch('freqtrade.exchange.exchange.Exchange.validate_trading_mode_and_collateral') | ||||
|     mocker.patch('freqtrade.exchange.exchange.Exchange.validate_trading_mode_and_margin_mode') | ||||
|     ex = get_patched_exchange(mocker, default_conf, id=exchange) | ||||
|     market = { | ||||
|         'symbol': market_symbol, | ||||
| @@ -3400,11 +3400,11 @@ def test__set_leverage(mocker, default_conf, exchange_name, trading_mode): | ||||
|     ) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("collateral", [ | ||||
|     (Collateral.CROSS), | ||||
|     (Collateral.ISOLATED) | ||||
| @pytest.mark.parametrize("margin_mode", [ | ||||
|     (MarginMode.CROSS), | ||||
|     (MarginMode.ISOLATED) | ||||
| ]) | ||||
| def test_set_margin_mode(mocker, default_conf, collateral): | ||||
| def test_set_margin_mode(mocker, default_conf, margin_mode): | ||||
|  | ||||
|     api_mock = MagicMock() | ||||
|     api_mock.set_margin_mode = MagicMock() | ||||
| @@ -3419,70 +3419,70 @@ def test_set_margin_mode(mocker, default_conf, collateral): | ||||
|         "set_margin_mode", | ||||
|         "set_margin_mode", | ||||
|         pair="XRP/USDT", | ||||
|         collateral=collateral | ||||
|         margin_mode=margin_mode | ||||
|     ) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("exchange_name, trading_mode, collateral, exception_thrown", [ | ||||
| @pytest.mark.parametrize("exchange_name, trading_mode, margin_mode, exception_thrown", [ | ||||
|     ("binance", TradingMode.SPOT, None, False), | ||||
|     ("binance", TradingMode.MARGIN, Collateral.ISOLATED, True), | ||||
|     ("binance", TradingMode.MARGIN, MarginMode.ISOLATED, True), | ||||
|     ("kraken", TradingMode.SPOT, None, False), | ||||
|     ("kraken", TradingMode.MARGIN, Collateral.ISOLATED, True), | ||||
|     ("kraken", TradingMode.FUTURES, Collateral.ISOLATED, True), | ||||
|     ("kraken", TradingMode.MARGIN, MarginMode.ISOLATED, True), | ||||
|     ("kraken", TradingMode.FUTURES, MarginMode.ISOLATED, True), | ||||
|     ("ftx", TradingMode.SPOT, None, False), | ||||
|     ("ftx", TradingMode.MARGIN, Collateral.ISOLATED, True), | ||||
|     ("ftx", TradingMode.FUTURES, Collateral.ISOLATED, True), | ||||
|     ("ftx", TradingMode.MARGIN, MarginMode.ISOLATED, True), | ||||
|     ("ftx", TradingMode.FUTURES, MarginMode.ISOLATED, True), | ||||
|     ("bittrex", TradingMode.SPOT, None, False), | ||||
|     ("bittrex", TradingMode.MARGIN, Collateral.CROSS, True), | ||||
|     ("bittrex", TradingMode.MARGIN, Collateral.ISOLATED, True), | ||||
|     ("bittrex", TradingMode.FUTURES, Collateral.CROSS, True), | ||||
|     ("bittrex", TradingMode.FUTURES, Collateral.ISOLATED, True), | ||||
|     ("gateio", TradingMode.MARGIN, Collateral.ISOLATED, True), | ||||
|     ("bittrex", TradingMode.MARGIN, MarginMode.CROSS, True), | ||||
|     ("bittrex", TradingMode.MARGIN, MarginMode.ISOLATED, True), | ||||
|     ("bittrex", TradingMode.FUTURES, MarginMode.CROSS, True), | ||||
|     ("bittrex", TradingMode.FUTURES, MarginMode.ISOLATED, True), | ||||
|     ("gateio", TradingMode.MARGIN, MarginMode.ISOLATED, True), | ||||
|     ("okex", TradingMode.SPOT, None, False), | ||||
|     ("okex", TradingMode.MARGIN, Collateral.CROSS, True), | ||||
|     ("okex", TradingMode.MARGIN, Collateral.ISOLATED, True), | ||||
|     ("okex", TradingMode.FUTURES, Collateral.CROSS, True), | ||||
|     ("okex", TradingMode.MARGIN, MarginMode.CROSS, True), | ||||
|     ("okex", TradingMode.MARGIN, MarginMode.ISOLATED, True), | ||||
|     ("okex", TradingMode.FUTURES, MarginMode.CROSS, True), | ||||
|  | ||||
|     ("binance", TradingMode.FUTURES, Collateral.ISOLATED, False), | ||||
|     ("gateio", TradingMode.FUTURES, Collateral.ISOLATED, False), | ||||
|     ("binance", TradingMode.FUTURES, MarginMode.ISOLATED, False), | ||||
|     ("gateio", TradingMode.FUTURES, MarginMode.ISOLATED, False), | ||||
|  | ||||
|     # * Remove once implemented | ||||
|     ("okex", TradingMode.FUTURES, Collateral.ISOLATED, True), | ||||
|     ("binance", TradingMode.MARGIN, Collateral.CROSS, True), | ||||
|     ("binance", TradingMode.FUTURES, Collateral.CROSS, True), | ||||
|     ("kraken", TradingMode.MARGIN, Collateral.CROSS, True), | ||||
|     ("kraken", TradingMode.FUTURES, Collateral.CROSS, True), | ||||
|     ("ftx", TradingMode.MARGIN, Collateral.CROSS, True), | ||||
|     ("ftx", TradingMode.FUTURES, Collateral.CROSS, True), | ||||
|     ("gateio", TradingMode.MARGIN, Collateral.CROSS, True), | ||||
|     ("gateio", TradingMode.FUTURES, Collateral.CROSS, True), | ||||
|     ("okex", TradingMode.FUTURES, MarginMode.ISOLATED, True), | ||||
|     ("binance", TradingMode.MARGIN, MarginMode.CROSS, True), | ||||
|     ("binance", TradingMode.FUTURES, MarginMode.CROSS, True), | ||||
|     ("kraken", TradingMode.MARGIN, MarginMode.CROSS, True), | ||||
|     ("kraken", TradingMode.FUTURES, MarginMode.CROSS, True), | ||||
|     ("ftx", TradingMode.MARGIN, MarginMode.CROSS, True), | ||||
|     ("ftx", TradingMode.FUTURES, MarginMode.CROSS, True), | ||||
|     ("gateio", TradingMode.MARGIN, MarginMode.CROSS, True), | ||||
|     ("gateio", TradingMode.FUTURES, MarginMode.CROSS, True), | ||||
|  | ||||
|     # * Uncomment once implemented | ||||
|     # ("okex", TradingMode.FUTURES, Collateral.ISOLATED, False), | ||||
|     # ("binance", TradingMode.MARGIN, Collateral.CROSS, False), | ||||
|     # ("binance", TradingMode.FUTURES, Collateral.CROSS, False), | ||||
|     # ("kraken", TradingMode.MARGIN, Collateral.CROSS, False), | ||||
|     # ("kraken", TradingMode.FUTURES, Collateral.CROSS, False), | ||||
|     # ("ftx", TradingMode.MARGIN, Collateral.CROSS, False), | ||||
|     # ("ftx", TradingMode.FUTURES, Collateral.CROSS, False), | ||||
|     # ("gateio", TradingMode.MARGIN, Collateral.CROSS, False), | ||||
|     # ("gateio", TradingMode.FUTURES, Collateral.CROSS, False), | ||||
|     # ("okex", TradingMode.FUTURES, MarginMode.ISOLATED, False), | ||||
|     # ("binance", TradingMode.MARGIN, MarginMode.CROSS, False), | ||||
|     # ("binance", TradingMode.FUTURES, MarginMode.CROSS, False), | ||||
|     # ("kraken", TradingMode.MARGIN, MarginMode.CROSS, False), | ||||
|     # ("kraken", TradingMode.FUTURES, MarginMode.CROSS, False), | ||||
|     # ("ftx", TradingMode.MARGIN, MarginMode.CROSS, False), | ||||
|     # ("ftx", TradingMode.FUTURES, MarginMode.CROSS, False), | ||||
|     # ("gateio", TradingMode.MARGIN, MarginMode.CROSS, False), | ||||
|     # ("gateio", TradingMode.FUTURES, MarginMode.CROSS, False), | ||||
| ]) | ||||
| def test_validate_trading_mode_and_collateral( | ||||
| def test_validate_trading_mode_and_margin_mode( | ||||
|     default_conf, | ||||
|     mocker, | ||||
|     exchange_name, | ||||
|     trading_mode, | ||||
|     collateral, | ||||
|     margin_mode, | ||||
|     exception_thrown | ||||
| ): | ||||
|     exchange = get_patched_exchange( | ||||
|         mocker, default_conf, id=exchange_name, mock_supported_modes=False) | ||||
|     if (exception_thrown): | ||||
|         with pytest.raises(OperationalException): | ||||
|             exchange.validate_trading_mode_and_collateral(trading_mode, collateral) | ||||
|             exchange.validate_trading_mode_and_margin_mode(trading_mode, margin_mode) | ||||
|     else: | ||||
|         exchange.validate_trading_mode_and_collateral(trading_mode, collateral) | ||||
|         exchange.validate_trading_mode_and_margin_mode(trading_mode, margin_mode) | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("exchange_name,trading_mode,ccxt_config", [ | ||||
| @@ -3508,7 +3508,7 @@ def test__ccxt_config( | ||||
|     ccxt_config | ||||
| ): | ||||
|     default_conf['trading_mode'] = trading_mode | ||||
|     default_conf['collateral'] = 'isolated' | ||||
|     default_conf['margin_mode'] = 'isolated' | ||||
|     exchange = get_patched_exchange(mocker, default_conf, id=exchange_name) | ||||
|     assert exchange._ccxt_config == ccxt_config | ||||
|  | ||||
| @@ -3609,7 +3609,7 @@ def test_get_liquidation_price(mocker, default_conf): | ||||
|             'marginRatio': None, | ||||
|             'liquidationPrice': 17.47, | ||||
|             'markPrice': 18.89, | ||||
|             'collateral': 1.52549075, | ||||
|             'margin_mode': 1.52549075, | ||||
|             'marginType': 'isolated', | ||||
|             'side': 'buy', | ||||
|             'percentage': 0.003177292946409658 | ||||
| @@ -3622,7 +3622,7 @@ def test_get_liquidation_price(mocker, default_conf): | ||||
|     ) | ||||
|     default_conf['dry_run'] = False | ||||
|     default_conf['trading_mode'] = 'futures' | ||||
|     default_conf['collateral'] = 'isolated' | ||||
|     default_conf['margin_mode'] = 'isolated' | ||||
|  | ||||
|     exchange = get_patched_exchange(mocker, default_conf, api_mock) | ||||
|     liq_price = exchange.get_liquidation_price( | ||||
| @@ -3786,7 +3786,7 @@ def test__fetch_and_calculate_funding_fees_datetime_called( | ||||
| def test__get_contract_size(mocker, default_conf, pair, expected_size, trading_mode): | ||||
|     api_mock = MagicMock() | ||||
|     default_conf['trading_mode'] = trading_mode | ||||
|     default_conf['collateral'] = 'isolated' | ||||
|     default_conf['margin_mode'] = 'isolated' | ||||
|     mocker.patch('freqtrade.exchange.Exchange.markets', { | ||||
|         'LTC/USD': { | ||||
|             'symbol': 'LTC/USD', | ||||
| @@ -3826,7 +3826,7 @@ def test__order_contracts_to_amount( | ||||
| ): | ||||
|     api_mock = MagicMock() | ||||
|     default_conf['trading_mode'] = trading_mode | ||||
|     default_conf['collateral'] = 'isolated' | ||||
|     default_conf['margin_mode'] = 'isolated' | ||||
|     mocker.patch('freqtrade.exchange.Exchange.markets', markets) | ||||
|     exchange = get_patched_exchange(mocker, default_conf, api_mock) | ||||
|  | ||||
| @@ -3910,7 +3910,7 @@ def test__trades_contracts_to_amount( | ||||
| ): | ||||
|     api_mock = MagicMock() | ||||
|     default_conf['trading_mode'] = trading_mode | ||||
|     default_conf['collateral'] = 'isolated' | ||||
|     default_conf['margin_mode'] = 'isolated' | ||||
|     mocker.patch('freqtrade.exchange.Exchange.markets', markets) | ||||
|     exchange = get_patched_exchange(mocker, default_conf, api_mock) | ||||
|  | ||||
| @@ -3946,7 +3946,7 @@ def test__amount_to_contracts( | ||||
| ): | ||||
|     api_mock = MagicMock() | ||||
|     default_conf['trading_mode'] = 'spot' | ||||
|     default_conf['collateral'] = 'isolated' | ||||
|     default_conf['margin_mode'] = 'isolated' | ||||
|     mocker.patch('freqtrade.exchange.Exchange.markets', { | ||||
|         'LTC/USD': { | ||||
|             'symbol': 'LTC/USD', | ||||
| @@ -3978,7 +3978,7 @@ def test__amount_to_contracts( | ||||
|     assert result_amount == param_amount | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize('exchange_name,open_rate,is_short,trading_mode,collateral', [ | ||||
| @pytest.mark.parametrize('exchange_name,open_rate,is_short,trading_mode,margin_mode', [ | ||||
|     # Bittrex | ||||
|     ('bittrex', 2.0, False, 'spot', None), | ||||
|     ('bittrex', 2.0, False, 'spot', 'cross'), | ||||
| @@ -3995,10 +3995,10 @@ def test_liquidation_price_is_none( | ||||
|     open_rate, | ||||
|     is_short, | ||||
|     trading_mode, | ||||
|     collateral | ||||
|     margin_mode | ||||
| ): | ||||
|     default_conf['trading_mode'] = trading_mode | ||||
|     default_conf['collateral'] = collateral | ||||
|     default_conf['margin_mode'] = margin_mode | ||||
|     exchange = get_patched_exchange(mocker, default_conf, id=exchange_name) | ||||
|     assert exchange.get_liquidation_price( | ||||
|         pair='DOGE/USDT', | ||||
| @@ -4012,7 +4012,7 @@ def test_liquidation_price_is_none( | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize( | ||||
|     'exchange_name, is_short, trading_mode, collateral, wallet_balance, ' | ||||
|     'exchange_name, is_short, trading_mode, margin_mode, wallet_balance, ' | ||||
|     'mm_ex_1, upnl_ex_1, maintenance_amt, position, open_rate, ' | ||||
|     'mm_ratio, expected', | ||||
|     [ | ||||
| @@ -4027,10 +4027,10 @@ def test_liquidation_price_is_none( | ||||
|     ]) | ||||
| def test_liquidation_price( | ||||
|     mocker, default_conf, exchange_name, open_rate, is_short, trading_mode, | ||||
|     collateral, wallet_balance, mm_ex_1, upnl_ex_1, maintenance_amt, position, mm_ratio, expected | ||||
|     margin_mode, wallet_balance, mm_ex_1, upnl_ex_1, maintenance_amt, position, mm_ratio, expected | ||||
| ): | ||||
|     default_conf['trading_mode'] = trading_mode | ||||
|     default_conf['collateral'] = collateral | ||||
|     default_conf['margin_mode'] = margin_mode | ||||
|     exchange = get_patched_exchange(mocker, default_conf, id=exchange_name) | ||||
|     exchange.get_maintenance_ratio_and_amt = MagicMock(return_value=(mm_ratio, maintenance_amt)) | ||||
|     assert isclose(round(exchange.get_liquidation_price( | ||||
|   | ||||
| @@ -1177,7 +1177,7 @@ def test_backtest_start_nomock_futures(default_conf_usdt, mocker, | ||||
|     # Tests detail-data loading | ||||
|     default_conf_usdt.update({ | ||||
|         "trading_mode": "futures", | ||||
|         "collateral": "isolated", | ||||
|         "margin_mode": "isolated", | ||||
|         "use_sell_signal": True, | ||||
|         "sell_profit_only": False, | ||||
|         "sell_profit_offset": 0.0, | ||||
|   | ||||
| @@ -749,7 +749,7 @@ def test_execute_entry(mocker, default_conf_usdt, fee, limit_order, | ||||
|     leverage = 1.0 if trading_mode == 'spot' else 5.0 | ||||
|     default_conf_usdt['exchange']['name'] = exchange_name | ||||
|     if margin_mode: | ||||
|         default_conf_usdt['collateral'] = margin_mode | ||||
|         default_conf_usdt['margin_mode'] = margin_mode | ||||
|     mocker.patch('freqtrade.exchange.Gateio.validate_ordertypes') | ||||
|     patch_RPCManager(mocker) | ||||
|     patch_exchange(mocker, id=exchange_name) | ||||
| @@ -4809,7 +4809,7 @@ def test_update_funding_fees_schedule(mocker, default_conf, trading_mode, calls, | ||||
|     patch_exchange(mocker) | ||||
|     mocker.patch('freqtrade.freqtradebot.FreqtradeBot.update_funding_fees', return_value=True) | ||||
|     default_conf['trading_mode'] = trading_mode | ||||
|     default_conf['collateral'] = 'isolated' | ||||
|     default_conf['margin_mode'] = 'isolated' | ||||
|     freqtrade = get_patched_freqtradebot(mocker, default_conf) | ||||
|  | ||||
|     time_machine.move_to(f"{t2} +00:00") | ||||
| @@ -4859,7 +4859,7 @@ def test_update_funding_fees( | ||||
|     patch_RPCManager(mocker) | ||||
|     patch_exchange(mocker) | ||||
|     default_conf['trading_mode'] = 'futures' | ||||
|     default_conf['collateral'] = 'isolated' | ||||
|     default_conf['margin_mode'] = 'isolated' | ||||
|  | ||||
|     date_midnight = arrow.get('2021-09-01 00:00:00') | ||||
|     date_eight = arrow.get('2021-09-01 08:00:00') | ||||
|   | ||||
		Reference in New Issue
	
	Block a user