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