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 """
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.exceptions import OperationalException
@ -46,25 +47,29 @@ class Gateio(Exchange):
raise OperationalException(
f'Exchange {self.name} does not support market orders.')
def fetch_order(self, order_id: str, pair: str, params={}) -> Dict:
order = super().fetch_order(order_id, pair, params)
def get_trades_for_order(self, order_id: str, pair: str, since: datetime,
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.
# As such, futures orders on gateio will not contain a fee, which causes
# a repeated "update fee" cycle and wrong calculations.
# Therefore we patch the response with fees if it's not available.
# An alternative also contianing fees would be
# privateFuturesGetSettleAccountBook({"settle": "usdt"})
pair_fees = self._trading_fees.get(pair, {})
if pair_fees and pair_fees['taker'] is not None:
order['fee'] = {
'currency': self.get_pair_quote_currency(pair),
'cost': abs(order['cost']) * pair_fees['taker'],
'rate': pair_fees['taker'],
}
return order
if pair_fees:
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),
'cost': abs(trade['cost']) * pair_fees[takerOrMaker],
'rate': pair_fees[takerOrMaker],
}
return trades
def fetch_stoploss_order(self, order_id: str, pair: str, params={}) -> Dict:
return self.fetch_order(

View File

@ -1,3 +1,4 @@
from datetime import datetime, timezone
from unittest.mock import MagicMock
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 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': {
'info': {'user_id': '',
'taker_fee': '0.0018',
@ -94,17 +100,19 @@ def test_fetch_order_gateio(mocker, default_conf):
default_conf['margin_mode'] = MarginMode.ISOLATED
api_mock = MagicMock()
api_mock.fetch_order = MagicMock(return_value={
'fee': None,
api_mock.fetch_my_trades = MagicMock(return_value=[{
'fee': {'cost': None},
'price': 3108.65,
'cost': 0.310865,
'order': '22255',
'takerOrMaker': takerormaker,
'amount': 1, # 1 contract
})
}])
exchange = get_patched_exchange(mocker, default_conf, api_mock=api_mock, id='gateio')
exchange._trading_fees = tick
order = exchange.fetch_order('22255', 'ETH/USDT:USDT')
assert order['fee']
assert order['fee']['rate'] == 0.0005
assert order['fee']['currency'] == 'USDT'
assert order['fee']['cost'] == 0.0001554325
trades = exchange.get_trades_for_order('22255', 'ETH/USDT:USDT', datetime.now(timezone.utc))
trade = trades[0]
assert trade['fee']
assert trade['fee']['rate'] == rate
assert trade['fee']['currency'] == 'USDT'
assert trade['fee']['cost'] == cost