ccxt-ir 4.3.46.0.2__py2.py3-none-any.whl → 4.5.0__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 +39 -35
- ccxt/abantether.py +9 -9
- ccxt/abstract/alpaca.py +4 -0
- ccxt/abstract/apex.py +31 -0
- ccxt/abstract/bigone.py +1 -1
- ccxt/abstract/binance.py +106 -48
- ccxt/abstract/binancecoinm.py +106 -48
- ccxt/abstract/binanceus.py +141 -83
- ccxt/abstract/binanceusdm.py +106 -48
- ccxt/abstract/bingx.py +50 -1
- ccxt/abstract/bitbank.py +5 -0
- ccxt/abstract/bitfinex.py +136 -65
- ccxt/abstract/bitflyer.py +1 -0
- ccxt/abstract/bitget.py +67 -0
- ccxt/abstract/bitmart.py +19 -1
- ccxt/abstract/bitopro.py +1 -0
- ccxt/abstract/bitrue.py +68 -68
- ccxt/abstract/bitstamp.py +1 -0
- ccxt/abstract/blofin.py +30 -0
- ccxt/abstract/btcbox.py +2 -0
- ccxt/abstract/bybit.py +28 -13
- ccxt/abstract/cex.py +28 -29
- ccxt/abstract/coinbaseexchange.py +1 -0
- ccxt/abstract/coinbaseinternational.py +1 -1
- ccxt/abstract/cryptocom.py +16 -0
- ccxt/abstract/cryptomus.py +20 -0
- ccxt/abstract/defx.py +69 -0
- ccxt/abstract/deribit.py +1 -0
- ccxt/abstract/derive.py +117 -0
- ccxt/abstract/digifinex.py +1 -0
- ccxt/abstract/ellipx.py +25 -0
- ccxt/abstract/foxbit.py +26 -0
- ccxt/abstract/gate.py +19 -0
- ccxt/abstract/gateio.py +19 -0
- ccxt/abstract/gemini.py +1 -0
- ccxt/abstract/hibachi.py +26 -0
- ccxt/abstract/hyperliquid.py +1 -1
- ccxt/abstract/independentreserve.py +6 -0
- ccxt/abstract/kraken.py +1 -0
- ccxt/abstract/krakenfutures.py +4 -0
- ccxt/abstract/kucoin.py +10 -0
- ccxt/abstract/kucoinfutures.py +18 -0
- ccxt/abstract/lbank.py +2 -1
- ccxt/abstract/luno.py +1 -0
- ccxt/abstract/mexc.py +2 -0
- ccxt/abstract/modetrade.py +119 -0
- ccxt/abstract/myokx.py +349 -0
- ccxt/abstract/oceanex.py +5 -0
- ccxt/abstract/okx.py +25 -0
- ccxt/abstract/okxus.py +349 -0
- ccxt/abstract/onetrading.py +0 -12
- ccxt/abstract/paradex.py +23 -0
- ccxt/abstract/phemex.py +2 -0
- ccxt/abstract/poloniex.py +36 -0
- ccxt/abstract/tradeogre.py +3 -1
- ccxt/abstract/upbit.py +51 -34
- ccxt/abstract/whitebit.py +16 -0
- ccxt/abstract/woo.py +64 -6
- ccxt/abstract/xt.py +10 -5
- ccxt/afratether.py +7 -7
- ccxt/alpaca.py +828 -51
- ccxt/apex.py +1875 -0
- ccxt/arzinja.py +7 -7
- ccxt/arzplus.py +9 -9
- ccxt/ascendex.py +501 -306
- ccxt/async_support/__init__.py +39 -35
- ccxt/async_support/abantether.py +10 -10
- ccxt/async_support/afratether.py +9 -9
- ccxt/async_support/alpaca.py +828 -51
- ccxt/async_support/apex.py +1875 -0
- ccxt/async_support/arzinja.py +10 -10
- ccxt/async_support/arzplus.py +12 -12
- ccxt/async_support/ascendex.py +502 -306
- ccxt/async_support/base/exchange.py +303 -89
- ccxt/async_support/base/ws/cache.py +9 -3
- ccxt/async_support/base/ws/client.py +173 -38
- ccxt/async_support/base/ws/future.py +25 -37
- ccxt/async_support/bequant.py +5 -3
- ccxt/async_support/bigone.py +279 -144
- ccxt/async_support/binance.py +2347 -1158
- ccxt/async_support/binancecoinm.py +9 -3
- ccxt/async_support/binanceus.py +17 -3
- ccxt/async_support/binanceusdm.py +9 -4
- ccxt/async_support/bingx.py +2962 -920
- ccxt/async_support/bit2c.py +147 -27
- ccxt/async_support/bitbank.py +151 -23
- ccxt/async_support/bitbns.py +104 -30
- ccxt/async_support/bitfinex.py +3291 -1113
- ccxt/async_support/bitflyer.py +202 -27
- ccxt/async_support/bitget.py +3683 -1538
- ccxt/async_support/bithumb.py +195 -38
- ccxt/async_support/bitimen.py +12 -12
- ccxt/async_support/bitir.py +38 -38
- ccxt/async_support/bitmart.py +1288 -350
- ccxt/async_support/bitmex.py +260 -75
- ccxt/async_support/bitopro.py +262 -62
- ccxt/async_support/bitpin.py +17 -16
- ccxt/async_support/bitrue.py +459 -290
- ccxt/async_support/bitso.py +199 -54
- ccxt/async_support/bitstamp.py +230 -96
- ccxt/async_support/bitteam.py +167 -25
- ccxt/async_support/{huobijp.py → bittrade.py} +158 -30
- ccxt/async_support/bitvavo.py +213 -49
- ccxt/async_support/blockchaincom.py +160 -46
- ccxt/async_support/blofin.py +502 -120
- ccxt/async_support/btcalpha.py +169 -31
- ccxt/async_support/btcbox.py +292 -23
- ccxt/async_support/btcmarkets.py +211 -58
- ccxt/async_support/btcturk.py +161 -38
- ccxt/async_support/bybit.py +1775 -1030
- ccxt/async_support/cex.py +1440 -1303
- ccxt/async_support/coinbase.py +724 -212
- ccxt/async_support/coinbaseadvanced.py +2 -1
- ccxt/async_support/coinbaseexchange.py +388 -89
- ccxt/async_support/coinbaseinternational.py +412 -57
- ccxt/async_support/coincatch.py +177 -78
- ccxt/async_support/coincheck.py +135 -19
- ccxt/async_support/coinex.py +606 -232
- ccxt/async_support/coinmate.py +189 -63
- ccxt/async_support/coinmetro.py +195 -54
- ccxt/async_support/coinone.py +158 -51
- ccxt/async_support/coinsph.py +336 -61
- ccxt/async_support/coinspot.py +151 -52
- ccxt/async_support/cryptocom.py +661 -111
- ccxt/async_support/cryptomus.py +1137 -0
- ccxt/async_support/defx.py +2071 -0
- ccxt/async_support/delta.py +299 -99
- ccxt/async_support/deribit.py +348 -126
- ccxt/async_support/derive.py +2572 -0
- ccxt/async_support/digifinex.py +430 -214
- ccxt/async_support/ellipx.py +2029 -0
- ccxt/async_support/eterex.py +10 -10
- ccxt/async_support/excoino.py +31 -31
- ccxt/async_support/exir.py +14 -14
- ccxt/async_support/exmo.py +344 -131
- ccxt/async_support/exnovin.py +10 -10
- ccxt/async_support/farhadexchange.py +12 -12
- ccxt/async_support/fmfwio.py +2 -1
- ccxt/async_support/foxbit.py +1935 -0
- ccxt/async_support/gate.py +1351 -529
- ccxt/async_support/gateio.py +2 -1
- ccxt/async_support/gemini.py +144 -39
- ccxt/async_support/hashkey.py +152 -109
- ccxt/async_support/hibachi.py +2080 -0
- ccxt/async_support/hitbtc.py +395 -167
- ccxt/async_support/hitobit.py +12 -12
- ccxt/async_support/hollaex.py +307 -119
- ccxt/async_support/htx.py +851 -383
- ccxt/async_support/huobi.py +2 -1
- ccxt/async_support/hyperliquid.py +1848 -536
- ccxt/async_support/independentreserve.py +288 -15
- ccxt/async_support/indodax.py +190 -33
- ccxt/async_support/jibitex.py +12 -12
- ccxt/async_support/kraken.py +795 -351
- ccxt/async_support/krakenfutures.py +214 -62
- ccxt/async_support/kucoin.py +715 -396
- ccxt/async_support/kucoinfutures.py +652 -89
- ccxt/async_support/latoken.py +217 -113
- ccxt/async_support/lbank.py +425 -97
- ccxt/async_support/luno.py +382 -35
- ccxt/async_support/mercado.py +113 -6
- ccxt/async_support/mexc.py +874 -437
- ccxt/async_support/modetrade.py +2818 -0
- ccxt/async_support/myokx.py +54 -0
- ccxt/async_support/ndax.py +221 -64
- ccxt/async_support/nobitex.py +31 -37
- ccxt/async_support/novadax.py +190 -34
- ccxt/async_support/oceanex.py +217 -28
- ccxt/async_support/okcoin.py +253 -145
- ccxt/async_support/okexchange.py +11 -11
- ccxt/async_support/okx.py +1088 -351
- ccxt/async_support/okxus.py +54 -0
- ccxt/async_support/ompfinex.py +25 -24
- ccxt/async_support/onetrading.py +213 -392
- ccxt/async_support/oxfun.py +245 -166
- ccxt/async_support/p2b.py +151 -29
- ccxt/async_support/paradex.py +562 -49
- ccxt/async_support/paymium.py +82 -19
- ccxt/async_support/phemex.py +713 -172
- ccxt/async_support/poloniex.py +1602 -283
- ccxt/async_support/probit.py +224 -95
- ccxt/async_support/ramzinex.py +30 -27
- ccxt/async_support/sarmayex.py +9 -9
- ccxt/async_support/sarrafex.py +13 -13
- ccxt/async_support/tabdeal.py +14 -13
- ccxt/async_support/tetherland.py +9 -9
- ccxt/async_support/timex.py +210 -51
- ccxt/async_support/tokocrypto.py +167 -47
- ccxt/async_support/tradeogre.py +266 -31
- ccxt/async_support/twox.py +9 -9
- ccxt/async_support/ubitex.py +12 -12
- ccxt/async_support/upbit.py +568 -165
- ccxt/async_support/vertex.py +160 -32
- ccxt/async_support/wallex.py +12 -12
- ccxt/async_support/wavesexchange.py +165 -30
- ccxt/async_support/whitebit.py +975 -127
- ccxt/async_support/woo.py +1918 -1016
- ccxt/async_support/woofipro.py +433 -141
- ccxt/async_support/xt.py +649 -193
- ccxt/async_support/yobit.py +195 -70
- ccxt/async_support/zaif.py +91 -15
- ccxt/async_support/zonda.py +151 -36
- ccxt/base/decimal_to_precision.py +14 -10
- ccxt/base/errors.py +49 -18
- ccxt/base/exchange.py +1556 -450
- ccxt/base/precise.py +10 -0
- ccxt/base/types.py +114 -6
- ccxt/bequant.py +5 -3
- ccxt/bigone.py +279 -144
- ccxt/binance.py +2347 -1158
- ccxt/binancecoinm.py +9 -3
- ccxt/binanceus.py +17 -3
- ccxt/binanceusdm.py +9 -4
- ccxt/bingx.py +2962 -920
- ccxt/bit2c.py +147 -27
- ccxt/bitbank.py +151 -23
- ccxt/bitbns.py +104 -30
- ccxt/bitfinex.py +3290 -1113
- ccxt/bitflyer.py +202 -27
- ccxt/bitget.py +3683 -1538
- ccxt/bithumb.py +194 -38
- ccxt/bitimen.py +9 -9
- ccxt/bitir.py +35 -35
- ccxt/bitmart.py +1288 -350
- ccxt/bitmex.py +260 -75
- ccxt/bitopro.py +262 -62
- ccxt/bitpin.py +15 -14
- ccxt/bitrue.py +459 -290
- ccxt/bitso.py +199 -54
- ccxt/bitstamp.py +230 -96
- ccxt/bitteam.py +167 -25
- ccxt/{huobijp.py → bittrade.py} +158 -30
- ccxt/bitvavo.py +213 -49
- ccxt/blockchaincom.py +160 -46
- ccxt/blofin.py +502 -120
- ccxt/btcalpha.py +169 -31
- ccxt/btcbox.py +291 -23
- ccxt/btcmarkets.py +211 -58
- ccxt/btcturk.py +161 -38
- ccxt/bybit.py +1775 -1030
- ccxt/cex.py +1439 -1303
- ccxt/coinbase.py +724 -212
- ccxt/coinbaseadvanced.py +2 -1
- ccxt/coinbaseexchange.py +388 -89
- ccxt/coinbaseinternational.py +412 -57
- ccxt/coincatch.py +177 -78
- ccxt/coincheck.py +135 -19
- ccxt/coinex.py +606 -232
- ccxt/coinmate.py +189 -63
- ccxt/coinmetro.py +194 -54
- ccxt/coinone.py +158 -51
- ccxt/coinsph.py +336 -61
- ccxt/coinspot.py +151 -52
- ccxt/cryptocom.py +661 -111
- ccxt/cryptomus.py +1137 -0
- ccxt/defx.py +2070 -0
- ccxt/delta.py +299 -99
- ccxt/deribit.py +348 -126
- ccxt/derive.py +2571 -0
- ccxt/digifinex.py +430 -214
- ccxt/ellipx.py +2029 -0
- ccxt/eterex.py +7 -7
- ccxt/excoino.py +29 -29
- ccxt/exir.py +11 -11
- ccxt/exmo.py +343 -131
- ccxt/exnovin.py +8 -8
- ccxt/farhadexchange.py +10 -10
- ccxt/fmfwio.py +2 -1
- ccxt/foxbit.py +1935 -0
- ccxt/gate.py +1351 -529
- ccxt/gateio.py +2 -1
- ccxt/gemini.py +144 -39
- ccxt/hashkey.py +152 -109
- ccxt/hibachi.py +2079 -0
- ccxt/hitbtc.py +395 -167
- ccxt/hitobit.py +9 -9
- ccxt/hollaex.py +307 -119
- ccxt/htx.py +851 -383
- ccxt/huobi.py +2 -1
- ccxt/hyperliquid.py +1848 -536
- ccxt/independentreserve.py +287 -15
- ccxt/indodax.py +190 -33
- ccxt/jibitex.py +9 -9
- ccxt/kraken.py +794 -351
- ccxt/krakenfutures.py +214 -62
- ccxt/kucoin.py +715 -396
- ccxt/kucoinfutures.py +652 -89
- ccxt/latoken.py +217 -113
- ccxt/lbank.py +425 -97
- ccxt/luno.py +382 -35
- ccxt/mercado.py +113 -6
- ccxt/mexc.py +873 -437
- ccxt/modetrade.py +2818 -0
- ccxt/myokx.py +54 -0
- ccxt/ndax.py +221 -64
- ccxt/nobitex.py +29 -35
- ccxt/novadax.py +190 -34
- ccxt/oceanex.py +217 -28
- ccxt/okcoin.py +253 -145
- ccxt/okexchange.py +9 -9
- ccxt/okx.py +1088 -351
- ccxt/okxus.py +54 -0
- ccxt/ompfinex.py +22 -21
- ccxt/onetrading.py +213 -392
- ccxt/oxfun.py +245 -166
- ccxt/p2b.py +151 -29
- ccxt/paradex.py +562 -49
- ccxt/paymium.py +82 -19
- ccxt/phemex.py +712 -172
- ccxt/poloniex.py +1601 -283
- ccxt/pro/__init__.py +76 -17
- ccxt/pro/alpaca.py +21 -6
- ccxt/pro/apex.py +984 -0
- ccxt/pro/ascendex.py +58 -10
- ccxt/pro/bequant.py +6 -1
- ccxt/pro/binance.py +728 -156
- ccxt/pro/binancecoinm.py +6 -2
- ccxt/pro/binanceus.py +8 -4
- ccxt/pro/binanceusdm.py +7 -2
- ccxt/pro/bingx.py +333 -142
- ccxt/pro/bitfinex.py +727 -262
- ccxt/pro/bitget.py +570 -79
- ccxt/pro/bithumb.py +20 -6
- ccxt/pro/bitmart.py +216 -87
- ccxt/pro/bitmex.py +47 -9
- ccxt/pro/bitopro.py +26 -14
- ccxt/pro/bitrue.py +22 -22
- ccxt/pro/bitstamp.py +54 -21
- ccxt/pro/{huobijp.py → bittrade.py} +7 -6
- ccxt/pro/bitvavo.py +191 -67
- ccxt/pro/blockchaincom.py +21 -8
- ccxt/pro/blofin.py +9 -1
- ccxt/pro/bybit.py +632 -245
- ccxt/pro/cex.py +59 -24
- ccxt/pro/coinbase.py +102 -73
- ccxt/pro/coinbaseadvanced.py +2 -1
- ccxt/pro/coinbaseexchange.py +8 -8
- ccxt/pro/coinbaseinternational.py +181 -25
- ccxt/pro/coincatch.py +6 -7
- ccxt/pro/coincheck.py +11 -6
- ccxt/pro/coinex.py +967 -665
- ccxt/pro/coinone.py +16 -9
- ccxt/pro/cryptocom.py +448 -45
- ccxt/pro/defx.py +831 -0
- ccxt/pro/deribit.py +150 -14
- ccxt/pro/derive.py +704 -0
- ccxt/pro/exmo.py +239 -6
- ccxt/pro/gate.py +623 -65
- ccxt/pro/gateio.py +2 -1
- ccxt/pro/gemini.py +27 -11
- ccxt/pro/hashkey.py +2 -2
- ccxt/pro/hitbtc.py +196 -91
- ccxt/pro/hollaex.py +23 -7
- ccxt/pro/htx.py +51 -14
- ccxt/pro/huobi.py +2 -1
- ccxt/pro/hyperliquid.py +591 -27
- ccxt/pro/independentreserve.py +9 -6
- ccxt/pro/kraken.py +640 -320
- ccxt/pro/krakenfutures.py +62 -35
- ccxt/pro/kucoin.py +267 -46
- ccxt/pro/kucoinfutures.py +165 -21
- ccxt/pro/lbank.py +102 -21
- ccxt/pro/luno.py +12 -8
- ccxt/pro/mexc.py +877 -111
- ccxt/pro/modetrade.py +1271 -0
- ccxt/pro/myokx.py +38 -0
- ccxt/pro/ndax.py +15 -2
- ccxt/pro/okcoin.py +23 -4
- ccxt/pro/okx.py +573 -98
- ccxt/pro/okxus.py +38 -0
- ccxt/pro/onetrading.py +30 -13
- ccxt/pro/oxfun.py +131 -27
- ccxt/pro/p2b.py +88 -22
- ccxt/pro/paradex.py +3 -3
- ccxt/pro/phemex.py +75 -21
- ccxt/pro/poloniex.py +124 -41
- ccxt/pro/probit.py +87 -80
- ccxt/pro/tradeogre.py +272 -0
- ccxt/pro/upbit.py +152 -12
- ccxt/pro/vertex.py +8 -3
- ccxt/pro/whitebit.py +58 -5
- ccxt/pro/woo.py +228 -37
- ccxt/pro/woofipro.py +106 -18
- ccxt/pro/xt.py +111 -5
- ccxt/probit.py +224 -95
- ccxt/protobuf/__init__.py +0 -0
- ccxt/protobuf/mexc/PrivateAccountV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PrivateDealsV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PrivateOrdersV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicAggreBookTickerV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicAggreDealsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicAggreDepthsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicBookTickerBatchV3Api_pb2.py +38 -0
- ccxt/protobuf/mexc/PublicBookTickerV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicDealsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicIncreaseDepthsBatchV3Api_pb2.py +38 -0
- ccxt/protobuf/mexc/PublicIncreaseDepthsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicLimitDepthsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicMiniTickerV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicMiniTickersV3Api_pb2.py +38 -0
- ccxt/protobuf/mexc/PublicSpotKlineV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PushDataV3ApiWrapper_pb2.py +52 -0
- ccxt/protobuf/mexc/__init__.py +0 -0
- ccxt/ramzinex.py +28 -25
- ccxt/sarmayex.py +7 -7
- ccxt/sarrafex.py +10 -10
- ccxt/static_dependencies/__init__.py +1 -1
- ccxt/static_dependencies/lark/py.typed +0 -0
- ccxt/static_dependencies/marshmallow/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
- ccxt/tabdeal.py +12 -11
- ccxt/test/tests_async.py +261 -57
- ccxt/test/tests_helpers.py +1 -3
- ccxt/test/tests_init.py +4 -3
- ccxt/test/tests_sync.py +261 -57
- ccxt/tetherland.py +7 -7
- ccxt/timex.py +210 -51
- ccxt/tokocrypto.py +167 -47
- ccxt/tradeogre.py +266 -31
- ccxt/twox.py +7 -7
- ccxt/ubitex.py +9 -9
- ccxt/upbit.py +568 -165
- ccxt/vertex.py +160 -32
- ccxt/wallex.py +9 -9
- ccxt/wavesexchange.py +165 -30
- ccxt/whitebit.py +975 -127
- ccxt/woo.py +1917 -1016
- ccxt/woofipro.py +432 -141
- ccxt/xt.py +649 -193
- ccxt/yobit.py +194 -70
- ccxt/zaif.py +91 -15
- ccxt/zonda.py +151 -36
- {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/METADATA +225 -73
- ccxt_ir-4.5.0.dist-info/RECORD +743 -0
- {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/WHEEL +1 -1
- ccxt/abstract/ace.py +0 -15
- ccxt/abstract/bitbay.py +0 -53
- ccxt/abstract/bitcoincom.py +0 -115
- ccxt/abstract/bitfinex2.py +0 -139
- ccxt/abstract/bitpanda.py +0 -35
- ccxt/abstract/bl3p.py +0 -19
- ccxt/abstract/coinlist.py +0 -54
- ccxt/abstract/currencycom.py +0 -68
- ccxt/abstract/hitbtc3.py +0 -115
- ccxt/abstract/idex.py +0 -26
- ccxt/abstract/kuna.py +0 -182
- ccxt/abstract/lykke.py +0 -29
- ccxt/abstract/poloniexfutures.py +0 -48
- ccxt/abstract/wazirx.py +0 -30
- ccxt/ace.py +0 -1012
- ccxt/async_support/ace.py +0 -1012
- ccxt/async_support/base/ws/aiohttp_client.py +0 -125
- ccxt/async_support/base/ws/fast_client.py +0 -96
- ccxt/async_support/bitbay.py +0 -17
- ccxt/async_support/bitcoincom.py +0 -17
- ccxt/async_support/bitfinex2.py +0 -3552
- ccxt/async_support/bitpanda.py +0 -16
- ccxt/async_support/bl3p.py +0 -485
- ccxt/async_support/coinlist.py +0 -2243
- ccxt/async_support/currencycom.py +0 -1950
- ccxt/async_support/hitbtc3.py +0 -16
- ccxt/async_support/idex.py +0 -1766
- ccxt/async_support/kuna.py +0 -1841
- ccxt/async_support/lykke.py +0 -1270
- ccxt/async_support/poloniexfutures.py +0 -1717
- ccxt/async_support/wazirx.py +0 -1224
- ccxt/bitbay.py +0 -17
- ccxt/bitcoincom.py +0 -17
- ccxt/bitfinex2.py +0 -3552
- ccxt/bitpanda.py +0 -16
- ccxt/bl3p.py +0 -485
- ccxt/coinlist.py +0 -2243
- ccxt/currencycom.py +0 -1950
- ccxt/hitbtc3.py +0 -16
- ccxt/idex.py +0 -1766
- ccxt/kuna.py +0 -1841
- ccxt/lykke.py +0 -1270
- ccxt/poloniexfutures.py +0 -1717
- ccxt/pro/bitcoincom.py +0 -34
- ccxt/pro/bitfinex2.py +0 -1083
- ccxt/pro/bitpanda.py +0 -15
- ccxt/pro/currencycom.py +0 -536
- ccxt/pro/idex.py +0 -672
- ccxt/pro/poloniexfutures.py +0 -990
- ccxt/pro/wazirx.py +0 -749
- ccxt/test/base/__init__.py +0 -29
- ccxt/test/base/test_account.py +0 -26
- ccxt/test/base/test_balance.py +0 -56
- ccxt/test/base/test_borrow_interest.py +0 -35
- ccxt/test/base/test_borrow_rate.py +0 -32
- ccxt/test/base/test_calculate_fee.py +0 -51
- ccxt/test/base/test_crypto.py +0 -127
- ccxt/test/base/test_currency.py +0 -76
- ccxt/test/base/test_datetime.py +0 -109
- ccxt/test/base/test_decimal_to_precision.py +0 -392
- ccxt/test/base/test_deep_extend.py +0 -68
- ccxt/test/base/test_deposit_withdrawal.py +0 -50
- ccxt/test/base/test_exchange_datetime_functions.py +0 -76
- ccxt/test/base/test_funding_rate_history.py +0 -29
- ccxt/test/base/test_last_price.py +0 -31
- ccxt/test/base/test_ledger_entry.py +0 -45
- ccxt/test/base/test_ledger_item.py +0 -48
- ccxt/test/base/test_leverage_tier.py +0 -33
- ccxt/test/base/test_liquidation.py +0 -50
- ccxt/test/base/test_margin_mode.py +0 -24
- ccxt/test/base/test_margin_modification.py +0 -35
- ccxt/test/base/test_market.py +0 -193
- ccxt/test/base/test_number.py +0 -411
- ccxt/test/base/test_ohlcv.py +0 -33
- ccxt/test/base/test_open_interest.py +0 -32
- ccxt/test/base/test_order.py +0 -64
- ccxt/test/base/test_order_book.py +0 -69
- ccxt/test/base/test_position.py +0 -60
- ccxt/test/base/test_shared_methods.py +0 -353
- ccxt/test/base/test_status.py +0 -24
- ccxt/test/base/test_throttle.py +0 -126
- ccxt/test/base/test_ticker.py +0 -92
- ccxt/test/base/test_trade.py +0 -47
- ccxt/test/base/test_trading_fee.py +0 -26
- ccxt/test/base/test_transaction.py +0 -39
- ccxt/test/test_async.py +0 -1649
- ccxt/test/test_sync.py +0 -1648
- ccxt/wazirx.py +0 -1224
- ccxt_ir-4.3.46.0.2.dist-info/RECORD +0 -772
- /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
- {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info/licenses}/LICENSE.txt +0 -0
- {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/top_level.txt +0 -0
ccxt/pro/gate.py
CHANGED
|
@@ -6,23 +6,47 @@
|
|
|
6
6
|
import ccxt.async_support
|
|
7
7
|
from ccxt.async_support.base.ws.cache import ArrayCache, ArrayCacheBySymbolById, ArrayCacheBySymbolBySide, ArrayCacheByTimestamp
|
|
8
8
|
import hashlib
|
|
9
|
-
from ccxt.base.types import Balances, Int, Liquidation, Order, OrderBook, Position, Str, Strings, Ticker, Tickers, Trade
|
|
9
|
+
from ccxt.base.types import Any, Balances, Bool, Int, Liquidation, Market, MarketType, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade
|
|
10
10
|
from ccxt.async_support.base.ws.client import Client
|
|
11
11
|
from typing import List
|
|
12
|
+
from ccxt.base.errors import ExchangeError
|
|
12
13
|
from ccxt.base.errors import AuthenticationError
|
|
13
14
|
from ccxt.base.errors import ArgumentsRequired
|
|
14
15
|
from ccxt.base.errors import BadRequest
|
|
15
|
-
from ccxt.base.errors import
|
|
16
|
+
from ccxt.base.errors import NotSupported
|
|
17
|
+
from ccxt.base.errors import ChecksumError
|
|
16
18
|
from ccxt.base.precise import Precise
|
|
17
19
|
|
|
18
20
|
|
|
19
21
|
class gate(ccxt.async_support.gate):
|
|
20
22
|
|
|
21
|
-
def describe(self):
|
|
23
|
+
def describe(self) -> Any:
|
|
22
24
|
return self.deep_extend(super(gate, self).describe(), {
|
|
23
25
|
'has': {
|
|
24
26
|
'ws': True,
|
|
27
|
+
'cancelAllOrdersWs': True,
|
|
28
|
+
'cancelOrderWs': True,
|
|
29
|
+
'createMarketBuyOrderWithCostWs': True,
|
|
30
|
+
'createMarketOrderWs': True,
|
|
31
|
+
'createMarketOrderWithCostWs': False,
|
|
32
|
+
'createMarketSellOrderWithCostWs': False,
|
|
33
|
+
'createOrderWs': True,
|
|
34
|
+
'createOrdersWs': True,
|
|
35
|
+
'createPostOnlyOrderWs': True,
|
|
36
|
+
'createReduceOnlyOrderWs': True,
|
|
37
|
+
'createStopLimitOrderWs': True,
|
|
38
|
+
'createStopLossOrderWs': True,
|
|
39
|
+
'createStopMarketOrderWs': False,
|
|
40
|
+
'createStopOrderWs': True,
|
|
41
|
+
'createTakeProfitOrderWs': True,
|
|
42
|
+
'createTriggerOrderWs': True,
|
|
43
|
+
'editOrderWs': True,
|
|
44
|
+
'fetchOrderWs': True,
|
|
45
|
+
'fetchOrdersWs': False,
|
|
46
|
+
'fetchOpenOrdersWs': True,
|
|
47
|
+
'fetchClosedOrdersWs': True,
|
|
25
48
|
'watchOrderBook': True,
|
|
49
|
+
'watchBidsAsks': True,
|
|
26
50
|
'watchTicker': True,
|
|
27
51
|
'watchTickers': True,
|
|
28
52
|
'watchTrades': True,
|
|
@@ -82,6 +106,7 @@ class gate(ccxt.async_support.gate):
|
|
|
82
106
|
'interval': '100ms',
|
|
83
107
|
'snapshotDelay': 10, # how many deltas to cache before fetching a snapshot
|
|
84
108
|
'snapshotMaxRetries': 3,
|
|
109
|
+
'checksum': True,
|
|
85
110
|
},
|
|
86
111
|
'watchBalance': {
|
|
87
112
|
'settle': 'usdt', # or btc
|
|
@@ -95,18 +120,258 @@ class gate(ccxt.async_support.gate):
|
|
|
95
120
|
'exceptions': {
|
|
96
121
|
'ws': {
|
|
97
122
|
'exact': {
|
|
123
|
+
'1': BadRequest,
|
|
98
124
|
'2': BadRequest,
|
|
99
125
|
'4': AuthenticationError,
|
|
100
126
|
'6': AuthenticationError,
|
|
101
127
|
'11': AuthenticationError,
|
|
102
128
|
},
|
|
129
|
+
'broad': {},
|
|
103
130
|
},
|
|
104
131
|
},
|
|
105
132
|
})
|
|
106
133
|
|
|
134
|
+
async def create_order_ws(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
|
135
|
+
"""
|
|
136
|
+
|
|
137
|
+
https://www.gate.io/docs/developers/apiv4/ws/en/#order-place
|
|
138
|
+
https://www.gate.io/docs/developers/futures/ws/en/#order-place
|
|
139
|
+
|
|
140
|
+
Create an order on the exchange
|
|
141
|
+
:param str symbol: Unified CCXT market symbol
|
|
142
|
+
:param str type: 'limit' or 'market' *"market" is contract only*
|
|
143
|
+
:param str side: 'buy' or 'sell'
|
|
144
|
+
:param float amount: the amount of currency to trade
|
|
145
|
+
:param float [price]: *ignored in "market" orders* the price at which the order is to be fulfilled at in units of the quote currency
|
|
146
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
147
|
+
:param float [params.stopPrice]: The price at which a trigger order is triggered at
|
|
148
|
+
:param str [params.timeInForce]: "GTC", "IOC", or "PO"
|
|
149
|
+
:param float [params.stopLossPrice]: The price at which a stop loss order is triggered at
|
|
150
|
+
:param float [params.takeProfitPrice]: The price at which a take profit order is triggered at
|
|
151
|
+
:param str [params.marginMode]: 'cross' or 'isolated' - marginMode for margin trading if not provided self.options['defaultMarginMode'] is used
|
|
152
|
+
:param int [params.iceberg]: Amount to display for the iceberg order, Null or 0 for normal orders, Set to -1 to hide the order completely
|
|
153
|
+
:param str [params.text]: User defined information
|
|
154
|
+
:param str [params.account]: *spot and margin only* "spot", "margin" or "cross_margin"
|
|
155
|
+
:param bool [params.auto_borrow]: *margin only* Used in margin or cross margin trading to allow automatic loan of insufficient amount if balance is not enough
|
|
156
|
+
:param str [params.settle]: *contract only* Unified Currency Code for settle currency
|
|
157
|
+
:param bool [params.reduceOnly]: *contract only* Indicates if self order is to reduce the size of a position
|
|
158
|
+
:param bool [params.close]: *contract only* Set to close the position, with size set to 0
|
|
159
|
+
:param bool [params.auto_size]: *contract only* Set side to close dual-mode position, close_long closes the long side, while close_short the short one, size also needs to be set to 0
|
|
160
|
+
:param int [params.price_type]: *contract only* 0 latest deal price, 1 mark price, 2 index price
|
|
161
|
+
:param float [params.cost]: *spot market buy only* the quote quantity that can be used alternative for the amount
|
|
162
|
+
:returns dict|None: `An order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
163
|
+
"""
|
|
164
|
+
await self.load_markets()
|
|
165
|
+
market = self.market(symbol)
|
|
166
|
+
symbol = market['symbol']
|
|
167
|
+
messageType = self.get_type_by_market(market)
|
|
168
|
+
channel = messageType + '.order_place'
|
|
169
|
+
url = self.get_url_by_market(market)
|
|
170
|
+
params['textIsRequired'] = True
|
|
171
|
+
request = self.create_order_request(symbol, type, side, amount, price, params)
|
|
172
|
+
await self.authenticate(url, messageType)
|
|
173
|
+
rawOrder = await self.request_private(url, request, channel)
|
|
174
|
+
order = self.parse_order(rawOrder, market)
|
|
175
|
+
return order
|
|
176
|
+
|
|
177
|
+
async def create_orders_ws(self, orders: List[OrderRequest], params={}):
|
|
178
|
+
"""
|
|
179
|
+
create a list of trade orders
|
|
180
|
+
|
|
181
|
+
https://www.gate.io/docs/developers/futures/ws/en/#order-batch-place
|
|
182
|
+
|
|
183
|
+
:param Array orders: list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
|
|
184
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
185
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
186
|
+
"""
|
|
187
|
+
await self.load_markets()
|
|
188
|
+
request = self.createOrdersRequest(orders, params)
|
|
189
|
+
firstOrder = orders[0]
|
|
190
|
+
market = self.market(firstOrder['symbol'])
|
|
191
|
+
if market['swap'] is not True:
|
|
192
|
+
raise NotSupported(self.id + ' createOrdersWs is not supported for swap markets')
|
|
193
|
+
messageType = self.get_type_by_market(market)
|
|
194
|
+
channel = messageType + '.order_batch_place'
|
|
195
|
+
url = self.get_url_by_market(market)
|
|
196
|
+
await self.authenticate(url, messageType)
|
|
197
|
+
rawOrders = await self.request_private(url, request, channel)
|
|
198
|
+
return self.parse_orders(rawOrders, market)
|
|
199
|
+
|
|
200
|
+
async def cancel_all_orders_ws(self, symbol: Str = None, params={}):
|
|
201
|
+
"""
|
|
202
|
+
cancel all open orders
|
|
203
|
+
|
|
204
|
+
https://www.gate.io/docs/developers/futures/ws/en/#cancel-all-open-orders-matched
|
|
205
|
+
https://www.gate.io/docs/developers/apiv4/ws/en/#order-cancel-all-with-specified-currency-pair
|
|
206
|
+
|
|
207
|
+
:param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
|
|
208
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
209
|
+
:param str [params.channel]: the channel to use, defaults to spot.order_cancel_cp or futures.order_cancel_cp
|
|
210
|
+
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
211
|
+
"""
|
|
212
|
+
await self.load_markets()
|
|
213
|
+
market = None if (symbol is None) else self.market(symbol)
|
|
214
|
+
trigger = self.safe_bool_2(params, 'stop', 'trigger')
|
|
215
|
+
messageType = self.get_type_by_market(market)
|
|
216
|
+
channel = messageType + '.order_cancel_cp'
|
|
217
|
+
channel, params = self.handle_option_and_params(params, 'cancelAllOrdersWs', 'channel', channel)
|
|
218
|
+
url = self.get_url_by_market(market)
|
|
219
|
+
params = self.omit(params, ['stop', 'trigger'])
|
|
220
|
+
type, query = self.handle_market_type_and_params('cancelAllOrders', market, params)
|
|
221
|
+
request, requestParams = self.multiOrderSpotPrepareRequest(market, trigger, query) if (type == 'spot') else self.prepareRequest(market, type, query)
|
|
222
|
+
await self.authenticate(url, messageType)
|
|
223
|
+
rawOrders = await self.request_private(url, self.extend(request, requestParams), channel)
|
|
224
|
+
return self.parse_orders(rawOrders, market)
|
|
225
|
+
|
|
226
|
+
async def cancel_order_ws(self, id: str, symbol: Str = None, params={}):
|
|
227
|
+
"""
|
|
228
|
+
Cancels an open order
|
|
229
|
+
|
|
230
|
+
https://www.gate.io/docs/developers/apiv4/ws/en/#order-cancel
|
|
231
|
+
https://www.gate.io/docs/developers/futures/ws/en/#order-cancel
|
|
232
|
+
|
|
233
|
+
:param str id: Order id
|
|
234
|
+
:param str symbol: Unified market symbol
|
|
235
|
+
:param dict [params]: Parameters specified by the exchange api
|
|
236
|
+
:param bool [params.trigger]: True if the order to be cancelled is a trigger order
|
|
237
|
+
:returns: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
238
|
+
"""
|
|
239
|
+
await self.load_markets()
|
|
240
|
+
market = None if (symbol is None) else self.market(symbol)
|
|
241
|
+
trigger = self.safe_value_n(params, ['is_stop_order', 'stop', 'trigger'], False)
|
|
242
|
+
params = self.omit(params, ['is_stop_order', 'stop', 'trigger'])
|
|
243
|
+
type, query = self.handle_market_type_and_params('cancelOrder', market, params)
|
|
244
|
+
request, requestParams = self.spotOrderPrepareRequest(market, trigger, query) if (type == 'spot' or type == 'margin') else self.prepareRequest(market, type, query)
|
|
245
|
+
messageType = self.get_type_by_market(market)
|
|
246
|
+
channel = messageType + '.order_cancel'
|
|
247
|
+
url = self.get_url_by_market(market)
|
|
248
|
+
await self.authenticate(url, messageType)
|
|
249
|
+
request['order_id'] = str(id)
|
|
250
|
+
res = await self.request_private(url, self.extend(request, requestParams), channel)
|
|
251
|
+
return self.parse_order(res, market)
|
|
252
|
+
|
|
253
|
+
async def edit_order_ws(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
|
|
254
|
+
"""
|
|
255
|
+
edit a trade order, gate currently only supports the modification of the price or amount fields
|
|
256
|
+
|
|
257
|
+
https://www.gate.io/docs/developers/apiv4/ws/en/#order-amend
|
|
258
|
+
https://www.gate.io/docs/developers/futures/ws/en/#order-amend
|
|
259
|
+
|
|
260
|
+
:param str id: order id
|
|
261
|
+
:param str symbol: unified symbol of the market to create an order in
|
|
262
|
+
:param str type: 'market' or 'limit'
|
|
263
|
+
:param str side: 'buy' or 'sell'
|
|
264
|
+
:param float amount: how much of the currency you want to trade in units of the base currency
|
|
265
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
266
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
267
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
268
|
+
"""
|
|
269
|
+
await self.load_markets()
|
|
270
|
+
market = self.market(symbol)
|
|
271
|
+
extendedRequest = self.edit_order_request(id, symbol, type, side, amount, price, params)
|
|
272
|
+
messageType = self.get_type_by_market(market)
|
|
273
|
+
channel = messageType + '.order_amend'
|
|
274
|
+
url = self.get_url_by_market(market)
|
|
275
|
+
await self.authenticate(url, messageType)
|
|
276
|
+
rawOrder = await self.request_private(url, extendedRequest, channel)
|
|
277
|
+
return self.parse_order(rawOrder, market)
|
|
278
|
+
|
|
279
|
+
async def fetch_order_ws(self, id: str, symbol: Str = None, params={}):
|
|
280
|
+
"""
|
|
281
|
+
Retrieves information on an order
|
|
282
|
+
|
|
283
|
+
https://www.gate.io/docs/developers/apiv4/ws/en/#order-status
|
|
284
|
+
https://www.gate.io/docs/developers/futures/ws/en/#order-status
|
|
285
|
+
|
|
286
|
+
:param str id: Order id
|
|
287
|
+
:param str symbol: Unified market symbol, *required for spot and margin*
|
|
288
|
+
:param dict [params]: Parameters specified by the exchange api
|
|
289
|
+
:param bool [params.trigger]: True if the order being fetched is a trigger order
|
|
290
|
+
:param str [params.marginMode]: 'cross' or 'isolated' - marginMode for margin trading if not provided self.options['defaultMarginMode'] is used
|
|
291
|
+
:param str [params.type]: 'spot', 'swap', or 'future', if not provided self.options['defaultMarginMode'] is used
|
|
292
|
+
:param str [params.settle]: 'btc' or 'usdt' - settle currency for perpetual swap and future - market settle currency is used if symbol is not None, default="usdt" for swap and "btc" for future
|
|
293
|
+
:returns: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
294
|
+
"""
|
|
295
|
+
await self.load_markets()
|
|
296
|
+
market = None if (symbol is None) else self.market(symbol)
|
|
297
|
+
request, requestParams = self.fetchOrderRequest(id, symbol, params)
|
|
298
|
+
messageType = self.get_type_by_market(market)
|
|
299
|
+
channel = messageType + '.order_status'
|
|
300
|
+
url = self.get_url_by_market(market)
|
|
301
|
+
await self.authenticate(url, messageType)
|
|
302
|
+
rawOrder = await self.request_private(url, self.extend(request, requestParams), channel)
|
|
303
|
+
return self.parse_order(rawOrder, market)
|
|
304
|
+
|
|
305
|
+
async def fetch_open_orders_ws(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
|
306
|
+
"""
|
|
307
|
+
fetch all unfilled currently open orders
|
|
308
|
+
|
|
309
|
+
https://www.gate.io/docs/developers/futures/ws/en/#order-list
|
|
310
|
+
|
|
311
|
+
:param str symbol: unified market symbol
|
|
312
|
+
:param int [since]: the earliest time in ms to fetch open orders for
|
|
313
|
+
:param int [limit]: the maximum number of open orders structures to retrieve
|
|
314
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
315
|
+
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
316
|
+
"""
|
|
317
|
+
return await self.fetch_orders_by_status_ws('open', symbol, since, limit, params)
|
|
318
|
+
|
|
319
|
+
async def fetch_closed_orders_ws(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
|
320
|
+
"""
|
|
321
|
+
fetches information on multiple closed orders made by the user
|
|
322
|
+
|
|
323
|
+
https://www.gate.io/docs/developers/futures/ws/en/#order-list
|
|
324
|
+
|
|
325
|
+
:param str symbol: unified market symbol of the market orders were made in
|
|
326
|
+
:param int [since]: the earliest time in ms to fetch orders for
|
|
327
|
+
:param int [limit]: the maximum number of order structures to retrieve
|
|
328
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
329
|
+
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
330
|
+
"""
|
|
331
|
+
return await self.fetch_orders_by_status_ws('finished', symbol, since, limit, params)
|
|
332
|
+
|
|
333
|
+
async def fetch_orders_by_status_ws(self, status: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
|
334
|
+
"""
|
|
335
|
+
|
|
336
|
+
https://www.gate.io/docs/developers/futures/ws/en/#order-list
|
|
337
|
+
|
|
338
|
+
fetches information on multiple orders made by the user by status
|
|
339
|
+
:param str status: requested order status
|
|
340
|
+
:param str symbol: unified market symbol of the market orders were made in
|
|
341
|
+
:param int|None [since]: the earliest time in ms to fetch orders for
|
|
342
|
+
:param int|None [limit]: the maximum number of order structures to retrieve
|
|
343
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
344
|
+
:param int [params.orderId]: order id to begin at
|
|
345
|
+
:param int [params.limit]: the maximum number of order structures to retrieve
|
|
346
|
+
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
347
|
+
"""
|
|
348
|
+
await self.load_markets()
|
|
349
|
+
market = None
|
|
350
|
+
if symbol is not None:
|
|
351
|
+
market = self.market(symbol)
|
|
352
|
+
symbol = market['symbol']
|
|
353
|
+
if market['swap'] is not True:
|
|
354
|
+
raise NotSupported(self.id + ' fetchOrdersByStatusWs is only supported by swap markets. Use rest API for other markets')
|
|
355
|
+
request, requestParams = self.prepareOrdersByStatusRequest(status, symbol, since, limit, params)
|
|
356
|
+
newRequest = self.omit(request, ['settle'])
|
|
357
|
+
messageType = self.get_type_by_market(market)
|
|
358
|
+
channel = messageType + '.order_list'
|
|
359
|
+
url = self.get_url_by_market(market)
|
|
360
|
+
await self.authenticate(url, messageType)
|
|
361
|
+
rawOrders = await self.request_private(url, self.extend(newRequest, requestParams), channel)
|
|
362
|
+
orders = self.parse_orders(rawOrders, market)
|
|
363
|
+
return self.filter_by_symbol_since_limit(orders, symbol, since, limit)
|
|
364
|
+
|
|
107
365
|
async def watch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
|
108
366
|
"""
|
|
109
367
|
watches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
|
368
|
+
|
|
369
|
+
https://www.gate.com/docs/developers/apiv4/ws/en/#order-book-channel
|
|
370
|
+
https://www.gate.com/docs/developers/apiv4/ws/en/#order-book-v2-api
|
|
371
|
+
https://www.gate.com/docs/developers/futures/ws/en/#order-book-api
|
|
372
|
+
https://www.gate.com/docs/developers/futures/ws/en/#order-book-v2-api
|
|
373
|
+
https://www.gate.com/docs/developers/delivery/ws/en/#order-book-api
|
|
374
|
+
|
|
110
375
|
:param str symbol: unified symbol of the market to fetch the order book for
|
|
111
376
|
:param int [limit]: the maximum amount of order book entries to return
|
|
112
377
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -123,7 +388,7 @@ class gate(ccxt.async_support.gate):
|
|
|
123
388
|
url = self.get_url_by_market(market)
|
|
124
389
|
payload = [marketId, interval]
|
|
125
390
|
if limit is None:
|
|
126
|
-
limit = 100
|
|
391
|
+
limit = 100 # max 100 atm
|
|
127
392
|
if market['contract']:
|
|
128
393
|
stringLimit = str(limit)
|
|
129
394
|
payload.append(stringLimit)
|
|
@@ -134,6 +399,31 @@ class gate(ccxt.async_support.gate):
|
|
|
134
399
|
orderbook = await self.subscribe_public(url, messageHash, payload, channel, query, subscription)
|
|
135
400
|
return orderbook.limit()
|
|
136
401
|
|
|
402
|
+
async def un_watch_order_book(self, symbol: str, params={}) -> Any:
|
|
403
|
+
"""
|
|
404
|
+
unWatches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
|
405
|
+
:param str symbol: unified symbol of the market to fetch the order book for
|
|
406
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
407
|
+
:returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
|
|
408
|
+
"""
|
|
409
|
+
await self.load_markets()
|
|
410
|
+
market = self.market(symbol)
|
|
411
|
+
symbol = market['symbol']
|
|
412
|
+
marketId = market['id']
|
|
413
|
+
interval = '100ms'
|
|
414
|
+
interval, params = self.handle_option_and_params(params, 'watchOrderBook', 'interval', interval)
|
|
415
|
+
messageType = self.get_type_by_market(market)
|
|
416
|
+
channel = messageType + '.order_book_update'
|
|
417
|
+
subMessageHash = 'orderbook' + ':' + symbol
|
|
418
|
+
messageHash = 'unsubscribe:orderbook' + ':' + symbol
|
|
419
|
+
url = self.get_url_by_market(market)
|
|
420
|
+
payload = [marketId, interval]
|
|
421
|
+
limit = self.safe_integer(params, 'limit', 100)
|
|
422
|
+
if market['contract']:
|
|
423
|
+
stringLimit = str(limit)
|
|
424
|
+
payload.append(stringLimit)
|
|
425
|
+
return await self.un_subscribe_public_multiple(url, 'orderbook', [symbol], [messageHash], [subMessageHash], payload, channel, params)
|
|
426
|
+
|
|
137
427
|
def handle_order_book_subscription(self, client: Client, message, subscription):
|
|
138
428
|
symbol = self.safe_string(subscription, 'symbol')
|
|
139
429
|
limit = self.safe_integer(subscription, 'limit')
|
|
@@ -224,10 +514,12 @@ class gate(ccxt.async_support.gate):
|
|
|
224
514
|
elif nonce >= deltaStart - 1:
|
|
225
515
|
self.handle_delta(storedOrderBook, delta)
|
|
226
516
|
else:
|
|
227
|
-
error = InvalidNonce(self.id + ' orderbook update has a nonce bigger than u')
|
|
228
517
|
del client.subscriptions[messageHash]
|
|
229
518
|
del self.orderbooks[symbol]
|
|
230
|
-
|
|
519
|
+
checksum = self.handle_option('watchOrderBook', 'checksum', True)
|
|
520
|
+
if checksum:
|
|
521
|
+
error = ChecksumError(self.id + ' ' + self.orderbook_checksum_message(symbol))
|
|
522
|
+
client.reject(error, messageHash)
|
|
231
523
|
client.resolve(storedOrderBook, messageHash)
|
|
232
524
|
|
|
233
525
|
def get_cache_index(self, orderBook, cache):
|
|
@@ -268,7 +560,9 @@ class gate(ccxt.async_support.gate):
|
|
|
268
560
|
|
|
269
561
|
async def watch_ticker(self, symbol: str, params={}) -> Ticker:
|
|
270
562
|
"""
|
|
271
|
-
|
|
563
|
+
|
|
564
|
+
https://www.gate.io/docs/developers/apiv4/ws/en/#tickers-channel
|
|
565
|
+
|
|
272
566
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
273
567
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
|
274
568
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -283,7 +577,9 @@ class gate(ccxt.async_support.gate):
|
|
|
283
577
|
|
|
284
578
|
async def watch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
|
285
579
|
"""
|
|
286
|
-
|
|
580
|
+
|
|
581
|
+
https://www.gate.io/docs/developers/apiv4/ws/en/#tickers-channel
|
|
582
|
+
|
|
287
583
|
watches a price ticker, a statistical calculation with the information calculated over the past 24 hours for all markets of a specific list
|
|
288
584
|
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
|
289
585
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -314,8 +610,10 @@ class gate(ccxt.async_support.gate):
|
|
|
314
610
|
|
|
315
611
|
async def watch_bids_asks(self, symbols: Strings = None, params={}) -> Tickers:
|
|
316
612
|
"""
|
|
317
|
-
|
|
318
|
-
|
|
613
|
+
|
|
614
|
+
https://www.gate.io/docs/developers/apiv4/ws/en/#best-bid-or-ask-price
|
|
615
|
+
https://www.gate.io/docs/developers/apiv4/ws/en/#order-book-channel
|
|
616
|
+
|
|
319
617
|
watches best bid & ask for symbols
|
|
320
618
|
:param str[] symbols: unified symbol of the market to fetch the ticker for
|
|
321
619
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -408,7 +706,7 @@ class gate(ccxt.async_support.gate):
|
|
|
408
706
|
async def watch_trades_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
|
409
707
|
"""
|
|
410
708
|
get the list of most recent trades for a particular symbol
|
|
411
|
-
:param str
|
|
709
|
+
:param str[] symbols: unified symbol of the market to fetch trades for
|
|
412
710
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
|
413
711
|
:param int [limit]: the maximum amount of trades to fetch
|
|
414
712
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -432,6 +730,37 @@ class gate(ccxt.async_support.gate):
|
|
|
432
730
|
limit = trades.getLimit(tradeSymbol, limit)
|
|
433
731
|
return self.filter_by_since_limit(trades, since, limit, 'timestamp', True)
|
|
434
732
|
|
|
733
|
+
async def un_watch_trades_for_symbols(self, symbols: List[str], params={}) -> Any:
|
|
734
|
+
"""
|
|
735
|
+
get the list of most recent trades for a particular symbol
|
|
736
|
+
:param str[] symbols: unified symbol of the market to fetch trades for
|
|
737
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
738
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
|
739
|
+
"""
|
|
740
|
+
await self.load_markets()
|
|
741
|
+
symbols = self.market_symbols(symbols)
|
|
742
|
+
marketIds = self.market_ids(symbols)
|
|
743
|
+
market = self.market(symbols[0])
|
|
744
|
+
messageType = self.get_type_by_market(market)
|
|
745
|
+
channel = messageType + '.trades'
|
|
746
|
+
subMessageHashes = []
|
|
747
|
+
messageHashes = []
|
|
748
|
+
for i in range(0, len(symbols)):
|
|
749
|
+
symbol = symbols[i]
|
|
750
|
+
subMessageHashes.append('trades:' + symbol)
|
|
751
|
+
messageHashes.append('unsubscribe:trades:' + symbol)
|
|
752
|
+
url = self.get_url_by_market(market)
|
|
753
|
+
return await self.un_subscribe_public_multiple(url, 'trades', symbols, messageHashes, subMessageHashes, marketIds, channel, params)
|
|
754
|
+
|
|
755
|
+
async def un_watch_trades(self, symbol: str, params={}) -> Any:
|
|
756
|
+
"""
|
|
757
|
+
get the list of most recent trades for a particular symbol
|
|
758
|
+
:param str symbol: unified symbol of the market to fetch trades for
|
|
759
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
760
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
|
761
|
+
"""
|
|
762
|
+
return await self.un_watch_trades_for_symbols([symbol], params)
|
|
763
|
+
|
|
435
764
|
def handle_trades(self, client: Client, message):
|
|
436
765
|
#
|
|
437
766
|
# {
|
|
@@ -549,7 +878,7 @@ class gate(ccxt.async_support.gate):
|
|
|
549
878
|
:param int [since]: the earliest time in ms to fetch trades for
|
|
550
879
|
:param int [limit]: the maximum number of trade structures to retrieve
|
|
551
880
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
552
|
-
:returns dict[]: a list of
|
|
881
|
+
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
|
553
882
|
"""
|
|
554
883
|
await self.load_markets()
|
|
555
884
|
subType = None
|
|
@@ -739,11 +1068,15 @@ class gate(ccxt.async_support.gate):
|
|
|
739
1068
|
|
|
740
1069
|
async def watch_positions(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
|
|
741
1070
|
"""
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
1071
|
+
|
|
1072
|
+
https://www.gate.io/docs/developers/futures/ws/en/#positions-subscription
|
|
1073
|
+
https://www.gate.io/docs/developers/delivery/ws/en/#positions-subscription
|
|
1074
|
+
https://www.gate.io/docs/developers/options/ws/en/#positions-channel
|
|
1075
|
+
|
|
745
1076
|
watch all open positions
|
|
746
|
-
:param str[]
|
|
1077
|
+
:param str[] [symbols]: list of unified market symbols to watch positions for
|
|
1078
|
+
:param int [since]: the earliest time in ms to fetch positions for
|
|
1079
|
+
:param int [limit]: the maximum number of positions to retrieve
|
|
747
1080
|
:param dict params: extra parameters specific to the exchange API endpoint
|
|
748
1081
|
:returns dict[]: a list of `position structure <https://docs.ccxt.com/en/latest/manual.html#position-structure>`
|
|
749
1082
|
"""
|
|
@@ -774,7 +1107,7 @@ class gate(ccxt.async_support.gate):
|
|
|
774
1107
|
client = self.client(url)
|
|
775
1108
|
self.set_positions_cache(client, type, symbols)
|
|
776
1109
|
fetchPositionsSnapshot = self.handle_option('watchPositions', 'fetchPositionsSnapshot', True)
|
|
777
|
-
awaitPositionsSnapshot = self.
|
|
1110
|
+
awaitPositionsSnapshot = self.handle_option('watchPositions', 'awaitPositionsSnapshot', True)
|
|
778
1111
|
cache = self.safe_value(self.positions, type)
|
|
779
1112
|
if fetchPositionsSnapshot and awaitPositionsSnapshot and cache is None:
|
|
780
1113
|
return await client.future(type + ':fetchPositionsSnapshot')
|
|
@@ -803,7 +1136,9 @@ class gate(ccxt.async_support.gate):
|
|
|
803
1136
|
cache = self.positions[type]
|
|
804
1137
|
for i in range(0, len(positions)):
|
|
805
1138
|
position = positions[i]
|
|
806
|
-
|
|
1139
|
+
contracts = self.safe_number(position, 'contracts', 0)
|
|
1140
|
+
if contracts > 0:
|
|
1141
|
+
cache.append(position)
|
|
807
1142
|
# don't remove the future from the .futures cache
|
|
808
1143
|
future = client.futures[messageHash]
|
|
809
1144
|
future.resolve(cache)
|
|
@@ -847,8 +1182,28 @@ class gate(ccxt.async_support.gate):
|
|
|
847
1182
|
for i in range(0, len(data)):
|
|
848
1183
|
rawPosition = data[i]
|
|
849
1184
|
position = self.parse_position(rawPosition)
|
|
850
|
-
|
|
851
|
-
|
|
1185
|
+
symbol = self.safe_string(position, 'symbol')
|
|
1186
|
+
side = self.safe_string(position, 'side')
|
|
1187
|
+
# Control when position is closed no side is returned
|
|
1188
|
+
if side is None:
|
|
1189
|
+
prevLongPosition = self.safe_dict(cache, symbol + 'long')
|
|
1190
|
+
if prevLongPosition is not None:
|
|
1191
|
+
position['side'] = prevLongPosition['side']
|
|
1192
|
+
newPositions.append(position)
|
|
1193
|
+
cache.append(position)
|
|
1194
|
+
prevShortPosition = self.safe_dict(cache, symbol + 'short')
|
|
1195
|
+
if prevShortPosition is not None:
|
|
1196
|
+
position['side'] = prevShortPosition['side']
|
|
1197
|
+
newPositions.append(position)
|
|
1198
|
+
cache.append(position)
|
|
1199
|
+
# if no prev position is found, default to long
|
|
1200
|
+
if prevLongPosition is None and prevShortPosition is None:
|
|
1201
|
+
position['side'] = 'long'
|
|
1202
|
+
newPositions.append(position)
|
|
1203
|
+
cache.append(position)
|
|
1204
|
+
else:
|
|
1205
|
+
newPositions.append(position)
|
|
1206
|
+
cache.append(position)
|
|
852
1207
|
messageHashes = self.find_message_hashes(client, type + ':positions::')
|
|
853
1208
|
for i in range(0, len(messageHashes)):
|
|
854
1209
|
messageHash = messageHashes[i]
|
|
@@ -869,7 +1224,7 @@ class gate(ccxt.async_support.gate):
|
|
|
869
1224
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
870
1225
|
:param str [params.type]: spot, margin, swap, future, or option. Required if listening to all symbols.
|
|
871
1226
|
:param boolean [params.isInverse]: if future, listen to inverse or linear contracts
|
|
872
|
-
:returns dict[]: a list of
|
|
1227
|
+
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
873
1228
|
"""
|
|
874
1229
|
await self.load_markets()
|
|
875
1230
|
market = None
|
|
@@ -956,7 +1311,7 @@ class gate(ccxt.async_support.gate):
|
|
|
956
1311
|
elif event == 'finish':
|
|
957
1312
|
status = self.safe_string(parsed, 'status')
|
|
958
1313
|
if status is None:
|
|
959
|
-
left = self.
|
|
1314
|
+
left = self.safe_integer(info, 'left')
|
|
960
1315
|
parsed['status'] = 'closed' if (left == 0) else 'canceled'
|
|
961
1316
|
stored.append(parsed)
|
|
962
1317
|
symbol = parsed['symbol']
|
|
@@ -971,9 +1326,11 @@ class gate(ccxt.async_support.gate):
|
|
|
971
1326
|
async def watch_my_liquidations(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
|
|
972
1327
|
"""
|
|
973
1328
|
watch the public liquidations of a trading pair
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
1329
|
+
|
|
1330
|
+
https://www.gate.io/docs/developers/futures/ws/en/#liquidates-api
|
|
1331
|
+
https://www.gate.io/docs/developers/delivery/ws/en/#liquidates-api
|
|
1332
|
+
https://www.gate.io/docs/developers/options/ws/en/#liquidates-channel
|
|
1333
|
+
|
|
977
1334
|
:param str symbol: unified CCXT market symbol
|
|
978
1335
|
:param int [since]: the earliest time in ms to fetch liquidations for
|
|
979
1336
|
:param int [limit]: the maximum number of liquidation structures to retrieve
|
|
@@ -982,13 +1339,15 @@ class gate(ccxt.async_support.gate):
|
|
|
982
1339
|
"""
|
|
983
1340
|
return self.watch_my_liquidations_for_symbols([symbol], since, limit, params)
|
|
984
1341
|
|
|
985
|
-
async def watch_my_liquidations_for_symbols(self, symbols: List[str]
|
|
1342
|
+
async def watch_my_liquidations_for_symbols(self, symbols: List[str], since: Int = None, limit: Int = None, params={}) -> List[Liquidation]:
|
|
986
1343
|
"""
|
|
987
1344
|
watch the private liquidations of a trading pair
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
1345
|
+
|
|
1346
|
+
https://www.gate.io/docs/developers/futures/ws/en/#liquidates-api
|
|
1347
|
+
https://www.gate.io/docs/developers/delivery/ws/en/#liquidates-api
|
|
1348
|
+
https://www.gate.io/docs/developers/options/ws/en/#liquidates-channel
|
|
1349
|
+
|
|
1350
|
+
:param str[] symbols: unified CCXT market symbols
|
|
992
1351
|
:param int [since]: the earliest time in ms to fetch liquidations for
|
|
993
1352
|
:param int [limit]: the maximum number of liquidation structures to retrieve
|
|
994
1353
|
:param dict [params]: exchange specific parameters for the gate api endpoint
|
|
@@ -1134,38 +1493,88 @@ class gate(ccxt.async_support.gate):
|
|
|
1134
1493
|
'datetime': self.iso8601(timestamp),
|
|
1135
1494
|
})
|
|
1136
1495
|
|
|
1137
|
-
def handle_error_message(self, client: Client, message):
|
|
1138
|
-
#
|
|
1139
|
-
#
|
|
1140
|
-
#
|
|
1141
|
-
#
|
|
1142
|
-
#
|
|
1143
|
-
# }
|
|
1144
|
-
#
|
|
1145
|
-
#
|
|
1146
|
-
#
|
|
1147
|
-
#
|
|
1148
|
-
#
|
|
1149
|
-
#
|
|
1150
|
-
#
|
|
1151
|
-
#
|
|
1152
|
-
#
|
|
1153
|
-
#
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1496
|
+
def handle_error_message(self, client: Client, message) -> Bool:
|
|
1497
|
+
#
|
|
1498
|
+
# {
|
|
1499
|
+
# "time": 1647274664,
|
|
1500
|
+
# "channel": "futures.orders",
|
|
1501
|
+
# "event": "subscribe",
|
|
1502
|
+
# "error": {code: 2, message: "unknown contract BTC_USDT_20220318"},
|
|
1503
|
+
# }
|
|
1504
|
+
# {
|
|
1505
|
+
# "time": 1647276473,
|
|
1506
|
+
# "channel": "futures.orders",
|
|
1507
|
+
# "event": "subscribe",
|
|
1508
|
+
# "error": {
|
|
1509
|
+
# "code": 4,
|
|
1510
|
+
# "message": "{"label":"INVALID_KEY","message":"Invalid key provided"}\n"
|
|
1511
|
+
# },
|
|
1512
|
+
# "result": null
|
|
1513
|
+
# }
|
|
1514
|
+
# {
|
|
1515
|
+
# header: {
|
|
1516
|
+
# response_time: '1718551891329',
|
|
1517
|
+
# status: '400',
|
|
1518
|
+
# channel: 'spot.order_place',
|
|
1519
|
+
# event: 'api',
|
|
1520
|
+
# client_id: '81.34.68.6-0xc16375e2c0',
|
|
1521
|
+
# conn_id: '9539116e0e09678f'
|
|
1522
|
+
# },
|
|
1523
|
+
# data: {errs: {label: 'AUTHENTICATION_FAILED', message: 'Not login'}},
|
|
1524
|
+
# request_id: '10406147'
|
|
1525
|
+
# }
|
|
1526
|
+
# {
|
|
1527
|
+
# "time": 1739853211,
|
|
1528
|
+
# "time_ms": 1739853211201,
|
|
1529
|
+
# "id": 1,
|
|
1530
|
+
# "conn_id": "62f2c1dabbe186d7",
|
|
1531
|
+
# "trace_id": "cdb02a8c0b61086b2fe6f8fad2f98c54",
|
|
1532
|
+
# "channel": "spot.trades",
|
|
1533
|
+
# "event": "subscribe",
|
|
1534
|
+
# "payload": [
|
|
1535
|
+
# "LUNARLENS_USDT",
|
|
1536
|
+
# "ETH_USDT"
|
|
1537
|
+
# ],
|
|
1538
|
+
# "error": {
|
|
1539
|
+
# "code": 2,
|
|
1540
|
+
# "message": "unknown currency pair: LUNARLENS_USDT"
|
|
1541
|
+
# },
|
|
1542
|
+
# "result": {
|
|
1543
|
+
# "status": "fail"
|
|
1544
|
+
# },
|
|
1545
|
+
# "requestId": "cdb02a8c0b61086b2fe6f8fad2f98c54"
|
|
1546
|
+
# }
|
|
1547
|
+
#
|
|
1548
|
+
data = self.safe_dict(message, 'data')
|
|
1549
|
+
errs = self.safe_dict(data, 'errs')
|
|
1550
|
+
error = self.safe_dict(message, 'error', errs)
|
|
1551
|
+
code = self.safe_string_2(error, 'code', 'label')
|
|
1552
|
+
id = self.safe_string_n(message, ['id', 'requestId', 'request_id'])
|
|
1553
|
+
if error is not None:
|
|
1160
1554
|
messageHash = self.safe_string(client.subscriptions, id)
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1555
|
+
try:
|
|
1556
|
+
self.throw_exactly_matched_exception(self.exceptions['ws']['exact'], code, self.json(message))
|
|
1557
|
+
self.throw_exactly_matched_exception(self.exceptions['exact'], code, self.json(errs))
|
|
1558
|
+
errorMessage = self.safe_string(error, 'message', self.safe_string(errs, 'message'))
|
|
1559
|
+
self.throw_broadly_matched_exception(self.exceptions['ws']['broad'], errorMessage, self.json(message))
|
|
1560
|
+
raise ExchangeError(self.json(message))
|
|
1561
|
+
except Exception as e:
|
|
1562
|
+
client.reject(e, messageHash)
|
|
1563
|
+
if (messageHash is not None) and (messageHash in client.subscriptions):
|
|
1564
|
+
del client.subscriptions[messageHash]
|
|
1565
|
+
# remove subscriptions for watchSymbols
|
|
1566
|
+
channel = self.safe_string(message, 'channel')
|
|
1567
|
+
if (channel is not None) and (channel.find('.') > 0):
|
|
1568
|
+
parsedChannel = channel.split('.')
|
|
1569
|
+
payload = self.safe_list(message, 'payload', [])
|
|
1570
|
+
for i in range(0, len(payload)):
|
|
1571
|
+
marketType = parsedChannel[0] == 'swap' if 'futures' else parsedChannel[0]
|
|
1572
|
+
symbol = self.safe_symbol(payload[i], None, '_', marketType)
|
|
1573
|
+
messageHashSymbol = parsedChannel[1] + ':' + symbol
|
|
1574
|
+
if (messageHashSymbol is not None) and (messageHashSymbol in client.subscriptions):
|
|
1575
|
+
del client.subscriptions[messageHashSymbol]
|
|
1576
|
+
if (id is not None) and (id in client.subscriptions):
|
|
1577
|
+
del client.subscriptions[id]
|
|
1169
1578
|
return True
|
|
1170
1579
|
return False
|
|
1171
1580
|
|
|
@@ -1188,6 +1597,73 @@ class gate(ccxt.async_support.gate):
|
|
|
1188
1597
|
if id in client.subscriptions:
|
|
1189
1598
|
del client.subscriptions[id]
|
|
1190
1599
|
|
|
1600
|
+
def handle_un_subscribe(self, client: Client, message):
|
|
1601
|
+
#
|
|
1602
|
+
# {
|
|
1603
|
+
# "time":1725534679,
|
|
1604
|
+
# "time_ms":1725534679786,
|
|
1605
|
+
# "id":2,
|
|
1606
|
+
# "conn_id":"fac539b443fd7002",
|
|
1607
|
+
# "trace_id":"efe1d282b630b4aa266b84bee177791a",
|
|
1608
|
+
# "channel":"spot.trades",
|
|
1609
|
+
# "event":"unsubscribe",
|
|
1610
|
+
# "payload":[
|
|
1611
|
+
# "LTC_USDT"
|
|
1612
|
+
# ],
|
|
1613
|
+
# "result":{
|
|
1614
|
+
# "status":"success"
|
|
1615
|
+
# },
|
|
1616
|
+
# "requestId":"efe1d282b630b4aa266b84bee177791a"
|
|
1617
|
+
# }
|
|
1618
|
+
#
|
|
1619
|
+
id = self.safe_string(message, 'id')
|
|
1620
|
+
keys = list(client.subscriptions.keys())
|
|
1621
|
+
for i in range(0, len(keys)):
|
|
1622
|
+
messageHash = keys[i]
|
|
1623
|
+
if not (messageHash in client.subscriptions):
|
|
1624
|
+
continue
|
|
1625
|
+
# the previous iteration can have deleted the messageHash from the subscriptions
|
|
1626
|
+
if messageHash.startswith('unsubscribe'):
|
|
1627
|
+
subscription = client.subscriptions[messageHash]
|
|
1628
|
+
subId = self.safe_string(subscription, 'id')
|
|
1629
|
+
if id != subId:
|
|
1630
|
+
continue
|
|
1631
|
+
messageHashes = self.safe_list(subscription, 'messageHashes', [])
|
|
1632
|
+
subMessageHashes = self.safe_list(subscription, 'subMessageHashes', [])
|
|
1633
|
+
for j in range(0, len(messageHashes)):
|
|
1634
|
+
unsubHash = messageHashes[j]
|
|
1635
|
+
subHash = subMessageHashes[j]
|
|
1636
|
+
self.clean_unsubscription(client, subHash, unsubHash)
|
|
1637
|
+
self.clean_cache(subscription)
|
|
1638
|
+
|
|
1639
|
+
def clean_cache(self, subscription: dict):
|
|
1640
|
+
topic = self.safe_string(subscription, 'topic', '')
|
|
1641
|
+
symbols = self.safe_list(subscription, 'symbols', [])
|
|
1642
|
+
symbolsLength = len(symbols)
|
|
1643
|
+
if topic == 'ohlcv':
|
|
1644
|
+
symbolsAndTimeFrames = self.safe_list(subscription, 'symbolsAndTimeframes', [])
|
|
1645
|
+
for i in range(0, len(symbolsAndTimeFrames)):
|
|
1646
|
+
symbolAndTimeFrame = symbolsAndTimeFrames[i]
|
|
1647
|
+
symbol = self.safe_string(symbolAndTimeFrame, 0)
|
|
1648
|
+
timeframe = self.safe_string(symbolAndTimeFrame, 1)
|
|
1649
|
+
del self.ohlcvs[symbol][timeframe]
|
|
1650
|
+
elif symbolsLength > 0:
|
|
1651
|
+
for i in range(0, len(symbols)):
|
|
1652
|
+
symbol = symbols[i]
|
|
1653
|
+
if topic.endswith('trades'):
|
|
1654
|
+
del self.trades[symbol]
|
|
1655
|
+
elif topic == 'orderbook':
|
|
1656
|
+
del self.orderbooks[symbol]
|
|
1657
|
+
elif topic == 'ticker':
|
|
1658
|
+
del self.tickers[symbol]
|
|
1659
|
+
else:
|
|
1660
|
+
if topic.endswith('trades'):
|
|
1661
|
+
# don't reset self.myTrades directly here
|
|
1662
|
+
# because in c# we need to use a different object
|
|
1663
|
+
keys = list(self.trades.keys())
|
|
1664
|
+
for i in range(0, len(keys)):
|
|
1665
|
+
del self.trades[keys[i]]
|
|
1666
|
+
|
|
1191
1667
|
def handle_message(self, client: Client, message):
|
|
1192
1668
|
#
|
|
1193
1669
|
# subscribe
|
|
@@ -1284,6 +1760,9 @@ class gate(ccxt.async_support.gate):
|
|
|
1284
1760
|
if event == 'subscribe':
|
|
1285
1761
|
self.handle_subscription_status(client, message)
|
|
1286
1762
|
return
|
|
1763
|
+
if event == 'unsubscribe':
|
|
1764
|
+
self.handle_un_subscribe(client, message)
|
|
1765
|
+
return
|
|
1287
1766
|
channel = self.safe_string(message, 'channel', '')
|
|
1288
1767
|
channelParts = channel.split('.')
|
|
1289
1768
|
channelType = self.safe_value(channelParts, 1)
|
|
@@ -1302,6 +1781,17 @@ class gate(ccxt.async_support.gate):
|
|
|
1302
1781
|
method = self.safe_value(v4Methods, channelType)
|
|
1303
1782
|
if method is not None:
|
|
1304
1783
|
method(client, message)
|
|
1784
|
+
requestId = self.safe_string(message, 'request_id')
|
|
1785
|
+
if requestId == 'authenticated':
|
|
1786
|
+
self.handle_authentication_message(client, message)
|
|
1787
|
+
return
|
|
1788
|
+
if requestId is not None:
|
|
1789
|
+
data = self.safe_dict(message, 'data')
|
|
1790
|
+
# use safeValue may be Array or an Object
|
|
1791
|
+
result = self.safe_value(data, 'result')
|
|
1792
|
+
ack = self.safe_bool(message, 'ack')
|
|
1793
|
+
if ack is not True:
|
|
1794
|
+
client.resolve(result, requestId)
|
|
1305
1795
|
|
|
1306
1796
|
def get_url_by_market(self, market):
|
|
1307
1797
|
baseUrl = self.urls['api'][market['type']]
|
|
@@ -1310,7 +1800,7 @@ class gate(ccxt.async_support.gate):
|
|
|
1310
1800
|
else:
|
|
1311
1801
|
return baseUrl
|
|
1312
1802
|
|
|
1313
|
-
def get_type_by_market(self, market):
|
|
1803
|
+
def get_type_by_market(self, market: Market):
|
|
1314
1804
|
if market['spot']:
|
|
1315
1805
|
return 'spot'
|
|
1316
1806
|
elif market['option']:
|
|
@@ -1318,7 +1808,7 @@ class gate(ccxt.async_support.gate):
|
|
|
1318
1808
|
else:
|
|
1319
1809
|
return 'futures'
|
|
1320
1810
|
|
|
1321
|
-
def get_url_by_market_type(self, type, isInverse=False):
|
|
1811
|
+
def get_url_by_market_type(self, type: MarketType, isInverse=False):
|
|
1322
1812
|
api = self.urls['api']
|
|
1323
1813
|
url = api[type]
|
|
1324
1814
|
if (type == 'swap') or (type == 'future'):
|
|
@@ -1377,6 +1867,74 @@ class gate(ccxt.async_support.gate):
|
|
|
1377
1867
|
message = self.extend(request, params)
|
|
1378
1868
|
return await self.watch_multiple(url, messageHashes, message, messageHashes)
|
|
1379
1869
|
|
|
1870
|
+
async def un_subscribe_public_multiple(self, url, topic, symbols, messageHashes, subMessageHashes, payload, channel, params={}):
|
|
1871
|
+
requestId = self.request_id()
|
|
1872
|
+
time = self.seconds()
|
|
1873
|
+
request: dict = {
|
|
1874
|
+
'id': requestId,
|
|
1875
|
+
'time': time,
|
|
1876
|
+
'channel': channel,
|
|
1877
|
+
'event': 'unsubscribe',
|
|
1878
|
+
'payload': payload,
|
|
1879
|
+
}
|
|
1880
|
+
sub = {
|
|
1881
|
+
'id': str(requestId),
|
|
1882
|
+
'topic': topic,
|
|
1883
|
+
'unsubscribe': True,
|
|
1884
|
+
'messageHashes': messageHashes,
|
|
1885
|
+
'subMessageHashes': subMessageHashes,
|
|
1886
|
+
'symbols': symbols,
|
|
1887
|
+
}
|
|
1888
|
+
message = self.extend(request, params)
|
|
1889
|
+
return await self.watch_multiple(url, messageHashes, message, messageHashes, sub)
|
|
1890
|
+
|
|
1891
|
+
async def authenticate(self, url, messageType):
|
|
1892
|
+
channel = messageType + '.login'
|
|
1893
|
+
client = self.client(url)
|
|
1894
|
+
messageHash = 'authenticated'
|
|
1895
|
+
future = client.future(messageHash)
|
|
1896
|
+
authenticated = self.safe_value(client.subscriptions, messageHash)
|
|
1897
|
+
if authenticated is None:
|
|
1898
|
+
return await self.request_private(url, {}, channel, messageHash)
|
|
1899
|
+
return future
|
|
1900
|
+
|
|
1901
|
+
def handle_authentication_message(self, client: Client, message):
|
|
1902
|
+
messageHash = 'authenticated'
|
|
1903
|
+
future = self.safe_value(client.futures, messageHash)
|
|
1904
|
+
future.resolve(True)
|
|
1905
|
+
|
|
1906
|
+
async def request_private(self, url, reqParams, channel, requestId: Str = None):
|
|
1907
|
+
self.check_required_credentials()
|
|
1908
|
+
# uid is required for some subscriptions only so it's not a part of required credentials
|
|
1909
|
+
event = 'api'
|
|
1910
|
+
if requestId is None:
|
|
1911
|
+
reqId = self.request_id()
|
|
1912
|
+
requestId = str(reqId)
|
|
1913
|
+
messageHash = requestId
|
|
1914
|
+
time = self.seconds()
|
|
1915
|
+
# unfortunately, PHP demands double quotes for the escaped newline symbol
|
|
1916
|
+
signatureString = "\n".join([event, channel, self.json(reqParams), str(time)]) # eslint-disable-line quotes
|
|
1917
|
+
signature = self.hmac(self.encode(signatureString), self.encode(self.secret), hashlib.sha512, 'hex')
|
|
1918
|
+
payload: dict = {
|
|
1919
|
+
'req_id': requestId,
|
|
1920
|
+
'timestamp': str(time),
|
|
1921
|
+
'api_key': self.apiKey,
|
|
1922
|
+
'signature': signature,
|
|
1923
|
+
'req_param': reqParams,
|
|
1924
|
+
}
|
|
1925
|
+
if (channel == 'spot.order_place') or (channel == 'futures.order_place'):
|
|
1926
|
+
payload['req_header'] = {
|
|
1927
|
+
'X-Gate-Channel-Id': 'ccxt',
|
|
1928
|
+
}
|
|
1929
|
+
request: dict = {
|
|
1930
|
+
'id': requestId,
|
|
1931
|
+
'time': time,
|
|
1932
|
+
'channel': channel,
|
|
1933
|
+
'event': event,
|
|
1934
|
+
'payload': payload,
|
|
1935
|
+
}
|
|
1936
|
+
return await self.watch(url, messageHash, request, messageHash, requestId)
|
|
1937
|
+
|
|
1380
1938
|
async def subscribe_private(self, url, messageHash, payload, channel, params, requiresUid=False):
|
|
1381
1939
|
self.check_required_credentials()
|
|
1382
1940
|
# uid is required for some subscriptions only so it's not a part of required credentials
|
|
@@ -1402,7 +1960,7 @@ class gate(ccxt.async_support.gate):
|
|
|
1402
1960
|
'id': requestId,
|
|
1403
1961
|
'time': time,
|
|
1404
1962
|
'channel': channel,
|
|
1405
|
-
'event':
|
|
1963
|
+
'event': event,
|
|
1406
1964
|
'auth': auth,
|
|
1407
1965
|
}
|
|
1408
1966
|
if payload is not None:
|
|
@@ -1413,4 +1971,4 @@ class gate(ccxt.async_support.gate):
|
|
|
1413
1971
|
# in case of authenticationError we will throw
|
|
1414
1972
|
client.subscriptions[tempSubscriptionHash] = messageHash
|
|
1415
1973
|
message = self.extend(request, params)
|
|
1416
|
-
return await self.watch(url, messageHash, message, messageHash)
|
|
1974
|
+
return await self.watch(url, messageHash, message, messageHash, messageHash)
|