Merge pull request #8360 from freqtrade/okx_stop

Okx stoploss on exchange
This commit is contained in:
Matthias
2023-03-20 19:19:59 +01:00
committed by GitHub
3 changed files with 169 additions and 7 deletions

View File

@@ -1039,9 +1039,9 @@ def test_validate_ordertypes(default_conf, mocker):
('bybit', 'last', True),
('bybit', 'mark', True),
('bybit', 'index', True),
# ('okx', 'last', True),
# ('okx', 'mark', True),
# ('okx', 'index', True),
('okx', 'last', True),
('okx', 'mark', True),
('okx', 'index', True),
('gate', 'last', True),
('gate', 'mark', True),
('gate', 'index', True),

View File

@@ -2,11 +2,13 @@ from datetime import datetime, timedelta, timezone
from pathlib import Path
from unittest.mock import MagicMock, PropertyMock
import ccxt
import pytest
from freqtrade.enums import CandleType, MarginMode, TradingMode
from freqtrade.exceptions import RetryableOrderError
from freqtrade.exchange.exchange import timeframe_to_minutes
from tests.conftest import get_mock_coro, get_patched_exchange, log_has
from tests.conftest import EXMS, get_mock_coro, get_patched_exchange, log_has
from tests.exchange.test_exchange import ccxt_exceptionhandlers
@@ -476,3 +478,84 @@ def test_load_leverage_tiers_okx(default_conf, mocker, markets, tmpdir, caplog,
exchange.load_leverage_tiers()
assert log_has(logmsg, caplog)
@pytest.mark.usefixtures("init_persistence")
def test_fetch_stoploss_order_okx(default_conf, mocker):
default_conf['dry_run'] = False
api_mock = MagicMock()
api_mock.fetch_order = MagicMock()
exchange = get_patched_exchange(mocker, default_conf, api_mock, id='okx')
exchange.fetch_stoploss_order('1234', 'ETH/BTC')
assert api_mock.fetch_order.call_count == 1
assert api_mock.fetch_order.call_args_list[0][0][0] == '1234'
assert api_mock.fetch_order.call_args_list[0][0][1] == 'ETH/BTC'
assert api_mock.fetch_order.call_args_list[0][1]['params'] == {'stop': True}
api_mock.fetch_order = MagicMock(side_effect=ccxt.OrderNotFound)
api_mock.fetch_open_orders = MagicMock(return_value=[])
api_mock.fetch_closed_orders = MagicMock(return_value=[])
api_mock.fetch_canceled_orders = MagicMock(creturn_value=[])
with pytest.raises(RetryableOrderError):
exchange.fetch_stoploss_order('1234', 'ETH/BTC')
assert api_mock.fetch_order.call_count == 1
assert api_mock.fetch_open_orders.call_count == 1
assert api_mock.fetch_closed_orders.call_count == 1
assert api_mock.fetch_canceled_orders.call_count == 1
api_mock.fetch_order.reset_mock()
api_mock.fetch_open_orders.reset_mock()
api_mock.fetch_closed_orders.reset_mock()
api_mock.fetch_canceled_orders.reset_mock()
api_mock.fetch_closed_orders = MagicMock(return_value=[
{
'id': '1234',
'status': 'closed',
'info': {'ordId': '123455'}
}
])
mocker.patch(f"{EXMS}.fetch_order", MagicMock(return_value={'id': '123455'}))
resp = exchange.fetch_stoploss_order('1234', 'ETH/BTC')
assert api_mock.fetch_order.call_count == 1
assert api_mock.fetch_open_orders.call_count == 1
assert api_mock.fetch_closed_orders.call_count == 1
assert api_mock.fetch_canceled_orders.call_count == 0
assert resp['id'] == '1234'
assert resp['id_stop'] == '123455'
assert resp['type'] == 'stoploss'
default_conf['dry_run'] = True
exchange = get_patched_exchange(mocker, default_conf, api_mock, id='okx')
dro_mock = mocker.patch(f"{EXMS}.fetch_dry_run_order", MagicMock(return_value={'id': '123455'}))
api_mock.fetch_order.reset_mock()
api_mock.fetch_open_orders.reset_mock()
api_mock.fetch_closed_orders.reset_mock()
api_mock.fetch_canceled_orders.reset_mock()
resp = exchange.fetch_stoploss_order('1234', 'ETH/BTC')
assert api_mock.fetch_order.call_count == 0
assert api_mock.fetch_open_orders.call_count == 0
assert api_mock.fetch_closed_orders.call_count == 0
assert api_mock.fetch_canceled_orders.call_count == 0
assert dro_mock.call_count == 1
@pytest.mark.parametrize('sl1,sl2,sl3,side', [
(1501, 1499, 1501, "sell"),
(1499, 1501, 1499, "buy")
])
def test_stoploss_adjust_okx(mocker, default_conf, sl1, sl2, sl3, side):
exchange = get_patched_exchange(mocker, default_conf, id='okx')
order = {
'type': 'stoploss',
'price': 1500,
'stopLossPrice': 1500,
}
assert exchange.stoploss_adjust(sl1, order, side=side)
assert not exchange.stoploss_adjust(sl2, order, side=side)