ccxt / ccxt

A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading API with support for more than 100 bitcoin/altcoin exchanges
https://docs.ccxt.com
MIT License
32.45k stars 7.46k forks source link

OKX - Issue when closing orders #15931

Closed pfpietro closed 1 year ago

pfpietro commented 1 year ago

Hi all, my issue is probably something really simple but I don't get where am I doing wrong. I open a position with a given amount and close the position with the same amount. But somehow when closing, the order opens a order 2.5 times bigger than the expected.

OPEN ORDER:

params = {'tdMode': 'cross', 'ccy': 'USDT'}
order = await self.okx.create_order(
    symbol='XRP/USDT', type='market', side='sell',
    amount=99.43, price=0.39024, params=params
)

RESULT:

{'amount': 99.431119,
 'average': 0.39005,
 'clientOrderId': 'e847386590ce4dBCce71dedc37e12254',
 'cost': 38.78310796595,
 'datetime': '2022-12-02T17:29:58.048Z',
 'fee': {'cost': 0.03878310796595, 'currency': 'USDT'},
 'fees': [{'cost': 0.03878310796595, 'currency': 'USDT'}],
 'filled': 99.431119,
 'id': '518962064594153472',
 'info': {'accFillSz': '99.431119',
          'avgPx': '0.39005',
          'cTime': '1670002198048',
          'category': 'normal',
          'ccy': 'USDT',
          'clOrdId': 'e847386590ce4dBCce71dedc37e12254',
          'fee': '-0.03878310796595',
          'feeCcy': 'USDT',
          'fillPx': '0.39005',
          'fillSz': '99.431119',
          'fillTime': '1670002198049',
          'instId': 'XRP-USDT',
          'instType': 'MARGIN',
          'lever': '5',
          'ordId': '518962064594153472',
          'ordType': 'market',
          'pnl': '0',
          'posSide': 'net',
          'px': '',
          'quickMgnType': '',
          'rebate': '0',
          'rebateCcy': 'XRP',
          'reduceOnly': 'false',
          'side': 'sell',
          'slOrdPx': '',
          'slTriggerPx': '',
          'slTriggerPxType': '',
          'source': '',
          'state': 'filled',
          'sz': '99.431119',
          'tag': 'e847386590ce4dBC',
          'tdMode': 'cross',
          'tgtCcy': '',
          'tpOrdPx': '',
          'tpTriggerPx': '',
          'tpTriggerPxType': '',
          'tradeId': '96628344',
          'uTime': '1670002198050'},
 'lastTradeTimestamp': 1670002198049,
 'postOnly': None,
 'price': 0.39005,
 'reduceOnly': False,
 'remaining': 0.0,
 'side': 'sell',
 'status': 'closed',
 'stopPrice': None,
 'symbol': 'XRP/USDT',
 'timeInForce': 'IOC',
 'timestamp': 1670002198048,
 'trades': [],
 'type': 'market'}

Now when I close the current order:

params = {'tdMode': 'cross', 'ccy': 'USDT'}
order = await self.okx.create_order(
    symbol='XRP/USDT', type='market', side='buy',
    amount=99.43, price=0.39017, params=params
)

If get the following:

{'amount': 99.43111,
 'average': 0.39015,
 'clientOrderId': 'e847386590ce4dBC328bc6dfc937795f',
 'cost': 99.43110980145,
 'datetime': '2022-12-02T17:36:47.913Z',
 'fee': {'cost': 0.254853543, 'currency': 'XRP'},
 'fees': [{'cost': 0.254853543, 'currency': 'XRP'}],
 'filled': 254.853543,
 'id': '518963783692562432',
 'info': {'accFillSz': '254.853543',
          'avgPx': '0.39015',
          'cTime': '1670002607913',
          'category': 'normal',
          'ccy': 'USDT',
          'clOrdId': 'e847386590ce4dBC328bc6dfc937795f',
          'fee': '-0.254853543',
          'feeCcy': 'XRP',
          'fillPx': '0.39015',
          'fillSz': '254.853543',
          'fillTime': '1670002607945',
          'instId': 'XRP-USDT',
          'instType': 'MARGIN',
          'lever': '5',
          'ordId': '518963783692562432',
          'ordType': 'market',
          'pnl': '-0.04872621986595',
          'posSide': 'net',
          'px': '',
          'quickMgnType': '',
          'rebate': '0',
          'rebateCcy': 'USDT',
          'reduceOnly': 'false',
          'side': 'buy',
          'slOrdPx': '',
          'slTriggerPx': '',
          'slTriggerPxType': '',
          'source': '',
          'state': 'filled',
          'sz': '99.43111',
          'tag': 'e847386590ce4dBC',
          'tdMode': 'cross',
          'tgtCcy': '',
          'tpOrdPx': '',
          'tpTriggerPx': '',
          'tpTriggerPxType': '',
          'tradeId': '96628440',
          'uTime': '1670002607950'},
 'lastTradeTimestamp': 1670002607945,
 'postOnly': None,
 'price': 0.39015,
 'reduceOnly': False,
 'remaining': -155.422433,
 'side': 'buy',
 'status': 'closed',
 'stopPrice': None,
 'symbol': 'XRP/USDT',
 'timeInForce': 'IOC',
 'timestamp': 1670002607913,
 'trades': [],
 'type': 'market'}

How come in the second one I get the COST completely different from the first one ?

pfpietro commented 1 year ago

Also setting 'reduceOnly': 'true' in the params I get insufficient margin.

Dan-krm commented 1 year ago

@pfpietro I've opened a pull request that adds reduceOnly to createOrder. Once the PR is merged this request will work properly for closing your order:

params = {'marginMode': 'cross', 'reduceOnly': true}
order = await self.okx.create_order(
    symbol='XRP/USDT', type='market', side='buy',
    amount=35.2446, price=undefined, params=params
)

I'd recommend using 'marginMode' instead of 'tdMode' and you need to enter the amount in USDT which can be found from fetchPosition -> info -> availPos

Alternatively you could try using the implicit api https://docs.ccxt.com/en/latest/manual.html#implicit-api with this endpoint privatePostTradeClosePosition https://www.okx.com/docs-v5/en/#rest-api-trade-close-positions

order = await self.okx.privatePostTradeClosePosition({
    'instId': 'XRP-USDT',
    'mgnMode': 'cross',
})
pfpietro commented 1 year ago

Thanks Dan.