mirror of
https://github.com/freqtrade/freqtrade.git
synced 2024-11-10 18:23:55 +00:00
129 lines
4.8 KiB
Python
129 lines
4.8 KiB
Python
""" Gate.io exchange subclass """
|
|
import logging
|
|
from typing import Dict, List, Optional, Tuple
|
|
|
|
from freqtrade.enums import Collateral, TradingMode
|
|
from freqtrade.exceptions import OperationalException
|
|
from freqtrade.exchange import Exchange
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class Gateio(Exchange):
|
|
"""
|
|
Gate.io exchange class. Contains adjustments needed for Freqtrade to work
|
|
with this exchange.
|
|
|
|
Please note that this exchange is not included in the list of exchanges
|
|
officially supported by the Freqtrade development team. So some features
|
|
may still not work as expected.
|
|
"""
|
|
|
|
_ft_has: Dict = {
|
|
"ohlcv_candle_limit": 1000,
|
|
"ohlcv_volume_currency": "quote",
|
|
}
|
|
|
|
_headers = {'X-Gate-Channel-Id': 'freqtrade'}
|
|
|
|
_supported_trading_mode_collateral_pairs: List[Tuple[TradingMode, Collateral]] = [
|
|
# TradingMode.SPOT always supported and not required in this list
|
|
# (TradingMode.MARGIN, Collateral.CROSS),
|
|
# (TradingMode.FUTURES, Collateral.CROSS),
|
|
(TradingMode.FUTURES, Collateral.ISOLATED)
|
|
]
|
|
|
|
def validate_ordertypes(self, order_types: Dict) -> None:
|
|
super().validate_ordertypes(order_types)
|
|
|
|
if any(v == 'market' for k, v in order_types.items()):
|
|
raise OperationalException(
|
|
f'Exchange {self.name} does not support market orders.')
|
|
|
|
def get_maintenance_ratio_and_amt(
|
|
self,
|
|
pair: str,
|
|
nominal_value: Optional[float] = 0.0,
|
|
) -> Tuple[float, Optional[float]]:
|
|
"""
|
|
:return: The maintenance margin ratio and maintenance amount
|
|
"""
|
|
info = self.markets[pair]['info']
|
|
return (float(info['maintenance_rate']), None)
|
|
|
|
def liquidation_price_helper(
|
|
self,
|
|
open_rate: float, # Entry price of position
|
|
is_short: bool,
|
|
leverage: float,
|
|
trading_mode: TradingMode,
|
|
mm_ratio: float,
|
|
collateral: Collateral,
|
|
maintenance_amt: Optional[float] = None, # (Binance)
|
|
position: Optional[float] = None, # (Binance and Gateio) Absolute value of position size
|
|
wallet_balance: Optional[float] = None, # (Binance and Gateio)
|
|
taker_fee_rate: Optional[float] = None, # (Gateio & Okex)
|
|
liability: Optional[float] = None, # (Okex)
|
|
interest: Optional[float] = None, # (Okex)
|
|
position_assets: Optional[float] = None, # * (Okex) Might be same as position
|
|
mm_ex_1: Optional[float] = 0.0, # (Binance) Cross only
|
|
upnl_ex_1: Optional[float] = 0.0, # (Binance) Cross only
|
|
) -> Optional[float]:
|
|
"""
|
|
PERPETUAL: https://www.gate.io/help/futures/perpetual/22160/calculation-of-liquidation-price
|
|
|
|
:param exchange_name:
|
|
:param open_rate: Entry price of position
|
|
:param is_short: True if the trade is a short, false otherwise
|
|
:param leverage: The amount of leverage on the trade
|
|
:param trading_mode: SPOT, MARGIN, FUTURES, etc.
|
|
:param position: Absolute value of position size (in base currency)
|
|
:param mm_ratio:
|
|
:param collateral: Either ISOLATED or CROSS
|
|
:param maintenance_amt: # * Not required by Gateio
|
|
:param wallet_balance:
|
|
Cross-Margin Mode: crossWalletBalance
|
|
Isolated-Margin Mode: isolatedWalletBalance
|
|
:param position: Absolute value of position size (in base currency)
|
|
:param taker_fee_rate:
|
|
|
|
# * Not required by Gateio
|
|
:param liability:
|
|
:param interest:
|
|
:param position_assets:
|
|
:param mm_ex_1:
|
|
:param upnl_ex_1:
|
|
"""
|
|
if trading_mode == TradingMode.SPOT:
|
|
return None
|
|
|
|
if not collateral:
|
|
raise OperationalException(
|
|
"Parameter collateral is required by liquidation_price when trading_mode is "
|
|
f"{trading_mode}"
|
|
)
|
|
|
|
if (not wallet_balance or not position or not taker_fee_rate):
|
|
raise OperationalException(
|
|
"Parameters wallet_balance, position, taker_fee_rate"
|
|
"are required by Gateio.liquidation_price"
|
|
)
|
|
|
|
if trading_mode == TradingMode.FUTURES and collateral == Collateral.ISOLATED:
|
|
# if is_inverse:
|
|
# # ! Not implemented
|
|
# 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:
|
|
raise OperationalException(
|
|
f"Gateio does not support {collateral.value} Mode {trading_mode.value} trading ")
|