This commit is contained in:
Matthias 2022-03-26 16:19:29 +01:00
parent f5578aba48
commit f509959bd4
2 changed files with 35 additions and 22 deletions

View File

@ -1,6 +1,7 @@
""" Gate.io exchange subclass """ """ Gate.io exchange subclass """
import logging import logging
from typing import Dict, List, Tuple from datetime import datetime
from typing import Dict, List, Optional, Tuple
from freqtrade.enums import MarginMode, TradingMode from freqtrade.enums import MarginMode, TradingMode
from freqtrade.exceptions import OperationalException from freqtrade.exceptions import OperationalException
@ -46,25 +47,29 @@ class Gateio(Exchange):
raise OperationalException( raise OperationalException(
f'Exchange {self.name} does not support market orders.') f'Exchange {self.name} does not support market orders.')
def fetch_order(self, order_id: str, pair: str, params={}) -> Dict: def get_trades_for_order(self, order_id: str, pair: str, since: datetime,
order = super().fetch_order(order_id, pair, params) params: Optional[Dict] = None) -> List:
trades = super().get_trades_for_order(order_id, pair, since, params)
if self.trading_mode == TradingMode.FUTURES and order.get('fee') is None: if self.trading_mode == TradingMode.FUTURES:
# Futures usually don't contain fees in the response. # Futures usually don't contain fees in the response.
# As such, futures orders on gateio will not contain a fee, which causes # As such, futures orders on gateio will not contain a fee, which causes
# a repeated "update fee" cycle and wrong calculations. # a repeated "update fee" cycle and wrong calculations.
# Therefore we patch the response with fees if it's not available. # Therefore we patch the response with fees if it's not available.
# An alternative also contianing fees would be # An alternative also contianing fees would be
# privateFuturesGetSettleAccountBook({"settle": "usdt"}) # privateFuturesGetSettleAccountBook({"settle": "usdt"})
pair_fees = self._trading_fees.get(pair, {}) pair_fees = self._trading_fees.get(pair, {})
if pair_fees and pair_fees['taker'] is not None: if pair_fees:
order['fee'] = { for idx, trade in enumerate(trades):
if trade.get('fee', {}).get('cost') is None:
takerOrMaker = trade.get('takerOrMaker', 'taker')
if pair_fees.get(takerOrMaker) is not None:
trades[idx]['fee'] = {
'currency': self.get_pair_quote_currency(pair), 'currency': self.get_pair_quote_currency(pair),
'cost': abs(order['cost']) * pair_fees['taker'], 'cost': abs(trade['cost']) * pair_fees[takerOrMaker],
'rate': pair_fees['taker'], 'rate': pair_fees[takerOrMaker],
} }
return order return trades
def fetch_stoploss_order(self, order_id: str, pair: str, params={}) -> Dict: def fetch_stoploss_order(self, order_id: str, pair: str, params={}) -> Dict:
return self.fetch_order( return self.fetch_order(

View File

@ -1,3 +1,4 @@
from datetime import datetime, timezone
from unittest.mock import MagicMock from unittest.mock import MagicMock
import pytest import pytest
@ -72,8 +73,13 @@ def test_stoploss_adjust_gateio(mocker, default_conf, sl1, sl2, sl3, side):
assert exchange.stoploss_adjust(sl1, order, side) assert exchange.stoploss_adjust(sl1, order, side)
assert not exchange.stoploss_adjust(sl2, order, side) assert not exchange.stoploss_adjust(sl2, order, side)
@pytest.mark.parametrize('takerormaker,rate,cost', [
('taker', 0.0005, 0.0001554325),
('maker', 0.0, 0.0),
def test_fetch_order_gateio(mocker, default_conf): ])
def test_fetch_my_trades_gateio(mocker, default_conf, takerormaker, rate, cost):
mocker.patch('freqtrade.exchange.Exchange.exchange_has', return_value=True)
tick = {'ETH/USDT:USDT': { tick = {'ETH/USDT:USDT': {
'info': {'user_id': '', 'info': {'user_id': '',
'taker_fee': '0.0018', 'taker_fee': '0.0018',
@ -94,17 +100,19 @@ def test_fetch_order_gateio(mocker, default_conf):
default_conf['margin_mode'] = MarginMode.ISOLATED default_conf['margin_mode'] = MarginMode.ISOLATED
api_mock = MagicMock() api_mock = MagicMock()
api_mock.fetch_order = MagicMock(return_value={ api_mock.fetch_my_trades = MagicMock(return_value=[{
'fee': None, 'fee': {'cost': None},
'price': 3108.65, 'price': 3108.65,
'cost': 0.310865, 'cost': 0.310865,
'order': '22255',
'takerOrMaker': takerormaker,
'amount': 1, # 1 contract 'amount': 1, # 1 contract
}) }])
exchange = get_patched_exchange(mocker, default_conf, api_mock=api_mock, id='gateio') exchange = get_patched_exchange(mocker, default_conf, api_mock=api_mock, id='gateio')
exchange._trading_fees = tick exchange._trading_fees = tick
order = exchange.fetch_order('22255', 'ETH/USDT:USDT') trades = exchange.get_trades_for_order('22255', 'ETH/USDT:USDT', datetime.now(timezone.utc))
trade = trades[0]
assert order['fee'] assert trade['fee']
assert order['fee']['rate'] == 0.0005 assert trade['fee']['rate'] == rate
assert order['fee']['currency'] == 'USDT' assert trade['fee']['currency'] == 'USDT'
assert order['fee']['cost'] == 0.0001554325 assert trade['fee']['cost'] == cost