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/async_support/woo.py
CHANGED
|
@@ -5,16 +5,17 @@
|
|
|
5
5
|
|
|
6
6
|
from ccxt.async_support.base.exchange import Exchange
|
|
7
7
|
from ccxt.abstract.woo import ImplicitAPI
|
|
8
|
+
import asyncio
|
|
8
9
|
import hashlib
|
|
9
|
-
from ccxt.base.types import Account, Balances, Bool, Conversion, Currencies, Currency, Int, Leverage, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Trade, TradingFees, Transaction, TransferEntry
|
|
10
|
+
from ccxt.base.types import Account, Any, Balances, Bool, Conversion, Currencies, Currency, DepositAddress, Int, LedgerEntry, Leverage, MarginModification, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, FundingRate, FundingRates, Trade, TradingFeeInterface, TradingFees, Transaction, TransferEntry
|
|
10
11
|
from typing import List
|
|
11
|
-
from typing import Any
|
|
12
12
|
from ccxt.base.errors import ExchangeError
|
|
13
13
|
from ccxt.base.errors import AuthenticationError
|
|
14
14
|
from ccxt.base.errors import ArgumentsRequired
|
|
15
15
|
from ccxt.base.errors import BadRequest
|
|
16
16
|
from ccxt.base.errors import InvalidOrder
|
|
17
17
|
from ccxt.base.errors import NotSupported
|
|
18
|
+
from ccxt.base.errors import OperationFailed
|
|
18
19
|
from ccxt.base.errors import RateLimitExceeded
|
|
19
20
|
from ccxt.base.errors import OnMaintenance
|
|
20
21
|
from ccxt.base.decimal_to_precision import TICK_SIZE
|
|
@@ -23,7 +24,7 @@ from ccxt.base.precise import Precise
|
|
|
23
24
|
|
|
24
25
|
class woo(Exchange, ImplicitAPI):
|
|
25
26
|
|
|
26
|
-
def describe(self):
|
|
27
|
+
def describe(self) -> Any:
|
|
27
28
|
return self.deep_extend(super(woo, self).describe(), {
|
|
28
29
|
'id': 'woo',
|
|
29
30
|
'name': 'WOO X',
|
|
@@ -32,7 +33,7 @@ class woo(Exchange, ImplicitAPI):
|
|
|
32
33
|
'version': 'v1',
|
|
33
34
|
'certified': True,
|
|
34
35
|
'pro': True,
|
|
35
|
-
'hostname': '
|
|
36
|
+
'hostname': 'woox.io',
|
|
36
37
|
'has': {
|
|
37
38
|
'CORS': None,
|
|
38
39
|
'spot': True,
|
|
@@ -40,11 +41,11 @@ class woo(Exchange, ImplicitAPI):
|
|
|
40
41
|
'swap': True,
|
|
41
42
|
'future': False,
|
|
42
43
|
'option': False,
|
|
43
|
-
'addMargin':
|
|
44
|
+
'addMargin': True,
|
|
44
45
|
'cancelAllOrders': True,
|
|
45
46
|
'cancelAllOrdersAfter': True,
|
|
46
47
|
'cancelOrder': True,
|
|
47
|
-
'cancelWithdraw': False, # exchange have that endpoint disabled atm, but was once implemented in ccxt per old docs: https://
|
|
48
|
+
'cancelWithdraw': False, # exchange have that endpoint disabled atm, but was once implemented in ccxt per old docs: https://docx.woo.io/wootrade-documents/#cancel-withdraw-request
|
|
48
49
|
'closeAllPositions': False,
|
|
49
50
|
'closePosition': False,
|
|
50
51
|
'createConvertTrade': True,
|
|
@@ -52,7 +53,7 @@ class woo(Exchange, ImplicitAPI):
|
|
|
52
53
|
'createMarketBuyOrderWithCost': True,
|
|
53
54
|
'createMarketOrder': False,
|
|
54
55
|
'createMarketOrderWithCost': False,
|
|
55
|
-
'createMarketSellOrderWithCost':
|
|
56
|
+
'createMarketSellOrderWithCost': True,
|
|
56
57
|
'createOrder': True,
|
|
57
58
|
'createOrderWithTakeProfitAndStopLoss': True,
|
|
58
59
|
'createReduceOnlyOrder': True,
|
|
@@ -75,9 +76,13 @@ class woo(Exchange, ImplicitAPI):
|
|
|
75
76
|
'fetchConvertTradeHistory': True,
|
|
76
77
|
'fetchCurrencies': True,
|
|
77
78
|
'fetchDepositAddress': True,
|
|
79
|
+
'fetchDepositAddresses': False,
|
|
80
|
+
'fetchDepositAddressesByNetwork': False,
|
|
78
81
|
'fetchDeposits': True,
|
|
79
82
|
'fetchDepositsWithdrawals': True,
|
|
80
83
|
'fetchFundingHistory': True,
|
|
84
|
+
'fetchFundingInterval': True,
|
|
85
|
+
'fetchFundingIntervals': False,
|
|
81
86
|
'fetchFundingRate': True,
|
|
82
87
|
'fetchFundingRateHistory': True,
|
|
83
88
|
'fetchFundingRates': True,
|
|
@@ -108,7 +113,7 @@ class woo(Exchange, ImplicitAPI):
|
|
|
108
113
|
'fetchTickers': False,
|
|
109
114
|
'fetchTime': True,
|
|
110
115
|
'fetchTrades': True,
|
|
111
|
-
'fetchTradingFee':
|
|
116
|
+
'fetchTradingFee': True,
|
|
112
117
|
'fetchTradingFees': True,
|
|
113
118
|
'fetchTransactions': 'emulated',
|
|
114
119
|
'fetchTransfers': True,
|
|
@@ -119,7 +124,7 @@ class woo(Exchange, ImplicitAPI):
|
|
|
119
124
|
'setMargin': False,
|
|
120
125
|
'setPositionMode': True,
|
|
121
126
|
'transfer': True,
|
|
122
|
-
'withdraw': True, # exchange have that endpoint disabled atm, but was once implemented in ccxt per old docs: https://
|
|
127
|
+
'withdraw': True, # exchange have that endpoint disabled atm, but was once implemented in ccxt per old docs: https://docx.woo.io/wootrade-documents/#token-withdraw
|
|
123
128
|
},
|
|
124
129
|
'timeframes': {
|
|
125
130
|
'1m': '1m',
|
|
@@ -137,24 +142,24 @@ class woo(Exchange, ImplicitAPI):
|
|
|
137
142
|
'urls': {
|
|
138
143
|
'logo': 'https://user-images.githubusercontent.com/1294454/150730761-1a00e5e0-d28c-480f-9e65-089ce3e6ef3b.jpg',
|
|
139
144
|
'api': {
|
|
140
|
-
'pub': 'https://api-pub.
|
|
145
|
+
'pub': 'https://api-pub.woox.io',
|
|
141
146
|
'public': 'https://api.{hostname}',
|
|
142
147
|
'private': 'https://api.{hostname}',
|
|
143
148
|
},
|
|
144
149
|
'test': {
|
|
145
|
-
'pub': 'https://api-pub.staging.
|
|
146
|
-
'public': 'https://api.staging.
|
|
147
|
-
'private': 'https://api.staging.
|
|
150
|
+
'pub': 'https://api-pub.staging.woox.io',
|
|
151
|
+
'public': 'https://api.staging.woox.io',
|
|
152
|
+
'private': 'https://api.staging.woox.io',
|
|
148
153
|
},
|
|
149
|
-
'www': 'https://
|
|
154
|
+
'www': 'https://woox.io/',
|
|
150
155
|
'doc': [
|
|
151
|
-
'https://docs.
|
|
156
|
+
'https://docs.woox.io/',
|
|
152
157
|
],
|
|
153
158
|
'fees': [
|
|
154
|
-
'https://support.
|
|
159
|
+
'https://support.woox.io/hc/en-001/articles/4404611795353--Trading-Fees',
|
|
155
160
|
],
|
|
156
161
|
'referral': {
|
|
157
|
-
'url': 'https://
|
|
162
|
+
'url': 'https://woox.io/register?ref=DIJT0CNL',
|
|
158
163
|
'discount': 0.35,
|
|
159
164
|
},
|
|
160
165
|
},
|
|
@@ -163,7 +168,7 @@ class woo(Exchange, ImplicitAPI):
|
|
|
163
168
|
'pub': {
|
|
164
169
|
'get': {
|
|
165
170
|
'hist/kline': 10,
|
|
166
|
-
'hist/trades':
|
|
171
|
+
'hist/trades': 10,
|
|
167
172
|
},
|
|
168
173
|
},
|
|
169
174
|
'public': {
|
|
@@ -210,24 +215,27 @@ class woo(Exchange, ImplicitAPI):
|
|
|
210
215
|
'positions': 3.33, # 30 requests per 10 seconds
|
|
211
216
|
'position/{symbol}': 3.33,
|
|
212
217
|
'client/transaction_history': 60,
|
|
218
|
+
'client/futures_leverage': 60,
|
|
213
219
|
},
|
|
214
220
|
'post': {
|
|
215
|
-
'order':
|
|
221
|
+
'order': 1, # 10 requests per 1 second per symbol
|
|
216
222
|
'order/cancel_all_after': 1,
|
|
217
223
|
'asset/main_sub_transfer': 30, # 20 requests per 60 seconds
|
|
218
224
|
'asset/ltv': 30,
|
|
219
|
-
'asset/withdraw': 30, # implemented in ccxt, disabled on the exchange side https://
|
|
225
|
+
'asset/withdraw': 30, # implemented in ccxt, disabled on the exchange side https://docx.woo.io/wootrade-documents/#token-withdraw
|
|
220
226
|
'asset/internal_withdraw': 30,
|
|
221
227
|
'interest/repay': 60,
|
|
222
228
|
'client/account_mode': 120,
|
|
223
229
|
'client/position_mode': 5,
|
|
224
230
|
'client/leverage': 120,
|
|
231
|
+
'client/futures_leverage': 30,
|
|
232
|
+
'client/isolated_margin': 30,
|
|
225
233
|
},
|
|
226
234
|
'delete': {
|
|
227
235
|
'order': 1,
|
|
228
236
|
'client/order': 1,
|
|
229
237
|
'orders': 1,
|
|
230
|
-
'asset/withdraw': 120, # implemented in ccxt, disabled on the exchange side https://
|
|
238
|
+
'asset/withdraw': 120, # implemented in ccxt, disabled on the exchange side https://docx.woo.io/wootrade-documents/#cancel-withdraw-request
|
|
231
239
|
},
|
|
232
240
|
},
|
|
233
241
|
},
|
|
@@ -241,19 +249,56 @@ class woo(Exchange, ImplicitAPI):
|
|
|
241
249
|
'v3': {
|
|
242
250
|
'public': {
|
|
243
251
|
'get': {
|
|
244
|
-
'
|
|
252
|
+
'systemInfo': 1, # 10/1s
|
|
253
|
+
'instruments': 1, # 10/1s
|
|
254
|
+
'token': 1, # 10/1s
|
|
255
|
+
'tokenNetwork': 1, # 10/1s
|
|
256
|
+
'tokenInfo': 1, # 10/1s
|
|
257
|
+
'marketTrades': 1, # 10/1s
|
|
258
|
+
'marketTradesHistory': 1, # 10/1s
|
|
259
|
+
'orderbook': 1, # 10/1s
|
|
260
|
+
'kline': 1, # 10/1s
|
|
261
|
+
'klineHistory': 1, # 10/1s
|
|
262
|
+
'futures': 1, # 10/1s
|
|
263
|
+
'fundingRate': 1, # 10/1s
|
|
264
|
+
'fundingRateHistory': 1, # 10/1s
|
|
265
|
+
'insuranceFund': 1, # 10/1s
|
|
245
266
|
},
|
|
246
267
|
},
|
|
247
268
|
'private': {
|
|
248
269
|
'get': {
|
|
270
|
+
'trade/order': 2, # 5/1s
|
|
271
|
+
'trade/orders': 1, # 10/1s
|
|
272
|
+
'trade/algoOrder': 1, # 10/1s
|
|
273
|
+
'trade/algoOrders': 1, # 10/1s
|
|
274
|
+
'trade/transaction': 1, # 10/1s
|
|
275
|
+
'trade/transactionHistory': 5, # 2/1s
|
|
276
|
+
'trade/tradingFee': 5, # 2/1s
|
|
277
|
+
'account/info': 60, # 10/60s
|
|
278
|
+
'account/tokenConfig': 1, # 10/1s
|
|
279
|
+
'account/symbolConfig': 1, # 10/1s
|
|
280
|
+
'account/subAccounts/all': 60, # 10/60s
|
|
281
|
+
'account/referral/summary': 60, # 10/60s
|
|
282
|
+
'account/referral/rewardHistory': 60, # 10/60s
|
|
283
|
+
'account/credentials': 60, # 10/60s
|
|
284
|
+
'asset/balances': 1, # 10/1s
|
|
285
|
+
'asset/token/history': 60, # 10/60s
|
|
286
|
+
'asset/transfer/history': 30, # 20/60s
|
|
287
|
+
'asset/wallet/history': 60, # 10/60s
|
|
288
|
+
'asset/wallet/deposit': 60, # 10/60s
|
|
289
|
+
'asset/staking/yieldHistory': 60, # 10/60s
|
|
290
|
+
'futures/positions': 3.33, # 30/10s
|
|
291
|
+
'futures/leverage': 60, # 10/60s
|
|
292
|
+
'futures/defaultMarginMode': 60, # 10/60s
|
|
293
|
+
'futures/fundingFee/history': 30, # 20/60s
|
|
294
|
+
'spotMargin/interestRate': 60, # 10/60s
|
|
295
|
+
'spotMargin/interestHistory': 60, # 10/60s
|
|
296
|
+
'spotMargin/maxMargin': 60, # 10/60s
|
|
249
297
|
'algo/order/{oid}': 1,
|
|
250
298
|
'algo/orders': 1,
|
|
251
299
|
'balances': 1,
|
|
252
|
-
'accountinfo': 60,
|
|
253
300
|
'positions': 3.33,
|
|
254
301
|
'buypower': 1,
|
|
255
|
-
'referrals': 60,
|
|
256
|
-
'referral_rewards': 60,
|
|
257
302
|
'convert/exchangeInfo': 1,
|
|
258
303
|
'convert/assetInfo': 1,
|
|
259
304
|
'convert/rfq': 60,
|
|
@@ -261,16 +306,34 @@ class woo(Exchange, ImplicitAPI):
|
|
|
261
306
|
'convert/trades': 1,
|
|
262
307
|
},
|
|
263
308
|
'post': {
|
|
309
|
+
'trade/order': 2, # 5/1s
|
|
310
|
+
'trade/algoOrder': 5, # 2/1s
|
|
311
|
+
'trade/cancelAllAfter': 1, # 10/1s
|
|
312
|
+
'account/tradingMode': 120, # 5/60s
|
|
313
|
+
'account/listenKey': 20, # 5/10s
|
|
314
|
+
'asset/transfer': 30, # 20/60s
|
|
315
|
+
'asset/wallet/withdraw': 60, # 10/60s
|
|
316
|
+
'spotMargin/leverage': 120, # 5/60s
|
|
317
|
+
'spotMargin/interestRepay': 60, # 10/60s
|
|
264
318
|
'algo/order': 5,
|
|
265
319
|
'convert/rft': 60,
|
|
266
320
|
},
|
|
267
321
|
'put': {
|
|
322
|
+
'trade/order': 2, # 5/1s
|
|
323
|
+
'trade/algoOrder': 2, # 5/1s
|
|
324
|
+
'futures/leverage': 60, # 10/60s
|
|
325
|
+
'futures/positionMode': 120, # 5/60s
|
|
268
326
|
'order/{oid}': 2,
|
|
269
327
|
'order/client/{client_order_id}': 2,
|
|
270
328
|
'algo/order/{oid}': 2,
|
|
271
329
|
'algo/order/client/{client_order_id}': 2,
|
|
272
330
|
},
|
|
273
331
|
'delete': {
|
|
332
|
+
'trade/order': 1, # 10/1s
|
|
333
|
+
'trade/orders': 1, # 10/1s
|
|
334
|
+
'trade/algoOrder': 1, # 10/1s
|
|
335
|
+
'trade/algoOrders': 1, # 10/1s
|
|
336
|
+
'trade/allOrders': 1, # 10/1s
|
|
274
337
|
'algo/order/{order_id}': 1,
|
|
275
338
|
'algo/orders/pending': 1,
|
|
276
339
|
'algo/orders/pending/{symbol}': 1,
|
|
@@ -288,6 +351,8 @@ class woo(Exchange, ImplicitAPI):
|
|
|
288
351
|
},
|
|
289
352
|
},
|
|
290
353
|
'options': {
|
|
354
|
+
'timeDifference': 0, # the difference between system clock and exchange clock
|
|
355
|
+
'adjustForTimeDifference': False, # controls the adjustment logic upon instantiation
|
|
291
356
|
'sandboxMode': False,
|
|
292
357
|
'createMarketBuyOrderRequiresPrice': True,
|
|
293
358
|
# these network aliases require manual mapping here
|
|
@@ -302,6 +367,11 @@ class woo(Exchange, ImplicitAPI):
|
|
|
302
367
|
'TRC20': 'TRON',
|
|
303
368
|
'ERC20': 'ETH',
|
|
304
369
|
'BEP20': 'BSC',
|
|
370
|
+
'ARB': 'Arbitrum',
|
|
371
|
+
},
|
|
372
|
+
'networksById': {
|
|
373
|
+
'TRX': 'TRC20',
|
|
374
|
+
'TRON': 'TRC20',
|
|
305
375
|
},
|
|
306
376
|
# override defaultNetworkCodePriorities for a specific currency
|
|
307
377
|
'defaultNetworkCodeForCurrencies': {
|
|
@@ -313,10 +383,103 @@ class woo(Exchange, ImplicitAPI):
|
|
|
313
383
|
},
|
|
314
384
|
'brokerId': 'bc830de7-50f3-460b-9ee0-f430f83f9dad',
|
|
315
385
|
},
|
|
386
|
+
'features': {
|
|
387
|
+
'default': {
|
|
388
|
+
'sandbox': True,
|
|
389
|
+
'createOrder': {
|
|
390
|
+
'marginMode': True,
|
|
391
|
+
'triggerPrice': True,
|
|
392
|
+
'triggerPriceType': {
|
|
393
|
+
'last': True,
|
|
394
|
+
'mark': True,
|
|
395
|
+
'index': False,
|
|
396
|
+
},
|
|
397
|
+
'triggerDirection': False,
|
|
398
|
+
'stopLossPrice': False, # todo by triggerPrice
|
|
399
|
+
'takeProfitPrice': False, # todo by triggerPrice
|
|
400
|
+
'attachedStopLossTakeProfit': None,
|
|
401
|
+
'timeInForce': {
|
|
402
|
+
'IOC': True,
|
|
403
|
+
'FOK': True,
|
|
404
|
+
'PO': True,
|
|
405
|
+
'GTD': True,
|
|
406
|
+
},
|
|
407
|
+
'hedged': False,
|
|
408
|
+
'trailing': True,
|
|
409
|
+
'leverage': False,
|
|
410
|
+
'marketBuyByCost': True,
|
|
411
|
+
'marketBuyRequiresPrice': False,
|
|
412
|
+
'selfTradePrevention': False,
|
|
413
|
+
'iceberg': True, # todo implement
|
|
414
|
+
},
|
|
415
|
+
'createOrders': None,
|
|
416
|
+
'fetchMyTrades': {
|
|
417
|
+
'marginMode': False,
|
|
418
|
+
'limit': 500,
|
|
419
|
+
'daysBack': 90,
|
|
420
|
+
'untilDays': 10000,
|
|
421
|
+
'symbolRequired': False,
|
|
422
|
+
},
|
|
423
|
+
'fetchOrder': {
|
|
424
|
+
'marginMode': False,
|
|
425
|
+
'trigger': True,
|
|
426
|
+
'trailing': False,
|
|
427
|
+
'symbolRequired': False,
|
|
428
|
+
},
|
|
429
|
+
'fetchOpenOrders': {
|
|
430
|
+
'marginMode': False,
|
|
431
|
+
'limit': 500,
|
|
432
|
+
'trigger': True,
|
|
433
|
+
'trailing': True,
|
|
434
|
+
'symbolRequired': False,
|
|
435
|
+
},
|
|
436
|
+
'fetchOrders': {
|
|
437
|
+
'marginMode': False,
|
|
438
|
+
'limit': 500,
|
|
439
|
+
'daysBack': None,
|
|
440
|
+
'untilDays': 100000,
|
|
441
|
+
'trigger': True,
|
|
442
|
+
'trailing': True,
|
|
443
|
+
'symbolRequired': False,
|
|
444
|
+
},
|
|
445
|
+
'fetchClosedOrders': {
|
|
446
|
+
'marginMode': False,
|
|
447
|
+
'limit': 500,
|
|
448
|
+
'daysBack': None,
|
|
449
|
+
'daysBackCanceled': None,
|
|
450
|
+
'untilDays': 100000,
|
|
451
|
+
'trigger': True,
|
|
452
|
+
'trailing': True,
|
|
453
|
+
'symbolRequired': False,
|
|
454
|
+
},
|
|
455
|
+
'fetchOHLCV': {
|
|
456
|
+
'limit': 1000,
|
|
457
|
+
},
|
|
458
|
+
},
|
|
459
|
+
'spot': {
|
|
460
|
+
'extends': 'default',
|
|
461
|
+
},
|
|
462
|
+
'forSwap': {
|
|
463
|
+
'extends': 'default',
|
|
464
|
+
'createOrder': {
|
|
465
|
+
'hedged': True,
|
|
466
|
+
},
|
|
467
|
+
},
|
|
468
|
+
'swap': {
|
|
469
|
+
'linear': {
|
|
470
|
+
'extends': 'forSwap',
|
|
471
|
+
},
|
|
472
|
+
'inverse': None,
|
|
473
|
+
},
|
|
474
|
+
'future': {
|
|
475
|
+
'linear': None,
|
|
476
|
+
'inverse': None,
|
|
477
|
+
},
|
|
478
|
+
},
|
|
316
479
|
'commonCurrencies': {},
|
|
317
480
|
'exceptions': {
|
|
318
481
|
'exact': {
|
|
319
|
-
'-1000':
|
|
482
|
+
'-1000': OperationFailed, # {"code": -1000, "message": "An unknown error occurred while processing the request"} or {"success":false,"code":"-1000","message":"An internal error has occurred. We are unable to process your request. Please try again later."}
|
|
320
483
|
'-1001': AuthenticationError, # {"code": -1001, "message": "The api key or secret is in wrong format"}
|
|
321
484
|
'-1002': AuthenticationError, # {"code": -1002, "message": "API key or secret is invalid, it may because key have insufficient permission or the key is expired/revoked."}
|
|
322
485
|
'-1003': RateLimitExceeded, # {"code": -1003, "message": "Rate limit exceed."}
|
|
@@ -348,19 +511,22 @@ class woo(Exchange, ImplicitAPI):
|
|
|
348
511
|
async def fetch_status(self, params={}):
|
|
349
512
|
"""
|
|
350
513
|
the latest known information on the availability of the exchange API
|
|
351
|
-
|
|
514
|
+
|
|
515
|
+
https://developer.woox.io/api-reference/endpoint/public_data/systemInfo
|
|
516
|
+
|
|
352
517
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
353
518
|
:returns dict: a `status structure <https://docs.ccxt.com/#/?id=exchange-status-structure>`
|
|
354
519
|
"""
|
|
355
|
-
response = await self.
|
|
520
|
+
response = await self.v3PublicGetSystemInfo(params)
|
|
356
521
|
#
|
|
357
522
|
# {
|
|
358
523
|
# "success": True,
|
|
359
524
|
# "data": {
|
|
360
|
-
# "status":
|
|
361
|
-
# "msg": "System is functioning properly."
|
|
525
|
+
# "status": 0,
|
|
526
|
+
# "msg": "System is functioning properly.",
|
|
527
|
+
# "estimatedEndTime": 1749963600362
|
|
362
528
|
# },
|
|
363
|
-
# "timestamp":
|
|
529
|
+
# "timestamp": 1751442989564
|
|
364
530
|
# }
|
|
365
531
|
#
|
|
366
532
|
data = self.safe_dict(response, 'data', {})
|
|
@@ -379,22 +545,25 @@ class woo(Exchange, ImplicitAPI):
|
|
|
379
545
|
'info': response,
|
|
380
546
|
}
|
|
381
547
|
|
|
382
|
-
async def fetch_time(self, params={}):
|
|
548
|
+
async def fetch_time(self, params={}) -> Int:
|
|
383
549
|
"""
|
|
384
550
|
fetches the current integer timestamp in milliseconds from the exchange server
|
|
385
|
-
|
|
551
|
+
|
|
552
|
+
https://developer.woox.io/api-reference/endpoint/public_data/systemInfo
|
|
553
|
+
|
|
386
554
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
387
555
|
:returns int: the current integer timestamp in milliseconds from the exchange server
|
|
388
556
|
"""
|
|
389
|
-
response = await self.
|
|
557
|
+
response = await self.v3PublicGetSystemInfo(params)
|
|
390
558
|
#
|
|
391
559
|
# {
|
|
392
560
|
# "success": True,
|
|
393
561
|
# "data": {
|
|
394
|
-
# "status":
|
|
395
|
-
# "msg": "System is functioning properly."
|
|
562
|
+
# "status": 0,
|
|
563
|
+
# "msg": "System is functioning properly.",
|
|
564
|
+
# "estimatedEndTime": 1749963600362
|
|
396
565
|
# },
|
|
397
|
-
# "timestamp":
|
|
566
|
+
# "timestamp": 1751442989564
|
|
398
567
|
# }
|
|
399
568
|
#
|
|
400
569
|
return self.safe_integer(response, 'timestamp')
|
|
@@ -402,34 +571,50 @@ class woo(Exchange, ImplicitAPI):
|
|
|
402
571
|
async def fetch_markets(self, params={}) -> List[Market]:
|
|
403
572
|
"""
|
|
404
573
|
retrieves data on all markets for woo
|
|
405
|
-
|
|
574
|
+
|
|
575
|
+
https://developer.woox.io/api-reference/endpoint/public_data/instruments
|
|
576
|
+
|
|
406
577
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
407
578
|
:returns dict[]: an array of objects representing market data
|
|
408
579
|
"""
|
|
409
|
-
|
|
580
|
+
if self.options['adjustForTimeDifference']:
|
|
581
|
+
await self.load_time_difference()
|
|
582
|
+
response = await self.v3PublicGetInstruments(params)
|
|
410
583
|
#
|
|
411
|
-
#
|
|
412
|
-
#
|
|
413
|
-
# {
|
|
414
|
-
# "
|
|
415
|
-
#
|
|
416
|
-
#
|
|
417
|
-
#
|
|
418
|
-
#
|
|
419
|
-
#
|
|
420
|
-
#
|
|
421
|
-
#
|
|
422
|
-
#
|
|
423
|
-
#
|
|
424
|
-
#
|
|
425
|
-
#
|
|
584
|
+
# {
|
|
585
|
+
# "success": True,
|
|
586
|
+
# "data": {
|
|
587
|
+
# "rows": [
|
|
588
|
+
# {
|
|
589
|
+
# "symbol": "SPOT_AAVE_USDT",
|
|
590
|
+
# "status": "TRADING",
|
|
591
|
+
# "baseAsset": "AAVE",
|
|
592
|
+
# "baseAssetMultiplier": 1,
|
|
593
|
+
# "quoteAsset": "USDT",
|
|
594
|
+
# "quoteMin": "0",
|
|
595
|
+
# "quoteMax": "100000",
|
|
596
|
+
# "quoteTick": "0.01",
|
|
597
|
+
# "baseMin": "0.005",
|
|
598
|
+
# "baseMax": "5000",
|
|
599
|
+
# "baseTick": "0.0001",
|
|
600
|
+
# "minNotional": "1",
|
|
601
|
+
# "bidCapRatio": "1.1",
|
|
602
|
+
# "bidFloorRatio": null,
|
|
603
|
+
# "askCapRatio": null,
|
|
604
|
+
# "askFloorRatio": "0.9",
|
|
605
|
+
# "orderMode": "NORMAL",
|
|
606
|
+
# "impactNotional": null,
|
|
607
|
+
# "isAllowedRpi": False,
|
|
608
|
+
# "tickGranularity": null
|
|
609
|
+
# }
|
|
610
|
+
# ]
|
|
426
611
|
# },
|
|
427
|
-
#
|
|
428
|
-
#
|
|
429
|
-
# }
|
|
612
|
+
# "timestamp": 1751512951338
|
|
613
|
+
# }
|
|
430
614
|
#
|
|
431
|
-
data = self.
|
|
432
|
-
|
|
615
|
+
data = self.safe_dict(response, 'data', {})
|
|
616
|
+
rows = self.safe_list(data, 'rows', [])
|
|
617
|
+
return self.parse_markets(rows)
|
|
433
618
|
|
|
434
619
|
def parse_market(self, market: dict) -> Market:
|
|
435
620
|
marketId = self.safe_string(market, 'symbol')
|
|
@@ -453,6 +638,7 @@ class woo(Exchange, ImplicitAPI):
|
|
|
453
638
|
symbol = base + '/' + quote
|
|
454
639
|
contractSize: Num = None
|
|
455
640
|
linear: Bool = None
|
|
641
|
+
inverse: Bool = None
|
|
456
642
|
margin = True
|
|
457
643
|
contract = swap
|
|
458
644
|
if contract:
|
|
@@ -462,6 +648,8 @@ class woo(Exchange, ImplicitAPI):
|
|
|
462
648
|
symbol = base + '/' + quote + ':' + settle
|
|
463
649
|
contractSize = self.parse_number('1')
|
|
464
650
|
linear = True
|
|
651
|
+
inverse = False
|
|
652
|
+
active = self.safe_string(market, 'status') == 'TRADING'
|
|
465
653
|
return {
|
|
466
654
|
'id': marketId,
|
|
467
655
|
'symbol': symbol,
|
|
@@ -477,18 +665,18 @@ class woo(Exchange, ImplicitAPI):
|
|
|
477
665
|
'swap': swap,
|
|
478
666
|
'future': False,
|
|
479
667
|
'option': False,
|
|
480
|
-
'active':
|
|
668
|
+
'active': active,
|
|
481
669
|
'contract': contract,
|
|
482
670
|
'linear': linear,
|
|
483
|
-
'inverse':
|
|
671
|
+
'inverse': inverse,
|
|
484
672
|
'contractSize': contractSize,
|
|
485
673
|
'expiry': None,
|
|
486
674
|
'expiryDatetime': None,
|
|
487
675
|
'strike': None,
|
|
488
676
|
'optionType': None,
|
|
489
677
|
'precision': {
|
|
490
|
-
'amount': self.safe_number(market, '
|
|
491
|
-
'price': self.safe_number(market, '
|
|
678
|
+
'amount': self.safe_number(market, 'baseTick'),
|
|
679
|
+
'price': self.safe_number(market, 'quoteTick'),
|
|
492
680
|
},
|
|
493
681
|
'limits': {
|
|
494
682
|
'leverage': {
|
|
@@ -496,26 +684,28 @@ class woo(Exchange, ImplicitAPI):
|
|
|
496
684
|
'max': None,
|
|
497
685
|
},
|
|
498
686
|
'amount': {
|
|
499
|
-
'min': self.safe_number(market, '
|
|
500
|
-
'max': self.safe_number(market, '
|
|
687
|
+
'min': self.safe_number(market, 'baseMin'),
|
|
688
|
+
'max': self.safe_number(market, 'baseMax'),
|
|
501
689
|
},
|
|
502
690
|
'price': {
|
|
503
|
-
'min': self.safe_number(market, '
|
|
504
|
-
'max': self.safe_number(market, '
|
|
691
|
+
'min': self.safe_number(market, 'quoteMin'),
|
|
692
|
+
'max': self.safe_number(market, 'quoteMax'),
|
|
505
693
|
},
|
|
506
694
|
'cost': {
|
|
507
|
-
'min': self.safe_number(market, '
|
|
695
|
+
'min': self.safe_number(market, 'minNotional'),
|
|
508
696
|
'max': None,
|
|
509
697
|
},
|
|
510
698
|
},
|
|
511
|
-
'created':
|
|
699
|
+
'created': None,
|
|
512
700
|
'info': market,
|
|
513
701
|
}
|
|
514
702
|
|
|
515
703
|
async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
|
516
704
|
"""
|
|
517
705
|
get the list of most recent trades for a particular symbol
|
|
518
|
-
|
|
706
|
+
|
|
707
|
+
https://developer.woox.io/api-reference/endpoint/public_data/marketTrades
|
|
708
|
+
|
|
519
709
|
:param str symbol: unified symbol of the market to fetch trades for
|
|
520
710
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
|
521
711
|
:param int [limit]: the maximum amount of trades to fetch
|
|
@@ -529,38 +719,28 @@ class woo(Exchange, ImplicitAPI):
|
|
|
529
719
|
}
|
|
530
720
|
if limit is not None:
|
|
531
721
|
request['limit'] = limit
|
|
532
|
-
response = await self.
|
|
722
|
+
response = await self.v3PublicGetMarketTrades(self.extend(request, params))
|
|
533
723
|
#
|
|
534
|
-
#
|
|
535
|
-
#
|
|
536
|
-
#
|
|
537
|
-
#
|
|
538
|
-
#
|
|
539
|
-
#
|
|
540
|
-
#
|
|
541
|
-
#
|
|
542
|
-
#
|
|
543
|
-
#
|
|
544
|
-
#
|
|
545
|
-
#
|
|
546
|
-
#
|
|
547
|
-
# "executed_price": 46222.35,
|
|
548
|
-
# "executed_quantity": 0.0012,
|
|
549
|
-
# "executed_timestamp": "1641241162.329"
|
|
550
|
-
# },
|
|
551
|
-
# {
|
|
552
|
-
# "symbol": "SPOT_BTC_USDT",
|
|
553
|
-
# "side": "BUY",
|
|
554
|
-
# "executed_price": 46224.32,
|
|
555
|
-
# "executed_quantity": 0.00039,
|
|
556
|
-
# "executed_timestamp": "1641241162.287"
|
|
724
|
+
# {
|
|
725
|
+
# "success": True,
|
|
726
|
+
# "data": {
|
|
727
|
+
# "rows": [
|
|
728
|
+
# {
|
|
729
|
+
# "symbol": "SPOT_BTC_USDT",
|
|
730
|
+
# "side": "SELL",
|
|
731
|
+
# "source": 0,
|
|
732
|
+
# "executedPrice": "108741.01",
|
|
733
|
+
# "executedQuantity": "0.02477",
|
|
734
|
+
# "executedTimestamp": 1751513940144
|
|
735
|
+
# }
|
|
736
|
+
# ]
|
|
557
737
|
# },
|
|
558
|
-
#
|
|
559
|
-
#
|
|
560
|
-
# }
|
|
738
|
+
# "timestamp": 1751513988543
|
|
739
|
+
# }
|
|
561
740
|
#
|
|
562
|
-
|
|
563
|
-
|
|
741
|
+
data = self.safe_dict(response, 'data', {})
|
|
742
|
+
rows = self.safe_list(data, 'rows', [])
|
|
743
|
+
return self.parse_trades(rows, market, since, limit)
|
|
564
744
|
|
|
565
745
|
def parse_trade(self, trade: dict, market: Market = None) -> Trade:
|
|
566
746
|
#
|
|
@@ -569,42 +749,53 @@ class woo(Exchange, ImplicitAPI):
|
|
|
569
749
|
# {
|
|
570
750
|
# "symbol": "SPOT_BTC_USDT",
|
|
571
751
|
# "side": "SELL",
|
|
572
|
-
# "
|
|
573
|
-
# "
|
|
574
|
-
# "
|
|
752
|
+
# "source": 0,
|
|
753
|
+
# "executedPrice": "108741.01",
|
|
754
|
+
# "executedQuantity": "0.02477",
|
|
755
|
+
# "executedTimestamp": 1751513940144
|
|
575
756
|
# }
|
|
576
757
|
#
|
|
577
758
|
# fetchOrderTrades, fetchOrder
|
|
578
759
|
#
|
|
579
760
|
# {
|
|
580
|
-
# "id":
|
|
581
|
-
# "symbol": "
|
|
582
|
-
# "
|
|
761
|
+
# "id": 1734947821,
|
|
762
|
+
# "symbol": "SPOT_LTC_USDT",
|
|
763
|
+
# "orderId": 60780383217,
|
|
764
|
+
# "executedPrice": 87.86,
|
|
765
|
+
# "executedQuantity": 0.1,
|
|
766
|
+
# "fee": 0.0001,
|
|
767
|
+
# "realizedPnl": null,
|
|
768
|
+
# "feeAsset": "LTC",
|
|
769
|
+
# "orderTag": "default",
|
|
583
770
|
# "side": "BUY",
|
|
584
|
-
# "
|
|
585
|
-
# "
|
|
586
|
-
# "order_tag": "default", <-- self param only in "fetchOrderTrades"
|
|
587
|
-
# "executed_price": "1",
|
|
588
|
-
# "executed_quantity": "12",
|
|
589
|
-
# "fee_asset": "WOO",
|
|
590
|
-
# "is_maker": "1"
|
|
771
|
+
# "executedTimestamp": "1752055173.630",
|
|
772
|
+
# "isMaker": 0
|
|
591
773
|
# }
|
|
592
774
|
#
|
|
593
775
|
isFromFetchOrder = ('id' in trade)
|
|
594
|
-
|
|
776
|
+
timestampString = self.safe_string_2(trade, 'executed_timestamp', 'executedTimestamp')
|
|
777
|
+
timestamp = None
|
|
778
|
+
if timestampString is not None:
|
|
779
|
+
if timestampString.find('.') > -1:
|
|
780
|
+
timestamp = self.safe_timestamp_2(trade, 'executed_timestamp', 'executedTimestamp')
|
|
781
|
+
else:
|
|
782
|
+
timestamp = self.safe_integer(trade, 'executedTimestamp')
|
|
595
783
|
marketId = self.safe_string(trade, 'symbol')
|
|
596
784
|
market = self.safe_market(marketId, market)
|
|
597
785
|
symbol = market['symbol']
|
|
598
|
-
price = self.
|
|
599
|
-
amount = self.
|
|
600
|
-
order_id = self.
|
|
601
|
-
fee = self.parse_token_and_fee_temp(trade, 'fee_asset', 'fee')
|
|
786
|
+
price = self.safe_string_2(trade, 'executed_price', 'executedPrice')
|
|
787
|
+
amount = self.safe_string_2(trade, 'executed_quantity', 'executedQuantity')
|
|
788
|
+
order_id = self.safe_string_2(trade, 'order_id', 'orderId')
|
|
789
|
+
fee = self.parse_token_and_fee_temp(trade, ['fee_asset', 'feeAsset'], ['fee'])
|
|
790
|
+
feeCost = self.safe_string(fee, 'cost')
|
|
791
|
+
if feeCost is not None:
|
|
792
|
+
fee['cost'] = feeCost
|
|
602
793
|
cost = Precise.string_mul(price, amount)
|
|
603
794
|
side = self.safe_string_lower(trade, 'side')
|
|
604
795
|
id = self.safe_string(trade, 'id')
|
|
605
796
|
takerOrMaker: Str = None
|
|
606
797
|
if isFromFetchOrder:
|
|
607
|
-
isMaker = self.
|
|
798
|
+
isMaker = self.safe_string_2(trade, 'is_maker', 'isMaker') == '1'
|
|
608
799
|
takerOrMaker = 'maker' if isMaker else 'taker'
|
|
609
800
|
return self.safe_trade({
|
|
610
801
|
'id': id,
|
|
@@ -622,11 +813,11 @@ class woo(Exchange, ImplicitAPI):
|
|
|
622
813
|
'info': trade,
|
|
623
814
|
}, market)
|
|
624
815
|
|
|
625
|
-
def parse_token_and_fee_temp(self, item,
|
|
626
|
-
feeCost = self.
|
|
816
|
+
def parse_token_and_fee_temp(self, item, feeTokenKeys, feeAmountKeys):
|
|
817
|
+
feeCost = self.safe_string_n(item, feeAmountKeys)
|
|
627
818
|
fee = None
|
|
628
819
|
if feeCost is not None:
|
|
629
|
-
feeCurrencyId = self.
|
|
820
|
+
feeCurrencyId = self.safe_string_n(item, feeTokenKeys)
|
|
630
821
|
feeCurrencyCode = self.safe_currency_code(feeCurrencyId)
|
|
631
822
|
fee = {
|
|
632
823
|
'cost': feeCost,
|
|
@@ -634,41 +825,90 @@ class woo(Exchange, ImplicitAPI):
|
|
|
634
825
|
}
|
|
635
826
|
return fee
|
|
636
827
|
|
|
828
|
+
def parse_trading_fee(self, fee: dict, market: Market = None) -> TradingFeeInterface:
|
|
829
|
+
marketId = self.safe_string(fee, 'symbol')
|
|
830
|
+
symbol = self.safe_symbol(marketId, market)
|
|
831
|
+
return {
|
|
832
|
+
'info': fee,
|
|
833
|
+
'symbol': symbol,
|
|
834
|
+
'maker': self.parse_number(Precise.string_div(self.safe_string(fee, 'makerFee'), '100')),
|
|
835
|
+
'taker': self.parse_number(Precise.string_div(self.safe_string(fee, 'takerFee'), '100')),
|
|
836
|
+
'percentage': None,
|
|
837
|
+
'tierBased': None,
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
async def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
|
|
841
|
+
"""
|
|
842
|
+
fetch the trading fees for a market
|
|
843
|
+
|
|
844
|
+
https://developer.woox.io/api-reference/endpoint/trading/get_tradingFee
|
|
845
|
+
|
|
846
|
+
:param str symbol: unified market symbol
|
|
847
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
848
|
+
:param boolean [params.portfolioMargin]: set to True if you would like to fetch trading fees in a portfolio margin account
|
|
849
|
+
:param str [params.subType]: "linear" or "inverse"
|
|
850
|
+
:returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
|
|
851
|
+
"""
|
|
852
|
+
await self.load_markets()
|
|
853
|
+
market = self.market(symbol)
|
|
854
|
+
request: dict = {
|
|
855
|
+
'symbol': market['id'],
|
|
856
|
+
}
|
|
857
|
+
response = await self.v3PrivateGetTradeTradingFee(self.extend(request, params))
|
|
858
|
+
#
|
|
859
|
+
# {
|
|
860
|
+
# "success": True,
|
|
861
|
+
# "data": {
|
|
862
|
+
# "symbol": "SPOT_BTC_USDT",
|
|
863
|
+
# "takerFee": "10",
|
|
864
|
+
# "makerFee": "8"
|
|
865
|
+
# },
|
|
866
|
+
# "timestamp": 1751858977368
|
|
867
|
+
# }
|
|
868
|
+
#
|
|
869
|
+
data = self.safe_dict(response, 'data', {})
|
|
870
|
+
return self.parse_trading_fee(data, market)
|
|
871
|
+
|
|
637
872
|
async def fetch_trading_fees(self, params={}) -> TradingFees:
|
|
638
873
|
"""
|
|
639
874
|
fetch the trading fees for multiple markets
|
|
640
|
-
|
|
875
|
+
|
|
876
|
+
https://developer.woox.io/api-reference/endpoint/account/get_account_info
|
|
877
|
+
|
|
641
878
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
642
879
|
:returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
|
|
643
880
|
"""
|
|
644
881
|
await self.load_markets()
|
|
645
|
-
response = await self.
|
|
882
|
+
response = await self.v3PrivateGetAccountInfo(params)
|
|
646
883
|
#
|
|
647
884
|
# {
|
|
648
885
|
# "success": True,
|
|
649
886
|
# "data": {
|
|
650
|
-
# "applicationId": "
|
|
651
|
-
# "account": "
|
|
652
|
-
# "alias": "
|
|
653
|
-
# "accountMode": "MARGIN",
|
|
654
|
-
# "leverage": 1,
|
|
655
|
-
# "takerFeeRate": 1,
|
|
656
|
-
# "makerFeeRate": 1,
|
|
657
|
-
# "interestRate": 1,
|
|
658
|
-
# "futuresTakerFeeRate": 1,
|
|
659
|
-
# "futuresMakerFeeRate": 1,
|
|
887
|
+
# "applicationId": "251bf5c4-f3c8-4544-bb8b-80001007c3c0",
|
|
888
|
+
# "account": "carlos_jose_lima@yahoo.com",
|
|
889
|
+
# "alias": "carlos_jose_lima@yahoo.com",
|
|
660
890
|
# "otpauth": True,
|
|
661
|
-
# "
|
|
662
|
-
# "
|
|
663
|
-
# "
|
|
664
|
-
# "
|
|
665
|
-
# "
|
|
666
|
-
# "
|
|
667
|
-
# "
|
|
668
|
-
# "
|
|
669
|
-
# "
|
|
891
|
+
# "accountMode": "FUTURES",
|
|
892
|
+
# "positionMode": "ONE_WAY",
|
|
893
|
+
# "leverage": 0,
|
|
894
|
+
# "makerFeeRate": 0,
|
|
895
|
+
# "takerFeeRate": 0,
|
|
896
|
+
# "marginRatio": "10",
|
|
897
|
+
# "openMarginRatio": "10",
|
|
898
|
+
# "initialMarginRatio": "10",
|
|
899
|
+
# "maintenanceMarginRatio": "0.03",
|
|
900
|
+
# "totalCollateral": "165.55629469",
|
|
901
|
+
# "freeCollateral": "165.55629469",
|
|
902
|
+
# "totalAccountValue": "167.32418611",
|
|
903
|
+
# "totalTradingValue": "167.32418611",
|
|
904
|
+
# "totalVaultValue": "0",
|
|
905
|
+
# "totalStakingValue": "0",
|
|
906
|
+
# "totalLaunchpadValue": "0",
|
|
907
|
+
# "totalEarnValue": "0",
|
|
908
|
+
# "referrerID": null,
|
|
909
|
+
# "accountType": "Main"
|
|
670
910
|
# },
|
|
671
|
-
# "timestamp":
|
|
911
|
+
# "timestamp": 1752062807915
|
|
672
912
|
# }
|
|
673
913
|
#
|
|
674
914
|
data = self.safe_dict(response, 'data', {})
|
|
@@ -690,38 +930,52 @@ class woo(Exchange, ImplicitAPI):
|
|
|
690
930
|
async def fetch_currencies(self, params={}) -> Currencies:
|
|
691
931
|
"""
|
|
692
932
|
fetches all available currencies on an exchange
|
|
693
|
-
|
|
933
|
+
|
|
934
|
+
https://docs.woox.io/#available-token-public
|
|
935
|
+
|
|
694
936
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
695
937
|
:returns dict: an associative dictionary of currencies
|
|
696
938
|
"""
|
|
697
939
|
result: dict = {}
|
|
698
|
-
|
|
940
|
+
tokenResponsePromise = self.v1PublicGetToken(params)
|
|
699
941
|
#
|
|
700
|
-
#
|
|
701
|
-
#
|
|
942
|
+
# {
|
|
943
|
+
# "rows": [
|
|
702
944
|
# {
|
|
703
945
|
# "token": "ETH_USDT",
|
|
704
946
|
# "fullname": "Tether",
|
|
705
|
-
# "
|
|
947
|
+
# "network": "ETH",
|
|
948
|
+
# "decimals": "6",
|
|
949
|
+
# "delisted": False,
|
|
706
950
|
# "balance_token": "USDT",
|
|
707
|
-
# "created_time": "
|
|
708
|
-
# "updated_time": "
|
|
951
|
+
# "created_time": "1710123398",
|
|
952
|
+
# "updated_time": "1746528481",
|
|
953
|
+
# "can_collateral": True,
|
|
954
|
+
# "can_short": True
|
|
709
955
|
# },
|
|
710
956
|
# {
|
|
711
957
|
# "token": "BSC_USDT",
|
|
712
958
|
# "fullname": "Tether",
|
|
713
|
-
# "
|
|
959
|
+
# "network": "BSC",
|
|
960
|
+
# "decimals": "18",
|
|
961
|
+
# "delisted": False,
|
|
714
962
|
# "balance_token": "USDT",
|
|
715
|
-
# "created_time": "
|
|
716
|
-
# "updated_time": "
|
|
963
|
+
# "created_time": "1710123395",
|
|
964
|
+
# "updated_time": "1746528601",
|
|
965
|
+
# "can_collateral": True,
|
|
966
|
+
# "can_short": True
|
|
717
967
|
# },
|
|
718
968
|
# {
|
|
719
|
-
# "token": "
|
|
720
|
-
# "fullname": "
|
|
721
|
-
# "
|
|
722
|
-
# "
|
|
723
|
-
# "
|
|
724
|
-
# "
|
|
969
|
+
# "token": "ALGO",
|
|
970
|
+
# "fullname": "Algorand",
|
|
971
|
+
# "network": "ALGO",
|
|
972
|
+
# "decimals": "6",
|
|
973
|
+
# "delisted": False,
|
|
974
|
+
# "balance_token": "ALGO",
|
|
975
|
+
# "created_time": "1710123394",
|
|
976
|
+
# "updated_time": "1723087518",
|
|
977
|
+
# "can_collateral": True,
|
|
978
|
+
# "can_short": True
|
|
725
979
|
# },
|
|
726
980
|
# ...
|
|
727
981
|
# ],
|
|
@@ -729,58 +983,66 @@ class woo(Exchange, ImplicitAPI):
|
|
|
729
983
|
# }
|
|
730
984
|
#
|
|
731
985
|
# only make one request for currrencies...
|
|
732
|
-
|
|
986
|
+
tokenNetworkResponsePromise = self.v1PublicGetTokenNetwork(params)
|
|
733
987
|
#
|
|
734
988
|
# {
|
|
735
989
|
# "rows": [
|
|
736
990
|
# {
|
|
737
991
|
# "protocol": "ERC20",
|
|
992
|
+
# "network": "ETH",
|
|
738
993
|
# "token": "USDT",
|
|
739
|
-
# "name": "Ethereum",
|
|
740
|
-
# "minimum_withdrawal":
|
|
741
|
-
# "withdrawal_fee":
|
|
742
|
-
# "allow_deposit": 1,
|
|
743
|
-
# "allow_withdraw": 1
|
|
994
|
+
# "name": "Ethereum(ERC20)",
|
|
995
|
+
# "minimum_withdrawal": "10.00000000",
|
|
996
|
+
# "withdrawal_fee": "2.00000000",
|
|
997
|
+
# "allow_deposit": "1",
|
|
998
|
+
# "allow_withdraw": "1"
|
|
744
999
|
# },
|
|
745
1000
|
# {
|
|
746
1001
|
# "protocol": "TRC20",
|
|
1002
|
+
# "network": "TRX",
|
|
747
1003
|
# "token": "USDT",
|
|
748
|
-
# "name": "Tron",
|
|
749
|
-
# "minimum_withdrawal":
|
|
750
|
-
# "withdrawal_fee":
|
|
751
|
-
# "allow_deposit": 1,
|
|
752
|
-
# "allow_withdraw": 1
|
|
1004
|
+
# "name": "Tron(TRC20)",
|
|
1005
|
+
# "minimum_withdrawal": "10.00000000",
|
|
1006
|
+
# "withdrawal_fee": "4.50000000",
|
|
1007
|
+
# "allow_deposit": "1",
|
|
1008
|
+
# "allow_withdraw": "1"
|
|
753
1009
|
# },
|
|
754
1010
|
# ...
|
|
755
1011
|
# ],
|
|
756
1012
|
# "success": True
|
|
757
1013
|
# }
|
|
758
1014
|
#
|
|
1015
|
+
tokenResponse, tokenNetworkResponse = await asyncio.gather(*[tokenResponsePromise, tokenNetworkResponsePromise])
|
|
759
1016
|
tokenRows = self.safe_list(tokenResponse, 'rows', [])
|
|
760
|
-
|
|
761
|
-
|
|
1017
|
+
tokenNetworkRows = self.safe_list(tokenNetworkResponse, 'rows', [])
|
|
1018
|
+
networksById = self.group_by(tokenNetworkRows, 'token')
|
|
1019
|
+
tokensById = self.group_by(tokenRows, 'balance_token')
|
|
1020
|
+
currencyIds = list(tokensById.keys())
|
|
762
1021
|
for i in range(0, len(currencyIds)):
|
|
763
1022
|
currencyId = currencyIds[i]
|
|
764
|
-
networks = networksByCurrencyId[currencyId]
|
|
765
1023
|
code = self.safe_currency_code(currencyId)
|
|
766
|
-
|
|
767
|
-
|
|
1024
|
+
tokensByNetworkId = self.index_by(tokensById[currencyId], 'network')
|
|
1025
|
+
chainsByNetworkId = self.index_by(networksById[currencyId], 'network')
|
|
1026
|
+
keys = list(chainsByNetworkId.keys())
|
|
768
1027
|
resultingNetworks: dict = {}
|
|
769
|
-
for j in range(0, len(
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
if precision is not None:
|
|
777
|
-
minPrecision = precision if (minPrecision is None) else Precise.string_min(precision, minPrecision)
|
|
778
|
-
resultingNetworks[unifiedNetwork] = {
|
|
1028
|
+
for j in range(0, len(keys)):
|
|
1029
|
+
networkId = keys[j]
|
|
1030
|
+
tokenEntry = self.safe_dict(tokensByNetworkId, networkId, {})
|
|
1031
|
+
networkEntry = self.safe_dict(chainsByNetworkId, networkId, {})
|
|
1032
|
+
networkCode = self.network_id_to_code(networkId, code)
|
|
1033
|
+
specialNetworkId = self.safe_string(tokenEntry, 'token')
|
|
1034
|
+
resultingNetworks[networkCode] = {
|
|
779
1035
|
'id': networkId,
|
|
780
|
-
'
|
|
1036
|
+
'currencyNetworkId': specialNetworkId, # exchange uses special crrency-ids(coin + network junction)
|
|
1037
|
+
'network': networkCode,
|
|
1038
|
+
'active': None,
|
|
1039
|
+
'deposit': self.safe_string(networkEntry, 'allow_deposit') == '1',
|
|
1040
|
+
'withdraw': self.safe_string(networkEntry, 'allow_withdraw') == '1',
|
|
1041
|
+
'fee': self.safe_number(networkEntry, 'withdrawal_fee'),
|
|
1042
|
+
'precision': self.parse_number(self.parse_precision(self.safe_string(tokenEntry, 'decimals'))),
|
|
781
1043
|
'limits': {
|
|
782
1044
|
'withdraw': {
|
|
783
|
-
'min':
|
|
1045
|
+
'min': self.safe_number(networkEntry, 'minimum_withdrawal'),
|
|
784
1046
|
'max': None,
|
|
785
1047
|
},
|
|
786
1048
|
'deposit': {
|
|
@@ -788,23 +1050,19 @@ class woo(Exchange, ImplicitAPI):
|
|
|
788
1050
|
'max': None,
|
|
789
1051
|
},
|
|
790
1052
|
},
|
|
791
|
-
'
|
|
792
|
-
'deposit': None,
|
|
793
|
-
'withdraw': None,
|
|
794
|
-
'fee': None,
|
|
795
|
-
'precision': self.parse_number(precision),
|
|
796
|
-
'info': network,
|
|
1053
|
+
'info': [networkEntry, tokenEntry],
|
|
797
1054
|
}
|
|
798
|
-
result[code] = {
|
|
1055
|
+
result[code] = self.safe_currency_structure({
|
|
799
1056
|
'id': currencyId,
|
|
800
|
-
'name':
|
|
1057
|
+
'name': None,
|
|
801
1058
|
'code': code,
|
|
802
|
-
'precision':
|
|
1059
|
+
'precision': None,
|
|
803
1060
|
'active': None,
|
|
804
1061
|
'fee': None,
|
|
805
1062
|
'networks': resultingNetworks,
|
|
806
1063
|
'deposit': None,
|
|
807
1064
|
'withdraw': None,
|
|
1065
|
+
'type': 'crypto',
|
|
808
1066
|
'limits': {
|
|
809
1067
|
'deposit': {
|
|
810
1068
|
'min': None,
|
|
@@ -815,14 +1073,16 @@ class woo(Exchange, ImplicitAPI):
|
|
|
815
1073
|
'max': None,
|
|
816
1074
|
},
|
|
817
1075
|
},
|
|
818
|
-
'info':
|
|
819
|
-
}
|
|
1076
|
+
'info': [tokensByNetworkId, chainsByNetworkId],
|
|
1077
|
+
})
|
|
820
1078
|
return result
|
|
821
1079
|
|
|
822
1080
|
async def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
|
|
823
1081
|
"""
|
|
824
1082
|
create a market buy order by providing the symbol and cost
|
|
825
|
-
|
|
1083
|
+
|
|
1084
|
+
https://docs.woox.io/#send-order
|
|
1085
|
+
|
|
826
1086
|
:param str symbol: unified symbol of the market to create an order in
|
|
827
1087
|
:param float cost: how much you want to trade in units of the quote currency
|
|
828
1088
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -832,13 +1092,31 @@ class woo(Exchange, ImplicitAPI):
|
|
|
832
1092
|
market = self.market(symbol)
|
|
833
1093
|
if not market['spot']:
|
|
834
1094
|
raise NotSupported(self.id + ' createMarketBuyOrderWithCost() supports spot orders only')
|
|
835
|
-
|
|
836
|
-
|
|
1095
|
+
return await self.create_order(symbol, 'market', 'buy', cost, 1, params)
|
|
1096
|
+
|
|
1097
|
+
async def create_market_sell_order_with_cost(self, symbol: str, cost: float, params={}):
|
|
1098
|
+
"""
|
|
1099
|
+
create a market sell order by providing the symbol and cost
|
|
1100
|
+
|
|
1101
|
+
https://docs.woox.io/#send-order
|
|
1102
|
+
|
|
1103
|
+
:param str symbol: unified symbol of the market to create an order in
|
|
1104
|
+
:param float cost: how much you want to trade in units of the quote currency
|
|
1105
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1106
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
1107
|
+
"""
|
|
1108
|
+
await self.load_markets()
|
|
1109
|
+
market = self.market(symbol)
|
|
1110
|
+
if not market['spot']:
|
|
1111
|
+
raise NotSupported(self.id + ' createMarketSellOrderWithCost() supports spot orders only')
|
|
1112
|
+
return await self.create_order(symbol, 'market', 'sell', cost, 1, params)
|
|
837
1113
|
|
|
838
|
-
async def create_trailing_amount_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, trailingAmount=None, trailingTriggerPrice=None, params={}) -> Order:
|
|
1114
|
+
async def create_trailing_amount_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, trailingAmount: Num = None, trailingTriggerPrice: Num = None, params={}) -> Order:
|
|
839
1115
|
"""
|
|
840
1116
|
create a trailing order by providing the symbol, type, side, amount, price and trailingAmount
|
|
841
|
-
|
|
1117
|
+
|
|
1118
|
+
https://docs.woox.io/#send-algo-order
|
|
1119
|
+
|
|
842
1120
|
:param str symbol: unified symbol of the market to create an order in
|
|
843
1121
|
:param str type: 'market' or 'limit'
|
|
844
1122
|
:param str side: 'buy' or 'sell'
|
|
@@ -857,10 +1135,12 @@ class woo(Exchange, ImplicitAPI):
|
|
|
857
1135
|
params['trailingTriggerPrice'] = trailingTriggerPrice
|
|
858
1136
|
return await self.create_order(symbol, type, side, amount, price, params)
|
|
859
1137
|
|
|
860
|
-
async def create_trailing_percent_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, trailingPercent=None, trailingTriggerPrice=None, params={}) -> Order:
|
|
1138
|
+
async def create_trailing_percent_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, trailingPercent: Num = None, trailingTriggerPrice: Num = None, params={}) -> Order:
|
|
861
1139
|
"""
|
|
862
1140
|
create a trailing order by providing the symbol, type, side, amount, price and trailingPercent
|
|
863
|
-
|
|
1141
|
+
|
|
1142
|
+
https://docs.woox.io/#send-algo-order
|
|
1143
|
+
|
|
864
1144
|
:param str symbol: unified symbol of the market to create an order in
|
|
865
1145
|
:param str type: 'market' or 'limit'
|
|
866
1146
|
:param str side: 'buy' or 'sell'
|
|
@@ -882,24 +1162,28 @@ class woo(Exchange, ImplicitAPI):
|
|
|
882
1162
|
async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
|
883
1163
|
"""
|
|
884
1164
|
create a trade order
|
|
885
|
-
|
|
886
|
-
|
|
1165
|
+
|
|
1166
|
+
https://developer.woox.io/api-reference/endpoint/trading/post_order
|
|
1167
|
+
https://developer.woox.io/api-reference/endpoint/trading/post_algo_order
|
|
1168
|
+
|
|
887
1169
|
:param str symbol: unified symbol of the market to create an order in
|
|
888
1170
|
:param str type: 'market' or 'limit'
|
|
889
1171
|
:param str side: 'buy' or 'sell'
|
|
890
1172
|
:param float amount: how much of currency you want to trade in units of base currency
|
|
891
|
-
:param float [price]: the price at which the order is to be
|
|
1173
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
892
1174
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1175
|
+
:param str [params.marginMode]: *for swap markets only* 'cross' or 'isolated', default 'cross'
|
|
893
1176
|
:param float [params.triggerPrice]: The price a trigger order is triggered at
|
|
894
1177
|
:param dict [params.takeProfit]: *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered(perpetual swap markets only)
|
|
895
1178
|
:param float [params.takeProfit.triggerPrice]: take profit trigger price
|
|
896
1179
|
:param dict [params.stopLoss]: *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered(perpetual swap markets only)
|
|
897
1180
|
:param float [params.stopLoss.triggerPrice]: stop loss trigger price
|
|
898
|
-
:param float [params.algoType]: 'STOP'or 'TRAILING_STOP' or 'OCO' or 'CLOSE_POSITION'
|
|
1181
|
+
:param float [params.algoType]: 'STOP' or 'TRAILING_STOP' or 'OCO' or 'CLOSE_POSITION'
|
|
899
1182
|
:param float [params.cost]: *spot market buy only* the quote quantity that can be used alternative for the amount
|
|
900
1183
|
:param str [params.trailingAmount]: the quote amount to trail away from the current market price
|
|
901
1184
|
:param str [params.trailingPercent]: the percent to trail away from the current market price
|
|
902
1185
|
:param str [params.trailingTriggerPrice]: the price to trigger a trailing order, default uses the price argument
|
|
1186
|
+
:param str [params.position_side]: 'SHORT' or 'LONG' - if position mode is HEDGE_MODE and the trading involves futures, then is required, otherwise self parameter is not required
|
|
903
1187
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
904
1188
|
"""
|
|
905
1189
|
reduceOnly = self.safe_bool_2(params, 'reduceOnly', 'reduce_only')
|
|
@@ -912,7 +1196,11 @@ class woo(Exchange, ImplicitAPI):
|
|
|
912
1196
|
'symbol': market['id'],
|
|
913
1197
|
'side': orderSide,
|
|
914
1198
|
}
|
|
915
|
-
|
|
1199
|
+
marginMode: Str = None
|
|
1200
|
+
marginMode, params = self.handle_margin_mode_and_params('createOrder', params)
|
|
1201
|
+
if marginMode is not None:
|
|
1202
|
+
request['marginMode'] = self.encode_margin_mode(marginMode)
|
|
1203
|
+
triggerPrice = self.safe_string_2(params, 'triggerPrice', 'stopPrice')
|
|
916
1204
|
stopLoss = self.safe_value(params, 'stopLoss')
|
|
917
1205
|
takeProfit = self.safe_value(params, 'takeProfit')
|
|
918
1206
|
algoType = self.safe_string(params, 'algoType')
|
|
@@ -922,52 +1210,42 @@ class woo(Exchange, ImplicitAPI):
|
|
|
922
1210
|
isTrailingAmountOrder = trailingAmount is not None
|
|
923
1211
|
isTrailingPercentOrder = trailingPercent is not None
|
|
924
1212
|
isTrailing = isTrailingAmountOrder or isTrailingPercentOrder
|
|
925
|
-
|
|
1213
|
+
isConditional = isTrailing or triggerPrice is not None or stopLoss is not None or takeProfit is not None or (self.safe_value(params, 'childOrders') is not None)
|
|
926
1214
|
isMarket = orderType == 'MARKET'
|
|
927
1215
|
timeInForce = self.safe_string_lower(params, 'timeInForce')
|
|
928
1216
|
postOnly = self.is_post_only(isMarket, None, params)
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
priceKey = 'price' if isStop else 'order_price'
|
|
933
|
-
typeKey = 'type' if isStop else 'order_type'
|
|
934
|
-
request[typeKey] = orderType # LIMIT/MARKET/IOC/FOK/POST_ONLY/ASK/BID
|
|
935
|
-
if not isStop:
|
|
1217
|
+
clientOrderIdKey = 'clientAlgoOrderId' if isConditional else 'clientOrderId'
|
|
1218
|
+
request['type'] = orderType # LIMIT/MARKET/IOC/FOK/POST_ONLY/ASK/BID
|
|
1219
|
+
if not isConditional:
|
|
936
1220
|
if postOnly:
|
|
937
|
-
request['
|
|
1221
|
+
request['type'] = 'POST_ONLY'
|
|
938
1222
|
elif timeInForce == 'fok':
|
|
939
|
-
request['
|
|
1223
|
+
request['type'] = 'FOK'
|
|
940
1224
|
elif timeInForce == 'ioc':
|
|
941
|
-
request['
|
|
1225
|
+
request['type'] = 'IOC'
|
|
942
1226
|
if reduceOnly:
|
|
943
|
-
request[
|
|
944
|
-
if price is not None:
|
|
945
|
-
request[
|
|
946
|
-
if isMarket and not
|
|
1227
|
+
request['reduceOnly'] = reduceOnly
|
|
1228
|
+
if not isMarket and price is not None:
|
|
1229
|
+
request['price'] = self.price_to_precision(symbol, price)
|
|
1230
|
+
if isMarket and not isConditional:
|
|
947
1231
|
# for market buy it requires the amount of quote currency to spend
|
|
948
|
-
|
|
1232
|
+
cost = self.safe_string_n(params, ['cost', 'order_amount', 'orderAmount'])
|
|
1233
|
+
params = self.omit(params, ['cost', 'order_amount', 'orderAmount'])
|
|
1234
|
+
isPriceProvided = price is not None
|
|
1235
|
+
if market['spot'] and (isPriceProvided or (cost is not None)):
|
|
949
1236
|
quoteAmount = None
|
|
950
|
-
createMarketBuyOrderRequiresPrice = True
|
|
951
|
-
createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', True)
|
|
952
|
-
cost = self.safe_number_2(params, 'cost', 'order_amount')
|
|
953
|
-
params = self.omit(params, ['cost', 'order_amount'])
|
|
954
1237
|
if cost is not None:
|
|
955
1238
|
quoteAmount = self.cost_to_precision(symbol, cost)
|
|
956
|
-
elif createMarketBuyOrderRequiresPrice:
|
|
957
|
-
if price is None:
|
|
958
|
-
raise InvalidOrder(self.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend(amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to False and pass the cost to spend(quote quantity) in the amount argument')
|
|
959
|
-
else:
|
|
960
|
-
amountString = self.number_to_string(amount)
|
|
961
|
-
priceString = self.number_to_string(price)
|
|
962
|
-
costRequest = Precise.string_mul(amountString, priceString)
|
|
963
|
-
quoteAmount = self.cost_to_precision(symbol, costRequest)
|
|
964
1239
|
else:
|
|
965
|
-
|
|
966
|
-
|
|
1240
|
+
amountString = self.number_to_string(amount)
|
|
1241
|
+
priceString = self.number_to_string(price)
|
|
1242
|
+
costRequest = Precise.string_mul(amountString, priceString)
|
|
1243
|
+
quoteAmount = self.cost_to_precision(symbol, costRequest)
|
|
1244
|
+
request['amount'] = quoteAmount
|
|
967
1245
|
else:
|
|
968
|
-
request['
|
|
1246
|
+
request['quantity'] = self.amount_to_precision(symbol, amount)
|
|
969
1247
|
elif algoType != 'POSITIONAL_TP_SL':
|
|
970
|
-
request[
|
|
1248
|
+
request['quantity'] = self.amount_to_precision(symbol, amount)
|
|
971
1249
|
clientOrderId = self.safe_string_n(params, ['clOrdID', 'clientOrderId', 'client_order_id'])
|
|
972
1250
|
if clientOrderId is not None:
|
|
973
1251
|
request[clientOrderIdKey] = clientOrderId
|
|
@@ -981,9 +1259,9 @@ class woo(Exchange, ImplicitAPI):
|
|
|
981
1259
|
elif isTrailingPercentOrder:
|
|
982
1260
|
convertedTrailingPercent = Precise.string_div(trailingPercent, '100')
|
|
983
1261
|
request['callbackRate'] = convertedTrailingPercent
|
|
984
|
-
elif
|
|
1262
|
+
elif triggerPrice is not None:
|
|
985
1263
|
if algoType != 'TRAILING_STOP':
|
|
986
|
-
request['triggerPrice'] = self.price_to_precision(symbol,
|
|
1264
|
+
request['triggerPrice'] = self.price_to_precision(symbol, triggerPrice)
|
|
987
1265
|
request['algoType'] = 'STOP'
|
|
988
1266
|
elif (stopLoss is not None) or (takeProfit is not None):
|
|
989
1267
|
request['algoType'] = 'BRACKET'
|
|
@@ -993,9 +1271,10 @@ class woo(Exchange, ImplicitAPI):
|
|
|
993
1271
|
'algoType': 'POSITIONAL_TP_SL',
|
|
994
1272
|
'childOrders': [],
|
|
995
1273
|
}
|
|
1274
|
+
childOrders = outterOrder['childOrders']
|
|
996
1275
|
closeSide = 'SELL' if (orderSide == 'BUY') else 'BUY'
|
|
997
1276
|
if stopLoss is not None:
|
|
998
|
-
stopLossPrice = self.
|
|
1277
|
+
stopLossPrice = self.safe_string(stopLoss, 'triggerPrice', stopLoss)
|
|
999
1278
|
stopLossOrder: dict = {
|
|
1000
1279
|
'side': closeSide,
|
|
1001
1280
|
'algoType': 'STOP_LOSS',
|
|
@@ -1003,9 +1282,9 @@ class woo(Exchange, ImplicitAPI):
|
|
|
1003
1282
|
'type': 'CLOSE_POSITION',
|
|
1004
1283
|
'reduceOnly': True,
|
|
1005
1284
|
}
|
|
1006
|
-
|
|
1285
|
+
childOrders.append(stopLossOrder)
|
|
1007
1286
|
if takeProfit is not None:
|
|
1008
|
-
takeProfitPrice = self.
|
|
1287
|
+
takeProfitPrice = self.safe_string(takeProfit, 'triggerPrice', takeProfit)
|
|
1009
1288
|
takeProfitOrder: dict = {
|
|
1010
1289
|
'side': closeSide,
|
|
1011
1290
|
'algoType': 'TAKE_PROFIT',
|
|
@@ -1013,60 +1292,72 @@ class woo(Exchange, ImplicitAPI):
|
|
|
1013
1292
|
'type': 'CLOSE_POSITION',
|
|
1014
1293
|
'reduceOnly': True,
|
|
1015
1294
|
}
|
|
1016
|
-
|
|
1295
|
+
childOrders.append(takeProfitOrder)
|
|
1017
1296
|
request['childOrders'] = [outterOrder]
|
|
1018
1297
|
params = self.omit(params, ['clOrdID', 'clientOrderId', 'client_order_id', 'postOnly', 'timeInForce', 'stopPrice', 'triggerPrice', 'stopLoss', 'takeProfit', 'trailingPercent', 'trailingAmount', 'trailingTriggerPrice'])
|
|
1019
1298
|
response = None
|
|
1020
|
-
if
|
|
1021
|
-
response = await self.
|
|
1299
|
+
if isConditional:
|
|
1300
|
+
response = await self.v3PrivatePostTradeAlgoOrder(self.extend(request, params))
|
|
1301
|
+
#
|
|
1302
|
+
# {
|
|
1303
|
+
# "success": True,
|
|
1304
|
+
# "data": {
|
|
1305
|
+
# "rows": [
|
|
1306
|
+
# {
|
|
1307
|
+
# "orderId": "1578938",
|
|
1308
|
+
# "clientOrderId": "0",
|
|
1309
|
+
# "algoType": "STOP_LOSS",
|
|
1310
|
+
# "quantity": "0.1"
|
|
1311
|
+
# }
|
|
1312
|
+
# ]
|
|
1313
|
+
# },
|
|
1314
|
+
# "timestamp": "1686149372216"
|
|
1315
|
+
# }
|
|
1316
|
+
#
|
|
1022
1317
|
else:
|
|
1023
|
-
response = await self.
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
if data is not None:
|
|
1051
|
-
rows = self.safe_list(data, 'rows', [])
|
|
1052
|
-
return self.parse_order(rows[0], market)
|
|
1053
|
-
order = self.parse_order(response, market)
|
|
1054
|
-
order['type'] = type
|
|
1055
|
-
return order
|
|
1318
|
+
response = await self.v3PrivatePostTradeOrder(self.extend(request, params))
|
|
1319
|
+
#
|
|
1320
|
+
# {
|
|
1321
|
+
# "success": True,
|
|
1322
|
+
# "data": {
|
|
1323
|
+
# "orderId": 60667653330,
|
|
1324
|
+
# "clientOrderId": 0,
|
|
1325
|
+
# "type": "LIMIT",
|
|
1326
|
+
# "price": 60,
|
|
1327
|
+
# "quantity": 0.1,
|
|
1328
|
+
# "amount": null,
|
|
1329
|
+
# "bidAskLevel": null
|
|
1330
|
+
# },
|
|
1331
|
+
# "timestamp": 1751871779855
|
|
1332
|
+
# }
|
|
1333
|
+
#
|
|
1334
|
+
data = self.safe_dict(response, 'data', {})
|
|
1335
|
+
data = self.safe_dict(self.safe_list(data, 'rows'), 0, data)
|
|
1336
|
+
data['timestamp'] = self.safe_string(response, 'timestamp')
|
|
1337
|
+
return self.parse_order(data, market)
|
|
1338
|
+
|
|
1339
|
+
def encode_margin_mode(self, mode):
|
|
1340
|
+
modes = {
|
|
1341
|
+
'cross': 'CROSS',
|
|
1342
|
+
'isolated': 'ISOLATED',
|
|
1343
|
+
}
|
|
1344
|
+
return self.safe_string(modes, mode, mode)
|
|
1056
1345
|
|
|
1057
1346
|
async def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
|
|
1058
1347
|
"""
|
|
1059
1348
|
edit a trade order
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1349
|
+
|
|
1350
|
+
https://docs.woox.io/#edit-order
|
|
1351
|
+
https://docs.woox.io/#edit-order-by-client_order_id
|
|
1352
|
+
https://docs.woox.io/#edit-algo-order
|
|
1353
|
+
https://docs.woox.io/#edit-algo-order-by-client_order_id
|
|
1354
|
+
|
|
1064
1355
|
:param str id: order id
|
|
1065
1356
|
:param str symbol: unified symbol of the market to create an order in
|
|
1066
1357
|
:param str type: 'market' or 'limit'
|
|
1067
1358
|
:param str side: 'buy' or 'sell'
|
|
1068
1359
|
:param float amount: how much of currency you want to trade in units of base currency
|
|
1069
|
-
:param float [price]: the price at which the order is to be
|
|
1360
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
1070
1361
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1071
1362
|
:param float [params.triggerPrice]: The price a trigger order is triggered at
|
|
1072
1363
|
:param float [params.stopLossPrice]: price to trigger stop-loss orders
|
|
@@ -1089,9 +1380,9 @@ class woo(Exchange, ImplicitAPI):
|
|
|
1089
1380
|
clientOrderIdUnified = self.safe_string_2(params, 'clOrdID', 'clientOrderId')
|
|
1090
1381
|
clientOrderIdExchangeSpecific = self.safe_string(params, 'client_order_id', clientOrderIdUnified)
|
|
1091
1382
|
isByClientOrder = clientOrderIdExchangeSpecific is not None
|
|
1092
|
-
|
|
1093
|
-
if
|
|
1094
|
-
request['triggerPrice'] = self.price_to_precision(symbol,
|
|
1383
|
+
triggerPrice = self.safe_number_n(params, ['triggerPrice', 'stopPrice', 'takeProfitPrice', 'stopLossPrice'])
|
|
1384
|
+
if triggerPrice is not None:
|
|
1385
|
+
request['triggerPrice'] = self.price_to_precision(symbol, triggerPrice)
|
|
1095
1386
|
trailingTriggerPrice = self.safe_string_2(params, 'trailingTriggerPrice', 'activatedPrice', self.number_to_string(price))
|
|
1096
1387
|
trailingAmount = self.safe_string_2(params, 'trailingAmount', 'callbackValue')
|
|
1097
1388
|
trailingPercent = self.safe_string_2(params, 'trailingPercent', 'callbackRate')
|
|
@@ -1107,17 +1398,17 @@ class woo(Exchange, ImplicitAPI):
|
|
|
1107
1398
|
convertedTrailingPercent = Precise.string_div(trailingPercent, '100')
|
|
1108
1399
|
request['callbackRate'] = convertedTrailingPercent
|
|
1109
1400
|
params = self.omit(params, ['clOrdID', 'clientOrderId', 'client_order_id', 'stopPrice', 'triggerPrice', 'takeProfitPrice', 'stopLossPrice', 'trailingTriggerPrice', 'trailingAmount', 'trailingPercent'])
|
|
1110
|
-
|
|
1401
|
+
isConditional = isTrailing or (triggerPrice is not None) or (self.safe_value(params, 'childOrders') is not None)
|
|
1111
1402
|
response = None
|
|
1112
1403
|
if isByClientOrder:
|
|
1113
1404
|
request['client_order_id'] = clientOrderIdExchangeSpecific
|
|
1114
|
-
if
|
|
1405
|
+
if isConditional:
|
|
1115
1406
|
response = await self.v3PrivatePutAlgoOrderClientClientOrderId(self.extend(request, params))
|
|
1116
1407
|
else:
|
|
1117
1408
|
response = await self.v3PrivatePutOrderClientClientOrderId(self.extend(request, params))
|
|
1118
1409
|
else:
|
|
1119
1410
|
request['oid'] = id
|
|
1120
|
-
if
|
|
1411
|
+
if isConditional:
|
|
1121
1412
|
response = await self.v3PrivatePutAlgoOrderOid(self.extend(request, params))
|
|
1122
1413
|
else:
|
|
1123
1414
|
response = await self.v3PrivatePutOrderOid(self.extend(request, params))
|
|
@@ -1138,19 +1429,20 @@ class woo(Exchange, ImplicitAPI):
|
|
|
1138
1429
|
|
|
1139
1430
|
async def cancel_order(self, id: str, symbol: Str = None, params={}):
|
|
1140
1431
|
"""
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1432
|
+
|
|
1433
|
+
https://developer.woox.io/api-reference/endpoint/trading/cancel_order
|
|
1434
|
+
https://developer.woox.io/api-reference/endpoint/trading/cancel_algo_order
|
|
1435
|
+
|
|
1144
1436
|
cancels an open order
|
|
1145
1437
|
:param str id: order id
|
|
1146
1438
|
:param str symbol: unified symbol of the market the order was made in
|
|
1147
1439
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1148
|
-
:param boolean [params.
|
|
1440
|
+
:param boolean [params.trigger]: whether the order is a trigger/algo order
|
|
1149
1441
|
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
1150
1442
|
"""
|
|
1151
|
-
|
|
1152
|
-
params = self.omit(params, 'stop')
|
|
1153
|
-
if not
|
|
1443
|
+
isTrigger = self.safe_bool_2(params, 'trigger', 'stop', False)
|
|
1444
|
+
params = self.omit(params, ['trigger', 'stop'])
|
|
1445
|
+
if not isTrigger and (symbol is None):
|
|
1154
1446
|
raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol argument')
|
|
1155
1447
|
await self.load_markets()
|
|
1156
1448
|
market: Market = None
|
|
@@ -1159,167 +1451,219 @@ class woo(Exchange, ImplicitAPI):
|
|
|
1159
1451
|
request: dict = {}
|
|
1160
1452
|
clientOrderIdUnified = self.safe_string_2(params, 'clOrdID', 'clientOrderId')
|
|
1161
1453
|
clientOrderIdExchangeSpecific = self.safe_string(params, 'client_order_id', clientOrderIdUnified)
|
|
1454
|
+
params = self.omit(params, ['clOrdID', 'clientOrderId', 'client_order_id'])
|
|
1162
1455
|
isByClientOrder = clientOrderIdExchangeSpecific is not None
|
|
1163
1456
|
response = None
|
|
1164
|
-
if
|
|
1165
|
-
|
|
1166
|
-
|
|
1457
|
+
if isTrigger:
|
|
1458
|
+
if isByClientOrder:
|
|
1459
|
+
request['clientAlgoOrderId'] = clientOrderIdExchangeSpecific
|
|
1460
|
+
else:
|
|
1461
|
+
request['algoOrderId'] = id
|
|
1462
|
+
response = await self.v3PrivateDeleteTradeAlgoOrder(self.extend(request, params))
|
|
1167
1463
|
else:
|
|
1168
1464
|
request['symbol'] = market['id']
|
|
1169
1465
|
if isByClientOrder:
|
|
1170
|
-
request['
|
|
1171
|
-
params = self.omit(params, ['clOrdID', 'clientOrderId', 'client_order_id'])
|
|
1172
|
-
response = await self.v1PrivateDeleteClientOrder(self.extend(request, params))
|
|
1466
|
+
request['clientOrderId'] = clientOrderIdExchangeSpecific
|
|
1173
1467
|
else:
|
|
1174
|
-
request['
|
|
1175
|
-
|
|
1468
|
+
request['orderId'] = id
|
|
1469
|
+
response = await self.v3PrivateDeleteTradeOrder(self.extend(request, params))
|
|
1176
1470
|
#
|
|
1177
|
-
#
|
|
1471
|
+
# {
|
|
1472
|
+
# "success": True,
|
|
1473
|
+
# "data": {
|
|
1474
|
+
# "status": "CANCEL_SENT"
|
|
1475
|
+
# },
|
|
1476
|
+
# "timestamp": 1751940315838
|
|
1477
|
+
# }
|
|
1178
1478
|
#
|
|
1179
|
-
|
|
1479
|
+
data = self.safe_dict(response, 'data', {})
|
|
1480
|
+
data['timestamp'] = self.safe_string(response, 'timestamp')
|
|
1180
1481
|
if isByClientOrder:
|
|
1181
|
-
|
|
1482
|
+
data['clientOrderId'] = clientOrderIdExchangeSpecific
|
|
1182
1483
|
else:
|
|
1183
|
-
|
|
1184
|
-
return self.
|
|
1484
|
+
data['orderId'] = id
|
|
1485
|
+
return self.parse_order(data, market)
|
|
1185
1486
|
|
|
1186
1487
|
async def cancel_all_orders(self, symbol: Str = None, params={}):
|
|
1187
1488
|
"""
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1489
|
+
|
|
1490
|
+
https://developer.woox.io/api-reference/endpoint/trading/cancel_all_order
|
|
1491
|
+
https://developer.woox.io/api-reference/endpoint/trading/cancel_algo_orders
|
|
1492
|
+
|
|
1191
1493
|
cancel all open orders in a market
|
|
1192
1494
|
:param str symbol: unified market symbol
|
|
1193
1495
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1194
|
-
:param boolean [params.
|
|
1496
|
+
:param boolean [params.trigger]: whether the order is a trigger/algo order
|
|
1195
1497
|
:returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
1196
1498
|
"""
|
|
1197
1499
|
await self.load_markets()
|
|
1198
|
-
|
|
1500
|
+
trigger = self.safe_bool_2(params, 'stop', 'trigger')
|
|
1199
1501
|
params = self.omit(params, ['stop', 'trigger'])
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1502
|
+
request: dict = {}
|
|
1503
|
+
if symbol is not None:
|
|
1504
|
+
market = self.market(symbol)
|
|
1505
|
+
request['symbol'] = market['id']
|
|
1506
|
+
response = None
|
|
1507
|
+
if trigger:
|
|
1508
|
+
response = await self.v3PrivateDeleteTradeAlgoOrders(params)
|
|
1509
|
+
else:
|
|
1510
|
+
response = await self.v3PrivateDeleteTradeOrders(self.extend(request, params))
|
|
1209
1511
|
#
|
|
1210
1512
|
# {
|
|
1211
|
-
# "success":
|
|
1212
|
-
# "
|
|
1513
|
+
# "success": True,
|
|
1514
|
+
# "data": {
|
|
1515
|
+
# "status": "CANCEL_ALL_SENT"
|
|
1516
|
+
# },
|
|
1517
|
+
# "timestamp": 1751941988134
|
|
1213
1518
|
# }
|
|
1214
1519
|
#
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
]
|
|
1520
|
+
data = self.safe_dict(response, 'data', {})
|
|
1521
|
+
return [self.safe_order({'info': data})]
|
|
1218
1522
|
|
|
1219
1523
|
async def cancel_all_orders_after(self, timeout: Int, params={}):
|
|
1220
1524
|
"""
|
|
1221
1525
|
dead man's switch, cancel all orders after the given timeout
|
|
1222
|
-
|
|
1526
|
+
|
|
1527
|
+
https://developer.woox.io/api-reference/endpoint/trading/cancel_all_after
|
|
1528
|
+
|
|
1223
1529
|
:param number timeout: time in milliseconds, 0 represents cancel the timer
|
|
1224
|
-
:param boolean activated: countdown
|
|
1225
1530
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1226
1531
|
:returns dict: the api result
|
|
1227
1532
|
"""
|
|
1228
1533
|
await self.load_markets()
|
|
1229
1534
|
request: dict = {
|
|
1230
|
-
'
|
|
1535
|
+
'triggerAfter': min(timeout, 900000) if (timeout > 0) else 0,
|
|
1231
1536
|
}
|
|
1232
|
-
response = await self.
|
|
1537
|
+
response = await self.v3PrivatePostTradeCancelAllAfter(self.extend(request, params))
|
|
1233
1538
|
#
|
|
1234
|
-
#
|
|
1235
|
-
#
|
|
1236
|
-
#
|
|
1237
|
-
#
|
|
1238
|
-
#
|
|
1239
|
-
# "timestamp": 1711534302943
|
|
1539
|
+
# {
|
|
1540
|
+
# "success": True,
|
|
1541
|
+
# "timestamp": 123,
|
|
1542
|
+
# "data": {
|
|
1543
|
+
# "expectedTriggerTime": 123
|
|
1240
1544
|
# }
|
|
1545
|
+
# }
|
|
1241
1546
|
#
|
|
1242
|
-
return
|
|
1243
|
-
self.safe_order(response),
|
|
1244
|
-
]
|
|
1547
|
+
return response
|
|
1245
1548
|
|
|
1246
1549
|
async def fetch_order(self, id: str, symbol: Str = None, params={}):
|
|
1247
1550
|
"""
|
|
1248
|
-
|
|
1249
|
-
|
|
1551
|
+
|
|
1552
|
+
https://developer.woox.io/api-reference/endpoint/trading/get_order
|
|
1553
|
+
https://developer.woox.io/api-reference/endpoint/trading/get_algo_order
|
|
1554
|
+
|
|
1250
1555
|
fetches information on an order made by the user
|
|
1556
|
+
:param str id: the order id
|
|
1251
1557
|
:param str symbol: unified symbol of the market the order was made in
|
|
1252
1558
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1253
|
-
:param boolean [params.
|
|
1559
|
+
:param boolean [params.trigger]: whether the order is a trigger/algo order
|
|
1254
1560
|
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
1255
1561
|
"""
|
|
1256
1562
|
await self.load_markets()
|
|
1257
|
-
market =
|
|
1258
|
-
|
|
1563
|
+
market = None
|
|
1564
|
+
if symbol is not None:
|
|
1565
|
+
market = self.market(symbol)
|
|
1566
|
+
trigger = self.safe_bool_2(params, 'stop', 'trigger')
|
|
1259
1567
|
params = self.omit(params, ['stop', 'trigger'])
|
|
1260
1568
|
request: dict = {}
|
|
1261
1569
|
clientOrderId = self.safe_string_2(params, 'clOrdID', 'clientOrderId')
|
|
1262
1570
|
response = None
|
|
1263
|
-
if
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
response = await self.
|
|
1571
|
+
if trigger:
|
|
1572
|
+
if clientOrderId is not None:
|
|
1573
|
+
request['clientAlgoOrderId'] = id
|
|
1574
|
+
else:
|
|
1575
|
+
request['algoOrderId'] = id
|
|
1576
|
+
response = await self.v3PrivateGetTradeAlgoOrder(self.extend(request, params))
|
|
1577
|
+
#
|
|
1578
|
+
# {
|
|
1579
|
+
# "success": True,
|
|
1580
|
+
# "data": {
|
|
1581
|
+
# "algoOrderId": 10399260,
|
|
1582
|
+
# "clientAlgoOrderId": 0,
|
|
1583
|
+
# "rootAlgoOrderId": 10399260,
|
|
1584
|
+
# "parentAlgoOrderId": 0,
|
|
1585
|
+
# "symbol": "SPOT_LTC_USDT",
|
|
1586
|
+
# "algoOrderTag": "default",
|
|
1587
|
+
# "algoType": "TAKE_PROFIT",
|
|
1588
|
+
# "side": "BUY",
|
|
1589
|
+
# "quantity": 0.1,
|
|
1590
|
+
# "isTriggered": False,
|
|
1591
|
+
# "triggerPrice": 65,
|
|
1592
|
+
# "triggerStatus": "USELESS",
|
|
1593
|
+
# "type": "LIMIT",
|
|
1594
|
+
# "rootAlgoStatus": "NEW",
|
|
1595
|
+
# "algoStatus": "NEW",
|
|
1596
|
+
# "triggerPriceType": "MARKET_PRICE",
|
|
1597
|
+
# "price": 60,
|
|
1598
|
+
# "triggerTime": "0",
|
|
1599
|
+
# "totalExecutedQuantity": 0,
|
|
1600
|
+
# "visibleQuantity": 0.1,
|
|
1601
|
+
# "averageExecutedPrice": 0,
|
|
1602
|
+
# "totalFee": 0,
|
|
1603
|
+
# "feeAsset": "",
|
|
1604
|
+
# "totalRebate": 0,
|
|
1605
|
+
# "rebateAsset": "",
|
|
1606
|
+
# "reduceOnly": False,
|
|
1607
|
+
# "createdTime": "1752049747.732",
|
|
1608
|
+
# "updatedTime": "1752049747.732",
|
|
1609
|
+
# "positionSide": "BOTH"
|
|
1610
|
+
# },
|
|
1611
|
+
# "timestamp": 1752049767550
|
|
1612
|
+
# }
|
|
1613
|
+
#
|
|
1269
1614
|
else:
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
orders = self.safe_dict(response, 'data', response)
|
|
1308
|
-
return self.parse_order(orders, market)
|
|
1615
|
+
if clientOrderId is not None:
|
|
1616
|
+
request['clientOrderId'] = clientOrderId
|
|
1617
|
+
else:
|
|
1618
|
+
request['orderId'] = id
|
|
1619
|
+
response = await self.v3PrivateGetTradeOrder(self.extend(request, params))
|
|
1620
|
+
#
|
|
1621
|
+
# {
|
|
1622
|
+
# "success": True,
|
|
1623
|
+
# "data": {
|
|
1624
|
+
# "orderId": 60780315704,
|
|
1625
|
+
# "clientOrderId": 0,
|
|
1626
|
+
# "symbol": "SPOT_LTC_USDT",
|
|
1627
|
+
# "orderTag": "default",
|
|
1628
|
+
# "side": "BUY",
|
|
1629
|
+
# "quantity": 0.1,
|
|
1630
|
+
# "amount": null,
|
|
1631
|
+
# "type": "LIMIT",
|
|
1632
|
+
# "status": "NEW",
|
|
1633
|
+
# "price": 60,
|
|
1634
|
+
# "executed": 0,
|
|
1635
|
+
# "visible": 0.1,
|
|
1636
|
+
# "averageExecutedPrice": 0,
|
|
1637
|
+
# "totalFee": 0,
|
|
1638
|
+
# "feeAsset": "LTC",
|
|
1639
|
+
# "totalRebate": 0,
|
|
1640
|
+
# "rebateAsset": "USDT",
|
|
1641
|
+
# "reduceOnly": False,
|
|
1642
|
+
# "createdTime": "1752049062.496",
|
|
1643
|
+
# "realizedPnl": null,
|
|
1644
|
+
# "positionSide": "BOTH",
|
|
1645
|
+
# "bidAskLevel": null
|
|
1646
|
+
# },
|
|
1647
|
+
# "timestamp": 1752049393466
|
|
1648
|
+
# }
|
|
1649
|
+
#
|
|
1650
|
+
data = self.safe_dict(response, 'data', {})
|
|
1651
|
+
return self.parse_order(data, market)
|
|
1309
1652
|
|
|
1310
1653
|
async def fetch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
|
1311
1654
|
"""
|
|
1312
1655
|
fetches information on multiple orders made by the user
|
|
1313
|
-
|
|
1314
|
-
|
|
1656
|
+
|
|
1657
|
+
https://developer.woox.io/api-reference/endpoint/trading/get_orders
|
|
1658
|
+
https://developer.woox.io/api-reference/endpoint/trading/get_algo_orders
|
|
1659
|
+
|
|
1315
1660
|
:param str symbol: unified market symbol of the market orders were made in
|
|
1316
1661
|
:param int [since]: the earliest time in ms to fetch orders for
|
|
1317
1662
|
:param int [limit]: the maximum number of order structures to retrieve
|
|
1318
1663
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1319
|
-
:param boolean [params.
|
|
1664
|
+
:param boolean [params.trigger]: whether the order is a trigger/algo order
|
|
1320
1665
|
:param boolean [params.isTriggered]: whether the order has been triggered(False by default)
|
|
1321
1666
|
:param str [params.side]: 'buy' or 'sell'
|
|
1322
|
-
:param boolean [params.trailing]: set to True if you want to fetch trailing orders
|
|
1323
1667
|
:param boolean [params.paginate]: set to True if you want to fetch orders with pagination
|
|
1324
1668
|
:returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
1325
1669
|
"""
|
|
@@ -1330,75 +1674,125 @@ class woo(Exchange, ImplicitAPI):
|
|
|
1330
1674
|
return await self.fetch_paginated_call_incremental('fetchOrders', symbol, since, limit, params, 'page', 500)
|
|
1331
1675
|
request: dict = {}
|
|
1332
1676
|
market: Market = None
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
params = self.omit(params, ['stop', 'trailing', 'trigger'])
|
|
1677
|
+
trigger = self.safe_bool_2(params, 'stop', 'trigger')
|
|
1678
|
+
params = self.omit(params, ['stop', 'trigger'])
|
|
1336
1679
|
if symbol is not None:
|
|
1337
1680
|
market = self.market(symbol)
|
|
1338
1681
|
request['symbol'] = market['id']
|
|
1339
1682
|
if since is not None:
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1683
|
+
request['startTime'] = since
|
|
1684
|
+
until = self.safe_integer(params, 'until') # unified in milliseconds
|
|
1685
|
+
params = self.omit(params, ['until'])
|
|
1686
|
+
if until is not None:
|
|
1687
|
+
request['endTime'] = until
|
|
1344
1688
|
if limit is not None:
|
|
1345
|
-
request['size'] = limit
|
|
1346
|
-
else:
|
|
1347
|
-
request['size'] = 500
|
|
1348
|
-
if stop:
|
|
1349
|
-
request['algoType'] = 'stop'
|
|
1350
|
-
elif trailing:
|
|
1351
|
-
request['algoType'] = 'TRAILING_STOP'
|
|
1689
|
+
request['size'] = min(limit, 500)
|
|
1352
1690
|
response = None
|
|
1353
|
-
if
|
|
1354
|
-
response = await self.
|
|
1691
|
+
if trigger:
|
|
1692
|
+
response = await self.v3PrivateGetTradeAlgoOrders(self.extend(request, params))
|
|
1693
|
+
#
|
|
1694
|
+
# {
|
|
1695
|
+
# "success": True,
|
|
1696
|
+
# "data": {
|
|
1697
|
+
# "rows": [
|
|
1698
|
+
# {
|
|
1699
|
+
# "algoOrderId": 10399260,
|
|
1700
|
+
# "clientAlgoOrderId": 0,
|
|
1701
|
+
# "rootAlgoOrderId": 10399260,
|
|
1702
|
+
# "parentAlgoOrderId": 0,
|
|
1703
|
+
# "symbol": "SPOT_LTC_USDT",
|
|
1704
|
+
# "algoOrderTag": "default",
|
|
1705
|
+
# "algoType": "TAKE_PROFIT",
|
|
1706
|
+
# "side": "BUY",
|
|
1707
|
+
# "quantity": 0.1,
|
|
1708
|
+
# "isTriggered": False,
|
|
1709
|
+
# "triggerPrice": 65,
|
|
1710
|
+
# "triggerStatus": "USELESS",
|
|
1711
|
+
# "type": "LIMIT",
|
|
1712
|
+
# "rootAlgoStatus": "NEW",
|
|
1713
|
+
# "algoStatus": "NEW",
|
|
1714
|
+
# "triggerPriceType": "MARKET_PRICE",
|
|
1715
|
+
# "price": 60,
|
|
1716
|
+
# "triggerTime": "0",
|
|
1717
|
+
# "totalExecutedQuantity": 0,
|
|
1718
|
+
# "visibleQuantity": 0.1,
|
|
1719
|
+
# "averageExecutedPrice": 0,
|
|
1720
|
+
# "totalFee": 0,
|
|
1721
|
+
# "feeAsset": "",
|
|
1722
|
+
# "totalRebate": 0,
|
|
1723
|
+
# "rebateAsset": "",
|
|
1724
|
+
# "reduceOnly": False,
|
|
1725
|
+
# "createdTime": "1752049747.730",
|
|
1726
|
+
# "updatedTime": "1752049747.730",
|
|
1727
|
+
# "positionSide": "BOTH"
|
|
1728
|
+
# }
|
|
1729
|
+
# ],
|
|
1730
|
+
# "meta": {
|
|
1731
|
+
# "total": 7,
|
|
1732
|
+
# "recordsPerPage": 1,
|
|
1733
|
+
# "currentPage": 1
|
|
1734
|
+
# }
|
|
1735
|
+
# },
|
|
1736
|
+
# "timestamp": 1752053127448
|
|
1737
|
+
# }
|
|
1738
|
+
#
|
|
1355
1739
|
else:
|
|
1356
|
-
response = await self.
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1740
|
+
response = await self.v3PrivateGetTradeOrders(self.extend(request, params))
|
|
1741
|
+
#
|
|
1742
|
+
# {
|
|
1743
|
+
# "success": True,
|
|
1744
|
+
# "data": {
|
|
1745
|
+
# "rows": [
|
|
1746
|
+
# {
|
|
1747
|
+
# "orderId": 60780315704,
|
|
1748
|
+
# "clientOrderId": 0,
|
|
1749
|
+
# "symbol": "SPOT_LTC_USDT",
|
|
1750
|
+
# "orderTag": "default",
|
|
1751
|
+
# "side": "BUY",
|
|
1752
|
+
# "quantity": 0.1,
|
|
1753
|
+
# "amount": null,
|
|
1754
|
+
# "type": "LIMIT",
|
|
1755
|
+
# "status": "NEW",
|
|
1756
|
+
# "price": 60,
|
|
1757
|
+
# "executed": 0,
|
|
1758
|
+
# "visible": 0.1,
|
|
1759
|
+
# "averageExecutedPrice": 0,
|
|
1760
|
+
# "totalFee": 0,
|
|
1761
|
+
# "feeAsset": "LTC",
|
|
1762
|
+
# "totalRebate": 0,
|
|
1763
|
+
# "rebateAsset": "USDT",
|
|
1764
|
+
# "reduceOnly": False,
|
|
1765
|
+
# "createdTime": "1752049062.496",
|
|
1766
|
+
# "realizedPnl": null,
|
|
1767
|
+
# "positionSide": "BOTH",
|
|
1768
|
+
# "bidAskLevel": null
|
|
1769
|
+
# }
|
|
1770
|
+
# ],
|
|
1771
|
+
# "meta": {
|
|
1772
|
+
# "total": 11,
|
|
1773
|
+
# "recordsPerPage": 1,
|
|
1774
|
+
# "currentPage": 1
|
|
1775
|
+
# }
|
|
1776
|
+
# },
|
|
1777
|
+
# "timestamp": 1752053061236
|
|
1778
|
+
# }
|
|
1779
|
+
#
|
|
1780
|
+
data = self.safe_value(response, 'data', {})
|
|
1781
|
+
orders = self.safe_list(data, 'rows', [])
|
|
1390
1782
|
return self.parse_orders(orders, market, since, limit)
|
|
1391
1783
|
|
|
1392
1784
|
async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
|
1393
1785
|
"""
|
|
1394
1786
|
fetches information on multiple orders made by the user
|
|
1395
|
-
|
|
1396
|
-
|
|
1787
|
+
|
|
1788
|
+
https://developer.woox.io/api-reference/endpoint/trading/get_orders
|
|
1789
|
+
https://developer.woox.io/api-reference/endpoint/trading/get_algo_orders
|
|
1790
|
+
|
|
1397
1791
|
:param str symbol: unified market symbol of the market orders were made in
|
|
1398
1792
|
:param int [since]: the earliest time in ms to fetch orders for
|
|
1399
1793
|
:param int [limit]: the maximum number of order structures to retrieve
|
|
1400
1794
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1401
|
-
:param boolean [params.
|
|
1795
|
+
:param boolean [params.trigger]: whether the order is a trigger/algo order
|
|
1402
1796
|
:param boolean [params.isTriggered]: whether the order has been triggered(False by default)
|
|
1403
1797
|
:param str [params.side]: 'buy' or 'sell'
|
|
1404
1798
|
:param boolean [params.trailing]: set to True if you want to fetch trailing orders
|
|
@@ -1412,13 +1806,15 @@ class woo(Exchange, ImplicitAPI):
|
|
|
1412
1806
|
async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
|
1413
1807
|
"""
|
|
1414
1808
|
fetches information on multiple orders made by the user
|
|
1415
|
-
|
|
1416
|
-
|
|
1809
|
+
|
|
1810
|
+
https://developer.woox.io/api-reference/endpoint/trading/get_orders
|
|
1811
|
+
https://developer.woox.io/api-reference/endpoint/trading/get_algo_orders
|
|
1812
|
+
|
|
1417
1813
|
:param str symbol: unified market symbol of the market orders were made in
|
|
1418
1814
|
:param int [since]: the earliest time in ms to fetch orders for
|
|
1419
1815
|
:param int [limit]: the maximum number of order structures to retrieve
|
|
1420
1816
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1421
|
-
:param boolean [params.
|
|
1817
|
+
:param boolean [params.trigger]: whether the order is a trigger/algo order
|
|
1422
1818
|
:param boolean [params.isTriggered]: whether the order has been triggered(False by default)
|
|
1423
1819
|
:param str [params.side]: 'buy' or 'sell'
|
|
1424
1820
|
:param boolean [params.trailing]: set to True if you want to fetch trailing orders
|
|
@@ -1439,81 +1835,107 @@ class woo(Exchange, ImplicitAPI):
|
|
|
1439
1835
|
|
|
1440
1836
|
def parse_order(self, order: dict, market: Market = None) -> Order:
|
|
1441
1837
|
#
|
|
1442
|
-
#
|
|
1443
|
-
#
|
|
1444
|
-
#
|
|
1445
|
-
#
|
|
1446
|
-
#
|
|
1447
|
-
#
|
|
1448
|
-
#
|
|
1449
|
-
#
|
|
1450
|
-
#
|
|
1451
|
-
#
|
|
1452
|
-
#
|
|
1453
|
-
#
|
|
1454
|
-
#
|
|
1455
|
-
#
|
|
1456
|
-
#
|
|
1457
|
-
#
|
|
1458
|
-
#
|
|
1459
|
-
#
|
|
1460
|
-
#
|
|
1461
|
-
#
|
|
1462
|
-
#
|
|
1463
|
-
#
|
|
1464
|
-
#
|
|
1465
|
-
#
|
|
1466
|
-
#
|
|
1467
|
-
#
|
|
1468
|
-
#
|
|
1469
|
-
#
|
|
1470
|
-
#
|
|
1471
|
-
#
|
|
1472
|
-
#
|
|
1473
|
-
#
|
|
1474
|
-
#
|
|
1475
|
-
#
|
|
1476
|
-
#
|
|
1477
|
-
#
|
|
1478
|
-
#
|
|
1479
|
-
#
|
|
1480
|
-
#
|
|
1481
|
-
#
|
|
1482
|
-
#
|
|
1483
|
-
#
|
|
1484
|
-
#
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1838
|
+
# createOrder
|
|
1839
|
+
# {
|
|
1840
|
+
# "orderId": 60667653330,
|
|
1841
|
+
# "clientOrderId": 0,
|
|
1842
|
+
# "type": "LIMIT",
|
|
1843
|
+
# "price": 60,
|
|
1844
|
+
# "quantity": 0.1,
|
|
1845
|
+
# "amount": null,
|
|
1846
|
+
# "bidAskLevel": null,
|
|
1847
|
+
# "timestamp": 1751871779855
|
|
1848
|
+
# }
|
|
1849
|
+
#
|
|
1850
|
+
# createOrder - algo
|
|
1851
|
+
# {
|
|
1852
|
+
# "orderId": "1578938",
|
|
1853
|
+
# "clientOrderId": "0",
|
|
1854
|
+
# "algoType": "STOP_LOSS",
|
|
1855
|
+
# "quantity": "0.1",
|
|
1856
|
+
# "timestamp": "1686149372216"
|
|
1857
|
+
# }
|
|
1858
|
+
#
|
|
1859
|
+
# fetchOrder
|
|
1860
|
+
# {
|
|
1861
|
+
# "orderId": 60780315704,
|
|
1862
|
+
# "clientOrderId": 0,
|
|
1863
|
+
# "symbol": "SPOT_LTC_USDT",
|
|
1864
|
+
# "orderTag": "default",
|
|
1865
|
+
# "side": "BUY",
|
|
1866
|
+
# "quantity": 0.1,
|
|
1867
|
+
# "amount": null,
|
|
1868
|
+
# "type": "LIMIT",
|
|
1869
|
+
# "status": "NEW",
|
|
1870
|
+
# "price": 60,
|
|
1871
|
+
# "executed": 0,
|
|
1872
|
+
# "visible": 0.1,
|
|
1873
|
+
# "averageExecutedPrice": 0,
|
|
1874
|
+
# "totalFee": 0,
|
|
1875
|
+
# "feeAsset": "LTC",
|
|
1876
|
+
# "totalRebate": 0,
|
|
1877
|
+
# "rebateAsset": "USDT",
|
|
1878
|
+
# "reduceOnly": False,
|
|
1879
|
+
# "createdTime": "1752049062.496",
|
|
1880
|
+
# "realizedPnl": null,
|
|
1881
|
+
# "positionSide": "BOTH",
|
|
1882
|
+
# "bidAskLevel": null
|
|
1883
|
+
# }
|
|
1884
|
+
#
|
|
1885
|
+
# fetchOrder - algo
|
|
1886
|
+
# {
|
|
1887
|
+
# "algoOrderId": 10399260,
|
|
1888
|
+
# "clientAlgoOrderId": 0,
|
|
1889
|
+
# "rootAlgoOrderId": 10399260,
|
|
1890
|
+
# "parentAlgoOrderId": 0,
|
|
1891
|
+
# "symbol": "SPOT_LTC_USDT",
|
|
1892
|
+
# "algoOrderTag": "default",
|
|
1893
|
+
# "algoType": "TAKE_PROFIT",
|
|
1894
|
+
# "side": "BUY",
|
|
1895
|
+
# "quantity": 0.1,
|
|
1896
|
+
# "isTriggered": False,
|
|
1897
|
+
# "triggerPrice": 65,
|
|
1898
|
+
# "triggerStatus": "USELESS",
|
|
1899
|
+
# "type": "LIMIT",
|
|
1900
|
+
# "rootAlgoStatus": "NEW",
|
|
1901
|
+
# "algoStatus": "NEW",
|
|
1902
|
+
# "triggerPriceType": "MARKET_PRICE",
|
|
1903
|
+
# "price": 60,
|
|
1904
|
+
# "triggerTime": "0",
|
|
1905
|
+
# "totalExecutedQuantity": 0,
|
|
1906
|
+
# "visibleQuantity": 0.1,
|
|
1907
|
+
# "averageExecutedPrice": 0,
|
|
1908
|
+
# "totalFee": 0,
|
|
1909
|
+
# "feeAsset": "",
|
|
1910
|
+
# "totalRebate": 0,
|
|
1911
|
+
# "rebateAsset": "",
|
|
1912
|
+
# "reduceOnly": False,
|
|
1913
|
+
# "createdTime": "1752049747.732",
|
|
1914
|
+
# "updatedTime": "1752049747.732",
|
|
1915
|
+
# "positionSide": "BOTH"
|
|
1916
|
+
# }
|
|
1917
|
+
#
|
|
1918
|
+
timestamp = self.safe_timestamp(order, 'createdTime')
|
|
1919
|
+
if timestamp is None:
|
|
1920
|
+
timestamp = self.safe_integer(order, 'timestamp')
|
|
1921
|
+
orderId = self.safe_string_2(order, 'orderId', 'algoOrderId')
|
|
1922
|
+
clientOrderId = self.omit_zero(self.safe_string_2(order, 'clientOrderId', 'clientAlgoOrderId')) # Somehow, self always returns 0 for limit order
|
|
1488
1923
|
marketId = self.safe_string(order, 'symbol')
|
|
1489
1924
|
market = self.safe_market(marketId, market)
|
|
1490
1925
|
symbol = market['symbol']
|
|
1491
|
-
price = self.
|
|
1492
|
-
amount = self.
|
|
1493
|
-
cost = self.
|
|
1494
|
-
orderType = self.
|
|
1926
|
+
price = self.safe_string(order, 'price')
|
|
1927
|
+
amount = self.safe_string(order, 'quantity') # This is base amount
|
|
1928
|
+
cost = self.safe_string(order, 'amount') # This is quote amount
|
|
1929
|
+
orderType = self.safe_string_lower(order, 'type')
|
|
1495
1930
|
status = self.safe_value_2(order, 'status', 'algoStatus')
|
|
1496
1931
|
side = self.safe_string_lower(order, 'side')
|
|
1497
1932
|
filled = self.omit_zero(self.safe_value_2(order, 'executed', 'totalExecutedQuantity'))
|
|
1498
|
-
average = self.omit_zero(self.
|
|
1499
|
-
remaining = Precise.string_sub(cost, filled)
|
|
1500
|
-
fee = self.
|
|
1501
|
-
feeCurrency = self.
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
takeProfitPrice: Num = None
|
|
1505
|
-
stopLossPrice: Num = None
|
|
1506
|
-
childOrders = self.safe_value(order, 'childOrders')
|
|
1507
|
-
if childOrders is not None:
|
|
1508
|
-
first = self.safe_value(childOrders, 0)
|
|
1509
|
-
innerChildOrders = self.safe_value(first, 'childOrders', [])
|
|
1510
|
-
innerChildOrdersLength = len(innerChildOrders)
|
|
1511
|
-
if innerChildOrdersLength > 0:
|
|
1512
|
-
takeProfitOrder = self.safe_value(innerChildOrders, 0)
|
|
1513
|
-
stopLossOrder = self.safe_value(innerChildOrders, 1)
|
|
1514
|
-
takeProfitPrice = self.safe_number(takeProfitOrder, 'triggerPrice')
|
|
1515
|
-
stopLossPrice = self.safe_number(stopLossOrder, 'triggerPrice')
|
|
1516
|
-
lastUpdateTimestamp = self.safe_timestamp_2(order, 'updatedTime', 'updated_time')
|
|
1933
|
+
average = self.omit_zero(self.safe_string(order, 'averageExecutedPrice'))
|
|
1934
|
+
# remaining = Precise.string_sub(cost, filled)
|
|
1935
|
+
fee = self.safe_number(order, 'totalFee')
|
|
1936
|
+
feeCurrency = self.safe_string(order, 'feeAsset')
|
|
1937
|
+
triggerPrice = self.safe_number(order, 'triggerPrice')
|
|
1938
|
+
lastUpdateTimestamp = self.safe_timestamp(order, 'updatedTime')
|
|
1517
1939
|
return self.safe_order({
|
|
1518
1940
|
'id': orderId,
|
|
1519
1941
|
'clientOrderId': clientOrderId,
|
|
@@ -1526,19 +1948,18 @@ class woo(Exchange, ImplicitAPI):
|
|
|
1526
1948
|
'type': orderType,
|
|
1527
1949
|
'timeInForce': self.parse_time_in_force(orderType),
|
|
1528
1950
|
'postOnly': None, # TO_DO
|
|
1529
|
-
'reduceOnly': self.safe_bool(order, '
|
|
1951
|
+
'reduceOnly': self.safe_bool(order, 'reduceOnly'),
|
|
1530
1952
|
'side': side,
|
|
1531
1953
|
'price': price,
|
|
1532
|
-
'
|
|
1533
|
-
'
|
|
1534
|
-
'
|
|
1535
|
-
'stopLossPrice': stopLossPrice,
|
|
1954
|
+
'triggerPrice': triggerPrice,
|
|
1955
|
+
'takeProfitPrice': None,
|
|
1956
|
+
'stopLossPrice': None,
|
|
1536
1957
|
'average': average,
|
|
1537
1958
|
'amount': amount,
|
|
1538
1959
|
'filled': filled,
|
|
1539
|
-
'remaining':
|
|
1960
|
+
'remaining': None, # TO_DO
|
|
1540
1961
|
'cost': cost,
|
|
1541
|
-
'trades':
|
|
1962
|
+
'trades': None,
|
|
1542
1963
|
'fee': {
|
|
1543
1964
|
'cost': fee,
|
|
1544
1965
|
'currency': feeCurrency,
|
|
@@ -1565,7 +1986,9 @@ class woo(Exchange, ImplicitAPI):
|
|
|
1565
1986
|
async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
|
1566
1987
|
"""
|
|
1567
1988
|
fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
|
1568
|
-
|
|
1989
|
+
|
|
1990
|
+
https://developer.woox.io/api-reference/endpoint/public_data/orderbook
|
|
1991
|
+
|
|
1569
1992
|
:param str symbol: unified symbol of the market to fetch the order book for
|
|
1570
1993
|
:param int [limit]: the maximum amount of order book entries to return
|
|
1571
1994
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -1577,38 +2000,45 @@ class woo(Exchange, ImplicitAPI):
|
|
|
1577
2000
|
'symbol': market['id'],
|
|
1578
2001
|
}
|
|
1579
2002
|
if limit is not None:
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
response = await self.v1PublicGetOrderbookSymbol(self.extend(request, params))
|
|
2003
|
+
request['maxLevel'] = limit
|
|
2004
|
+
response = await self.v3PublicGetOrderbook(self.extend(request, params))
|
|
1583
2005
|
#
|
|
1584
|
-
# {
|
|
1585
|
-
# "success": True,
|
|
1586
|
-
# "timestamp": "1641562961192",
|
|
1587
|
-
# "asks": [
|
|
1588
|
-
# {price: '0.921', quantity: "76.01"},
|
|
1589
|
-
# {price: '0.933', quantity: "477.10"},
|
|
1590
|
-
# ...
|
|
1591
|
-
# ],
|
|
1592
|
-
# "bids": [
|
|
1593
|
-
# {price: '0.940', quantity: "13502.47"},
|
|
1594
|
-
# {price: '0.932', quantity: "43.91"},
|
|
1595
|
-
# ...
|
|
1596
|
-
# ]
|
|
1597
2006
|
# }
|
|
2007
|
+
# {
|
|
2008
|
+
# "success": True,
|
|
2009
|
+
# "timestamp": 1751620923344,
|
|
2010
|
+
# "data": {
|
|
2011
|
+
# "asks": [
|
|
2012
|
+
# {
|
|
2013
|
+
# "price": "108924.86",
|
|
2014
|
+
# "quantity": "0.032126"
|
|
2015
|
+
# }
|
|
2016
|
+
# ],
|
|
2017
|
+
# "bids": [
|
|
2018
|
+
# {
|
|
2019
|
+
# "price": "108924.85",
|
|
2020
|
+
# "quantity": "1.714147"
|
|
2021
|
+
# }
|
|
2022
|
+
# ]
|
|
2023
|
+
# }
|
|
2024
|
+
# }
|
|
1598
2025
|
#
|
|
2026
|
+
data = self.safe_dict(response, 'data', {})
|
|
1599
2027
|
timestamp = self.safe_integer(response, 'timestamp')
|
|
1600
|
-
return self.parse_order_book(
|
|
2028
|
+
return self.parse_order_book(data, symbol, timestamp, 'bids', 'asks', 'price', 'quantity')
|
|
1601
2029
|
|
|
1602
2030
|
async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
|
1603
2031
|
"""
|
|
1604
|
-
|
|
1605
|
-
|
|
2032
|
+
|
|
2033
|
+
https://developer.woox.io/api-reference/endpoint/public_data/klineHistory
|
|
2034
|
+
|
|
1606
2035
|
fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
1607
2036
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
|
1608
2037
|
:param str timeframe: the length of time each candle represents
|
|
1609
2038
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
|
1610
2039
|
:param int [limit]: max=1000, max=100 when since is defined and is less than(now - (999 * (timeframe in ms)))
|
|
1611
2040
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
2041
|
+
:param int [params.until]: the latest time in ms to fetch entries for
|
|
1612
2042
|
:returns int[][]: A list of candles ordered, open, high, low, close, volume
|
|
1613
2043
|
"""
|
|
1614
2044
|
await self.load_markets()
|
|
@@ -1617,70 +2047,44 @@ class woo(Exchange, ImplicitAPI):
|
|
|
1617
2047
|
'symbol': market['id'],
|
|
1618
2048
|
'type': self.safe_string(self.timeframes, timeframe, timeframe),
|
|
1619
2049
|
}
|
|
1620
|
-
|
|
1621
|
-
if (limit is not None) and (since is not None):
|
|
1622
|
-
oneThousandCandles = self.parse_timeframe(timeframe) * 1000 * 999 # 999 because there will be delay between self and the request, causing the latest candle to be excluded sometimes
|
|
1623
|
-
startWithLimit = self.milliseconds() - oneThousandCandles
|
|
1624
|
-
useHistEndpoint = since < startWithLimit
|
|
1625
|
-
if useHistEndpoint:
|
|
1626
|
-
request['start_time'] = since
|
|
1627
|
-
elif limit is not None: # the hist endpoint does not accept limit
|
|
2050
|
+
if limit is not None:
|
|
1628
2051
|
request['limit'] = min(limit, 1000)
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
# {
|
|
1661
|
-
# "symbol": "SPOT_BTC_USDT",
|
|
1662
|
-
# "open": 44181.40000000,
|
|
1663
|
-
# "close": 44174.29000000,
|
|
1664
|
-
# "high": 44193.44000000,
|
|
1665
|
-
# "low": 44148.34000000,
|
|
1666
|
-
# "volume": 110.11930100,
|
|
1667
|
-
# "amount": 4863796.24318878,
|
|
1668
|
-
# "type": "1m",
|
|
1669
|
-
# "start_timestamp": 1704153600000,
|
|
1670
|
-
# "end_timestamp": 1704153660000
|
|
1671
|
-
# },
|
|
1672
|
-
# ...
|
|
1673
|
-
# ]
|
|
1674
|
-
# }
|
|
1675
|
-
# }
|
|
1676
|
-
#
|
|
1677
|
-
rows = self.safe_list(response, 'rows', [])
|
|
2052
|
+
if since is not None:
|
|
2053
|
+
request['after'] = since
|
|
2054
|
+
until = self.safe_integer(params, 'until')
|
|
2055
|
+
params = self.omit(params, 'until')
|
|
2056
|
+
if until is not None:
|
|
2057
|
+
request['before'] = until
|
|
2058
|
+
response = await self.v3PublicGetKlineHistory(self.extend(request, params))
|
|
2059
|
+
#
|
|
2060
|
+
# {
|
|
2061
|
+
# "success": True,
|
|
2062
|
+
# "data": {
|
|
2063
|
+
# "rows": [
|
|
2064
|
+
# {
|
|
2065
|
+
# "symbol": "SPOT_BTC_USDT",
|
|
2066
|
+
# "open": "108994.16",
|
|
2067
|
+
# "close": "108994.16",
|
|
2068
|
+
# "high": "108994.16",
|
|
2069
|
+
# "low": "108994.16",
|
|
2070
|
+
# "volume": "0",
|
|
2071
|
+
# "amount": "0",
|
|
2072
|
+
# "type": "1m",
|
|
2073
|
+
# "startTimestamp": 1751622120000,
|
|
2074
|
+
# "endTimestamp": 1751622180000
|
|
2075
|
+
# }
|
|
2076
|
+
# ]
|
|
2077
|
+
# },
|
|
2078
|
+
# "timestamp": 1751622205410
|
|
2079
|
+
# }
|
|
2080
|
+
#
|
|
2081
|
+
data = self.safe_dict(response, 'data', {})
|
|
2082
|
+
rows = self.safe_list(data, 'rows', [])
|
|
1678
2083
|
return self.parse_ohlcvs(rows, market, timeframe, since, limit)
|
|
1679
2084
|
|
|
1680
2085
|
def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
|
|
1681
|
-
# example response in fetchOHLCV
|
|
1682
2086
|
return [
|
|
1683
|
-
self.safe_integer(ohlcv, '
|
|
2087
|
+
self.safe_integer(ohlcv, 'startTimestamp'),
|
|
1684
2088
|
self.safe_number(ohlcv, 'open'),
|
|
1685
2089
|
self.safe_number(ohlcv, 'high'),
|
|
1686
2090
|
self.safe_number(ohlcv, 'low'),
|
|
@@ -1691,7 +2095,9 @@ class woo(Exchange, ImplicitAPI):
|
|
|
1691
2095
|
async def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
|
1692
2096
|
"""
|
|
1693
2097
|
fetch all the trades made from a single order
|
|
1694
|
-
|
|
2098
|
+
|
|
2099
|
+
https://docs.woox.io/#get-trades
|
|
2100
|
+
|
|
1695
2101
|
:param str id: order id
|
|
1696
2102
|
:param str symbol: unified market symbol
|
|
1697
2103
|
:param int [since]: the earliest time in ms to fetch trades for
|
|
@@ -1731,7 +2137,9 @@ class woo(Exchange, ImplicitAPI):
|
|
|
1731
2137
|
async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
|
1732
2138
|
"""
|
|
1733
2139
|
fetch all trades made by the user
|
|
1734
|
-
|
|
2140
|
+
|
|
2141
|
+
https://developer.woox.io/api-reference/endpoint/trading/get_transactions
|
|
2142
|
+
|
|
1735
2143
|
:param str symbol: unified market symbol
|
|
1736
2144
|
:param int [since]: the earliest time in ms to fetch trades for
|
|
1737
2145
|
:param int [limit]: the maximum number of trades structures to retrieve
|
|
@@ -1750,86 +2158,157 @@ class woo(Exchange, ImplicitAPI):
|
|
|
1750
2158
|
market = self.market(symbol)
|
|
1751
2159
|
request['symbol'] = market['id']
|
|
1752
2160
|
if since is not None:
|
|
1753
|
-
request['
|
|
2161
|
+
request['startTime'] = since
|
|
2162
|
+
until = self.safe_integer(params, 'until') # unified in milliseconds
|
|
2163
|
+
params = self.omit(params, ['until'])
|
|
2164
|
+
if until is not None:
|
|
2165
|
+
request['endTime'] = until
|
|
1754
2166
|
if limit is not None:
|
|
1755
|
-
request['
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
#
|
|
1760
|
-
#
|
|
1761
|
-
#
|
|
1762
|
-
#
|
|
1763
|
-
#
|
|
1764
|
-
#
|
|
1765
|
-
#
|
|
1766
|
-
#
|
|
1767
|
-
#
|
|
1768
|
-
#
|
|
1769
|
-
#
|
|
1770
|
-
#
|
|
1771
|
-
#
|
|
1772
|
-
#
|
|
1773
|
-
#
|
|
1774
|
-
#
|
|
1775
|
-
#
|
|
1776
|
-
#
|
|
1777
|
-
# "
|
|
2167
|
+
request['limit'] = limit
|
|
2168
|
+
response = await self.v3PrivateGetTradeTransactionHistory(self.extend(request, params))
|
|
2169
|
+
#
|
|
2170
|
+
# {
|
|
2171
|
+
# "success": True,
|
|
2172
|
+
# "data": {
|
|
2173
|
+
# "rows": [
|
|
2174
|
+
# {
|
|
2175
|
+
# "id": 1734947821,
|
|
2176
|
+
# "symbol": "SPOT_LTC_USDT",
|
|
2177
|
+
# "orderId": 60780383217,
|
|
2178
|
+
# "executedPrice": 87.86,
|
|
2179
|
+
# "executedQuantity": 0.1,
|
|
2180
|
+
# "fee": 0.0001,
|
|
2181
|
+
# "realizedPnl": null,
|
|
2182
|
+
# "feeAsset": "LTC",
|
|
2183
|
+
# "orderTag": "default",
|
|
2184
|
+
# "side": "BUY",
|
|
2185
|
+
# "executedTimestamp": "1752055173.630",
|
|
2186
|
+
# "isMaker": 0
|
|
2187
|
+
# }
|
|
2188
|
+
# ],
|
|
2189
|
+
# "meta": {
|
|
2190
|
+
# "total": 1,
|
|
2191
|
+
# "recordsPerPage": 100,
|
|
2192
|
+
# "currentPage": 1
|
|
2193
|
+
# }
|
|
1778
2194
|
# },
|
|
1779
|
-
#
|
|
1780
|
-
#
|
|
1781
|
-
#
|
|
1782
|
-
|
|
2195
|
+
# "timestamp": 1752055545121
|
|
2196
|
+
# }
|
|
2197
|
+
#
|
|
2198
|
+
data = self.safe_dict(response, 'data', {})
|
|
2199
|
+
trades = self.safe_list(data, 'rows', [])
|
|
1783
2200
|
return self.parse_trades(trades, market, since, limit, params)
|
|
1784
2201
|
|
|
1785
2202
|
async def fetch_accounts(self, params={}) -> List[Account]:
|
|
1786
2203
|
"""
|
|
1787
2204
|
fetch all the accounts associated with a profile
|
|
1788
|
-
|
|
2205
|
+
|
|
2206
|
+
https://developer.woox.io/api-reference/endpoint/account/get_account_info
|
|
2207
|
+
https://developer.woox.io/api-reference/endpoint/account/sub_accounts
|
|
2208
|
+
|
|
1789
2209
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1790
2210
|
:returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
|
|
1791
2211
|
"""
|
|
1792
|
-
|
|
2212
|
+
mainAccountPromise = self.v3PrivateGetAccountInfo(params)
|
|
1793
2213
|
#
|
|
1794
2214
|
# {
|
|
1795
|
-
# "
|
|
1796
|
-
#
|
|
1797
|
-
#
|
|
1798
|
-
#
|
|
1799
|
-
#
|
|
1800
|
-
#
|
|
1801
|
-
#
|
|
1802
|
-
#
|
|
1803
|
-
#
|
|
1804
|
-
#
|
|
1805
|
-
#
|
|
1806
|
-
#
|
|
2215
|
+
# "success": True,
|
|
2216
|
+
# "data": {
|
|
2217
|
+
# "applicationId": "251bf5c4-f3c8-4544-bb8b-80001007c3c0",
|
|
2218
|
+
# "account": "carlos_jose_lima@yahoo.com",
|
|
2219
|
+
# "alias": "carlos_jose_lima@yahoo.com",
|
|
2220
|
+
# "otpauth": True,
|
|
2221
|
+
# "accountMode": "FUTURES",
|
|
2222
|
+
# "positionMode": "ONE_WAY",
|
|
2223
|
+
# "leverage": 0,
|
|
2224
|
+
# "marginRatio": "10",
|
|
2225
|
+
# "openMarginRatio": "10",
|
|
2226
|
+
# "initialMarginRatio": "10",
|
|
2227
|
+
# "maintenanceMarginRatio": "0.03",
|
|
2228
|
+
# "totalCollateral": "165.55629469",
|
|
2229
|
+
# "freeCollateral": "165.55629469",
|
|
2230
|
+
# "totalAccountValue": "167.32418611",
|
|
2231
|
+
# "totalTradingValue": "167.32418611",
|
|
2232
|
+
# "totalVaultValue": "0",
|
|
2233
|
+
# "totalStakingValue": "0",
|
|
2234
|
+
# "totalLaunchpadValue": "0",
|
|
2235
|
+
# "totalEarnValue": "0",
|
|
2236
|
+
# "referrerID": null,
|
|
2237
|
+
# "accountType": "Main"
|
|
2238
|
+
# },
|
|
2239
|
+
# "timestamp": 1752062807915
|
|
2240
|
+
# }
|
|
2241
|
+
#
|
|
2242
|
+
subAccountPromise = self.v3PrivateGetAccountSubAccountsAll(params)
|
|
2243
|
+
#
|
|
2244
|
+
# {
|
|
2245
|
+
# "success": True,
|
|
2246
|
+
# "data": {
|
|
2247
|
+
# "rows": [
|
|
2248
|
+
# {
|
|
2249
|
+
# "applicationId": "6b43de5c-0955-4887-9862-d84e4689f9fe",
|
|
2250
|
+
# "name": "sub_account_2",
|
|
2251
|
+
# "createdTime": "1606897264.994"
|
|
2252
|
+
# },
|
|
2253
|
+
# ]
|
|
2254
|
+
# },
|
|
2255
|
+
# "timestamp": 1721295317627
|
|
1807
2256
|
# }
|
|
1808
2257
|
#
|
|
1809
|
-
|
|
2258
|
+
mainAccountResponse, subAccountResponse = await asyncio.gather(*[mainAccountPromise, subAccountPromise])
|
|
2259
|
+
mainData = self.safe_dict(mainAccountResponse, 'data', {})
|
|
2260
|
+
mainRows = [mainData]
|
|
2261
|
+
subData = self.safe_dict(subAccountResponse, 'data', {})
|
|
2262
|
+
subRows = self.safe_list(subData, 'rows', [])
|
|
2263
|
+
rows = self.array_concat(mainRows, subRows)
|
|
1810
2264
|
return self.parse_accounts(rows, params)
|
|
1811
2265
|
|
|
1812
2266
|
def parse_account(self, account):
|
|
1813
2267
|
#
|
|
1814
2268
|
# {
|
|
1815
|
-
# "
|
|
1816
|
-
# "account": "
|
|
1817
|
-
# "
|
|
2269
|
+
# "applicationId": "251bf5c4-f3c8-4544-bb8b-80001007c3c0",
|
|
2270
|
+
# "account": "carlos_jose_lima@yahoo.com",
|
|
2271
|
+
# "alias": "carlos_jose_lima@yahoo.com",
|
|
2272
|
+
# "otpauth": True,
|
|
2273
|
+
# "accountMode": "FUTURES",
|
|
2274
|
+
# "positionMode": "ONE_WAY",
|
|
2275
|
+
# "leverage": 0,
|
|
2276
|
+
# "marginRatio": "10",
|
|
2277
|
+
# "openMarginRatio": "10",
|
|
2278
|
+
# "initialMarginRatio": "10",
|
|
2279
|
+
# "maintenanceMarginRatio": "0.03",
|
|
2280
|
+
# "totalCollateral": "165.55629469",
|
|
2281
|
+
# "freeCollateral": "165.55629469",
|
|
2282
|
+
# "totalAccountValue": "167.32418611",
|
|
2283
|
+
# "totalTradingValue": "167.32418611",
|
|
2284
|
+
# "totalVaultValue": "0",
|
|
2285
|
+
# "totalStakingValue": "0",
|
|
2286
|
+
# "totalLaunchpadValue": "0",
|
|
2287
|
+
# "totalEarnValue": "0",
|
|
2288
|
+
# "referrerID": null,
|
|
2289
|
+
# "accountType": "Main"
|
|
2290
|
+
# }
|
|
2291
|
+
#
|
|
2292
|
+
# {
|
|
2293
|
+
# "applicationId": "6b43de5c-0955-4887-9862-d84e4689f9fe",
|
|
2294
|
+
# "name": "sub_account_2",
|
|
2295
|
+
# "createdTime": "1606897264.994"
|
|
1818
2296
|
# }
|
|
1819
2297
|
#
|
|
1820
|
-
accountId = self.safe_string(account, 'account')
|
|
1821
2298
|
return {
|
|
1822
2299
|
'info': account,
|
|
1823
|
-
'id': self.safe_string(account, '
|
|
1824
|
-
'name':
|
|
2300
|
+
'id': self.safe_string(account, 'applicationId'),
|
|
2301
|
+
'name': self.safe_string_n(account, ['name', 'account', 'alias']),
|
|
1825
2302
|
'code': None,
|
|
1826
|
-
'type':
|
|
2303
|
+
'type': self.safe_string_lower(account, 'accountType', 'subaccount'),
|
|
1827
2304
|
}
|
|
1828
2305
|
|
|
1829
2306
|
async def fetch_balance(self, params={}) -> Balances:
|
|
1830
2307
|
"""
|
|
1831
2308
|
query for balance and get the amount of funds available for trading or funds locked in orders
|
|
1832
|
-
|
|
2309
|
+
|
|
2310
|
+
https://docs.woox.io/#get-current-holding-get-balance-new
|
|
2311
|
+
|
|
1833
2312
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1834
2313
|
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
|
1835
2314
|
"""
|
|
@@ -1875,10 +2354,12 @@ class woo(Exchange, ImplicitAPI):
|
|
|
1875
2354
|
result[code] = account
|
|
1876
2355
|
return self.safe_balance(result)
|
|
1877
2356
|
|
|
1878
|
-
async def fetch_deposit_address(self, code: str, params={}):
|
|
2357
|
+
async def fetch_deposit_address(self, code: str, params={}) -> DepositAddress:
|
|
1879
2358
|
"""
|
|
1880
2359
|
fetch the deposit address for a currency associated with self account
|
|
1881
|
-
|
|
2360
|
+
|
|
2361
|
+
https://developer.woox.io/api-reference/endpoint/assets/get_wallet_deposit
|
|
2362
|
+
|
|
1882
2363
|
:param str code: unified currency code
|
|
1883
2364
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1884
2365
|
:returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
|
|
@@ -1886,28 +2367,46 @@ class woo(Exchange, ImplicitAPI):
|
|
|
1886
2367
|
# self method is TODO because of networks unification
|
|
1887
2368
|
await self.load_markets()
|
|
1888
2369
|
currency = self.currency(code)
|
|
1889
|
-
|
|
1890
|
-
networkCode = self.
|
|
1891
|
-
params = self.omit(params, 'network')
|
|
1892
|
-
codeForExchange = networkCode + '_' + currency['code']
|
|
2370
|
+
networkCode = None
|
|
2371
|
+
networkCode, params = self.handle_network_code_and_params(params)
|
|
1893
2372
|
request: dict = {
|
|
1894
|
-
'token':
|
|
2373
|
+
'token': currency['id'],
|
|
2374
|
+
'network': self.network_code_to_id(networkCode),
|
|
1895
2375
|
}
|
|
1896
|
-
response = await self.
|
|
1897
|
-
#
|
|
1898
|
-
#
|
|
1899
|
-
#
|
|
1900
|
-
#
|
|
1901
|
-
#
|
|
1902
|
-
|
|
1903
|
-
|
|
2376
|
+
response = await self.v3PrivateGetAssetWalletDeposit(self.extend(request, params))
|
|
2377
|
+
#
|
|
2378
|
+
# {
|
|
2379
|
+
# "success": True,
|
|
2380
|
+
# "data": {
|
|
2381
|
+
# "address": "0x31d64B3230f8baDD91dE1710A65DF536aF8f7cDa",
|
|
2382
|
+
# "extra": ""
|
|
2383
|
+
# },
|
|
2384
|
+
# "timestamp": 1721300689532
|
|
2385
|
+
# }
|
|
2386
|
+
#
|
|
2387
|
+
data = self.safe_dict(response, 'data', {})
|
|
2388
|
+
return self.parse_deposit_address(data, currency)
|
|
2389
|
+
|
|
2390
|
+
def get_dedicated_network_id(self, currency, params: dict) -> Any:
|
|
2391
|
+
networkCode = None
|
|
2392
|
+
networkCode, params = self.handle_network_code_and_params(params)
|
|
2393
|
+
networkCode = self.network_id_to_code(networkCode, currency['code'])
|
|
2394
|
+
networkEntry = self.safe_dict(currency['networks'], networkCode)
|
|
2395
|
+
if networkEntry is None:
|
|
2396
|
+
supportedNetworks = list(currency['networks'].keys())
|
|
2397
|
+
raise BadRequest(self.id + ' can not determine a network code, please provide unified "network" param, one from the following: ' + self.json(supportedNetworks))
|
|
2398
|
+
currentyNetworkId = self.safe_string(networkEntry, 'currencyNetworkId')
|
|
2399
|
+
return [currentyNetworkId, params]
|
|
2400
|
+
|
|
2401
|
+
def parse_deposit_address(self, depositEntry, currency: Currency = None) -> DepositAddress:
|
|
2402
|
+
address = self.safe_string(depositEntry, 'address')
|
|
1904
2403
|
self.check_address(address)
|
|
1905
2404
|
return {
|
|
1906
|
-
'
|
|
2405
|
+
'info': depositEntry,
|
|
2406
|
+
'currency': self.safe_string(currency, 'code'),
|
|
2407
|
+
'network': None,
|
|
1907
2408
|
'address': address,
|
|
1908
|
-
'tag':
|
|
1909
|
-
'network': networkCode,
|
|
1910
|
-
'info': response,
|
|
2409
|
+
'tag': self.safe_string(depositEntry, 'extra'),
|
|
1911
2410
|
}
|
|
1912
2411
|
|
|
1913
2412
|
async def get_asset_history_rows(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> Any:
|
|
@@ -1916,91 +2415,123 @@ class woo(Exchange, ImplicitAPI):
|
|
|
1916
2415
|
currency: Currency = None
|
|
1917
2416
|
if code is not None:
|
|
1918
2417
|
currency = self.currency(code)
|
|
1919
|
-
request['
|
|
2418
|
+
request['token'] = currency['id']
|
|
2419
|
+
networkCode = None
|
|
2420
|
+
networkCode, params = self.handle_network_code_and_params(params)
|
|
2421
|
+
if networkCode is not None:
|
|
2422
|
+
request['network'] = self.network_code_to_id(networkCode)
|
|
1920
2423
|
if since is not None:
|
|
1921
|
-
request['
|
|
2424
|
+
request['startTime'] = since
|
|
1922
2425
|
if limit is not None:
|
|
1923
|
-
request['
|
|
2426
|
+
request['size'] = min(limit, 1000)
|
|
1924
2427
|
transactionType = self.safe_string(params, 'type')
|
|
1925
2428
|
params = self.omit(params, 'type')
|
|
1926
2429
|
if transactionType is not None:
|
|
1927
2430
|
request['type'] = transactionType
|
|
1928
|
-
response = await self.
|
|
1929
|
-
#
|
|
1930
|
-
#
|
|
1931
|
-
#
|
|
1932
|
-
# "
|
|
1933
|
-
#
|
|
1934
|
-
#
|
|
1935
|
-
#
|
|
1936
|
-
#
|
|
1937
|
-
#
|
|
1938
|
-
#
|
|
1939
|
-
#
|
|
1940
|
-
#
|
|
1941
|
-
#
|
|
1942
|
-
#
|
|
1943
|
-
#
|
|
1944
|
-
#
|
|
1945
|
-
#
|
|
1946
|
-
#
|
|
1947
|
-
#
|
|
1948
|
-
#
|
|
1949
|
-
#
|
|
1950
|
-
#
|
|
1951
|
-
#
|
|
1952
|
-
#
|
|
1953
|
-
#
|
|
1954
|
-
#
|
|
1955
|
-
#
|
|
1956
|
-
#
|
|
1957
|
-
#
|
|
1958
|
-
#
|
|
1959
|
-
#
|
|
1960
|
-
#
|
|
1961
|
-
#
|
|
1962
|
-
#
|
|
1963
|
-
|
|
2431
|
+
response = await self.v3PrivateGetAssetWalletHistory(self.extend(request, params))
|
|
2432
|
+
#
|
|
2433
|
+
# {
|
|
2434
|
+
# "success": True,
|
|
2435
|
+
# "data": {
|
|
2436
|
+
# "rows": [
|
|
2437
|
+
# {
|
|
2438
|
+
# "createdTime": "1734964440.523",
|
|
2439
|
+
# "updatedTime": "1734964614.081",
|
|
2440
|
+
# "id": "24122314340000585",
|
|
2441
|
+
# "externalId": "241223143600621",
|
|
2442
|
+
# "applicationId": "251bf5c4-f3c8-4544-bb8b-80001007c3c0",
|
|
2443
|
+
# "token": "ARB_USDCNATIVE",
|
|
2444
|
+
# "targetAddress": "0x4d6802d2736daa85e6242ef0dc0f00aa0e68f635",
|
|
2445
|
+
# "sourceAddress": "0x63DFE4e34A3bFC00eB0220786238a7C6cEF8Ffc4",
|
|
2446
|
+
# "extra": "",
|
|
2447
|
+
# "type": "BALANCE",
|
|
2448
|
+
# "tokenSide": "WITHDRAW",
|
|
2449
|
+
# "amount": "10.00000000",
|
|
2450
|
+
# "txId": "0x891ade0a47fd55466bb9d06702bea4edcb75ed9367d9afbc47b93a84f496d2e6",
|
|
2451
|
+
# "feeToken": "USDC",
|
|
2452
|
+
# "feeAmount": "2",
|
|
2453
|
+
# "status": "COMPLETED",
|
|
2454
|
+
# "confirmingThreshold": null,
|
|
2455
|
+
# "confirmedNumber": null
|
|
2456
|
+
# }
|
|
2457
|
+
# ],
|
|
2458
|
+
# "meta": {
|
|
2459
|
+
# "total": 1,
|
|
2460
|
+
# "records_per_page": 25,
|
|
2461
|
+
# "current_page": 1
|
|
2462
|
+
# }
|
|
2463
|
+
# },
|
|
2464
|
+
# "timestamp": 1752485344719
|
|
2465
|
+
# }
|
|
2466
|
+
#
|
|
2467
|
+
data = self.safe_dict(response, 'data', {})
|
|
2468
|
+
return [currency, self.safe_list(data, 'rows', [])]
|
|
1964
2469
|
|
|
1965
|
-
async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
|
|
2470
|
+
async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
|
|
1966
2471
|
"""
|
|
1967
2472
|
fetch the history of changes, actions done by the user or operations that altered balance of the user
|
|
1968
|
-
|
|
1969
|
-
|
|
2473
|
+
|
|
2474
|
+
https://developer.woox.io/api-reference/endpoint/assets/get_wallet_history
|
|
2475
|
+
|
|
2476
|
+
:param str [code]: unified currency code, default is None
|
|
1970
2477
|
:param int [since]: timestamp in ms of the earliest ledger entry, default is None
|
|
1971
|
-
:param int [limit]: max number of ledger
|
|
2478
|
+
:param int [limit]: max number of ledger entries to return, default is None
|
|
1972
2479
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1973
|
-
:returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger
|
|
2480
|
+
:returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger>`
|
|
1974
2481
|
"""
|
|
1975
|
-
|
|
2482
|
+
currencyRows = await self.get_asset_history_rows(code, since, limit, params)
|
|
2483
|
+
currency = self.safe_value(currencyRows, 0)
|
|
2484
|
+
rows = self.safe_list(currencyRows, 1)
|
|
1976
2485
|
return self.parse_ledger(rows, currency, since, limit, params)
|
|
1977
2486
|
|
|
1978
|
-
def parse_ledger_entry(self, item: dict, currency: Currency = None):
|
|
2487
|
+
def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
|
|
2488
|
+
#
|
|
2489
|
+
# {
|
|
2490
|
+
# "createdTime": "1734964440.523",
|
|
2491
|
+
# "updatedTime": "1734964614.081",
|
|
2492
|
+
# "id": "24122314340000585",
|
|
2493
|
+
# "externalId": "241223143600621",
|
|
2494
|
+
# "applicationId": "251bf5c4-f3c8-4544-bb8b-80001007c3c0",
|
|
2495
|
+
# "token": "ARB_USDCNATIVE",
|
|
2496
|
+
# "targetAddress": "0x4d6802d2736daa85e6242ef0dc0f00aa0e68f635",
|
|
2497
|
+
# "sourceAddress": "0x63DFE4e34A3bFC00eB0220786238a7C6cEF8Ffc4",
|
|
2498
|
+
# "extra": "",
|
|
2499
|
+
# "type": "BALANCE",
|
|
2500
|
+
# "tokenSide": "WITHDRAW",
|
|
2501
|
+
# "amount": "10.00000000",
|
|
2502
|
+
# "txId": "0x891ade0a47fd55466bb9d06702bea4edcb75ed9367d9afbc47b93a84f496d2e6",
|
|
2503
|
+
# "feeToken": "USDC",
|
|
2504
|
+
# "feeAmount": "2",
|
|
2505
|
+
# "status": "COMPLETED",
|
|
2506
|
+
# "confirmingThreshold": null,
|
|
2507
|
+
# "confirmedNumber": null
|
|
2508
|
+
# }
|
|
2509
|
+
#
|
|
1979
2510
|
networkizedCode = self.safe_string(item, 'token')
|
|
1980
|
-
|
|
1981
|
-
|
|
2511
|
+
code = self.safe_currency_code(networkizedCode, currency)
|
|
2512
|
+
currency = self.safe_currency(code, currency)
|
|
1982
2513
|
amount = self.safe_number(item, 'amount')
|
|
1983
|
-
side = self.safe_string(item, '
|
|
2514
|
+
side = self.safe_string(item, 'tokenSide')
|
|
1984
2515
|
direction = 'in' if (side == 'DEPOSIT') else 'out'
|
|
1985
|
-
timestamp = self.safe_timestamp(item, '
|
|
1986
|
-
fee = self.parse_token_and_fee_temp(item, '
|
|
1987
|
-
return {
|
|
2516
|
+
timestamp = self.safe_timestamp(item, 'createdTime')
|
|
2517
|
+
fee = self.parse_token_and_fee_temp(item, ['feeToken'], ['feeAmount'])
|
|
2518
|
+
return self.safe_ledger_entry({
|
|
2519
|
+
'info': item,
|
|
1988
2520
|
'id': self.safe_string(item, 'id'),
|
|
1989
2521
|
'currency': code,
|
|
1990
2522
|
'account': self.safe_string(item, 'account'),
|
|
1991
2523
|
'referenceAccount': None,
|
|
1992
|
-
'referenceId': self.safe_string(item, '
|
|
2524
|
+
'referenceId': self.safe_string(item, 'txId'),
|
|
1993
2525
|
'status': self.parse_transaction_status(self.safe_string(item, 'status')),
|
|
1994
2526
|
'amount': amount,
|
|
1995
2527
|
'before': None,
|
|
1996
2528
|
'after': None,
|
|
1997
|
-
'fee': fee,
|
|
1998
2529
|
'direction': direction,
|
|
1999
2530
|
'timestamp': timestamp,
|
|
2000
2531
|
'datetime': self.iso8601(timestamp),
|
|
2001
2532
|
'type': self.parse_ledger_entry_type(self.safe_string(item, 'type')),
|
|
2002
|
-
'
|
|
2003
|
-
}
|
|
2533
|
+
'fee': fee,
|
|
2534
|
+
}, currency)
|
|
2004
2535
|
|
|
2005
2536
|
def parse_ledger_entry_type(self, type):
|
|
2006
2537
|
types: dict = {
|
|
@@ -2025,7 +2556,9 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2025
2556
|
async def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
|
|
2026
2557
|
"""
|
|
2027
2558
|
fetch all deposits made to an account
|
|
2028
|
-
|
|
2559
|
+
|
|
2560
|
+
https://developer.woox.io/api-reference/endpoint/assets/get_wallet_history
|
|
2561
|
+
|
|
2029
2562
|
:param str code: unified currency code
|
|
2030
2563
|
:param int [since]: the earliest time in ms to fetch deposits for
|
|
2031
2564
|
:param int [limit]: the maximum number of deposits structures to retrieve
|
|
@@ -2033,14 +2566,16 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2033
2566
|
:returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
|
|
2034
2567
|
"""
|
|
2035
2568
|
request: dict = {
|
|
2036
|
-
'
|
|
2569
|
+
'tokenSide': 'DEPOSIT',
|
|
2037
2570
|
}
|
|
2038
2571
|
return await self.fetch_deposits_withdrawals(code, since, limit, self.extend(request, params))
|
|
2039
2572
|
|
|
2040
2573
|
async def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
|
|
2041
2574
|
"""
|
|
2042
2575
|
fetch all withdrawals made from an account
|
|
2043
|
-
|
|
2576
|
+
|
|
2577
|
+
https://developer.woox.io/api-reference/endpoint/assets/get_wallet_history
|
|
2578
|
+
|
|
2044
2579
|
:param str code: unified currency code
|
|
2045
2580
|
:param int [since]: the earliest time in ms to fetch withdrawals for
|
|
2046
2581
|
:param int [limit]: the maximum number of withdrawals structures to retrieve
|
|
@@ -2048,14 +2583,16 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2048
2583
|
:returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
|
|
2049
2584
|
"""
|
|
2050
2585
|
request: dict = {
|
|
2051
|
-
'
|
|
2586
|
+
'tokenSide': 'WITHDRAW',
|
|
2052
2587
|
}
|
|
2053
2588
|
return await self.fetch_deposits_withdrawals(code, since, limit, self.extend(request, params))
|
|
2054
2589
|
|
|
2055
2590
|
async def fetch_deposits_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
|
|
2056
2591
|
"""
|
|
2057
2592
|
fetch history of deposits and withdrawals
|
|
2058
|
-
|
|
2593
|
+
|
|
2594
|
+
https://developer.woox.io/api-reference/endpoint/assets/get_wallet_history
|
|
2595
|
+
|
|
2059
2596
|
:param str [code]: unified currency code for the currency of the deposit/withdrawals, default is None
|
|
2060
2597
|
:param int [since]: timestamp in ms of the earliest deposit/withdrawal, default is None
|
|
2061
2598
|
:param int [limit]: max number of deposit/withdrawals to return, default is None
|
|
@@ -2065,36 +2602,48 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2065
2602
|
request: dict = {
|
|
2066
2603
|
'type': 'BALANCE',
|
|
2067
2604
|
}
|
|
2068
|
-
|
|
2605
|
+
currencyRows = await self.get_asset_history_rows(code, since, limit, self.extend(request, params))
|
|
2606
|
+
currency = self.safe_value(currencyRows, 0)
|
|
2607
|
+
rows = self.safe_list(currencyRows, 1)
|
|
2608
|
+
return self.parse_transactions(rows, currency, since, limit, params)
|
|
2609
|
+
|
|
2610
|
+
def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
|
|
2069
2611
|
#
|
|
2070
2612
|
# {
|
|
2071
|
-
# "
|
|
2072
|
-
# "
|
|
2073
|
-
#
|
|
2074
|
-
#
|
|
2075
|
-
#
|
|
2076
|
-
#
|
|
2077
|
-
# "
|
|
2613
|
+
# "createdTime": "1734964440.523",
|
|
2614
|
+
# "updatedTime": "1734964614.081",
|
|
2615
|
+
# "id": "24122314340000585",
|
|
2616
|
+
# "externalId": "241223143600621",
|
|
2617
|
+
# "applicationId": "251bf5c4-f3c8-4544-bb8b-80001007c3c0",
|
|
2618
|
+
# "token": "ARB_USDCNATIVE",
|
|
2619
|
+
# "targetAddress": "0x4d6802d2736daa85e6242ef0dc0f00aa0e68f635",
|
|
2620
|
+
# "sourceAddress": "0x63DFE4e34A3bFC00eB0220786238a7C6cEF8Ffc4",
|
|
2621
|
+
# "extra": "",
|
|
2622
|
+
# "type": "BALANCE",
|
|
2623
|
+
# "tokenSide": "WITHDRAW",
|
|
2624
|
+
# "amount": "10.00000000",
|
|
2625
|
+
# "txId": "0x891ade0a47fd55466bb9d06702bea4edcb75ed9367d9afbc47b93a84f496d2e6",
|
|
2626
|
+
# "feeToken": "USDC",
|
|
2627
|
+
# "feeAmount": "2",
|
|
2628
|
+
# "status": "COMPLETED",
|
|
2629
|
+
# "confirmingThreshold": null,
|
|
2630
|
+
# "confirmedNumber": null
|
|
2078
2631
|
# }
|
|
2079
2632
|
#
|
|
2080
|
-
return self.parse_transactions(rows, currency, since, limit, params)
|
|
2081
|
-
|
|
2082
|
-
def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
|
|
2083
|
-
# example in fetchLedger
|
|
2084
2633
|
networkizedCode = self.safe_string(transaction, 'token')
|
|
2085
2634
|
currencyDefined = self.get_currency_from_chaincode(networkizedCode, currency)
|
|
2086
2635
|
code = currencyDefined['code']
|
|
2087
|
-
movementDirection = self.
|
|
2636
|
+
movementDirection = self.safe_string_lower_2(transaction, 'token_side', 'tokenSide')
|
|
2088
2637
|
if movementDirection == 'withdraw':
|
|
2089
2638
|
movementDirection = 'withdrawal'
|
|
2090
|
-
fee = self.parse_token_and_fee_temp(transaction, 'fee_token', 'fee_amount')
|
|
2091
|
-
addressTo = self.
|
|
2092
|
-
addressFrom = self.
|
|
2093
|
-
timestamp = self.
|
|
2639
|
+
fee = self.parse_token_and_fee_temp(transaction, ['fee_token', 'feeToken'], ['fee_amount', 'feeAmount'])
|
|
2640
|
+
addressTo = self.safe_string_2(transaction, 'target_address', 'targetAddress')
|
|
2641
|
+
addressFrom = self.safe_string_2(transaction, 'source_address', 'sourceAddress')
|
|
2642
|
+
timestamp = self.safe_timestamp_2(transaction, 'created_time', 'createdTime')
|
|
2094
2643
|
return {
|
|
2095
2644
|
'info': transaction,
|
|
2096
|
-
'id': self.
|
|
2097
|
-
'txid': self.
|
|
2645
|
+
'id': self.safe_string_n(transaction, ['id', 'withdraw_id', 'withdrawId']),
|
|
2646
|
+
'txid': self.safe_string_2(transaction, 'tx_id', 'txId'),
|
|
2098
2647
|
'timestamp': timestamp,
|
|
2099
2648
|
'datetime': self.iso8601(timestamp),
|
|
2100
2649
|
'address': None,
|
|
@@ -2107,7 +2656,7 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2107
2656
|
'amount': self.safe_number(transaction, 'amount'),
|
|
2108
2657
|
'currency': code,
|
|
2109
2658
|
'status': self.parse_transaction_status(self.safe_string(transaction, 'status')),
|
|
2110
|
-
'updated': self.
|
|
2659
|
+
'updated': self.safe_timestamp_2(transaction, 'updated_time', 'updatedTime'),
|
|
2111
2660
|
'comment': None,
|
|
2112
2661
|
'internal': None,
|
|
2113
2662
|
'fee': fee,
|
|
@@ -2127,7 +2676,9 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2127
2676
|
async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
|
|
2128
2677
|
"""
|
|
2129
2678
|
transfer currency internally between wallets on the same account
|
|
2130
|
-
|
|
2679
|
+
|
|
2680
|
+
https://docs.woox.io/#get-transfer-history
|
|
2681
|
+
|
|
2131
2682
|
:param str code: unified currency code
|
|
2132
2683
|
:param float amount: amount to transfer
|
|
2133
2684
|
:param str fromAccount: account to transfer from
|
|
@@ -2159,10 +2710,12 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2159
2710
|
transfer['toAccount'] = toAccount
|
|
2160
2711
|
return transfer
|
|
2161
2712
|
|
|
2162
|
-
async def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}) ->
|
|
2713
|
+
async def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[TransferEntry]:
|
|
2163
2714
|
"""
|
|
2164
2715
|
fetch a history of internal transfers made on an account
|
|
2165
|
-
|
|
2716
|
+
|
|
2717
|
+
https://developer.woox.io/api-reference/endpoint/assets/get_transfer_history
|
|
2718
|
+
|
|
2166
2719
|
:param str code: unified currency code of the currency transferred
|
|
2167
2720
|
:param int [since]: the earliest time in ms to fetch transfers for
|
|
2168
2721
|
:param int [limit]: the maximum number of transfers structures to retrieve
|
|
@@ -2171,41 +2724,52 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2171
2724
|
:returns dict[]: a list of `transfer structures <https://docs.ccxt.com/#/?id=transfer-structure>`
|
|
2172
2725
|
"""
|
|
2173
2726
|
request: dict = {}
|
|
2727
|
+
currency = None
|
|
2728
|
+
if code is not None:
|
|
2729
|
+
currency = self.currency(code)
|
|
2174
2730
|
if limit is not None:
|
|
2175
2731
|
request['size'] = limit
|
|
2176
2732
|
if since is not None:
|
|
2177
|
-
request['
|
|
2733
|
+
request['startTime'] = since
|
|
2178
2734
|
until = self.safe_integer(params, 'until') # unified in milliseconds
|
|
2179
2735
|
params = self.omit(params, ['until'])
|
|
2180
2736
|
if until is not None:
|
|
2181
|
-
request['
|
|
2182
|
-
response = await self.
|
|
2737
|
+
request['endTime'] = until
|
|
2738
|
+
response = await self.v3PrivateGetAssetTransferHistory(self.extend(request, params))
|
|
2183
2739
|
#
|
|
2184
2740
|
# {
|
|
2185
|
-
# "
|
|
2186
|
-
#
|
|
2187
|
-
#
|
|
2188
|
-
#
|
|
2189
|
-
#
|
|
2190
|
-
#
|
|
2191
|
-
#
|
|
2192
|
-
#
|
|
2193
|
-
#
|
|
2194
|
-
#
|
|
2195
|
-
#
|
|
2196
|
-
#
|
|
2741
|
+
# "success": True,
|
|
2742
|
+
# "data": {
|
|
2743
|
+
# "rows": [
|
|
2744
|
+
# {
|
|
2745
|
+
# "id": 225,
|
|
2746
|
+
# "token": "USDT",
|
|
2747
|
+
# "amount": "1000000",
|
|
2748
|
+
# "status": "COMPLETED",
|
|
2749
|
+
# "from": {
|
|
2750
|
+
# "applicationId": "046b5c5c-5b44-4d27-9593-ddc32c0a08ae",
|
|
2751
|
+
# "accountName": "Main"
|
|
2752
|
+
# },
|
|
2753
|
+
# "to": {
|
|
2754
|
+
# "applicationId": "082ae5ae-e26a-4fb1-be5b-03e5b4867663",
|
|
2755
|
+
# "accountName": "sub001"
|
|
2756
|
+
# },
|
|
2757
|
+
# "createdTime": "1642660941.534",
|
|
2758
|
+
# "updatedTime": "1642660941.950"
|
|
2759
|
+
# }
|
|
2760
|
+
# ],
|
|
2761
|
+
# "meta": {
|
|
2762
|
+
# "total": 46,
|
|
2763
|
+
# "recordsPerPage": 1,
|
|
2764
|
+
# "currentPage": 1
|
|
2197
2765
|
# }
|
|
2198
|
-
# ],
|
|
2199
|
-
# "meta": {
|
|
2200
|
-
# "total": 50,
|
|
2201
|
-
# "records_per_page": 25,
|
|
2202
|
-
# "current_page": 1
|
|
2203
2766
|
# },
|
|
2204
|
-
# "
|
|
2767
|
+
# "timestamp": 1721295317627
|
|
2205
2768
|
# }
|
|
2206
2769
|
#
|
|
2207
|
-
data = self.
|
|
2208
|
-
|
|
2770
|
+
data = self.safe_dict(response, 'data', {})
|
|
2771
|
+
rows = self.safe_list(data, 'rows', [])
|
|
2772
|
+
return self.parse_transfers(rows, currency, since, limit, params)
|
|
2209
2773
|
|
|
2210
2774
|
def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
|
|
2211
2775
|
#
|
|
@@ -2222,6 +2786,22 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2222
2786
|
# "created_time": "1709022325.427",
|
|
2223
2787
|
# "updated_time": "1709022325.542"
|
|
2224
2788
|
# }
|
|
2789
|
+
# {
|
|
2790
|
+
# "id": 225,
|
|
2791
|
+
# "token": "USDT",
|
|
2792
|
+
# "amount": "1000000",
|
|
2793
|
+
# "status": "COMPLETED",
|
|
2794
|
+
# "from": {
|
|
2795
|
+
# "applicationId": "046b5c5c-5b44-4d27-9593-ddc32c0a08ae",
|
|
2796
|
+
# "accountName": "Main"
|
|
2797
|
+
# },
|
|
2798
|
+
# "to": {
|
|
2799
|
+
# "applicationId": "082ae5ae-e26a-4fb1-be5b-03e5b4867663",
|
|
2800
|
+
# "accountName": "sub001"
|
|
2801
|
+
# },
|
|
2802
|
+
# "createdTime": "1642660941.534",
|
|
2803
|
+
# "updatedTime": "1642660941.950"
|
|
2804
|
+
# }
|
|
2225
2805
|
#
|
|
2226
2806
|
# transfer
|
|
2227
2807
|
# {
|
|
@@ -2229,22 +2809,22 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2229
2809
|
# "id": 200
|
|
2230
2810
|
# }
|
|
2231
2811
|
#
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
code = currencyDefined['code']
|
|
2235
|
-
timestamp = self.safe_timestamp(transfer, 'created_time')
|
|
2812
|
+
code = self.safe_currency_code(self.safe_string(transfer, 'token'), currency)
|
|
2813
|
+
timestamp = self.safe_timestamp(transfer, 'createdTime')
|
|
2236
2814
|
success = self.safe_bool(transfer, 'success')
|
|
2237
2815
|
status: Str = None
|
|
2238
2816
|
if success is not None:
|
|
2239
2817
|
status = 'ok' if success else 'failed'
|
|
2818
|
+
fromAccount = self.safe_dict(transfer, 'from', {})
|
|
2819
|
+
toAccount = self.safe_dict(transfer, 'to', {})
|
|
2240
2820
|
return {
|
|
2241
2821
|
'id': self.safe_string(transfer, 'id'),
|
|
2242
2822
|
'timestamp': timestamp,
|
|
2243
2823
|
'datetime': self.iso8601(timestamp),
|
|
2244
2824
|
'currency': code,
|
|
2245
2825
|
'amount': self.safe_number(transfer, 'amount'),
|
|
2246
|
-
'fromAccount': self.safe_string(
|
|
2247
|
-
'toAccount': self.safe_string(
|
|
2826
|
+
'fromAccount': self.safe_string(fromAccount, 'applicationId'),
|
|
2827
|
+
'toAccount': self.safe_string(toAccount, 'applicationId'),
|
|
2248
2828
|
'status': self.parse_transfer_status(self.safe_string(transfer, 'status', status)),
|
|
2249
2829
|
'info': transfer,
|
|
2250
2830
|
}
|
|
@@ -2259,10 +2839,12 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2259
2839
|
}
|
|
2260
2840
|
return self.safe_string(statuses, status, status)
|
|
2261
2841
|
|
|
2262
|
-
async def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
|
|
2842
|
+
async def withdraw(self, code: str, amount: float, address: str, tag: Str = None, params={}) -> Transaction:
|
|
2263
2843
|
"""
|
|
2264
2844
|
make a withdrawal
|
|
2265
|
-
|
|
2845
|
+
|
|
2846
|
+
https://docs.woox.io/#token-withdraw
|
|
2847
|
+
|
|
2266
2848
|
:param str code: unified currency code
|
|
2267
2849
|
:param float amount: the amount to withdraw
|
|
2268
2850
|
:param str address: the address to withdraw to
|
|
@@ -2280,15 +2862,9 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2280
2862
|
}
|
|
2281
2863
|
if tag is not None:
|
|
2282
2864
|
request['extra'] = tag
|
|
2283
|
-
|
|
2284
|
-
|
|
2285
|
-
|
|
2286
|
-
networkId = self.safe_string(networks, network, network)
|
|
2287
|
-
coinNetwork = self.safe_dict(currencyNetworks, networkId, {})
|
|
2288
|
-
coinNetworkId = self.safe_string(coinNetwork, 'id')
|
|
2289
|
-
if coinNetworkId is None:
|
|
2290
|
-
raise BadRequest(self.id + ' withdraw() require network parameter')
|
|
2291
|
-
request['token'] = coinNetworkId
|
|
2865
|
+
specialNetworkId: Str = None
|
|
2866
|
+
specialNetworkId, params = self.get_dedicated_network_id(currency, params)
|
|
2867
|
+
request['token'] = specialNetworkId
|
|
2292
2868
|
response = await self.v1PrivatePostAssetWithdraw(self.extend(request, params))
|
|
2293
2869
|
#
|
|
2294
2870
|
# {
|
|
@@ -2298,10 +2874,12 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2298
2874
|
#
|
|
2299
2875
|
return self.parse_transaction(response, currency)
|
|
2300
2876
|
|
|
2301
|
-
async def repay_margin(self, code: str, amount, symbol: Str = None, params={}):
|
|
2877
|
+
async def repay_margin(self, code: str, amount: float, symbol: Str = None, params={}):
|
|
2302
2878
|
"""
|
|
2303
2879
|
repay borrowed margin and interest
|
|
2304
|
-
|
|
2880
|
+
|
|
2881
|
+
https://docs.woox.io/#repay-interest
|
|
2882
|
+
|
|
2305
2883
|
:param str code: unified currency code of the currency to repay
|
|
2306
2884
|
:param float amount: the amount to repay
|
|
2307
2885
|
:param str symbol: not used by woo.repayMargin()
|
|
@@ -2347,7 +2925,7 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2347
2925
|
}
|
|
2348
2926
|
|
|
2349
2927
|
def nonce(self):
|
|
2350
|
-
return self.milliseconds()
|
|
2928
|
+
return self.milliseconds() - self.options['timeDifference']
|
|
2351
2929
|
|
|
2352
2930
|
def sign(self, path, section='public', method='GET', params={}, headers=None, body=None):
|
|
2353
2931
|
version = section[0]
|
|
@@ -2361,15 +2939,19 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2361
2939
|
url += access + '/' + pathWithParams
|
|
2362
2940
|
if params:
|
|
2363
2941
|
url += '?' + self.urlencode(params)
|
|
2942
|
+
elif access == 'pub':
|
|
2943
|
+
url += pathWithParams
|
|
2944
|
+
if params:
|
|
2945
|
+
url += '?' + self.urlencode(params)
|
|
2364
2946
|
else:
|
|
2365
2947
|
self.check_required_credentials()
|
|
2366
|
-
if method == 'POST' and (path == '
|
|
2948
|
+
if method == 'POST' and (path == 'trade/algoOrder' or path == 'trade/order'):
|
|
2367
2949
|
isSandboxMode = self.safe_bool(self.options, 'sandboxMode', False)
|
|
2368
2950
|
if not isSandboxMode:
|
|
2369
2951
|
applicationId = 'bc830de7-50f3-460b-9ee0-f430f83f9dad'
|
|
2370
2952
|
brokerId = self.safe_string(self.options, 'brokerId', applicationId)
|
|
2371
|
-
|
|
2372
|
-
if
|
|
2953
|
+
isTrigger = path.find('algo') > -1
|
|
2954
|
+
if isTrigger:
|
|
2373
2955
|
params['brokerId'] = brokerId
|
|
2374
2956
|
else:
|
|
2375
2957
|
params['broker_id'] = brokerId
|
|
@@ -2383,15 +2965,15 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2383
2965
|
}
|
|
2384
2966
|
if version == 'v3':
|
|
2385
2967
|
auth = ts + method + '/' + version + '/' + pathWithParams
|
|
2386
|
-
if method == 'POST' or method == 'PUT'
|
|
2968
|
+
if method == 'POST' or method == 'PUT':
|
|
2387
2969
|
body = self.json(params)
|
|
2388
2970
|
auth += body
|
|
2971
|
+
headers['content-type'] = 'application/json'
|
|
2389
2972
|
else:
|
|
2390
2973
|
if params:
|
|
2391
2974
|
query = self.urlencode(params)
|
|
2392
2975
|
url += '?' + query
|
|
2393
2976
|
auth += '?' + query
|
|
2394
|
-
headers['content-type'] = 'application/json'
|
|
2395
2977
|
else:
|
|
2396
2978
|
auth = self.urlencode(params)
|
|
2397
2979
|
if method == 'POST' or method == 'PUT' or method == 'DELETE':
|
|
@@ -2422,24 +3004,27 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2422
3004
|
def parse_income(self, income, market: Market = None):
|
|
2423
3005
|
#
|
|
2424
3006
|
# {
|
|
2425
|
-
# "id":
|
|
2426
|
-
# "symbol":"PERP_BTC_USDT",
|
|
2427
|
-
# "
|
|
2428
|
-
# "
|
|
2429
|
-
# "
|
|
2430
|
-
# "
|
|
2431
|
-
# "
|
|
2432
|
-
# "
|
|
2433
|
-
# "
|
|
3007
|
+
# "id": 1286360,
|
|
3008
|
+
# "symbol": "PERP_BTC_USDT",
|
|
3009
|
+
# "fundingRate": -0.00001445,
|
|
3010
|
+
# "markPrice": "26930.60000000",
|
|
3011
|
+
# "fundingFee": "9.56021744",
|
|
3012
|
+
# "fundingIntervalHours": 8,
|
|
3013
|
+
# "paymentType": "Pay",
|
|
3014
|
+
# "status": "COMPLETED",
|
|
3015
|
+
# "createdTime": 1696060873259,
|
|
3016
|
+
# "updatedTime": 1696060873286
|
|
2434
3017
|
# }
|
|
2435
3018
|
#
|
|
2436
3019
|
marketId = self.safe_string(income, 'symbol')
|
|
2437
3020
|
symbol = self.safe_symbol(marketId, market)
|
|
2438
|
-
amount = self.
|
|
3021
|
+
amount = self.safe_string(income, 'fundingFee')
|
|
2439
3022
|
code = self.safe_currency_code('USD')
|
|
2440
3023
|
id = self.safe_string(income, 'id')
|
|
2441
|
-
timestamp = self.
|
|
2442
|
-
rate = self.safe_number(income, '
|
|
3024
|
+
timestamp = self.safe_integer(income, 'updatedTime')
|
|
3025
|
+
rate = self.safe_number(income, 'fundingRate')
|
|
3026
|
+
paymentType = self.safe_string(income, 'paymentType')
|
|
3027
|
+
amount = Precise.string_neg(amount) if (paymentType == 'Pay') else amount
|
|
2443
3028
|
return {
|
|
2444
3029
|
'info': income,
|
|
2445
3030
|
'symbol': symbol,
|
|
@@ -2447,63 +3032,92 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2447
3032
|
'timestamp': timestamp,
|
|
2448
3033
|
'datetime': self.iso8601(timestamp),
|
|
2449
3034
|
'id': id,
|
|
2450
|
-
'amount': amount,
|
|
3035
|
+
'amount': self.parse_number(amount),
|
|
2451
3036
|
'rate': rate,
|
|
2452
3037
|
}
|
|
2453
3038
|
|
|
2454
3039
|
async def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
|
3040
|
+
"""
|
|
3041
|
+
fetch the history of funding payments paid and received on self account
|
|
3042
|
+
|
|
3043
|
+
https://developer.woox.io/api-reference/endpoint/futures/get_fundingFee_history
|
|
3044
|
+
|
|
3045
|
+
:param str [symbol]: unified market symbol
|
|
3046
|
+
:param int [since]: the earliest time in ms to fetch funding history for
|
|
3047
|
+
:param int [limit]: the maximum number of funding history structures to retrieve
|
|
3048
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
3049
|
+
:param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
|
|
3050
|
+
:returns dict: a `funding history structure <https://docs.ccxt.com/#/?id=funding-history-structure>`
|
|
3051
|
+
"""
|
|
2455
3052
|
await self.load_markets()
|
|
3053
|
+
paginate = False
|
|
3054
|
+
paginate, params = self.handle_option_and_params(params, 'fetchFundingHistory', 'paginate')
|
|
3055
|
+
if paginate:
|
|
3056
|
+
return await self.fetch_paginated_call_incremental('fetchFundingHistory', symbol, since, limit, params, 'page', 500)
|
|
2456
3057
|
request: dict = {}
|
|
2457
3058
|
market: Market = None
|
|
2458
3059
|
if symbol is not None:
|
|
2459
3060
|
market = self.market(symbol)
|
|
2460
3061
|
request['symbol'] = market['id']
|
|
2461
3062
|
if since is not None:
|
|
2462
|
-
request['
|
|
2463
|
-
|
|
3063
|
+
request['startTime'] = since
|
|
3064
|
+
until = self.safe_integer(params, 'until') # unified in milliseconds
|
|
3065
|
+
params = self.omit(params, ['until'])
|
|
3066
|
+
if until is not None:
|
|
3067
|
+
request['endTime'] = until
|
|
3068
|
+
if limit is not None:
|
|
3069
|
+
request['size'] = min(limit, 500)
|
|
3070
|
+
response = await self.v3PrivateGetFuturesFundingFeeHistory(self.extend(request, params))
|
|
2464
3071
|
#
|
|
2465
3072
|
# {
|
|
2466
|
-
# "
|
|
2467
|
-
#
|
|
2468
|
-
#
|
|
2469
|
-
# "
|
|
2470
|
-
# "
|
|
2471
|
-
# "
|
|
2472
|
-
#
|
|
2473
|
-
#
|
|
2474
|
-
#
|
|
2475
|
-
#
|
|
2476
|
-
#
|
|
2477
|
-
#
|
|
2478
|
-
#
|
|
2479
|
-
#
|
|
2480
|
-
#
|
|
2481
|
-
#
|
|
2482
|
-
#
|
|
3073
|
+
# "success": True,
|
|
3074
|
+
# "data": {
|
|
3075
|
+
# "meta": {
|
|
3076
|
+
# "total": 670,
|
|
3077
|
+
# "recordsPerPage": 25,
|
|
3078
|
+
# "currentPage": 1
|
|
3079
|
+
# },
|
|
3080
|
+
# "rows": [
|
|
3081
|
+
# {
|
|
3082
|
+
# "id": 1286360,
|
|
3083
|
+
# "symbol": "PERP_BTC_USDT",
|
|
3084
|
+
# "fundingRate": -0.00001445,
|
|
3085
|
+
# "markPrice": "26930.60000000",
|
|
3086
|
+
# "fundingFee": "9.56021744",
|
|
3087
|
+
# "fundingIntervalHours": 8,
|
|
3088
|
+
# "paymentType": "Pay",
|
|
3089
|
+
# "status": "COMPLETED",
|
|
3090
|
+
# "createdTime": 1696060873259,
|
|
3091
|
+
# "updatedTime": 1696060873286
|
|
3092
|
+
# }
|
|
3093
|
+
# ]
|
|
2483
3094
|
# },
|
|
2484
|
-
# "
|
|
3095
|
+
# "timestamp": 1721351502594
|
|
2485
3096
|
# }
|
|
2486
3097
|
#
|
|
2487
|
-
|
|
2488
|
-
|
|
3098
|
+
data = self.safe_dict(response, 'data', {})
|
|
3099
|
+
rows = self.safe_list(data, 'rows', [])
|
|
3100
|
+
return self.parse_incomes(rows, market, since, limit)
|
|
2489
3101
|
|
|
2490
|
-
def parse_funding_rate(self, fundingRate, market: Market = None):
|
|
2491
|
-
#
|
|
2492
|
-
# {
|
|
2493
|
-
# "symbol":"PERP_AAVE_USDT",
|
|
2494
|
-
# "est_funding_rate":-0.00003447,
|
|
2495
|
-
# "est_funding_rate_timestamp":1653633959001,
|
|
2496
|
-
# "last_funding_rate":-0.00002094,
|
|
2497
|
-
# "last_funding_rate_timestamp":1653631200000,
|
|
2498
|
-
# "next_funding_time":1653634800000
|
|
2499
|
-
# }
|
|
3102
|
+
def parse_funding_rate(self, fundingRate, market: Market = None) -> FundingRate:
|
|
2500
3103
|
#
|
|
3104
|
+
# {
|
|
3105
|
+
# "symbol": "PERP_BTC_USDT",
|
|
3106
|
+
# "estFundingRate": "-0.00000441",
|
|
3107
|
+
# "estFundingRateTimestamp": 1751623979022,
|
|
3108
|
+
# "lastFundingRate": "-0.00004953",
|
|
3109
|
+
# "lastFundingRateTimestamp": 1751616000000,
|
|
3110
|
+
# "nextFundingTime": 1751644800000,
|
|
3111
|
+
# "lastFundingIntervalHours": 8,
|
|
3112
|
+
# "estFundingIntervalHours": 8
|
|
3113
|
+
# }
|
|
2501
3114
|
#
|
|
2502
3115
|
symbol = self.safe_string(fundingRate, 'symbol')
|
|
2503
3116
|
market = self.market(symbol)
|
|
2504
|
-
nextFundingTimestamp = self.safe_integer(fundingRate, '
|
|
2505
|
-
estFundingRateTimestamp = self.safe_integer(fundingRate, '
|
|
2506
|
-
lastFundingRateTimestamp = self.safe_integer(fundingRate, '
|
|
3117
|
+
nextFundingTimestamp = self.safe_integer(fundingRate, 'nextFundingTime')
|
|
3118
|
+
estFundingRateTimestamp = self.safe_integer(fundingRate, 'estFundingRateTimestamp')
|
|
3119
|
+
lastFundingRateTimestamp = self.safe_integer(fundingRate, 'lastFundingRateTimestamp')
|
|
3120
|
+
intervalString = self.safe_string(fundingRate, 'estFundingIntervalHours')
|
|
2507
3121
|
return {
|
|
2508
3122
|
'info': fundingRate,
|
|
2509
3123
|
'symbol': market['symbol'],
|
|
@@ -2513,66 +3127,114 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2513
3127
|
'estimatedSettlePrice': None,
|
|
2514
3128
|
'timestamp': estFundingRateTimestamp,
|
|
2515
3129
|
'datetime': self.iso8601(estFundingRateTimestamp),
|
|
2516
|
-
'fundingRate': self.safe_number(fundingRate, '
|
|
3130
|
+
'fundingRate': self.safe_number(fundingRate, 'estFundingRate'),
|
|
2517
3131
|
'fundingTimestamp': nextFundingTimestamp,
|
|
2518
3132
|
'fundingDatetime': self.iso8601(nextFundingTimestamp),
|
|
2519
3133
|
'nextFundingRate': None,
|
|
2520
3134
|
'nextFundingTimestamp': None,
|
|
2521
3135
|
'nextFundingDatetime': None,
|
|
2522
|
-
'previousFundingRate': self.safe_number(fundingRate, '
|
|
3136
|
+
'previousFundingRate': self.safe_number(fundingRate, 'lastFundingRate'),
|
|
2523
3137
|
'previousFundingTimestamp': lastFundingRateTimestamp,
|
|
2524
3138
|
'previousFundingDatetime': self.iso8601(lastFundingRateTimestamp),
|
|
3139
|
+
'interval': intervalString + 'h',
|
|
2525
3140
|
}
|
|
2526
3141
|
|
|
2527
|
-
async def
|
|
3142
|
+
async def fetch_funding_interval(self, symbol: str, params={}) -> FundingRate:
|
|
3143
|
+
"""
|
|
3144
|
+
fetch the current funding rate interval
|
|
3145
|
+
|
|
3146
|
+
https://developer.woox.io/api-reference/endpoint/public_data/fundingRate
|
|
3147
|
+
|
|
3148
|
+
:param str symbol: unified market symbol
|
|
3149
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
3150
|
+
:returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
|
|
3151
|
+
"""
|
|
3152
|
+
return await self.fetch_funding_rate(symbol, params)
|
|
3153
|
+
|
|
3154
|
+
async def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
|
|
3155
|
+
"""
|
|
3156
|
+
fetch the current funding rate
|
|
3157
|
+
|
|
3158
|
+
https://developer.woox.io/api-reference/endpoint/public_data/fundingRate
|
|
3159
|
+
|
|
3160
|
+
:param str symbol: unified market symbol
|
|
3161
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
3162
|
+
:returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
|
|
3163
|
+
"""
|
|
2528
3164
|
await self.load_markets()
|
|
2529
3165
|
market = self.market(symbol)
|
|
2530
3166
|
request: dict = {
|
|
2531
3167
|
'symbol': market['id'],
|
|
2532
3168
|
}
|
|
2533
|
-
response = await self.
|
|
3169
|
+
response = await self.v3PublicGetFundingRate(self.extend(request, params))
|
|
2534
3170
|
#
|
|
2535
3171
|
# {
|
|
2536
|
-
# "success":
|
|
2537
|
-
# "
|
|
2538
|
-
#
|
|
2539
|
-
#
|
|
2540
|
-
#
|
|
2541
|
-
#
|
|
2542
|
-
#
|
|
2543
|
-
#
|
|
3172
|
+
# "success": True,
|
|
3173
|
+
# "data": {
|
|
3174
|
+
# "rows": [
|
|
3175
|
+
# {
|
|
3176
|
+
# "symbol": "PERP_BTC_USDT",
|
|
3177
|
+
# "estFundingRate": "-0.00000441",
|
|
3178
|
+
# "estFundingRateTimestamp": 1751623979022,
|
|
3179
|
+
# "lastFundingRate": "-0.00004953",
|
|
3180
|
+
# "lastFundingRateTimestamp": 1751616000000,
|
|
3181
|
+
# "nextFundingTime": 1751644800000,
|
|
3182
|
+
# "lastFundingIntervalHours": 8,
|
|
3183
|
+
# "estFundingIntervalHours": 8
|
|
3184
|
+
# }
|
|
3185
|
+
# ]
|
|
3186
|
+
# },
|
|
3187
|
+
# "timestamp": 1751624037798
|
|
2544
3188
|
# }
|
|
2545
3189
|
#
|
|
2546
|
-
|
|
3190
|
+
data = self.safe_dict(response, 'data', {})
|
|
3191
|
+
rows = self.safe_list(data, 'rows', [])
|
|
3192
|
+
first = self.safe_dict(rows, 0, {})
|
|
3193
|
+
return self.parse_funding_rate(first, market)
|
|
3194
|
+
|
|
3195
|
+
async def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
|
|
3196
|
+
"""
|
|
3197
|
+
fetch the funding rate for multiple markets
|
|
3198
|
+
|
|
3199
|
+
https://developer.woox.io/api-reference/endpoint/public_data/fundingRate
|
|
2547
3200
|
|
|
2548
|
-
|
|
3201
|
+
:param str[]|None symbols: list of unified market symbols
|
|
3202
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
3203
|
+
:returns dict[]: a list of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rates-structure>`, indexed by market symbols
|
|
3204
|
+
"""
|
|
2549
3205
|
await self.load_markets()
|
|
2550
3206
|
symbols = self.market_symbols(symbols)
|
|
2551
|
-
response = await self.
|
|
3207
|
+
response = await self.v3PublicGetFundingRate(params)
|
|
2552
3208
|
#
|
|
2553
3209
|
# {
|
|
2554
|
-
# "success":
|
|
2555
|
-
# "
|
|
2556
|
-
#
|
|
2557
|
-
#
|
|
2558
|
-
#
|
|
2559
|
-
#
|
|
2560
|
-
#
|
|
2561
|
-
#
|
|
2562
|
-
#
|
|
2563
|
-
#
|
|
2564
|
-
#
|
|
2565
|
-
#
|
|
3210
|
+
# "success": True,
|
|
3211
|
+
# "data": {
|
|
3212
|
+
# "rows": [
|
|
3213
|
+
# {
|
|
3214
|
+
# "symbol": "PERP_BTC_USDT",
|
|
3215
|
+
# "estFundingRate": "-0.00000441",
|
|
3216
|
+
# "estFundingRateTimestamp": 1751623979022,
|
|
3217
|
+
# "lastFundingRate": "-0.00004953",
|
|
3218
|
+
# "lastFundingRateTimestamp": 1751616000000,
|
|
3219
|
+
# "nextFundingTime": 1751644800000,
|
|
3220
|
+
# "lastFundingIntervalHours": 8,
|
|
3221
|
+
# "estFundingIntervalHours": 8
|
|
3222
|
+
# }
|
|
3223
|
+
# ]
|
|
3224
|
+
# },
|
|
3225
|
+
# "timestamp": 1751624037798
|
|
2566
3226
|
# }
|
|
2567
3227
|
#
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
return self.
|
|
3228
|
+
data = self.safe_dict(response, 'data', {})
|
|
3229
|
+
rows = self.safe_list(data, 'rows', [])
|
|
3230
|
+
return self.parse_funding_rates(rows, symbols)
|
|
2571
3231
|
|
|
2572
3232
|
async def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
|
2573
3233
|
"""
|
|
2574
3234
|
fetches historical funding rate prices
|
|
2575
|
-
|
|
3235
|
+
|
|
3236
|
+
https://developer.woox.io/api-reference/endpoint/public_data/fundingRateHistory
|
|
3237
|
+
|
|
2576
3238
|
:param str symbol: unified symbol of the market to fetch the funding rate history for
|
|
2577
3239
|
:param int [since]: timestamp in ms of the earliest funding rate to fetch
|
|
2578
3240
|
:param int [limit]: the maximum amount of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>` to fetch
|
|
@@ -2586,44 +3248,50 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2586
3248
|
paginate, params = self.handle_option_and_params(params, 'fetchFundingRateHistory', 'paginate')
|
|
2587
3249
|
if paginate:
|
|
2588
3250
|
return await self.fetch_paginated_call_incremental('fetchFundingRateHistory', symbol, since, limit, params, 'page', 25)
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
3251
|
+
if symbol is None:
|
|
3252
|
+
raise ArgumentsRequired(self.id + ' fetchFundingRateHistory() requires a symbol argument')
|
|
3253
|
+
market = self.market(symbol)
|
|
3254
|
+
symbol = market['symbol']
|
|
3255
|
+
request: dict = {
|
|
3256
|
+
'symbol': market['id'],
|
|
3257
|
+
}
|
|
2594
3258
|
if since is not None:
|
|
2595
|
-
request['
|
|
2596
|
-
request, params = self.handle_until_option('
|
|
2597
|
-
response = await self.
|
|
3259
|
+
request['startTime'] = since
|
|
3260
|
+
request, params = self.handle_until_option('endTime', request, params)
|
|
3261
|
+
response = await self.v3PublicGetFundingRateHistory(self.extend(request, params))
|
|
2598
3262
|
#
|
|
2599
3263
|
# {
|
|
2600
|
-
# "success":
|
|
2601
|
-
# "
|
|
2602
|
-
# "
|
|
2603
|
-
#
|
|
2604
|
-
#
|
|
2605
|
-
#
|
|
2606
|
-
#
|
|
2607
|
-
#
|
|
2608
|
-
#
|
|
2609
|
-
#
|
|
2610
|
-
#
|
|
2611
|
-
#
|
|
3264
|
+
# "success": True,
|
|
3265
|
+
# "data": {
|
|
3266
|
+
# "rows": [
|
|
3267
|
+
# {
|
|
3268
|
+
# "symbol": "PERP_BTC_USDT",
|
|
3269
|
+
# "fundingRate": "-0.00004953",
|
|
3270
|
+
# "fundingRateTimestamp": 1751616000000,
|
|
3271
|
+
# "nextFundingTime": 1751644800000,
|
|
3272
|
+
# "markPrice": "108708"
|
|
3273
|
+
# }
|
|
3274
|
+
# ],
|
|
3275
|
+
# "meta": {
|
|
3276
|
+
# "total": 11690,
|
|
3277
|
+
# "recordsPerPage": 25,
|
|
3278
|
+
# "currentPage": 1
|
|
2612
3279
|
# }
|
|
2613
|
-
#
|
|
2614
|
-
# "timestamp":
|
|
3280
|
+
# },
|
|
3281
|
+
# "timestamp": 1751632390031
|
|
2615
3282
|
# }
|
|
2616
3283
|
#
|
|
2617
|
-
|
|
3284
|
+
data = self.safe_dict(response, 'data', {})
|
|
3285
|
+
rows = self.safe_list(data, 'rows', [])
|
|
2618
3286
|
rates = []
|
|
2619
|
-
for i in range(0, len(
|
|
2620
|
-
entry =
|
|
3287
|
+
for i in range(0, len(rows)):
|
|
3288
|
+
entry = rows[i]
|
|
2621
3289
|
marketId = self.safe_string(entry, 'symbol')
|
|
2622
|
-
timestamp = self.safe_integer(entry, '
|
|
3290
|
+
timestamp = self.safe_integer(entry, 'fundingRateTimestamp')
|
|
2623
3291
|
rates.append({
|
|
2624
3292
|
'info': entry,
|
|
2625
3293
|
'symbol': self.safe_symbol(marketId),
|
|
2626
|
-
'fundingRate': self.safe_number(entry, '
|
|
3294
|
+
'fundingRate': self.safe_number(entry, 'fundingRate'),
|
|
2627
3295
|
'timestamp': timestamp,
|
|
2628
3296
|
'datetime': self.iso8601(timestamp),
|
|
2629
3297
|
})
|
|
@@ -2633,7 +3301,9 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2633
3301
|
async def set_position_mode(self, hedged: bool, symbol: Str = None, params={}):
|
|
2634
3302
|
"""
|
|
2635
3303
|
set hedged to True or False for a market
|
|
2636
|
-
|
|
3304
|
+
|
|
3305
|
+
https://developer.woox.io/api-reference/endpoint/futures/position_mode
|
|
3306
|
+
|
|
2637
3307
|
:param bool hedged: set to True to use HEDGE_MODE, False for ONE_WAY
|
|
2638
3308
|
:param str symbol: not used by woo setPositionMode
|
|
2639
3309
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -2645,14 +3315,13 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2645
3315
|
else:
|
|
2646
3316
|
hedgeMode = 'ONE_WAY'
|
|
2647
3317
|
request: dict = {
|
|
2648
|
-
'
|
|
3318
|
+
'positionMode': hedgeMode,
|
|
2649
3319
|
}
|
|
2650
|
-
response = await self.
|
|
3320
|
+
response = await self.v3PrivatePutFuturesPositionMode(self.extend(request, params))
|
|
2651
3321
|
#
|
|
2652
3322
|
# {
|
|
2653
3323
|
# "success": True,
|
|
2654
|
-
# "
|
|
2655
|
-
# "timestamp": "1709195608551"
|
|
3324
|
+
# "timestamp": 1752550492845
|
|
2656
3325
|
# }
|
|
2657
3326
|
#
|
|
2658
3327
|
return response
|
|
@@ -2660,112 +3329,296 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2660
3329
|
async def fetch_leverage(self, symbol: str, params={}) -> Leverage:
|
|
2661
3330
|
"""
|
|
2662
3331
|
fetch the set leverage for a market
|
|
2663
|
-
|
|
3332
|
+
|
|
3333
|
+
https://developer.woox.io/api-reference/endpoint/account/get_account_info
|
|
3334
|
+
https://developer.woox.io/api-reference/endpoint/futures/get_leverage
|
|
3335
|
+
|
|
2664
3336
|
:param str symbol: unified market symbol
|
|
2665
3337
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
3338
|
+
:param str [params.marginMode]: *for swap markets only* 'cross' or 'isolated'
|
|
3339
|
+
:param str [params.positionMode]: *for swap markets only* 'ONE_WAY' or 'HEDGE_MODE'
|
|
2666
3340
|
:returns dict: a `leverage structure <https://docs.ccxt.com/#/?id=leverage-structure>`
|
|
2667
3341
|
"""
|
|
2668
3342
|
await self.load_markets()
|
|
2669
3343
|
market = self.market(symbol)
|
|
2670
|
-
response =
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
|
|
2697
|
-
|
|
2698
|
-
|
|
3344
|
+
response: dict = None
|
|
3345
|
+
if market['spot']:
|
|
3346
|
+
response = await self.v3PrivateGetAccountInfo(params)
|
|
3347
|
+
#
|
|
3348
|
+
# {
|
|
3349
|
+
# "success": True,
|
|
3350
|
+
# "data": {
|
|
3351
|
+
# "applicationId": "dsa",
|
|
3352
|
+
# "account": "dsa",
|
|
3353
|
+
# "alias": "haha",
|
|
3354
|
+
# "otpauth": True,
|
|
3355
|
+
# "accountMode": "FUTURES",
|
|
3356
|
+
# "positionMode": "ONE_WAY",
|
|
3357
|
+
# "leverage": 0,
|
|
3358
|
+
# "marginRatio": "10",
|
|
3359
|
+
# "openMarginRatio": "10",
|
|
3360
|
+
# "initialMarginRatio": "10",
|
|
3361
|
+
# "maintenanceMarginRatio": "0.03",
|
|
3362
|
+
# "totalCollateral": "165.6115334",
|
|
3363
|
+
# "freeCollateral": "165.6115334",
|
|
3364
|
+
# "totalAccountValue": "167.52723093",
|
|
3365
|
+
# "totalTradingValue": "167.52723093",
|
|
3366
|
+
# "totalVaultValue": "0",
|
|
3367
|
+
# "totalStakingValue": "0",
|
|
3368
|
+
# "totalLaunchpadValue": "0",
|
|
3369
|
+
# "totalEarnValue": "0",
|
|
3370
|
+
# "referrerID": null,
|
|
3371
|
+
# "accountType": "Main"
|
|
3372
|
+
# },
|
|
3373
|
+
# "timestamp": 1752645129054
|
|
3374
|
+
# }
|
|
3375
|
+
#
|
|
3376
|
+
elif market['swap']:
|
|
3377
|
+
request: dict = {
|
|
3378
|
+
'symbol': market['id'],
|
|
3379
|
+
}
|
|
3380
|
+
marginMode: Str = None
|
|
3381
|
+
marginMode, params = self.handle_margin_mode_and_params('fetchLeverage', params, 'cross')
|
|
3382
|
+
request['marginMode'] = self.encode_margin_mode(marginMode)
|
|
3383
|
+
response = await self.v3PrivateGetFuturesLeverage(self.extend(request, params))
|
|
3384
|
+
#
|
|
3385
|
+
# HEDGE_MODE
|
|
3386
|
+
# {
|
|
3387
|
+
# "success": True,
|
|
3388
|
+
# "data":
|
|
3389
|
+
# {
|
|
3390
|
+
# "symbol": "PERP_ETH_USDT",
|
|
3391
|
+
# "marginMode": "CROSS",
|
|
3392
|
+
# "positionMode": "HEDGE_MODE",
|
|
3393
|
+
# "details": [
|
|
3394
|
+
# {
|
|
3395
|
+
# "positionSide": "LONG",
|
|
3396
|
+
# "leverage": 10
|
|
3397
|
+
# },
|
|
3398
|
+
# {
|
|
3399
|
+
# "positionSide": "SHORT",
|
|
3400
|
+
# "leverage": 10
|
|
3401
|
+
# }
|
|
3402
|
+
# ]
|
|
3403
|
+
# },
|
|
3404
|
+
# "timestamp": 1720886470482
|
|
3405
|
+
# }
|
|
3406
|
+
#
|
|
3407
|
+
# ONE_WAY
|
|
3408
|
+
# {
|
|
3409
|
+
# "success": True,
|
|
3410
|
+
# "data": {
|
|
3411
|
+
# "symbol": "PERP_ETH_USDT",
|
|
3412
|
+
# "marginMode": "ISOLATED",
|
|
3413
|
+
# "positionMode": "ONE_WAY",
|
|
3414
|
+
# "details": [
|
|
3415
|
+
# {
|
|
3416
|
+
# "positionSide": "BOTH",
|
|
3417
|
+
# "leverage": 10
|
|
3418
|
+
# }
|
|
3419
|
+
# ]
|
|
3420
|
+
# },
|
|
3421
|
+
# "timestamp": 1720886810317
|
|
3422
|
+
# }
|
|
3423
|
+
#
|
|
3424
|
+
else:
|
|
3425
|
+
raise NotSupported(self.id + ' fetchLeverage() is not supported for ' + market['type'] + ' markets')
|
|
2699
3426
|
data = self.safe_dict(response, 'data', {})
|
|
2700
3427
|
return self.parse_leverage(data, market)
|
|
2701
3428
|
|
|
2702
3429
|
def parse_leverage(self, leverage: dict, market: Market = None) -> Leverage:
|
|
2703
|
-
|
|
3430
|
+
marketId = self.safe_string(leverage, 'symbol')
|
|
3431
|
+
market = self.safe_market(marketId, market)
|
|
3432
|
+
marginMode = self.safe_string_lower(leverage, 'marginMode')
|
|
3433
|
+
spotLeverage = self.safe_integer(leverage, 'leverage')
|
|
3434
|
+
if spotLeverage == 0:
|
|
3435
|
+
spotLeverage = None
|
|
3436
|
+
longLeverage = spotLeverage
|
|
3437
|
+
shortLeverage = spotLeverage
|
|
3438
|
+
details = self.safe_list(leverage, 'details', [])
|
|
3439
|
+
for i in range(0, len(details)):
|
|
3440
|
+
position = self.safe_dict(details, i, {})
|
|
3441
|
+
positionLeverage = self.safe_integer(position, 'leverage')
|
|
3442
|
+
side = self.safe_string(position, 'positionSide')
|
|
3443
|
+
if side == 'BOTH':
|
|
3444
|
+
longLeverage = positionLeverage
|
|
3445
|
+
shortLeverage = positionLeverage
|
|
3446
|
+
elif side == 'LONG':
|
|
3447
|
+
longLeverage = positionLeverage
|
|
3448
|
+
elif side == 'SHORT':
|
|
3449
|
+
shortLeverage = positionLeverage
|
|
2704
3450
|
return {
|
|
2705
3451
|
'info': leverage,
|
|
2706
3452
|
'symbol': market['symbol'],
|
|
2707
|
-
'marginMode':
|
|
2708
|
-
'longLeverage':
|
|
2709
|
-
'shortLeverage':
|
|
3453
|
+
'marginMode': marginMode,
|
|
3454
|
+
'longLeverage': longLeverage,
|
|
3455
|
+
'shortLeverage': shortLeverage,
|
|
2710
3456
|
}
|
|
2711
3457
|
|
|
2712
|
-
async def set_leverage(self, leverage:
|
|
3458
|
+
async def set_leverage(self, leverage: int, symbol: Str = None, params={}):
|
|
3459
|
+
"""
|
|
3460
|
+
set the level of leverage for a market
|
|
3461
|
+
|
|
3462
|
+
https://developer.woox.io/api-reference/endpoint/spot_margin/set_leverage
|
|
3463
|
+
https://developer.woox.io/api-reference/endpoint/futures/set_leverage
|
|
3464
|
+
|
|
3465
|
+
:param float leverage: the rate of leverage(1, 2, 3, 4 or 5 for spot markets, 1, 2, 3, 4, 5, 10, 15, 20 for swap markets)
|
|
3466
|
+
:param str [symbol]: unified market symbol(is mandatory for swap markets)
|
|
3467
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
3468
|
+
:param str [params.marginMode]: *for swap markets only* 'cross' or 'isolated'
|
|
3469
|
+
:param str [params.positionMode]: *for swap markets only* 'ONE_WAY' or 'HEDGE_MODE'
|
|
3470
|
+
:returns dict: response from the exchange
|
|
3471
|
+
"""
|
|
2713
3472
|
await self.load_markets()
|
|
2714
|
-
if (leverage < 1) or (leverage > 20):
|
|
2715
|
-
raise BadRequest(self.id + ' leverage should be between 1 and 20')
|
|
2716
3473
|
request: dict = {
|
|
2717
3474
|
'leverage': leverage,
|
|
2718
3475
|
}
|
|
2719
|
-
|
|
3476
|
+
market: Market = None
|
|
3477
|
+
if symbol is not None:
|
|
3478
|
+
market = self.market(symbol)
|
|
3479
|
+
if (symbol is None) or market['spot']:
|
|
3480
|
+
return await self.v3PrivatePostSpotMarginLeverage(self.extend(request, params))
|
|
3481
|
+
elif market['swap']:
|
|
3482
|
+
request['symbol'] = market['id']
|
|
3483
|
+
marginMode: Str = None
|
|
3484
|
+
marginMode, params = self.handle_margin_mode_and_params('fetchLeverage', params, 'cross')
|
|
3485
|
+
request['marginMode'] = self.encode_margin_mode(marginMode)
|
|
3486
|
+
return await self.v3PrivatePutFuturesLeverage(self.extend(request, params))
|
|
3487
|
+
else:
|
|
3488
|
+
raise NotSupported(self.id + ' fetchLeverage() is not supported for ' + market['type'] + ' markets')
|
|
3489
|
+
|
|
3490
|
+
async def add_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
|
|
3491
|
+
"""
|
|
3492
|
+
add margin
|
|
3493
|
+
|
|
3494
|
+
https://docs.woox.io/#update-isolated-margin-setting
|
|
3495
|
+
|
|
3496
|
+
:param str symbol: unified market symbol
|
|
3497
|
+
:param float amount: amount of margin to add
|
|
3498
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
3499
|
+
:param str [params.position_side]: 'LONG' or 'SHORT' in hedge mode, 'BOTH' in one way mode
|
|
3500
|
+
:returns dict: a `margin structure <https://docs.ccxt.com/#/?id=add-margin-structure>`
|
|
3501
|
+
"""
|
|
3502
|
+
return await self.modify_margin_helper(symbol, amount, 'ADD', params)
|
|
3503
|
+
|
|
3504
|
+
async def reduce_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
|
|
3505
|
+
"""
|
|
3506
|
+
remove margin from a position
|
|
3507
|
+
|
|
3508
|
+
https://docs.woox.io/#update-isolated-margin-setting
|
|
3509
|
+
|
|
3510
|
+
:param str symbol: unified market symbol
|
|
3511
|
+
:param float amount: amount of margin to remove
|
|
3512
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
3513
|
+
:param str [params.position_side]: 'LONG' or 'SHORT' in hedge mode, 'BOTH' in one way mode
|
|
3514
|
+
:returns dict: a `margin structure <https://docs.ccxt.com/#/?id=reduce-margin-structure>`
|
|
3515
|
+
"""
|
|
3516
|
+
return await self.modify_margin_helper(symbol, amount, 'REDUCE', params)
|
|
3517
|
+
|
|
3518
|
+
async def modify_margin_helper(self, symbol: str, amount, type, params={}) -> MarginModification:
|
|
3519
|
+
await self.load_markets()
|
|
3520
|
+
market = self.market(symbol)
|
|
3521
|
+
request: dict = {
|
|
3522
|
+
'symbol': market['id'],
|
|
3523
|
+
'adjust_token': 'USDT', # todo check
|
|
3524
|
+
'adjust_amount': amount,
|
|
3525
|
+
'action': type,
|
|
3526
|
+
}
|
|
3527
|
+
return await self.v1PrivatePostClientIsolatedMargin(self.extend(request, params))
|
|
2720
3528
|
|
|
2721
|
-
async def fetch_position(self, symbol: Str
|
|
3529
|
+
async def fetch_position(self, symbol: Str, params={}):
|
|
3530
|
+
"""
|
|
3531
|
+
fetch data on an open position
|
|
3532
|
+
|
|
3533
|
+
https://developer.woox.io/api-reference/endpoint/futures/get_positions
|
|
3534
|
+
|
|
3535
|
+
:param str symbol: unified market symbol of the market the position is held in
|
|
3536
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
3537
|
+
:returns dict: a `position structure <https://docs.ccxt.com/#/?id=position-structure>`
|
|
3538
|
+
"""
|
|
2722
3539
|
await self.load_markets()
|
|
2723
3540
|
market = self.market(symbol)
|
|
2724
3541
|
request: dict = {
|
|
2725
3542
|
'symbol': market['id'],
|
|
2726
3543
|
}
|
|
2727
|
-
response = await self.
|
|
3544
|
+
response = await self.v3PrivateGetFuturesPositions(self.extend(request, params))
|
|
2728
3545
|
#
|
|
2729
3546
|
# {
|
|
2730
|
-
# "
|
|
2731
|
-
# "
|
|
2732
|
-
#
|
|
2733
|
-
#
|
|
2734
|
-
#
|
|
2735
|
-
#
|
|
2736
|
-
#
|
|
2737
|
-
#
|
|
2738
|
-
#
|
|
2739
|
-
#
|
|
2740
|
-
#
|
|
3547
|
+
# "success": True,
|
|
3548
|
+
# "data": {
|
|
3549
|
+
# "positions": [
|
|
3550
|
+
# {
|
|
3551
|
+
# "symbol": "PERP_LTC_USDT",
|
|
3552
|
+
# "holding": "0.1",
|
|
3553
|
+
# "pendingLongQty": "0",
|
|
3554
|
+
# "pendingShortQty": "0",
|
|
3555
|
+
# "settlePrice": "96.87",
|
|
3556
|
+
# "averageOpenPrice": "96.87",
|
|
3557
|
+
# "pnl24H": "0",
|
|
3558
|
+
# "fee24H": "0.0048435",
|
|
3559
|
+
# "markPrice": "96.83793449",
|
|
3560
|
+
# "estLiqPrice": "0",
|
|
3561
|
+
# "timestamp": 1752500555823,
|
|
3562
|
+
# "adlQuantile": 2,
|
|
3563
|
+
# "positionSide": "BOTH",
|
|
3564
|
+
# "marginMode": "CROSS",
|
|
3565
|
+
# "isolatedMarginToken": "",
|
|
3566
|
+
# "isolatedMarginAmount": "0",
|
|
3567
|
+
# "isolatedFrozenLong": "0",
|
|
3568
|
+
# "isolatedFrozenShort": "0",
|
|
3569
|
+
# "leverage": 10
|
|
3570
|
+
# }
|
|
3571
|
+
# ]
|
|
3572
|
+
# },
|
|
3573
|
+
# "timestamp": 1752500579848
|
|
2741
3574
|
# }
|
|
2742
3575
|
#
|
|
2743
|
-
|
|
3576
|
+
result = self.safe_dict(response, 'data', {})
|
|
3577
|
+
positions = self.safe_list(result, 'positions', [])
|
|
3578
|
+
first = self.safe_dict(positions, 0, {})
|
|
3579
|
+
return self.parse_position(first, market)
|
|
3580
|
+
|
|
3581
|
+
async def fetch_positions(self, symbols: Strings = None, params={}) -> List[Position]:
|
|
3582
|
+
"""
|
|
3583
|
+
fetch all open positions
|
|
2744
3584
|
|
|
2745
|
-
|
|
3585
|
+
https://developer.woox.io/api-reference/endpoint/futures/get_positions
|
|
3586
|
+
|
|
3587
|
+
:param str[] [symbols]: list of unified market symbols
|
|
3588
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
3589
|
+
:returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
|
|
3590
|
+
"""
|
|
2746
3591
|
await self.load_markets()
|
|
2747
|
-
response = await self.
|
|
3592
|
+
response = await self.v3PrivateGetFuturesPositions(params)
|
|
2748
3593
|
#
|
|
2749
3594
|
# {
|
|
2750
3595
|
# "success": True,
|
|
2751
3596
|
# "data": {
|
|
2752
3597
|
# "positions": [
|
|
2753
3598
|
# {
|
|
2754
|
-
# "symbol": "
|
|
2755
|
-
# "holding": 1,
|
|
2756
|
-
# "pendingLongQty": 0,
|
|
2757
|
-
# "pendingShortQty":
|
|
2758
|
-
# "settlePrice":
|
|
2759
|
-
# "averageOpenPrice":
|
|
2760
|
-
# "pnl24H":
|
|
2761
|
-
# "fee24H":
|
|
2762
|
-
# "markPrice":
|
|
2763
|
-
# "estLiqPrice":
|
|
2764
|
-
# "timestamp":
|
|
3599
|
+
# "symbol": "PERP_LTC_USDT",
|
|
3600
|
+
# "holding": "0.1",
|
|
3601
|
+
# "pendingLongQty": "0",
|
|
3602
|
+
# "pendingShortQty": "0",
|
|
3603
|
+
# "settlePrice": "96.87",
|
|
3604
|
+
# "averageOpenPrice": "96.87",
|
|
3605
|
+
# "pnl24H": "0",
|
|
3606
|
+
# "fee24H": "0.0048435",
|
|
3607
|
+
# "markPrice": "96.83793449",
|
|
3608
|
+
# "estLiqPrice": "0",
|
|
3609
|
+
# "timestamp": 1752500555823,
|
|
3610
|
+
# "adlQuantile": 2,
|
|
3611
|
+
# "positionSide": "BOTH",
|
|
3612
|
+
# "marginMode": "CROSS",
|
|
3613
|
+
# "isolatedMarginToken": "",
|
|
3614
|
+
# "isolatedMarginAmount": "0",
|
|
3615
|
+
# "isolatedFrozenLong": "0",
|
|
3616
|
+
# "isolatedFrozenShort": "0",
|
|
3617
|
+
# "leverage": 10
|
|
2765
3618
|
# }
|
|
2766
3619
|
# ]
|
|
2767
3620
|
# },
|
|
2768
|
-
# "timestamp":
|
|
3621
|
+
# "timestamp": 1752500579848
|
|
2769
3622
|
# }
|
|
2770
3623
|
#
|
|
2771
3624
|
result = self.safe_dict(response, 'data', {})
|
|
@@ -2774,18 +3627,51 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2774
3627
|
|
|
2775
3628
|
def parse_position(self, position: dict, market: Market = None):
|
|
2776
3629
|
#
|
|
3630
|
+
# v1PrivateGetPositionSymbol
|
|
3631
|
+
# {
|
|
3632
|
+
# "symbol": "PERP_ETH_USDT",
|
|
3633
|
+
# "position_side": "BOTH",
|
|
3634
|
+
# "leverage": 10,
|
|
3635
|
+
# "margin_mode": "CROSS",
|
|
3636
|
+
# "average_open_price": 3139.9,
|
|
3637
|
+
# "isolated_margin_amount": 0.0,
|
|
3638
|
+
# "isolated_margin_token": "",
|
|
3639
|
+
# "opening_time": "1720627963.094",
|
|
3640
|
+
# "mark_price": 3155.19169891,
|
|
3641
|
+
# "pending_short_qty": 0.0,
|
|
3642
|
+
# "pending_long_qty": 0.0,
|
|
3643
|
+
# "holding": -0.7,
|
|
3644
|
+
# "pnl_24_h": 0.0,
|
|
3645
|
+
# "est_liq_price": 9107.40055552,
|
|
3646
|
+
# "settle_price": 3151.0319904,
|
|
3647
|
+
# "success": True,
|
|
3648
|
+
# "fee_24_h": 0.0,
|
|
3649
|
+
# "isolated_frozen_long": 0.0,
|
|
3650
|
+
# "isolated_frozen_short": 0.0,
|
|
3651
|
+
# "timestamp": "1720867502.544"
|
|
3652
|
+
# }
|
|
3653
|
+
#
|
|
3654
|
+
# v3PrivateGetPositions
|
|
2777
3655
|
# {
|
|
2778
|
-
# "symbol": "
|
|
2779
|
-
# "holding": 1,
|
|
2780
|
-
# "pendingLongQty": 0,
|
|
2781
|
-
# "pendingShortQty":
|
|
2782
|
-
# "settlePrice":
|
|
2783
|
-
# "averageOpenPrice":
|
|
2784
|
-
# "pnl24H":
|
|
2785
|
-
# "fee24H":
|
|
2786
|
-
# "markPrice":
|
|
2787
|
-
# "estLiqPrice":
|
|
2788
|
-
# "timestamp":
|
|
3656
|
+
# "symbol": "PERP_LTC_USDT",
|
|
3657
|
+
# "holding": "0.1",
|
|
3658
|
+
# "pendingLongQty": "0",
|
|
3659
|
+
# "pendingShortQty": "0",
|
|
3660
|
+
# "settlePrice": "96.87",
|
|
3661
|
+
# "averageOpenPrice": "96.87",
|
|
3662
|
+
# "pnl24H": "0",
|
|
3663
|
+
# "fee24H": "0.0048435",
|
|
3664
|
+
# "markPrice": "96.83793449",
|
|
3665
|
+
# "estLiqPrice": "0",
|
|
3666
|
+
# "timestamp": 1752500555823,
|
|
3667
|
+
# "adlQuantile": 2,
|
|
3668
|
+
# "positionSide": "BOTH",
|
|
3669
|
+
# "marginMode": "CROSS",
|
|
3670
|
+
# "isolatedMarginToken": "",
|
|
3671
|
+
# "isolatedMarginAmount": "0",
|
|
3672
|
+
# "isolatedFrozenLong": "0",
|
|
3673
|
+
# "isolatedFrozenShort": "0",
|
|
3674
|
+
# "leverage": 10
|
|
2789
3675
|
# }
|
|
2790
3676
|
#
|
|
2791
3677
|
contract = self.safe_string(position, 'symbol')
|
|
@@ -2797,13 +3683,20 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2797
3683
|
else:
|
|
2798
3684
|
side = 'short'
|
|
2799
3685
|
contractSize = self.safe_string(market, 'contractSize')
|
|
2800
|
-
markPrice = self.
|
|
2801
|
-
|
|
2802
|
-
|
|
3686
|
+
markPrice = self.safe_string_2(position, 'markPrice', 'mark_price')
|
|
3687
|
+
timestampString = self.safe_string(position, 'timestamp')
|
|
3688
|
+
timestamp = None
|
|
3689
|
+
if timestampString is not None:
|
|
3690
|
+
if timestampString.find('.') > -1:
|
|
3691
|
+
timestamp = self.safe_timestamp(position, 'timestamp')
|
|
3692
|
+
else:
|
|
3693
|
+
timestamp = self.safe_integer(position, 'timestamp')
|
|
3694
|
+
entryPrice = self.safe_string_2(position, 'averageOpenPrice', 'average_open_price')
|
|
2803
3695
|
priceDifference = Precise.string_sub(markPrice, entryPrice)
|
|
2804
3696
|
unrealisedPnl = Precise.string_mul(priceDifference, size)
|
|
2805
3697
|
size = Precise.string_abs(size)
|
|
2806
3698
|
notional = Precise.string_mul(size, markPrice)
|
|
3699
|
+
positionSide = self.safe_string(position, 'positionSide') # 'SHORT' or 'LONG' for hedged, 'BOTH' for non-hedged
|
|
2807
3700
|
return self.safe_position({
|
|
2808
3701
|
'info': position,
|
|
2809
3702
|
'id': None,
|
|
@@ -2817,20 +3710,19 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2817
3710
|
'maintenanceMarginPercentage': None,
|
|
2818
3711
|
'entryPrice': self.parse_number(entryPrice),
|
|
2819
3712
|
'notional': self.parse_number(notional),
|
|
2820
|
-
'leverage':
|
|
3713
|
+
'leverage': self.safe_number(position, 'leverage'),
|
|
2821
3714
|
'unrealizedPnl': self.parse_number(unrealisedPnl),
|
|
2822
3715
|
'contracts': self.parse_number(size),
|
|
2823
3716
|
'contractSize': self.parse_number(contractSize),
|
|
2824
3717
|
'marginRatio': None,
|
|
2825
|
-
'liquidationPrice': self.
|
|
3718
|
+
'liquidationPrice': self.safe_number_2(position, 'estLiqPrice', 'est_liq_price'),
|
|
2826
3719
|
'markPrice': self.parse_number(markPrice),
|
|
2827
3720
|
'lastPrice': None,
|
|
2828
3721
|
'collateral': None,
|
|
2829
|
-
'marginMode': '
|
|
2830
|
-
'marginType': None,
|
|
3722
|
+
'marginMode': self.safe_string_lower_2(position, 'marginMode', 'margin_mode'),
|
|
2831
3723
|
'side': side,
|
|
2832
3724
|
'percentage': None,
|
|
2833
|
-
'hedged':
|
|
3725
|
+
'hedged': positionSide != 'BOTH',
|
|
2834
3726
|
'stopLossPrice': None,
|
|
2835
3727
|
'takeProfitPrice': None,
|
|
2836
3728
|
})
|
|
@@ -2838,7 +3730,9 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2838
3730
|
async def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
|
|
2839
3731
|
"""
|
|
2840
3732
|
fetch a quote for converting from one currency to another
|
|
2841
|
-
|
|
3733
|
+
|
|
3734
|
+
https://docs.woox.io/#get-quote-rfq
|
|
3735
|
+
|
|
2842
3736
|
:param str fromCode: the currency that you want to sell and convert from
|
|
2843
3737
|
:param str toCode: the currency that you want to buy and convert into
|
|
2844
3738
|
:param float [amount]: how much you want to trade in units of the from currency
|
|
@@ -2878,7 +3772,9 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2878
3772
|
async def create_convert_trade(self, id: str, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
|
|
2879
3773
|
"""
|
|
2880
3774
|
convert from one currency to another
|
|
2881
|
-
|
|
3775
|
+
|
|
3776
|
+
https://docs.woox.io/#send-quote-rft
|
|
3777
|
+
|
|
2882
3778
|
:param str id: the id of the trade that you want to make
|
|
2883
3779
|
:param str fromCode: the currency that you want to sell and convert from
|
|
2884
3780
|
:param str toCode: the currency that you want to buy and convert into
|
|
@@ -2907,7 +3803,9 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2907
3803
|
async def fetch_convert_trade(self, id: str, code: Str = None, params={}) -> Conversion:
|
|
2908
3804
|
"""
|
|
2909
3805
|
fetch the data for a conversion trade
|
|
2910
|
-
|
|
3806
|
+
|
|
3807
|
+
https://docs.woox.io/#get-quote-trade
|
|
3808
|
+
|
|
2911
3809
|
:param str id: the id of the trade that you want to fetch
|
|
2912
3810
|
:param str [code]: the unified currency code of the conversion trade
|
|
2913
3811
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -2946,7 +3844,9 @@ class woo(Exchange, ImplicitAPI):
|
|
|
2946
3844
|
async def fetch_convert_trade_history(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Conversion]:
|
|
2947
3845
|
"""
|
|
2948
3846
|
fetch the users history of conversion trades
|
|
2949
|
-
|
|
3847
|
+
|
|
3848
|
+
https://docs.woox.io/#get-quote-trades
|
|
3849
|
+
|
|
2950
3850
|
:param str [code]: the unified currency code
|
|
2951
3851
|
:param int [since]: the earliest time in ms to fetch conversions for
|
|
2952
3852
|
:param int [limit]: the maximum number of conversion structures to retrieve
|
|
@@ -3043,7 +3943,9 @@ class woo(Exchange, ImplicitAPI):
|
|
|
3043
3943
|
async def fetch_convert_currencies(self, params={}) -> Currencies:
|
|
3044
3944
|
"""
|
|
3045
3945
|
fetches all available currencies that can be converted
|
|
3046
|
-
|
|
3946
|
+
|
|
3947
|
+
https://docs.woox.io/#get-quote-asset-info
|
|
3948
|
+
|
|
3047
3949
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
3048
3950
|
:returns dict: an associative dictionary of currencies
|
|
3049
3951
|
"""
|