okx: Use proper history endpoint for fetch_orders

This commit is contained in:
Matthias
2023-09-16 20:00:39 +02:00
parent 5745722a37
commit 14c5f435aa
2 changed files with 84 additions and 0 deletions

View File

@@ -1,4 +1,5 @@
import logging
from datetime import timedelta
from typing import Any, Dict, List, Optional, Tuple
import ccxt
@@ -10,6 +11,7 @@ from freqtrade.exceptions import (DDosProtection, OperationalException, Retryabl
from freqtrade.exchange import Exchange, date_minus_candles
from freqtrade.exchange.common import retrier
from freqtrade.misc import safe_value_fallback2
from freqtrade.util import dt_now, dt_ts
logger = logging.getLogger(__name__)
@@ -240,3 +242,18 @@ class Okx(Exchange):
pair=pair,
params=params1,
)
def _fetch_orders_emulate(self, pair: str, since_ms: int) -> List[Dict]:
orders = []
orders = self._api.fetch_closed_orders(pair, since=since_ms)
if (since_ms < dt_ts(dt_now() - timedelta(days=6, hours=23))):
# Regular fetch_closed_orders only returns 7 days of data.
# Force usage of "archive" endpoint, which returns 3 months of data.
params = {'method': 'privateGetTradeOrdersHistoryArchive'}
orders_hist = self._api.fetch_closed_orders(pair, since=since_ms, params=params)
orders.extend(orders_hist)
orders_open = self._api.fetch_open_orders(pair, since=since_ms)
orders.extend(orders_open)
return orders

View File

@@ -618,3 +618,70 @@ def test__get_stop_params_okx(mocker, default_conf):
assert params['tdMode'] == 'isolated'
assert params['posSide'] == 'net'
def test_fetch_orders_okx(default_conf, mocker, limit_order):
api_mock = MagicMock()
api_mock.fetch_orders = MagicMock(return_value=[
limit_order['buy'],
limit_order['sell'],
])
api_mock.fetch_open_orders = MagicMock(return_value=[limit_order['buy']])
api_mock.fetch_closed_orders = MagicMock(return_value=[limit_order['buy']])
mocker.patch(f'{EXMS}.exchange_has', return_value=True)
start_time = datetime.now(timezone.utc) - timedelta(days=20)
exchange = get_patched_exchange(mocker, default_conf, api_mock, id='okx')
# Not available in dry-run
assert exchange.fetch_orders('mocked', start_time) == []
assert api_mock.fetch_orders.call_count == 0
default_conf['dry_run'] = False
exchange = get_patched_exchange(mocker, default_conf, api_mock, id='okx')
def has_resp(_, endpoint):
if endpoint == 'fetchOrders':
return False
if endpoint == 'fetchClosedOrders':
return True
if endpoint == 'fetchOpenOrders':
return True
mocker.patch(f'{EXMS}.exchange_has', has_resp)
history_params = {'method': 'privateGetTradeOrdersHistoryArchive'}
# happy path without fetchOrders
exchange.fetch_orders('mocked', start_time)
assert api_mock.fetch_orders.call_count == 0
assert api_mock.fetch_open_orders.call_count == 1
assert api_mock.fetch_closed_orders.call_count == 2
assert 'params' not in api_mock.fetch_closed_orders.call_args_list[0][1]
assert api_mock.fetch_closed_orders.call_args_list[1][1]['params'] == history_params
api_mock.fetch_open_orders.reset_mock()
api_mock.fetch_closed_orders.reset_mock()
# regular closed_orders endpoint only has history for 7 days.
exchange.fetch_orders('mocked', datetime.now(timezone.utc) - timedelta(days=6))
assert api_mock.fetch_orders.call_count == 0
assert api_mock.fetch_open_orders.call_count == 1
assert api_mock.fetch_closed_orders.call_count == 1
assert 'params' not in api_mock.fetch_closed_orders.call_args_list[0][1]
mocker.patch(f'{EXMS}.exchange_has', return_value=True)
# Unhappy path - first fetch-orders call fails.
api_mock.fetch_orders = MagicMock(side_effect=ccxt.NotSupported())
api_mock.fetch_open_orders.reset_mock()
api_mock.fetch_closed_orders.reset_mock()
exchange.fetch_orders('mocked', start_time)
assert api_mock.fetch_orders.call_count == 1
assert api_mock.fetch_open_orders.call_count == 1
assert api_mock.fetch_closed_orders.call_count == 2
assert 'params' not in api_mock.fetch_closed_orders.call_args_list[0][1]
assert api_mock.fetch_closed_orders.call_args_list[1][1]['params'] == history_params