mirror of
https://github.com/freqtrade/freqtrade.git
synced 2025-11-29 08:33:07 +00:00
okx: Use proper history endpoint for fetch_orders
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user