gateio, ftx and binance all use same funding fee formula
This commit is contained in:
		| @@ -1,9 +1,8 @@ | ||||
| """ Binance exchange subclass """ | ||||
| import json | ||||
| import logging | ||||
| from datetime import datetime | ||||
| from pathlib import Path | ||||
| from typing import Any, Dict, List, Optional, Tuple | ||||
| from typing import Dict, List, Optional, Tuple | ||||
|  | ||||
| import arrow | ||||
| import ccxt | ||||
| @@ -30,13 +29,7 @@ class Binance(Exchange): | ||||
|         "l2_limit_range": [5, 10, 20, 50, 100, 500, 1000], | ||||
|     } | ||||
|     funding_fee_times: List[int] = [0, 8, 16]  # hours of the day | ||||
|     _funding_interest_rates: Dict = {}  # TODO-lev: delete | ||||
|  | ||||
|     def __init__(self, config: Dict[str, Any], validate: bool = True) -> None: | ||||
|         super().__init__(config, validate) | ||||
|         # TODO-lev: Uncomment once lev-exchange merged in | ||||
|         # if self.trading_mode == TradingMode.FUTURES: | ||||
|         # self._funding_interest_rates = self._get_funding_interest_rates() | ||||
|     # but the schedule won't check within this timeframe | ||||
|  | ||||
|     _supported_trading_mode_collateral_pairs: List[Tuple[TradingMode, Collateral]] = [ | ||||
|         # TradingMode.SPOT always supported and not required in this list | ||||
| @@ -218,38 +211,6 @@ class Binance(Exchange): | ||||
|         except ccxt.BaseError as e: | ||||
|             raise OperationalException(e) from e | ||||
|  | ||||
|     def _get_mark_price(self, pair: str, date: datetime) -> float: | ||||
|         raise OperationalException(f'_get_mark_price has not been implemented on {self.name}') | ||||
|  | ||||
|     def _get_funding_rate(self, pair: str, premium_index: float) -> Optional[float]: | ||||
|         """ | ||||
|             Get's the funding_rate for a pair at a specific date and time in the past | ||||
|         """ | ||||
|         raise OperationalException(f'_get_mark_price has not been implemented on {self.name}') | ||||
|  | ||||
|     def _get_funding_fee( | ||||
|         self, | ||||
|         pair: str, | ||||
|         contract_size: float, | ||||
|         mark_price: float, | ||||
|         funding_rate: Optional[float], | ||||
|     ) -> float: | ||||
|         """ | ||||
|             Calculates a single funding fee | ||||
|             :param contract_size: The amount/quanity | ||||
|             :param mark_price: The price of the asset that the contract is based off of | ||||
|             :param funding_rate: the interest rate and the premium | ||||
|                 - interest rate: 0.03% daily, BNBUSDT, LINKUSDT, and LTCUSDT are 0% | ||||
|                 - premium: varies by price difference between the perpetual contract and mark price | ||||
|         """ | ||||
|         if mark_price is None: | ||||
|             raise OperationalException("Mark price cannot be None for Binance._get_funding_fee") | ||||
|         nominal_value = mark_price * contract_size | ||||
|         if funding_rate is None: | ||||
|             raise OperationalException( | ||||
|                 "Funding rate should never be none on Binance._get_funding_fee") | ||||
|         return nominal_value * funding_rate | ||||
|  | ||||
|     async def _async_get_historic_ohlcv(self, pair: str, timeframe: str, | ||||
|                                         since_ms: int, is_new_pair: bool | ||||
|                                         ) -> List: | ||||
|   | ||||
| @@ -1649,17 +1649,19 @@ class Exchange: | ||||
|         self, | ||||
|         pair: str, | ||||
|         contract_size: float, | ||||
|         funding_rate: float, | ||||
|         mark_price: float, | ||||
|         funding_rate: Optional[float] | ||||
|     ) -> float: | ||||
|         """ | ||||
|             Calculates a single funding fee | ||||
|             :param contract_size: The amount/quanity | ||||
|             :param mark_price: The price of the asset that the contract is based off of | ||||
|             :param funding_rate: the interest rate and the premium | ||||
|                 - interest rate: | ||||
|                 - premium: varies by price difference between the perpetual contract and mark price | ||||
|         """ | ||||
|         raise OperationalException(f"Funding fee has not been implemented for {self.name}") | ||||
|         nominal_value = mark_price * contract_size | ||||
|         return nominal_value * funding_rate | ||||
|  | ||||
|     @retrier | ||||
|     def _set_leverage( | ||||
|   | ||||
| @@ -1,6 +1,5 @@ | ||||
| """ FTX exchange subclass """ | ||||
| import logging | ||||
| from datetime import datetime | ||||
| from typing import Any, Dict, List, Optional, Tuple | ||||
|  | ||||
| import ccxt | ||||
| @@ -184,25 +183,3 @@ class Ftx(Exchange): | ||||
|             :nominal_value: Here for super method, not used on FTX | ||||
|         """ | ||||
|         return 20.0 | ||||
|  | ||||
|     def _get_funding_rate(self, pair: str, when: datetime) -> Optional[float]: | ||||
|         """FTX doesn't use this""" | ||||
|         return None | ||||
|  | ||||
|     def _get_funding_fee( | ||||
|         self, | ||||
|         pair: str, | ||||
|         contract_size: float, | ||||
|         mark_price: float, | ||||
|         premium_index: Optional[float], | ||||
|         # index_price: float, | ||||
|         # interest_rate: float) | ||||
|     ) -> float: | ||||
|         """ | ||||
|             Calculates a single funding fee | ||||
|             Always paid in USD on FTX  # TODO: How do we account for this | ||||
|             : param contract_size: The amount/quanity | ||||
|             : param mark_price: The price of the asset that the contract is based off of | ||||
|             : param funding_rate: Must be None on ftx | ||||
|         """ | ||||
|         return (contract_size * mark_price) / 24 | ||||
|   | ||||
| @@ -342,14 +342,6 @@ def test__set_leverage_binance(mocker, default_conf): | ||||
|     ) | ||||
|  | ||||
|  | ||||
| def test_get_funding_rate(): | ||||
|     return | ||||
|  | ||||
|  | ||||
| def test__get_funding_fee(): | ||||
|     return | ||||
|  | ||||
|  | ||||
| @pytest.mark.asyncio | ||||
| async def test__async_get_historic_ohlcv_binance(default_conf, mocker, caplog): | ||||
|     ohlcv = [ | ||||
|   | ||||
| @@ -3292,3 +3292,11 @@ def test_get_funding_fee_dates(): | ||||
|  | ||||
| def test_calculate_funding_fees(): | ||||
|     return | ||||
|  | ||||
|  | ||||
| def test__get_funding_rate(default_conf, mocker): | ||||
|     return | ||||
|  | ||||
|  | ||||
| def test__get_funding_fee(): | ||||
|     return | ||||
|   | ||||
| @@ -1,4 +1,3 @@ | ||||
| from datetime import datetime, timedelta | ||||
| from random import randint | ||||
| from unittest.mock import MagicMock | ||||
|  | ||||
| @@ -268,18 +267,3 @@ def test_fill_leverage_brackets_ftx(default_conf, mocker): | ||||
|     exchange = get_patched_exchange(mocker, default_conf, id="ftx") | ||||
|     exchange.fill_leverage_brackets() | ||||
|     assert exchange._leverage_brackets == {} | ||||
|  | ||||
|  | ||||
| @pytest.mark.parametrize("pair,when", [ | ||||
|     ('XRP/USDT', datetime.utcnow()), | ||||
|     ('ADA/BTC', datetime.utcnow()), | ||||
|     ('XRP/USDT', datetime.utcnow() - timedelta(hours=30)), | ||||
| ]) | ||||
| def test__get_funding_rate(default_conf, mocker, pair, when): | ||||
|     api_mock = MagicMock() | ||||
|     exchange = get_patched_exchange(mocker, default_conf, api_mock, id="ftx") | ||||
|     assert exchange._get_funding_rate(pair, when) is None | ||||
|  | ||||
|  | ||||
| def test__get_funding_fee(): | ||||
|     return | ||||
|   | ||||
		Reference in New Issue
	
	Block a user