ccxt 4.3.11__py2.py3-none-any.whl → 4.3.12__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ccxt/__init__.py +1 -1
- ccxt/async_support/__init__.py +1 -1
- ccxt/async_support/base/exchange.py +1 -1
- ccxt/async_support/bigone.py +22 -22
- ccxt/async_support/binance.py +7 -7
- ccxt/async_support/bingx.py +2 -2
- ccxt/async_support/bitget.py +10 -8
- ccxt/async_support/bitmart.py +7 -11
- ccxt/async_support/bitmex.py +2 -2
- ccxt/async_support/bybit.py +75 -65
- ccxt/async_support/coinbase.py +8 -8
- ccxt/async_support/coinbaseinternational.py +2 -2
- ccxt/async_support/coinex.py +501 -445
- ccxt/async_support/coinlist.py +12 -12
- ccxt/async_support/coinmetro.py +2 -2
- ccxt/async_support/cryptocom.py +16 -16
- ccxt/async_support/digifinex.py +3 -3
- ccxt/async_support/gate.py +2 -2
- ccxt/async_support/hitbtc.py +3 -3
- ccxt/async_support/htx.py +6 -9
- ccxt/async_support/indodax.py +2 -2
- ccxt/async_support/kraken.py +3 -1
- ccxt/async_support/kucoin.py +4 -4
- ccxt/async_support/kucoinfutures.py +6 -6
- ccxt/async_support/mexc.py +5 -5
- ccxt/async_support/okx.py +9 -9
- ccxt/async_support/poloniexfutures.py +4 -4
- ccxt/async_support/probit.py +2 -2
- ccxt/async_support/whitebit.py +72 -1
- ccxt/async_support/woo.py +2 -2
- ccxt/base/exchange.py +14 -2
- ccxt/base/types.py +25 -0
- ccxt/bigone.py +22 -22
- ccxt/binance.py +7 -7
- ccxt/bingx.py +2 -2
- ccxt/bitget.py +10 -8
- ccxt/bitmart.py +7 -11
- ccxt/bitmex.py +2 -2
- ccxt/bybit.py +75 -65
- ccxt/coinbase.py +8 -8
- ccxt/coinbaseinternational.py +2 -2
- ccxt/coinex.py +501 -445
- ccxt/coinlist.py +12 -12
- ccxt/coinmetro.py +2 -2
- ccxt/cryptocom.py +16 -16
- ccxt/digifinex.py +3 -3
- ccxt/gate.py +2 -2
- ccxt/hitbtc.py +3 -3
- ccxt/htx.py +6 -9
- ccxt/indodax.py +2 -2
- ccxt/kraken.py +3 -1
- ccxt/kucoin.py +4 -4
- ccxt/kucoinfutures.py +6 -6
- ccxt/mexc.py +5 -5
- ccxt/okx.py +9 -9
- ccxt/poloniexfutures.py +4 -4
- ccxt/pro/__init__.py +1 -1
- ccxt/pro/bitget.py +139 -87
- ccxt/pro/bybit.py +192 -12
- ccxt/pro/coinbase.py +90 -20
- ccxt/pro/mexc.py +21 -1
- ccxt/probit.py +2 -2
- ccxt/test/base/test_datetime.py +6 -0
- ccxt/test/base/test_ledger_entry.py +2 -2
- ccxt/whitebit.py +72 -1
- ccxt/woo.py +2 -2
- {ccxt-4.3.11.dist-info → ccxt-4.3.12.dist-info}/METADATA +4 -4
- {ccxt-4.3.11.dist-info → ccxt-4.3.12.dist-info}/RECORD +70 -72
- ccxt/async_support/flowbtc.py +0 -34
- ccxt/flowbtc.py +0 -34
- {ccxt-4.3.11.dist-info → ccxt-4.3.12.dist-info}/WHEEL +0 -0
- {ccxt-4.3.11.dist-info → ccxt-4.3.12.dist-info}/top_level.txt +0 -0
ccxt/pro/bitget.py
CHANGED
@@ -658,54 +658,69 @@ class bitget(ccxt.async_support.bitget):
|
|
658
658
|
# "side": "buy",
|
659
659
|
# "tradeId": "1116461060594286593"
|
660
660
|
# }
|
661
|
+
# swap private
|
661
662
|
#
|
662
|
-
#
|
663
|
-
#
|
664
|
-
#
|
665
|
-
#
|
666
|
-
#
|
667
|
-
#
|
668
|
-
#
|
669
|
-
#
|
670
|
-
#
|
671
|
-
#
|
672
|
-
#
|
673
|
-
#
|
674
|
-
#
|
675
|
-
#
|
676
|
-
#
|
677
|
-
#
|
678
|
-
#
|
679
|
-
#
|
680
|
-
#
|
681
|
-
#
|
682
|
-
#
|
683
|
-
#
|
684
|
-
#
|
685
|
-
#
|
686
|
-
#
|
687
|
-
#
|
688
|
-
#
|
689
|
-
#
|
690
|
-
#
|
691
|
-
#
|
692
|
-
#
|
693
|
-
#
|
694
|
-
#
|
695
|
-
#
|
696
|
-
#
|
663
|
+
# {
|
664
|
+
# "orderId": "1169142761031114781",
|
665
|
+
# "tradeId": "1169142761312637004",
|
666
|
+
# "symbol": "LTCUSDT",
|
667
|
+
# "orderType": "market",
|
668
|
+
# "side": "buy",
|
669
|
+
# "price": "80.87",
|
670
|
+
# "baseVolume": "0.1",
|
671
|
+
# "quoteVolume": "8.087",
|
672
|
+
# "profit": "0",
|
673
|
+
# "tradeSide": "open",
|
674
|
+
# "posMode": "hedge_mode",
|
675
|
+
# "tradeScope": "taker",
|
676
|
+
# "feeDetail": [
|
677
|
+
# {
|
678
|
+
# "feeCoin": "USDT",
|
679
|
+
# "deduction": "no",
|
680
|
+
# "totalDeductionFee": "0",
|
681
|
+
# "totalFee": "-0.0048522"
|
682
|
+
# }
|
683
|
+
# ],
|
684
|
+
# "cTime": "1714471276596",
|
685
|
+
# "uTime": "1714471276596"
|
686
|
+
# }
|
687
|
+
# spot private
|
688
|
+
# {
|
689
|
+
# "orderId": "1169142457356959747",
|
690
|
+
# "tradeId": "1169142457636958209",
|
691
|
+
# "symbol": "LTCUSDT",
|
692
|
+
# "orderType": "market",
|
693
|
+
# "side": "buy",
|
694
|
+
# "priceAvg": "81.069",
|
695
|
+
# "size": "0.074",
|
696
|
+
# "amount": "5.999106",
|
697
|
+
# "tradeScope": "taker",
|
698
|
+
# "feeDetail": [
|
699
|
+
# {
|
700
|
+
# "feeCoin": "LTC",
|
701
|
+
# "deduction": "no",
|
702
|
+
# "totalDeductionFee": "0",
|
703
|
+
# "totalFee": "0.000074"
|
704
|
+
# }
|
705
|
+
# ],
|
706
|
+
# "cTime": "1714471204194",
|
707
|
+
# "uTime": "1714471204194"
|
708
|
+
# }
|
697
709
|
#
|
698
|
-
instId = self.
|
710
|
+
instId = self.safe_string_2(trade, 'symbol', 'instId')
|
711
|
+
posMode = self.safe_string(trade, 'posMode')
|
712
|
+
defaultType = 'contract' if (posMode is not None) else 'spot'
|
699
713
|
if market is None:
|
700
|
-
market = self.safe_market(instId, None, None,
|
714
|
+
market = self.safe_market(instId, None, None, defaultType)
|
701
715
|
timestamp = self.safe_integer_n(trade, ['uTime', 'cTime', 'ts'])
|
702
|
-
|
716
|
+
feeDetail = self.safe_list(trade, 'feeDetail', [])
|
717
|
+
first = self.safe_dict(feeDetail, 0)
|
703
718
|
fee = None
|
704
|
-
if
|
705
|
-
feeCurrencyId = self.safe_string(
|
719
|
+
if first is not None:
|
720
|
+
feeCurrencyId = self.safe_string(first, 'feeCoin')
|
706
721
|
feeCurrencyCode = self.safe_currency_code(feeCurrencyId)
|
707
722
|
fee = {
|
708
|
-
'cost': Precise.string_abs(
|
723
|
+
'cost': Precise.string_abs(self.safe_string(first, 'totalFee')),
|
709
724
|
'currency': feeCurrencyCode,
|
710
725
|
}
|
711
726
|
return self.safe_trade({
|
@@ -715,12 +730,12 @@ class bitget(ccxt.async_support.bitget):
|
|
715
730
|
'timestamp': timestamp,
|
716
731
|
'datetime': self.iso8601(timestamp),
|
717
732
|
'symbol': market['symbol'],
|
718
|
-
'type':
|
733
|
+
'type': self.safe_string(trade, 'orderType'),
|
719
734
|
'side': self.safe_string(trade, 'side'),
|
720
|
-
'takerOrMaker':
|
735
|
+
'takerOrMaker': self.safe_string(trade, 'tradeScope'),
|
721
736
|
'price': self.safe_string_2(trade, 'priceAvg', 'price'),
|
722
|
-
'amount': self.
|
723
|
-
'cost': self.
|
737
|
+
'amount': self.safe_string_2(trade, 'size', 'baseVolume'),
|
738
|
+
'cost': self.safe_string_2(trade, 'amount', 'quoteVolume'),
|
724
739
|
'fee': fee,
|
725
740
|
}, market)
|
726
741
|
|
@@ -1100,8 +1115,6 @@ class bitget(ccxt.async_support.bitget):
|
|
1100
1115
|
marketSymbols = {}
|
1101
1116
|
for i in range(0, len(data)):
|
1102
1117
|
order = data[i]
|
1103
|
-
if 'tradeId' in order:
|
1104
|
-
self.handle_my_trades(client, order)
|
1105
1118
|
marketId = self.safe_string(order, 'instId')
|
1106
1119
|
market = self.safe_market(marketId, None, None, marketType)
|
1107
1120
|
parsed = self.parse_ws_order(order, market)
|
@@ -1293,8 +1306,6 @@ class bitget(ccxt.async_support.bitget):
|
|
1293
1306
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1294
1307
|
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
1295
1308
|
"""
|
1296
|
-
# only contracts stream provides the trade info consistently in between order updates
|
1297
|
-
# the spot stream only provides on limit orders updates so we can't support it for spot
|
1298
1309
|
await self.load_markets()
|
1299
1310
|
market = None
|
1300
1311
|
messageHash = 'myTrades'
|
@@ -1302,16 +1313,12 @@ class bitget(ccxt.async_support.bitget):
|
|
1302
1313
|
market = self.market(symbol)
|
1303
1314
|
symbol = market['symbol']
|
1304
1315
|
messageHash = messageHash + ':' + symbol
|
1305
|
-
type = None
|
1306
|
-
type, params = self.handle_market_type_and_params('watchMyTrades', market, params)
|
1307
|
-
if type == 'spot':
|
1308
|
-
raise NotSupported(self.id + ' watchMyTrades is not supported for ' + type + ' markets.')
|
1309
1316
|
instType = None
|
1310
1317
|
instType, params = self.get_inst_type(market, params)
|
1311
|
-
subscriptionHash = '
|
1318
|
+
subscriptionHash = 'fill:' + instType
|
1312
1319
|
args = {
|
1313
1320
|
'instType': instType,
|
1314
|
-
'channel': '
|
1321
|
+
'channel': 'fill',
|
1315
1322
|
'instId': 'default',
|
1316
1323
|
}
|
1317
1324
|
trades = await self.watch_private(messageHash, subscriptionHash, args, params)
|
@@ -1321,47 +1328,91 @@ class bitget(ccxt.async_support.bitget):
|
|
1321
1328
|
|
1322
1329
|
def handle_my_trades(self, client: Client, message):
|
1323
1330
|
#
|
1324
|
-
#
|
1325
|
-
#
|
1331
|
+
# spot
|
1332
|
+
# {
|
1333
|
+
# "action": "snapshot",
|
1334
|
+
# "arg": {
|
1335
|
+
# "instType": "SPOT",
|
1336
|
+
# "channel": "fill",
|
1337
|
+
# "instId": "default"
|
1338
|
+
# },
|
1339
|
+
# "data": [
|
1340
|
+
# {
|
1341
|
+
# "orderId": "1169142457356959747",
|
1342
|
+
# "tradeId": "1169142457636958209",
|
1343
|
+
# "symbol": "LTCUSDT",
|
1344
|
+
# "orderType": "market",
|
1345
|
+
# "side": "buy",
|
1346
|
+
# "priceAvg": "81.069",
|
1347
|
+
# "size": "0.074",
|
1348
|
+
# "amount": "5.999106",
|
1349
|
+
# "tradeScope": "taker",
|
1350
|
+
# "feeDetail": [
|
1351
|
+
# {
|
1352
|
+
# "feeCoin": "LTC",
|
1353
|
+
# "deduction": "no",
|
1354
|
+
# "totalDeductionFee": "0",
|
1355
|
+
# "totalFee": "0.000074"
|
1356
|
+
# }
|
1357
|
+
# ],
|
1358
|
+
# "cTime": "1714471204194",
|
1359
|
+
# "uTime": "1714471204194"
|
1360
|
+
# }
|
1361
|
+
# ],
|
1362
|
+
# "ts": 1714471204270
|
1363
|
+
# }
|
1364
|
+
# swap
|
1326
1365
|
# {
|
1327
|
-
# "
|
1328
|
-
# "
|
1329
|
-
#
|
1330
|
-
#
|
1331
|
-
#
|
1332
|
-
#
|
1333
|
-
#
|
1334
|
-
#
|
1335
|
-
#
|
1336
|
-
#
|
1337
|
-
#
|
1338
|
-
#
|
1339
|
-
#
|
1340
|
-
#
|
1341
|
-
#
|
1342
|
-
#
|
1343
|
-
#
|
1344
|
-
#
|
1345
|
-
#
|
1346
|
-
#
|
1347
|
-
#
|
1348
|
-
#
|
1349
|
-
#
|
1350
|
-
#
|
1351
|
-
#
|
1366
|
+
# "action": "snapshot",
|
1367
|
+
# "arg": {
|
1368
|
+
# "instType": "USDT-FUTURES",
|
1369
|
+
# "channel": "fill",
|
1370
|
+
# "instId": "default"
|
1371
|
+
# },
|
1372
|
+
# "data": [
|
1373
|
+
# {
|
1374
|
+
# "orderId": "1169142761031114781",
|
1375
|
+
# "tradeId": "1169142761312637004",
|
1376
|
+
# "symbol": "LTCUSDT",
|
1377
|
+
# "orderType": "market",
|
1378
|
+
# "side": "buy",
|
1379
|
+
# "price": "80.87",
|
1380
|
+
# "baseVolume": "0.1",
|
1381
|
+
# "quoteVolume": "8.087",
|
1382
|
+
# "profit": "0",
|
1383
|
+
# "tradeSide": "open",
|
1384
|
+
# "posMode": "hedge_mode",
|
1385
|
+
# "tradeScope": "taker",
|
1386
|
+
# "feeDetail": [
|
1387
|
+
# {
|
1388
|
+
# "feeCoin": "USDT",
|
1389
|
+
# "deduction": "no",
|
1390
|
+
# "totalDeductionFee": "0",
|
1391
|
+
# "totalFee": "-0.0048522"
|
1392
|
+
# }
|
1393
|
+
# ],
|
1394
|
+
# "cTime": "1714471276596",
|
1395
|
+
# "uTime": "1714471276596"
|
1396
|
+
# }
|
1397
|
+
# ],
|
1398
|
+
# "ts": 1714471276629
|
1352
1399
|
# }
|
1353
1400
|
#
|
1354
1401
|
if self.myTrades is None:
|
1355
1402
|
limit = self.safe_integer(self.options, 'tradesLimit', 1000)
|
1356
1403
|
self.myTrades = ArrayCache(limit)
|
1357
1404
|
stored = self.myTrades
|
1358
|
-
|
1359
|
-
|
1360
|
-
symbol = parsed['symbol']
|
1405
|
+
data = self.safe_list(message, 'data', [])
|
1406
|
+
length = len(data)
|
1361
1407
|
messageHash = 'myTrades'
|
1408
|
+
for i in range(0, length):
|
1409
|
+
trade = data[i]
|
1410
|
+
parsed = self.parse_ws_trade(trade)
|
1411
|
+
stored.append(parsed)
|
1412
|
+
symbol = parsed['symbol']
|
1413
|
+
symbolSpecificMessageHash = 'myTrades:' + symbol
|
1414
|
+
client.resolve(stored, symbolSpecificMessageHash)
|
1362
1415
|
client.resolve(stored, messageHash)
|
1363
|
-
symbolSpecificMessageHash = 'myTrades:' + symbol
|
1364
|
-
client.resolve(stored, symbolSpecificMessageHash)
|
1365
1416
|
|
1366
1417
|
async def watch_balance(self, params={}) -> Balances:
|
1367
1418
|
"""
|
@@ -1623,6 +1674,7 @@ class bitget(ccxt.async_support.bitget):
|
|
1623
1674
|
methods = {
|
1624
1675
|
'ticker': self.handle_ticker,
|
1625
1676
|
'trade': self.handle_trades,
|
1677
|
+
'fill': self.handle_my_trades,
|
1626
1678
|
'orders': self.handle_order,
|
1627
1679
|
'ordersAlgo': self.handle_order,
|
1628
1680
|
'account': self.handle_balance,
|
ccxt/pro/bybit.py
CHANGED
@@ -7,7 +7,7 @@ import ccxt.async_support
|
|
7
7
|
from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide, ArrayCacheByTimestamp
|
8
8
|
import asyncio
|
9
9
|
import hashlib
|
10
|
-
from ccxt.base.types import Balances, Int, Order, OrderBook, Position, Str, Strings, Ticker, Tickers, Trade
|
10
|
+
from ccxt.base.types import Balances, Int, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade
|
11
11
|
from ccxt.async_support.base.ws.client import Client
|
12
12
|
from typing import List
|
13
13
|
from ccxt.base.errors import ExchangeError
|
@@ -22,7 +22,7 @@ class bybit(ccxt.async_support.bybit):
|
|
22
22
|
return self.deep_extend(super(bybit, self).describe(), {
|
23
23
|
'has': {
|
24
24
|
'ws': True,
|
25
|
-
'createOrderWs': False,
|
25
|
+
'createOrderWs': False, # available only in sandbox
|
26
26
|
'editOrderWs': False,
|
27
27
|
'fetchOpenOrdersWs': False,
|
28
28
|
'fetchOrderWs': False,
|
@@ -60,6 +60,7 @@ class bybit(ccxt.async_support.bybit):
|
|
60
60
|
},
|
61
61
|
'contract': 'wss://stream.{hostname}/v5/private',
|
62
62
|
'usdc': 'wss://stream.{hostname}/trade/option/usdc/private/v1',
|
63
|
+
'trade': 'wss://stream-testnet.bybit.com/v5/trade',
|
63
64
|
},
|
64
65
|
},
|
65
66
|
},
|
@@ -78,6 +79,7 @@ class bybit(ccxt.async_support.bybit):
|
|
78
79
|
},
|
79
80
|
'contract': 'wss://stream-testnet.{hostname}/v5/private',
|
80
81
|
'usdc': 'wss://stream-testnet.{hostname}/trade/option/usdc/private/v1',
|
82
|
+
'trade': 'wss://stream-testnet.bybit.com/v5/trade',
|
81
83
|
},
|
82
84
|
},
|
83
85
|
},
|
@@ -172,6 +174,127 @@ class bybit(ccxt.async_support.bybit):
|
|
172
174
|
params = self.omit(params, ['type', 'subType', 'settle', 'defaultSettle', 'unifiedMargin'])
|
173
175
|
return params
|
174
176
|
|
177
|
+
async def create_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
178
|
+
"""
|
179
|
+
create a trade order
|
180
|
+
:see: https://bybit-exchange.github.io/docs/v5/order/create-order
|
181
|
+
:see: https://bybit-exchange.github.io/docs/v5/websocket/trade/guideline#createamendcancel-order
|
182
|
+
:param str symbol: unified symbol of the market to create an order in
|
183
|
+
:param str type: 'market' or 'limit'
|
184
|
+
:param str side: 'buy' or 'sell'
|
185
|
+
:param float amount: how much of currency you want to trade in units of base currency
|
186
|
+
:param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
|
187
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
188
|
+
:param str [params.timeInForce]: "GTC", "IOC", "FOK"
|
189
|
+
:param bool [params.postOnly]: True or False whether the order is post-only
|
190
|
+
:param bool [params.reduceOnly]: True or False whether the order is reduce-only
|
191
|
+
:param str [params.positionIdx]: *contracts only* 0 for one-way mode, 1 buy side of hedged mode, 2 sell side of hedged mode
|
192
|
+
:param boolean [params.isLeverage]: *unified spot only* False then spot trading True then margin trading
|
193
|
+
:param str [params.tpslMode]: *contract only* 'full' or 'partial'
|
194
|
+
:param str [params.mmp]: *option only* market maker protection
|
195
|
+
:param str [params.triggerDirection]: *contract only* the direction for trigger orders, 'above' or 'below'
|
196
|
+
:param float [params.triggerPrice]: The price at which a trigger order is triggered at
|
197
|
+
:param float [params.stopLossPrice]: The price at which a stop loss order is triggered at
|
198
|
+
:param float [params.takeProfitPrice]: The price at which a take profit order is triggered at
|
199
|
+
:param dict [params.takeProfit]: *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered
|
200
|
+
:param float [params.takeProfit.triggerPrice]: take profit trigger price
|
201
|
+
:param dict [params.stopLoss]: *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered
|
202
|
+
:param float [params.stopLoss.triggerPrice]: stop loss trigger price
|
203
|
+
:param str [params.trailingAmount]: the quote amount to trail away from the current market price
|
204
|
+
:param str [params.trailingTriggerPrice]: the price to trigger a trailing order, default uses the price argument
|
205
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
206
|
+
"""
|
207
|
+
await self.load_markets()
|
208
|
+
orderRequest = self.create_order_request(symbol, type, side, amount, price, params, True)
|
209
|
+
url = self.urls['api']['ws']['private']['trade']
|
210
|
+
await self.authenticate(url)
|
211
|
+
requestId = str(self.request_id())
|
212
|
+
request = {
|
213
|
+
'op': 'order.create',
|
214
|
+
'reqId': requestId,
|
215
|
+
'args': [
|
216
|
+
orderRequest,
|
217
|
+
],
|
218
|
+
'header': {
|
219
|
+
'X-BAPI-TIMESTAMP': str(self.milliseconds()),
|
220
|
+
'X-BAPI-RECV-WINDOW': str(self.options['recvWindow']),
|
221
|
+
},
|
222
|
+
}
|
223
|
+
return await self.watch(url, requestId, request, requestId, True)
|
224
|
+
|
225
|
+
async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
|
226
|
+
"""
|
227
|
+
edit a trade order
|
228
|
+
:see: https://bybit-exchange.github.io/docs/v5/order/amend-order
|
229
|
+
:see: https://bybit-exchange.github.io/docs/v5/websocket/trade/guideline#createamendcancel-order
|
230
|
+
:param str id: cancel order id
|
231
|
+
:param str symbol: unified symbol of the market to create an order in
|
232
|
+
:param str type: 'market' or 'limit'
|
233
|
+
:param str side: 'buy' or 'sell'
|
234
|
+
:param float amount: how much of currency you want to trade in units of base currency
|
235
|
+
:param float price: the price at which the order is to be fullfilled, in units of the base currency, ignored in market orders
|
236
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
237
|
+
:param float [params.triggerPrice]: The price that a trigger order is triggered at
|
238
|
+
:param float [params.stopLossPrice]: The price that a stop loss order is triggered at
|
239
|
+
:param float [params.takeProfitPrice]: The price that a take profit order is triggered at
|
240
|
+
:param dict [params.takeProfit]: *takeProfit object in params* containing the triggerPrice that the attached take profit order will be triggered
|
241
|
+
:param float [params.takeProfit.triggerPrice]: take profit trigger price
|
242
|
+
:param dict [params.stopLoss]: *stopLoss object in params* containing the triggerPrice that the attached stop loss order will be triggered
|
243
|
+
:param float [params.stopLoss.triggerPrice]: stop loss trigger price
|
244
|
+
:param str [params.triggerBy]: 'IndexPrice', 'MarkPrice' or 'LastPrice', default is 'LastPrice', required if no initial value for triggerPrice
|
245
|
+
:param str [params.slTriggerBy]: 'IndexPrice', 'MarkPrice' or 'LastPrice', default is 'LastPrice', required if no initial value for stopLoss
|
246
|
+
:param str [params.tpTriggerby]: 'IndexPrice', 'MarkPrice' or 'LastPrice', default is 'LastPrice', required if no initial value for takeProfit
|
247
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
248
|
+
"""
|
249
|
+
await self.load_markets()
|
250
|
+
orderRequest = self.edit_order_request(id, symbol, type, side, amount, price, params)
|
251
|
+
url = self.urls['api']['ws']['private']['trade']
|
252
|
+
await self.authenticate(url)
|
253
|
+
requestId = str(self.request_id())
|
254
|
+
request = {
|
255
|
+
'op': 'order.amend',
|
256
|
+
'reqId': requestId,
|
257
|
+
'args': [
|
258
|
+
orderRequest,
|
259
|
+
],
|
260
|
+
'header': {
|
261
|
+
'X-BAPI-TIMESTAMP': str(self.milliseconds()),
|
262
|
+
'X-BAPI-RECV-WINDOW': str(self.options['recvWindow']),
|
263
|
+
},
|
264
|
+
}
|
265
|
+
return await self.watch(url, requestId, request, requestId, True)
|
266
|
+
|
267
|
+
async def cancel_order_ws(self, id: str, symbol: Str = None, params={}):
|
268
|
+
"""
|
269
|
+
cancels an open order
|
270
|
+
:see: https://bybit-exchange.github.io/docs/v5/order/cancel-order
|
271
|
+
:see: https://bybit-exchange.github.io/docs/v5/websocket/trade/guideline#createamendcancel-order
|
272
|
+
:param str id: order id
|
273
|
+
:param str symbol: unified symbol of the market the order was made in
|
274
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
275
|
+
:param boolean [params.stop]: *spot only* whether the order is a stop order
|
276
|
+
:param str [params.orderFilter]: *spot only* 'Order' or 'StopOrder' or 'tpslOrder'
|
277
|
+
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
278
|
+
"""
|
279
|
+
await self.load_markets()
|
280
|
+
orderRequest = self.cancelOrderRequest(id, symbol, params)
|
281
|
+
url = self.urls['api']['ws']['private']['trade']
|
282
|
+
await self.authenticate(url)
|
283
|
+
requestId = str(self.request_id())
|
284
|
+
del orderRequest['orderFilter']
|
285
|
+
request = {
|
286
|
+
'op': 'order.cancel',
|
287
|
+
'reqId': requestId,
|
288
|
+
'args': [
|
289
|
+
orderRequest,
|
290
|
+
],
|
291
|
+
'header': {
|
292
|
+
'X-BAPI-TIMESTAMP': str(self.milliseconds()),
|
293
|
+
'X-BAPI-RECV-WINDOW': str(self.options['recvWindow']),
|
294
|
+
},
|
295
|
+
}
|
296
|
+
return await self.watch(url, requestId, request, requestId, True)
|
297
|
+
|
175
298
|
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
176
299
|
"""
|
177
300
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
@@ -1029,6 +1152,32 @@ class bybit(ccxt.async_support.bybit):
|
|
1029
1152
|
limit = orders.getLimit(symbol, limit)
|
1030
1153
|
return self.filter_by_symbol_since_limit(orders, symbol, since, limit, True)
|
1031
1154
|
|
1155
|
+
def handle_order_ws(self, client: Client, message):
|
1156
|
+
#
|
1157
|
+
# {
|
1158
|
+
# "reqId":"1",
|
1159
|
+
# "retCode":0,
|
1160
|
+
# "retMsg":"OK",
|
1161
|
+
# "op":"order.create",
|
1162
|
+
# "data":{
|
1163
|
+
# "orderId":"1673523595617593600",
|
1164
|
+
# "orderLinkId":"1673523595617593601"
|
1165
|
+
# },
|
1166
|
+
# "header":{
|
1167
|
+
# "X-Bapi-Limit":"20",
|
1168
|
+
# "X-Bapi-Limit-Status":"19",
|
1169
|
+
# "X-Bapi-Limit-Reset-Timestamp":"1714235558880",
|
1170
|
+
# "Traceid":"584a06d373f2fdcb3a4dfdd81d27df11",
|
1171
|
+
# "Timenow":"1714235558881"
|
1172
|
+
# },
|
1173
|
+
# "connId":"cojidqec0hv9fgvhtbt0-40e"
|
1174
|
+
# }
|
1175
|
+
#
|
1176
|
+
messageHash = self.safe_string(message, 'reqId')
|
1177
|
+
data = self.safe_dict(message, 'data')
|
1178
|
+
order = self.parse_order(data)
|
1179
|
+
client.resolve(order, messageHash)
|
1180
|
+
|
1032
1181
|
def handle_order(self, client: Client, message):
|
1033
1182
|
#
|
1034
1183
|
# spot
|
@@ -1599,11 +1748,32 @@ class bybit(ccxt.async_support.bybit):
|
|
1599
1748
|
#
|
1600
1749
|
# {code: '-10009', desc: "Invalid period!"}
|
1601
1750
|
#
|
1602
|
-
|
1751
|
+
# {
|
1752
|
+
# "reqId":"1",
|
1753
|
+
# "retCode":170131,
|
1754
|
+
# "retMsg":"Insufficient balance.",
|
1755
|
+
# "op":"order.create",
|
1756
|
+
# "data":{
|
1757
|
+
#
|
1758
|
+
# },
|
1759
|
+
# "header":{
|
1760
|
+
# "X-Bapi-Limit":"20",
|
1761
|
+
# "X-Bapi-Limit-Status":"19",
|
1762
|
+
# "X-Bapi-Limit-Reset-Timestamp":"1714236608944",
|
1763
|
+
# "Traceid":"3d7168a137bf32a947b7e5e6a575ac7f",
|
1764
|
+
# "Timenow":"1714236608946"
|
1765
|
+
# },
|
1766
|
+
# "connId":"cojifin88smerbj9t560-406"
|
1767
|
+
# }
|
1768
|
+
#
|
1769
|
+
code = self.safe_string_n(message, ['code', 'ret_code', 'retCode'])
|
1603
1770
|
try:
|
1604
|
-
if code is not None:
|
1771
|
+
if code is not None and code != '0':
|
1605
1772
|
feedback = self.id + ' ' + self.json(message)
|
1606
1773
|
self.throw_exactly_matched_exception(self.exceptions['exact'], code, feedback)
|
1774
|
+
msg = self.safe_string_2(message, 'retMsg', 'ret_msg')
|
1775
|
+
self.throw_broadly_matched_exception(self.exceptions['broad'], msg, feedback)
|
1776
|
+
raise ExchangeError(feedback)
|
1607
1777
|
success = self.safe_value(message, 'success')
|
1608
1778
|
if success is not None and not success:
|
1609
1779
|
ret_msg = self.safe_string(message, 'ret_msg')
|
@@ -1621,7 +1791,8 @@ class bybit(ccxt.async_support.bybit):
|
|
1621
1791
|
if messageHash in client.subscriptions:
|
1622
1792
|
del client.subscriptions[messageHash]
|
1623
1793
|
else:
|
1624
|
-
|
1794
|
+
messageHash = self.safe_string(message, 'reqId')
|
1795
|
+
client.reject(error, messageHash)
|
1625
1796
|
return True
|
1626
1797
|
|
1627
1798
|
def handle_message(self, client: Client, message):
|
@@ -1638,15 +1809,11 @@ class bybit(ccxt.async_support.bybit):
|
|
1638
1809
|
self.handle_pong(client, message)
|
1639
1810
|
return
|
1640
1811
|
# pong
|
1641
|
-
op = self.safe_string(message, 'op')
|
1642
|
-
if op == 'pong':
|
1643
|
-
self.handle_pong(client, message)
|
1644
|
-
return
|
1645
1812
|
event = self.safe_string(message, 'event')
|
1646
1813
|
if event == 'sub':
|
1647
1814
|
self.handle_subscription_status(client, message)
|
1648
1815
|
return
|
1649
|
-
topic = self.
|
1816
|
+
topic = self.safe_string_2(message, 'topic', 'op')
|
1650
1817
|
methods = {
|
1651
1818
|
'orderbook': self.handle_order_book,
|
1652
1819
|
'kline': self.handle_ohlcv,
|
@@ -1662,6 +1829,11 @@ class bybit(ccxt.async_support.bybit):
|
|
1662
1829
|
'ticketInfo': self.handle_my_trades,
|
1663
1830
|
'user.openapi.perp.trade': self.handle_my_trades,
|
1664
1831
|
'position': self.handle_positions,
|
1832
|
+
'pong': self.handle_pong,
|
1833
|
+
'order.create': self.handle_order_ws,
|
1834
|
+
'order.amend': self.handle_order_ws,
|
1835
|
+
'order.cancel': self.handle_order_ws,
|
1836
|
+
'auth': self.handle_authenticate,
|
1665
1837
|
}
|
1666
1838
|
exacMethod = self.safe_value(methods, topic)
|
1667
1839
|
if exacMethod is not None:
|
@@ -1676,7 +1848,7 @@ class bybit(ccxt.async_support.bybit):
|
|
1676
1848
|
return
|
1677
1849
|
# unified auth acknowledgement
|
1678
1850
|
type = self.safe_string(message, 'type')
|
1679
|
-
if
|
1851
|
+
if type == 'AUTH_RESP':
|
1680
1852
|
self.handle_authenticate(client, message)
|
1681
1853
|
|
1682
1854
|
def ping(self, client):
|
@@ -1708,9 +1880,17 @@ class bybit(ccxt.async_support.bybit):
|
|
1708
1880
|
# "conn_id": "ce3dpomvha7dha97tvp0-2xh"
|
1709
1881
|
# }
|
1710
1882
|
#
|
1883
|
+
# {
|
1884
|
+
# "retCode":0,
|
1885
|
+
# "retMsg":"OK",
|
1886
|
+
# "op":"auth",
|
1887
|
+
# "connId":"cojifin88smerbj9t560-404"
|
1888
|
+
# }
|
1889
|
+
#
|
1711
1890
|
success = self.safe_value(message, 'success')
|
1891
|
+
code = self.safe_integer(message, 'retCode')
|
1712
1892
|
messageHash = 'authenticated'
|
1713
|
-
if success:
|
1893
|
+
if success or code == 0:
|
1714
1894
|
future = self.safe_value(client.futures, messageHash)
|
1715
1895
|
future.resolve(True)
|
1716
1896
|
else:
|