ccxt-ir 4.3.46.0.2__py2.py3-none-any.whl → 4.5.0__py2.py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ccxt/__init__.py +39 -35
- ccxt/abantether.py +9 -9
- ccxt/abstract/alpaca.py +4 -0
- ccxt/abstract/apex.py +31 -0
- ccxt/abstract/bigone.py +1 -1
- ccxt/abstract/binance.py +106 -48
- ccxt/abstract/binancecoinm.py +106 -48
- ccxt/abstract/binanceus.py +141 -83
- ccxt/abstract/binanceusdm.py +106 -48
- ccxt/abstract/bingx.py +50 -1
- ccxt/abstract/bitbank.py +5 -0
- ccxt/abstract/bitfinex.py +136 -65
- ccxt/abstract/bitflyer.py +1 -0
- ccxt/abstract/bitget.py +67 -0
- ccxt/abstract/bitmart.py +19 -1
- ccxt/abstract/bitopro.py +1 -0
- ccxt/abstract/bitrue.py +68 -68
- ccxt/abstract/bitstamp.py +1 -0
- ccxt/abstract/blofin.py +30 -0
- ccxt/abstract/btcbox.py +2 -0
- ccxt/abstract/bybit.py +28 -13
- ccxt/abstract/cex.py +28 -29
- ccxt/abstract/coinbaseexchange.py +1 -0
- ccxt/abstract/coinbaseinternational.py +1 -1
- ccxt/abstract/cryptocom.py +16 -0
- ccxt/abstract/cryptomus.py +20 -0
- ccxt/abstract/defx.py +69 -0
- ccxt/abstract/deribit.py +1 -0
- ccxt/abstract/derive.py +117 -0
- ccxt/abstract/digifinex.py +1 -0
- ccxt/abstract/ellipx.py +25 -0
- ccxt/abstract/foxbit.py +26 -0
- ccxt/abstract/gate.py +19 -0
- ccxt/abstract/gateio.py +19 -0
- ccxt/abstract/gemini.py +1 -0
- ccxt/abstract/hibachi.py +26 -0
- ccxt/abstract/hyperliquid.py +1 -1
- ccxt/abstract/independentreserve.py +6 -0
- ccxt/abstract/kraken.py +1 -0
- ccxt/abstract/krakenfutures.py +4 -0
- ccxt/abstract/kucoin.py +10 -0
- ccxt/abstract/kucoinfutures.py +18 -0
- ccxt/abstract/lbank.py +2 -1
- ccxt/abstract/luno.py +1 -0
- ccxt/abstract/mexc.py +2 -0
- ccxt/abstract/modetrade.py +119 -0
- ccxt/abstract/myokx.py +349 -0
- ccxt/abstract/oceanex.py +5 -0
- ccxt/abstract/okx.py +25 -0
- ccxt/abstract/okxus.py +349 -0
- ccxt/abstract/onetrading.py +0 -12
- ccxt/abstract/paradex.py +23 -0
- ccxt/abstract/phemex.py +2 -0
- ccxt/abstract/poloniex.py +36 -0
- ccxt/abstract/tradeogre.py +3 -1
- ccxt/abstract/upbit.py +51 -34
- ccxt/abstract/whitebit.py +16 -0
- ccxt/abstract/woo.py +64 -6
- ccxt/abstract/xt.py +10 -5
- ccxt/afratether.py +7 -7
- ccxt/alpaca.py +828 -51
- ccxt/apex.py +1875 -0
- ccxt/arzinja.py +7 -7
- ccxt/arzplus.py +9 -9
- ccxt/ascendex.py +501 -306
- ccxt/async_support/__init__.py +39 -35
- ccxt/async_support/abantether.py +10 -10
- ccxt/async_support/afratether.py +9 -9
- ccxt/async_support/alpaca.py +828 -51
- ccxt/async_support/apex.py +1875 -0
- ccxt/async_support/arzinja.py +10 -10
- ccxt/async_support/arzplus.py +12 -12
- ccxt/async_support/ascendex.py +502 -306
- ccxt/async_support/base/exchange.py +303 -89
- ccxt/async_support/base/ws/cache.py +9 -3
- ccxt/async_support/base/ws/client.py +173 -38
- ccxt/async_support/base/ws/future.py +25 -37
- ccxt/async_support/bequant.py +5 -3
- ccxt/async_support/bigone.py +279 -144
- ccxt/async_support/binance.py +2347 -1158
- ccxt/async_support/binancecoinm.py +9 -3
- ccxt/async_support/binanceus.py +17 -3
- ccxt/async_support/binanceusdm.py +9 -4
- ccxt/async_support/bingx.py +2962 -920
- ccxt/async_support/bit2c.py +147 -27
- ccxt/async_support/bitbank.py +151 -23
- ccxt/async_support/bitbns.py +104 -30
- ccxt/async_support/bitfinex.py +3291 -1113
- ccxt/async_support/bitflyer.py +202 -27
- ccxt/async_support/bitget.py +3683 -1538
- ccxt/async_support/bithumb.py +195 -38
- ccxt/async_support/bitimen.py +12 -12
- ccxt/async_support/bitir.py +38 -38
- ccxt/async_support/bitmart.py +1288 -350
- ccxt/async_support/bitmex.py +260 -75
- ccxt/async_support/bitopro.py +262 -62
- ccxt/async_support/bitpin.py +17 -16
- ccxt/async_support/bitrue.py +459 -290
- ccxt/async_support/bitso.py +199 -54
- ccxt/async_support/bitstamp.py +230 -96
- ccxt/async_support/bitteam.py +167 -25
- ccxt/async_support/{huobijp.py → bittrade.py} +158 -30
- ccxt/async_support/bitvavo.py +213 -49
- ccxt/async_support/blockchaincom.py +160 -46
- ccxt/async_support/blofin.py +502 -120
- ccxt/async_support/btcalpha.py +169 -31
- ccxt/async_support/btcbox.py +292 -23
- ccxt/async_support/btcmarkets.py +211 -58
- ccxt/async_support/btcturk.py +161 -38
- ccxt/async_support/bybit.py +1775 -1030
- ccxt/async_support/cex.py +1440 -1303
- ccxt/async_support/coinbase.py +724 -212
- ccxt/async_support/coinbaseadvanced.py +2 -1
- ccxt/async_support/coinbaseexchange.py +388 -89
- ccxt/async_support/coinbaseinternational.py +412 -57
- ccxt/async_support/coincatch.py +177 -78
- ccxt/async_support/coincheck.py +135 -19
- ccxt/async_support/coinex.py +606 -232
- ccxt/async_support/coinmate.py +189 -63
- ccxt/async_support/coinmetro.py +195 -54
- ccxt/async_support/coinone.py +158 -51
- ccxt/async_support/coinsph.py +336 -61
- ccxt/async_support/coinspot.py +151 -52
- ccxt/async_support/cryptocom.py +661 -111
- ccxt/async_support/cryptomus.py +1137 -0
- ccxt/async_support/defx.py +2071 -0
- ccxt/async_support/delta.py +299 -99
- ccxt/async_support/deribit.py +348 -126
- ccxt/async_support/derive.py +2572 -0
- ccxt/async_support/digifinex.py +430 -214
- ccxt/async_support/ellipx.py +2029 -0
- ccxt/async_support/eterex.py +10 -10
- ccxt/async_support/excoino.py +31 -31
- ccxt/async_support/exir.py +14 -14
- ccxt/async_support/exmo.py +344 -131
- ccxt/async_support/exnovin.py +10 -10
- ccxt/async_support/farhadexchange.py +12 -12
- ccxt/async_support/fmfwio.py +2 -1
- ccxt/async_support/foxbit.py +1935 -0
- ccxt/async_support/gate.py +1351 -529
- ccxt/async_support/gateio.py +2 -1
- ccxt/async_support/gemini.py +144 -39
- ccxt/async_support/hashkey.py +152 -109
- ccxt/async_support/hibachi.py +2080 -0
- ccxt/async_support/hitbtc.py +395 -167
- ccxt/async_support/hitobit.py +12 -12
- ccxt/async_support/hollaex.py +307 -119
- ccxt/async_support/htx.py +851 -383
- ccxt/async_support/huobi.py +2 -1
- ccxt/async_support/hyperliquid.py +1848 -536
- ccxt/async_support/independentreserve.py +288 -15
- ccxt/async_support/indodax.py +190 -33
- ccxt/async_support/jibitex.py +12 -12
- ccxt/async_support/kraken.py +795 -351
- ccxt/async_support/krakenfutures.py +214 -62
- ccxt/async_support/kucoin.py +715 -396
- ccxt/async_support/kucoinfutures.py +652 -89
- ccxt/async_support/latoken.py +217 -113
- ccxt/async_support/lbank.py +425 -97
- ccxt/async_support/luno.py +382 -35
- ccxt/async_support/mercado.py +113 -6
- ccxt/async_support/mexc.py +874 -437
- ccxt/async_support/modetrade.py +2818 -0
- ccxt/async_support/myokx.py +54 -0
- ccxt/async_support/ndax.py +221 -64
- ccxt/async_support/nobitex.py +31 -37
- ccxt/async_support/novadax.py +190 -34
- ccxt/async_support/oceanex.py +217 -28
- ccxt/async_support/okcoin.py +253 -145
- ccxt/async_support/okexchange.py +11 -11
- ccxt/async_support/okx.py +1088 -351
- ccxt/async_support/okxus.py +54 -0
- ccxt/async_support/ompfinex.py +25 -24
- ccxt/async_support/onetrading.py +213 -392
- ccxt/async_support/oxfun.py +245 -166
- ccxt/async_support/p2b.py +151 -29
- ccxt/async_support/paradex.py +562 -49
- ccxt/async_support/paymium.py +82 -19
- ccxt/async_support/phemex.py +713 -172
- ccxt/async_support/poloniex.py +1602 -283
- ccxt/async_support/probit.py +224 -95
- ccxt/async_support/ramzinex.py +30 -27
- ccxt/async_support/sarmayex.py +9 -9
- ccxt/async_support/sarrafex.py +13 -13
- ccxt/async_support/tabdeal.py +14 -13
- ccxt/async_support/tetherland.py +9 -9
- ccxt/async_support/timex.py +210 -51
- ccxt/async_support/tokocrypto.py +167 -47
- ccxt/async_support/tradeogre.py +266 -31
- ccxt/async_support/twox.py +9 -9
- ccxt/async_support/ubitex.py +12 -12
- ccxt/async_support/upbit.py +568 -165
- ccxt/async_support/vertex.py +160 -32
- ccxt/async_support/wallex.py +12 -12
- ccxt/async_support/wavesexchange.py +165 -30
- ccxt/async_support/whitebit.py +975 -127
- ccxt/async_support/woo.py +1918 -1016
- ccxt/async_support/woofipro.py +433 -141
- ccxt/async_support/xt.py +649 -193
- ccxt/async_support/yobit.py +195 -70
- ccxt/async_support/zaif.py +91 -15
- ccxt/async_support/zonda.py +151 -36
- ccxt/base/decimal_to_precision.py +14 -10
- ccxt/base/errors.py +49 -18
- ccxt/base/exchange.py +1556 -450
- ccxt/base/precise.py +10 -0
- ccxt/base/types.py +114 -6
- ccxt/bequant.py +5 -3
- ccxt/bigone.py +279 -144
- ccxt/binance.py +2347 -1158
- ccxt/binancecoinm.py +9 -3
- ccxt/binanceus.py +17 -3
- ccxt/binanceusdm.py +9 -4
- ccxt/bingx.py +2962 -920
- ccxt/bit2c.py +147 -27
- ccxt/bitbank.py +151 -23
- ccxt/bitbns.py +104 -30
- ccxt/bitfinex.py +3290 -1113
- ccxt/bitflyer.py +202 -27
- ccxt/bitget.py +3683 -1538
- ccxt/bithumb.py +194 -38
- ccxt/bitimen.py +9 -9
- ccxt/bitir.py +35 -35
- ccxt/bitmart.py +1288 -350
- ccxt/bitmex.py +260 -75
- ccxt/bitopro.py +262 -62
- ccxt/bitpin.py +15 -14
- ccxt/bitrue.py +459 -290
- ccxt/bitso.py +199 -54
- ccxt/bitstamp.py +230 -96
- ccxt/bitteam.py +167 -25
- ccxt/{huobijp.py → bittrade.py} +158 -30
- ccxt/bitvavo.py +213 -49
- ccxt/blockchaincom.py +160 -46
- ccxt/blofin.py +502 -120
- ccxt/btcalpha.py +169 -31
- ccxt/btcbox.py +291 -23
- ccxt/btcmarkets.py +211 -58
- ccxt/btcturk.py +161 -38
- ccxt/bybit.py +1775 -1030
- ccxt/cex.py +1439 -1303
- ccxt/coinbase.py +724 -212
- ccxt/coinbaseadvanced.py +2 -1
- ccxt/coinbaseexchange.py +388 -89
- ccxt/coinbaseinternational.py +412 -57
- ccxt/coincatch.py +177 -78
- ccxt/coincheck.py +135 -19
- ccxt/coinex.py +606 -232
- ccxt/coinmate.py +189 -63
- ccxt/coinmetro.py +194 -54
- ccxt/coinone.py +158 -51
- ccxt/coinsph.py +336 -61
- ccxt/coinspot.py +151 -52
- ccxt/cryptocom.py +661 -111
- ccxt/cryptomus.py +1137 -0
- ccxt/defx.py +2070 -0
- ccxt/delta.py +299 -99
- ccxt/deribit.py +348 -126
- ccxt/derive.py +2571 -0
- ccxt/digifinex.py +430 -214
- ccxt/ellipx.py +2029 -0
- ccxt/eterex.py +7 -7
- ccxt/excoino.py +29 -29
- ccxt/exir.py +11 -11
- ccxt/exmo.py +343 -131
- ccxt/exnovin.py +8 -8
- ccxt/farhadexchange.py +10 -10
- ccxt/fmfwio.py +2 -1
- ccxt/foxbit.py +1935 -0
- ccxt/gate.py +1351 -529
- ccxt/gateio.py +2 -1
- ccxt/gemini.py +144 -39
- ccxt/hashkey.py +152 -109
- ccxt/hibachi.py +2079 -0
- ccxt/hitbtc.py +395 -167
- ccxt/hitobit.py +9 -9
- ccxt/hollaex.py +307 -119
- ccxt/htx.py +851 -383
- ccxt/huobi.py +2 -1
- ccxt/hyperliquid.py +1848 -536
- ccxt/independentreserve.py +287 -15
- ccxt/indodax.py +190 -33
- ccxt/jibitex.py +9 -9
- ccxt/kraken.py +794 -351
- ccxt/krakenfutures.py +214 -62
- ccxt/kucoin.py +715 -396
- ccxt/kucoinfutures.py +652 -89
- ccxt/latoken.py +217 -113
- ccxt/lbank.py +425 -97
- ccxt/luno.py +382 -35
- ccxt/mercado.py +113 -6
- ccxt/mexc.py +873 -437
- ccxt/modetrade.py +2818 -0
- ccxt/myokx.py +54 -0
- ccxt/ndax.py +221 -64
- ccxt/nobitex.py +29 -35
- ccxt/novadax.py +190 -34
- ccxt/oceanex.py +217 -28
- ccxt/okcoin.py +253 -145
- ccxt/okexchange.py +9 -9
- ccxt/okx.py +1088 -351
- ccxt/okxus.py +54 -0
- ccxt/ompfinex.py +22 -21
- ccxt/onetrading.py +213 -392
- ccxt/oxfun.py +245 -166
- ccxt/p2b.py +151 -29
- ccxt/paradex.py +562 -49
- ccxt/paymium.py +82 -19
- ccxt/phemex.py +712 -172
- ccxt/poloniex.py +1601 -283
- ccxt/pro/__init__.py +76 -17
- ccxt/pro/alpaca.py +21 -6
- ccxt/pro/apex.py +984 -0
- ccxt/pro/ascendex.py +58 -10
- ccxt/pro/bequant.py +6 -1
- ccxt/pro/binance.py +728 -156
- ccxt/pro/binancecoinm.py +6 -2
- ccxt/pro/binanceus.py +8 -4
- ccxt/pro/binanceusdm.py +7 -2
- ccxt/pro/bingx.py +333 -142
- ccxt/pro/bitfinex.py +727 -262
- ccxt/pro/bitget.py +570 -79
- ccxt/pro/bithumb.py +20 -6
- ccxt/pro/bitmart.py +216 -87
- ccxt/pro/bitmex.py +47 -9
- ccxt/pro/bitopro.py +26 -14
- ccxt/pro/bitrue.py +22 -22
- ccxt/pro/bitstamp.py +54 -21
- ccxt/pro/{huobijp.py → bittrade.py} +7 -6
- ccxt/pro/bitvavo.py +191 -67
- ccxt/pro/blockchaincom.py +21 -8
- ccxt/pro/blofin.py +9 -1
- ccxt/pro/bybit.py +632 -245
- ccxt/pro/cex.py +59 -24
- ccxt/pro/coinbase.py +102 -73
- ccxt/pro/coinbaseadvanced.py +2 -1
- ccxt/pro/coinbaseexchange.py +8 -8
- ccxt/pro/coinbaseinternational.py +181 -25
- ccxt/pro/coincatch.py +6 -7
- ccxt/pro/coincheck.py +11 -6
- ccxt/pro/coinex.py +967 -665
- ccxt/pro/coinone.py +16 -9
- ccxt/pro/cryptocom.py +448 -45
- ccxt/pro/defx.py +831 -0
- ccxt/pro/deribit.py +150 -14
- ccxt/pro/derive.py +704 -0
- ccxt/pro/exmo.py +239 -6
- ccxt/pro/gate.py +623 -65
- ccxt/pro/gateio.py +2 -1
- ccxt/pro/gemini.py +27 -11
- ccxt/pro/hashkey.py +2 -2
- ccxt/pro/hitbtc.py +196 -91
- ccxt/pro/hollaex.py +23 -7
- ccxt/pro/htx.py +51 -14
- ccxt/pro/huobi.py +2 -1
- ccxt/pro/hyperliquid.py +591 -27
- ccxt/pro/independentreserve.py +9 -6
- ccxt/pro/kraken.py +640 -320
- ccxt/pro/krakenfutures.py +62 -35
- ccxt/pro/kucoin.py +267 -46
- ccxt/pro/kucoinfutures.py +165 -21
- ccxt/pro/lbank.py +102 -21
- ccxt/pro/luno.py +12 -8
- ccxt/pro/mexc.py +877 -111
- ccxt/pro/modetrade.py +1271 -0
- ccxt/pro/myokx.py +38 -0
- ccxt/pro/ndax.py +15 -2
- ccxt/pro/okcoin.py +23 -4
- ccxt/pro/okx.py +573 -98
- ccxt/pro/okxus.py +38 -0
- ccxt/pro/onetrading.py +30 -13
- ccxt/pro/oxfun.py +131 -27
- ccxt/pro/p2b.py +88 -22
- ccxt/pro/paradex.py +3 -3
- ccxt/pro/phemex.py +75 -21
- ccxt/pro/poloniex.py +124 -41
- ccxt/pro/probit.py +87 -80
- ccxt/pro/tradeogre.py +272 -0
- ccxt/pro/upbit.py +152 -12
- ccxt/pro/vertex.py +8 -3
- ccxt/pro/whitebit.py +58 -5
- ccxt/pro/woo.py +228 -37
- ccxt/pro/woofipro.py +106 -18
- ccxt/pro/xt.py +111 -5
- ccxt/probit.py +224 -95
- ccxt/protobuf/__init__.py +0 -0
- ccxt/protobuf/mexc/PrivateAccountV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PrivateDealsV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PrivateOrdersV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicAggreBookTickerV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicAggreDealsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicAggreDepthsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicBookTickerBatchV3Api_pb2.py +38 -0
- ccxt/protobuf/mexc/PublicBookTickerV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicDealsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicIncreaseDepthsBatchV3Api_pb2.py +38 -0
- ccxt/protobuf/mexc/PublicIncreaseDepthsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicLimitDepthsV3Api_pb2.py +39 -0
- ccxt/protobuf/mexc/PublicMiniTickerV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PublicMiniTickersV3Api_pb2.py +38 -0
- ccxt/protobuf/mexc/PublicSpotKlineV3Api_pb2.py +37 -0
- ccxt/protobuf/mexc/PushDataV3ApiWrapper_pb2.py +52 -0
- ccxt/protobuf/mexc/__init__.py +0 -0
- ccxt/ramzinex.py +28 -25
- ccxt/sarmayex.py +7 -7
- ccxt/sarrafex.py +10 -10
- ccxt/static_dependencies/__init__.py +1 -1
- ccxt/static_dependencies/lark/py.typed +0 -0
- ccxt/static_dependencies/marshmallow/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
- ccxt/tabdeal.py +12 -11
- ccxt/test/tests_async.py +261 -57
- ccxt/test/tests_helpers.py +1 -3
- ccxt/test/tests_init.py +4 -3
- ccxt/test/tests_sync.py +261 -57
- ccxt/tetherland.py +7 -7
- ccxt/timex.py +210 -51
- ccxt/tokocrypto.py +167 -47
- ccxt/tradeogre.py +266 -31
- ccxt/twox.py +7 -7
- ccxt/ubitex.py +9 -9
- ccxt/upbit.py +568 -165
- ccxt/vertex.py +160 -32
- ccxt/wallex.py +9 -9
- ccxt/wavesexchange.py +165 -30
- ccxt/whitebit.py +975 -127
- ccxt/woo.py +1917 -1016
- ccxt/woofipro.py +432 -141
- ccxt/xt.py +649 -193
- ccxt/yobit.py +194 -70
- ccxt/zaif.py +91 -15
- ccxt/zonda.py +151 -36
- {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/METADATA +225 -73
- ccxt_ir-4.5.0.dist-info/RECORD +743 -0
- {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/WHEEL +1 -1
- ccxt/abstract/ace.py +0 -15
- ccxt/abstract/bitbay.py +0 -53
- ccxt/abstract/bitcoincom.py +0 -115
- ccxt/abstract/bitfinex2.py +0 -139
- ccxt/abstract/bitpanda.py +0 -35
- ccxt/abstract/bl3p.py +0 -19
- ccxt/abstract/coinlist.py +0 -54
- ccxt/abstract/currencycom.py +0 -68
- ccxt/abstract/hitbtc3.py +0 -115
- ccxt/abstract/idex.py +0 -26
- ccxt/abstract/kuna.py +0 -182
- ccxt/abstract/lykke.py +0 -29
- ccxt/abstract/poloniexfutures.py +0 -48
- ccxt/abstract/wazirx.py +0 -30
- ccxt/ace.py +0 -1012
- ccxt/async_support/ace.py +0 -1012
- ccxt/async_support/base/ws/aiohttp_client.py +0 -125
- ccxt/async_support/base/ws/fast_client.py +0 -96
- ccxt/async_support/bitbay.py +0 -17
- ccxt/async_support/bitcoincom.py +0 -17
- ccxt/async_support/bitfinex2.py +0 -3552
- ccxt/async_support/bitpanda.py +0 -16
- ccxt/async_support/bl3p.py +0 -485
- ccxt/async_support/coinlist.py +0 -2243
- ccxt/async_support/currencycom.py +0 -1950
- ccxt/async_support/hitbtc3.py +0 -16
- ccxt/async_support/idex.py +0 -1766
- ccxt/async_support/kuna.py +0 -1841
- ccxt/async_support/lykke.py +0 -1270
- ccxt/async_support/poloniexfutures.py +0 -1717
- ccxt/async_support/wazirx.py +0 -1224
- ccxt/bitbay.py +0 -17
- ccxt/bitcoincom.py +0 -17
- ccxt/bitfinex2.py +0 -3552
- ccxt/bitpanda.py +0 -16
- ccxt/bl3p.py +0 -485
- ccxt/coinlist.py +0 -2243
- ccxt/currencycom.py +0 -1950
- ccxt/hitbtc3.py +0 -16
- ccxt/idex.py +0 -1766
- ccxt/kuna.py +0 -1841
- ccxt/lykke.py +0 -1270
- ccxt/poloniexfutures.py +0 -1717
- ccxt/pro/bitcoincom.py +0 -34
- ccxt/pro/bitfinex2.py +0 -1083
- ccxt/pro/bitpanda.py +0 -15
- ccxt/pro/currencycom.py +0 -536
- ccxt/pro/idex.py +0 -672
- ccxt/pro/poloniexfutures.py +0 -990
- ccxt/pro/wazirx.py +0 -749
- ccxt/test/base/__init__.py +0 -29
- ccxt/test/base/test_account.py +0 -26
- ccxt/test/base/test_balance.py +0 -56
- ccxt/test/base/test_borrow_interest.py +0 -35
- ccxt/test/base/test_borrow_rate.py +0 -32
- ccxt/test/base/test_calculate_fee.py +0 -51
- ccxt/test/base/test_crypto.py +0 -127
- ccxt/test/base/test_currency.py +0 -76
- ccxt/test/base/test_datetime.py +0 -109
- ccxt/test/base/test_decimal_to_precision.py +0 -392
- ccxt/test/base/test_deep_extend.py +0 -68
- ccxt/test/base/test_deposit_withdrawal.py +0 -50
- ccxt/test/base/test_exchange_datetime_functions.py +0 -76
- ccxt/test/base/test_funding_rate_history.py +0 -29
- ccxt/test/base/test_last_price.py +0 -31
- ccxt/test/base/test_ledger_entry.py +0 -45
- ccxt/test/base/test_ledger_item.py +0 -48
- ccxt/test/base/test_leverage_tier.py +0 -33
- ccxt/test/base/test_liquidation.py +0 -50
- ccxt/test/base/test_margin_mode.py +0 -24
- ccxt/test/base/test_margin_modification.py +0 -35
- ccxt/test/base/test_market.py +0 -193
- ccxt/test/base/test_number.py +0 -411
- ccxt/test/base/test_ohlcv.py +0 -33
- ccxt/test/base/test_open_interest.py +0 -32
- ccxt/test/base/test_order.py +0 -64
- ccxt/test/base/test_order_book.py +0 -69
- ccxt/test/base/test_position.py +0 -60
- ccxt/test/base/test_shared_methods.py +0 -353
- ccxt/test/base/test_status.py +0 -24
- ccxt/test/base/test_throttle.py +0 -126
- ccxt/test/base/test_ticker.py +0 -92
- ccxt/test/base/test_trade.py +0 -47
- ccxt/test/base/test_trading_fee.py +0 -26
- ccxt/test/base/test_transaction.py +0 -39
- ccxt/test/test_async.py +0 -1649
- ccxt/test/test_sync.py +0 -1648
- ccxt/wazirx.py +0 -1224
- ccxt_ir-4.3.46.0.2.dist-info/RECORD +0 -772
- /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
- {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info/licenses}/LICENSE.txt +0 -0
- {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/top_level.txt +0 -0
ccxt/async_support/phemex.py
CHANGED
|
@@ -5,9 +5,10 @@
|
|
|
5
5
|
|
|
6
6
|
from ccxt.async_support.base.exchange import Exchange
|
|
7
7
|
from ccxt.abstract.phemex import ImplicitAPI
|
|
8
|
+
import asyncio
|
|
8
9
|
import hashlib
|
|
9
10
|
import numbers
|
|
10
|
-
from ccxt.base.types import Balances, Currencies, Currency, Int, LeverageTier, LeverageTiers, MarginModification, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
|
11
|
+
from ccxt.base.types import Any, Balances, Conversion, Currencies, Currency, DepositAddress, Int, LeverageTier, LeverageTiers, MarginModification, Market, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, Trade, Transaction, TransferEntry
|
|
11
12
|
from typing import List
|
|
12
13
|
from ccxt.base.errors import ExchangeError
|
|
13
14
|
from ccxt.base.errors import AuthenticationError
|
|
@@ -19,17 +20,17 @@ from ccxt.base.errors import BadSymbol
|
|
|
19
20
|
from ccxt.base.errors import InsufficientFunds
|
|
20
21
|
from ccxt.base.errors import InvalidOrder
|
|
21
22
|
from ccxt.base.errors import OrderNotFound
|
|
22
|
-
from ccxt.base.errors import CancelPending
|
|
23
23
|
from ccxt.base.errors import DuplicateOrderId
|
|
24
24
|
from ccxt.base.errors import DDoSProtection
|
|
25
25
|
from ccxt.base.errors import RateLimitExceeded
|
|
26
|
+
from ccxt.base.errors import CancelPending
|
|
26
27
|
from ccxt.base.decimal_to_precision import TICK_SIZE
|
|
27
28
|
from ccxt.base.precise import Precise
|
|
28
29
|
|
|
29
30
|
|
|
30
31
|
class phemex(Exchange, ImplicitAPI):
|
|
31
32
|
|
|
32
|
-
def describe(self):
|
|
33
|
+
def describe(self) -> Any:
|
|
33
34
|
return self.deep_extend(super(phemex, self).describe(), {
|
|
34
35
|
'id': 'phemex',
|
|
35
36
|
'name': 'Phemex',
|
|
@@ -50,6 +51,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
50
51
|
'cancelAllOrders': True,
|
|
51
52
|
'cancelOrder': True,
|
|
52
53
|
'closePosition': False,
|
|
54
|
+
'createConvertTrade': True,
|
|
53
55
|
'createOrder': True,
|
|
54
56
|
'createReduceOnlyOrder': True,
|
|
55
57
|
'createStopLimitOrder': True,
|
|
@@ -60,10 +62,15 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
60
62
|
'fetchBorrowRateHistories': False,
|
|
61
63
|
'fetchBorrowRateHistory': False,
|
|
62
64
|
'fetchClosedOrders': True,
|
|
65
|
+
'fetchConvertQuote': True,
|
|
66
|
+
'fetchConvertTrade': False,
|
|
67
|
+
'fetchConvertTradeHistory': True,
|
|
63
68
|
'fetchCrossBorrowRate': False,
|
|
64
69
|
'fetchCrossBorrowRates': False,
|
|
65
70
|
'fetchCurrencies': True,
|
|
66
71
|
'fetchDepositAddress': True,
|
|
72
|
+
'fetchDepositAddresses': False,
|
|
73
|
+
'fetchDepositAddressesByNetwork': False,
|
|
67
74
|
'fetchDeposits': True,
|
|
68
75
|
'fetchFundingHistory': True,
|
|
69
76
|
'fetchFundingRate': True,
|
|
@@ -80,6 +87,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
80
87
|
'fetchMarkOHLCV': False,
|
|
81
88
|
'fetchMyTrades': True,
|
|
82
89
|
'fetchOHLCV': True,
|
|
90
|
+
'fetchOpenInterest': True,
|
|
83
91
|
'fetchOpenOrders': True,
|
|
84
92
|
'fetchOrder': True,
|
|
85
93
|
'fetchOrderBook': True,
|
|
@@ -118,7 +126,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
118
126
|
'private': 'https://{hostname}',
|
|
119
127
|
},
|
|
120
128
|
'www': 'https://phemex.com',
|
|
121
|
-
'doc': 'https://
|
|
129
|
+
'doc': 'https://phemex-docs.github.io/#overview',
|
|
122
130
|
'fees': 'https://phemex.com/fees-conditions',
|
|
123
131
|
'referral': {
|
|
124
132
|
'url': 'https://phemex.com/register?referralCode=EDNVJ',
|
|
@@ -176,6 +184,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
176
184
|
'v2': {
|
|
177
185
|
'get': {
|
|
178
186
|
'public/products': 5,
|
|
187
|
+
'public/products-plus': 5,
|
|
179
188
|
'md/v2/orderbook': 5, # ?symbol=<symbol>&id=<id>
|
|
180
189
|
'md/v2/trade': 5, # ?symbol=<symbol>&id=<id>
|
|
181
190
|
'md/v2/ticker/24hr': 5, # ?symbol=<symbol>&id=<id>
|
|
@@ -273,6 +282,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
273
282
|
# swap
|
|
274
283
|
'orders/replace': 1, # ?symbol=<symbol>&orderID=<orderID>&origClOrdID=<origClOrdID>&clOrdID=<clOrdID>&price=<price>&priceEp=<priceEp>&orderQty=<orderQty>&stopPx=<stopPx>&stopPxEp=<stopPxEp>&takeProfit=<takeProfit>&takeProfitEp=<takeProfitEp>&stopLoss=<stopLoss>&stopLossEp=<stopLossEp>&pegOffsetValueEp=<pegOffsetValueEp>&pegPriceType=<pegPriceType>
|
|
275
284
|
'g-orders/replace': 1, # ?symbol=<symbol>&orderID=<orderID>&origClOrdID=<origClOrdID>&clOrdID=<clOrdID>&price=<price>&priceEp=<priceEp>&orderQty=<orderQty>&stopPx=<stopPx>&stopPxEp=<stopPxEp>&takeProfit=<takeProfit>&takeProfitEp=<takeProfitEp>&stopLoss=<stopLoss>&stopLossEp=<stopLossEp>&pegOffsetValueEp=<pegOffsetValueEp>&pegPriceType=<pegPriceType>
|
|
285
|
+
'g-orders/create': 1,
|
|
276
286
|
'positions/leverage': 5, # ?symbol=<symbol>&leverage=<leverage>&leverageEr=<leverageEr>
|
|
277
287
|
'g-positions/leverage': 5, # ?symbol=<symbol>&leverage=<leverage>&leverageEr=<leverageEr>
|
|
278
288
|
'g-positions/switch-pos-mode-sync': 5, # ?symbol=<symbol>&targetPosMode=<targetPosMode>
|
|
@@ -302,6 +312,114 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
302
312
|
'maker': self.parse_number('0.001'),
|
|
303
313
|
},
|
|
304
314
|
},
|
|
315
|
+
'features': {
|
|
316
|
+
'default': {
|
|
317
|
+
'sandbox': True,
|
|
318
|
+
'createOrder': {
|
|
319
|
+
'marginMode': False,
|
|
320
|
+
'triggerPrice': True,
|
|
321
|
+
# todo
|
|
322
|
+
'triggerPriceType': {
|
|
323
|
+
'mark': True,
|
|
324
|
+
'last': True,
|
|
325
|
+
'index': True,
|
|
326
|
+
},
|
|
327
|
+
'triggerDirection': False,
|
|
328
|
+
'stopLossPrice': False, # todo
|
|
329
|
+
'takeProfitPrice': False, # todo
|
|
330
|
+
'attachedStopLossTakeProfit': None,
|
|
331
|
+
'timeInForce': {
|
|
332
|
+
'IOC': True,
|
|
333
|
+
'FOK': True,
|
|
334
|
+
'PO': True,
|
|
335
|
+
'GTD': False,
|
|
336
|
+
},
|
|
337
|
+
'hedged': False,
|
|
338
|
+
'leverage': False,
|
|
339
|
+
'marketBuyByCost': True,
|
|
340
|
+
'marketBuyRequiresPrice': False,
|
|
341
|
+
'selfTradePrevention': False,
|
|
342
|
+
'trailing': False,
|
|
343
|
+
'iceberg': False,
|
|
344
|
+
},
|
|
345
|
+
'createOrders': None,
|
|
346
|
+
'fetchMyTrades': {
|
|
347
|
+
'marginMode': False,
|
|
348
|
+
'limit': 200,
|
|
349
|
+
'daysBack': 100000,
|
|
350
|
+
'untilDays': 2, # todo implement
|
|
351
|
+
'symbolRequired': False,
|
|
352
|
+
},
|
|
353
|
+
'fetchOrder': {
|
|
354
|
+
'marginMode': False,
|
|
355
|
+
'trigger': False,
|
|
356
|
+
'trailing': False,
|
|
357
|
+
'symbolRequired': True,
|
|
358
|
+
},
|
|
359
|
+
'fetchOpenOrders': {
|
|
360
|
+
'marginMode': False,
|
|
361
|
+
'limit': None,
|
|
362
|
+
'trigger': False,
|
|
363
|
+
'trailing': False,
|
|
364
|
+
'symbolRequired': True,
|
|
365
|
+
},
|
|
366
|
+
'fetchOrders': {
|
|
367
|
+
'marginMode': False,
|
|
368
|
+
'limit': None,
|
|
369
|
+
'daysBack': None,
|
|
370
|
+
'untilDays': None,
|
|
371
|
+
'trigger': False,
|
|
372
|
+
'trailing': False,
|
|
373
|
+
'symbolRequired': True,
|
|
374
|
+
},
|
|
375
|
+
'fetchClosedOrders': {
|
|
376
|
+
'marginMode': False,
|
|
377
|
+
'limit': 200,
|
|
378
|
+
'daysBack': 100000,
|
|
379
|
+
'daysBackCanceled': 100000,
|
|
380
|
+
'untilDays': 2,
|
|
381
|
+
'trigger': False,
|
|
382
|
+
'trailing': False,
|
|
383
|
+
'symbolRequired': False,
|
|
384
|
+
},
|
|
385
|
+
'fetchOHLCV': {
|
|
386
|
+
'limit': 1000,
|
|
387
|
+
},
|
|
388
|
+
},
|
|
389
|
+
'spot': {
|
|
390
|
+
'extends': 'default',
|
|
391
|
+
},
|
|
392
|
+
'forDerivatives': {
|
|
393
|
+
'extends': 'default',
|
|
394
|
+
'createOrder': {
|
|
395
|
+
'triggerDirection': True,
|
|
396
|
+
'attachedStopLossTakeProfit': {
|
|
397
|
+
'triggerPriceType': {
|
|
398
|
+
'mark': True,
|
|
399
|
+
'last': True,
|
|
400
|
+
'index': True,
|
|
401
|
+
},
|
|
402
|
+
'price': True,
|
|
403
|
+
},
|
|
404
|
+
'hedged': True,
|
|
405
|
+
},
|
|
406
|
+
'fetchOHLCV': {
|
|
407
|
+
'limit': 2000,
|
|
408
|
+
},
|
|
409
|
+
},
|
|
410
|
+
'swap': {
|
|
411
|
+
'linear': {
|
|
412
|
+
'extends': 'forDerivatives',
|
|
413
|
+
},
|
|
414
|
+
'inverse': {
|
|
415
|
+
'extends': 'forDerivatives',
|
|
416
|
+
},
|
|
417
|
+
},
|
|
418
|
+
'future': {
|
|
419
|
+
'linear': None,
|
|
420
|
+
'inverse': None,
|
|
421
|
+
},
|
|
422
|
+
},
|
|
305
423
|
'requiredCredentials': {
|
|
306
424
|
'apiKey': True,
|
|
307
425
|
'secret': True,
|
|
@@ -481,6 +599,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
481
599
|
},
|
|
482
600
|
'defaultNetworks': {
|
|
483
601
|
'USDT': 'ETH',
|
|
602
|
+
'MKR': 'ETH',
|
|
484
603
|
},
|
|
485
604
|
'defaultSubType': 'linear',
|
|
486
605
|
'accountsByType': {
|
|
@@ -500,6 +619,13 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
500
619
|
'transfer': {
|
|
501
620
|
'fillResponseFromRequest': True,
|
|
502
621
|
},
|
|
622
|
+
'triggerPriceTypesMap': {
|
|
623
|
+
'last': 'ByLastPrice',
|
|
624
|
+
'mark': 'ByMarkPrice',
|
|
625
|
+
'index': 'ByIndexPrice',
|
|
626
|
+
'ask': 'ByAskPrice',
|
|
627
|
+
'bid': 'ByBidPrice',
|
|
628
|
+
},
|
|
503
629
|
},
|
|
504
630
|
})
|
|
505
631
|
|
|
@@ -514,7 +640,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
514
640
|
def parse_swap_market(self, market: dict):
|
|
515
641
|
#
|
|
516
642
|
# {
|
|
517
|
-
# "symbol":"BTCUSD",
|
|
643
|
+
# "symbol":"BTCUSD", #
|
|
518
644
|
# "code":"1",
|
|
519
645
|
# "type":"Perpetual",
|
|
520
646
|
# "displaySymbol":"BTC / USD",
|
|
@@ -522,7 +648,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
522
648
|
# "markSymbol":".MBTC",
|
|
523
649
|
# "fundingRateSymbol":".BTCFR",
|
|
524
650
|
# "fundingRate8hSymbol":".BTCFR8H",
|
|
525
|
-
# "contractUnderlyingAssets":"USD",
|
|
651
|
+
# "contractUnderlyingAssets":"USD", # or eg. `1000 SHIB`
|
|
526
652
|
# "settleCurrency":"BTC",
|
|
527
653
|
# "quoteCurrency":"USD",
|
|
528
654
|
# "contractSize":"1 USD",
|
|
@@ -562,15 +688,20 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
562
688
|
# }
|
|
563
689
|
#
|
|
564
690
|
id = self.safe_string(market, 'symbol')
|
|
565
|
-
|
|
691
|
+
contractUnderlyingAssets = self.safe_string(market, 'contractUnderlyingAssets')
|
|
692
|
+
baseId = self.safe_string(market, 'baseCurrency', contractUnderlyingAssets)
|
|
566
693
|
quoteId = self.safe_string(market, 'quoteCurrency')
|
|
567
694
|
settleId = self.safe_string(market, 'settleCurrency')
|
|
568
695
|
base = self.safe_currency_code(baseId)
|
|
696
|
+
base = base.replace(' ', '') # replace space for junction codes, eg. `1000 SHIB`
|
|
569
697
|
quote = self.safe_currency_code(quoteId)
|
|
570
698
|
settle = self.safe_currency_code(settleId)
|
|
571
699
|
inverse = False
|
|
572
700
|
if settleId != quoteId:
|
|
573
701
|
inverse = True
|
|
702
|
+
# some unhandled cases
|
|
703
|
+
if not ('baseCurrency' in market) and base == quote:
|
|
704
|
+
base = settle
|
|
574
705
|
priceScale = self.safe_integer(market, 'priceScale')
|
|
575
706
|
ratioScale = self.safe_integer(market, 'ratioScale')
|
|
576
707
|
valueScale = self.safe_integer(market, 'valueScale')
|
|
@@ -743,17 +874,20 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
743
874
|
'max': self.parse_safe_number(self.safe_string(market, 'maxOrderValue')),
|
|
744
875
|
},
|
|
745
876
|
},
|
|
746
|
-
'created':
|
|
877
|
+
'created': self.safe_integer(market, 'listTime'),
|
|
747
878
|
'info': market,
|
|
748
879
|
})
|
|
749
880
|
|
|
750
881
|
async def fetch_markets(self, params={}) -> List[Market]:
|
|
751
882
|
"""
|
|
752
883
|
retrieves data on all markets for phemex
|
|
884
|
+
|
|
885
|
+
https://phemex-docs.github.io/#query-product-information-3
|
|
886
|
+
|
|
753
887
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
754
888
|
:returns dict[]: an array of objects representing market data
|
|
755
889
|
"""
|
|
756
|
-
|
|
890
|
+
v2ProductsPromise = self.v2GetPublicProducts(params)
|
|
757
891
|
#
|
|
758
892
|
# {
|
|
759
893
|
# "code":0,
|
|
@@ -903,7 +1037,8 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
903
1037
|
# }
|
|
904
1038
|
# }
|
|
905
1039
|
#
|
|
906
|
-
|
|
1040
|
+
v1ProductsPromise = self.v1GetExchangePublicProducts(params)
|
|
1041
|
+
v2Products, v1Products = await asyncio.gather(*[v2ProductsPromise, v1ProductsPromise])
|
|
907
1042
|
v1ProductsData = self.safe_value(v1Products, 'data', [])
|
|
908
1043
|
#
|
|
909
1044
|
# {
|
|
@@ -940,14 +1075,14 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
940
1075
|
# ]
|
|
941
1076
|
# }
|
|
942
1077
|
#
|
|
943
|
-
v2ProductsData = self.
|
|
944
|
-
products = self.
|
|
945
|
-
perpetualProductsV2 = self.
|
|
1078
|
+
v2ProductsData = self.safe_dict(v2Products, 'data', {})
|
|
1079
|
+
products = self.safe_list(v2ProductsData, 'products', [])
|
|
1080
|
+
perpetualProductsV2 = self.safe_list(v2ProductsData, 'perpProductsV2', [])
|
|
946
1081
|
products = self.array_concat(products, perpetualProductsV2)
|
|
947
|
-
riskLimits = self.
|
|
948
|
-
riskLimitsV2 = self.
|
|
1082
|
+
riskLimits = self.safe_list(v2ProductsData, 'riskLimits', [])
|
|
1083
|
+
riskLimitsV2 = self.safe_list(v2ProductsData, 'riskLimitsV2', [])
|
|
949
1084
|
riskLimits = self.array_concat(riskLimits, riskLimitsV2)
|
|
950
|
-
currencies = self.
|
|
1085
|
+
currencies = self.safe_list(v2ProductsData, 'currencies', [])
|
|
951
1086
|
riskLimitsById = self.index_by(riskLimits, 'symbol')
|
|
952
1087
|
v1ProductsById = self.index_by(v1ProductsData, 'symbol')
|
|
953
1088
|
currenciesByCode = self.index_by(currencies, 'currency')
|
|
@@ -955,16 +1090,16 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
955
1090
|
for i in range(0, len(products)):
|
|
956
1091
|
market = products[i]
|
|
957
1092
|
type = self.safe_string_lower(market, 'type')
|
|
958
|
-
if (type == 'perpetual') or (type == 'perpetualv2'):
|
|
1093
|
+
if (type == 'perpetual') or (type == 'perpetualv2') or (type == 'perpetualpilot'):
|
|
959
1094
|
id = self.safe_string(market, 'symbol')
|
|
960
|
-
riskLimitValues = self.
|
|
1095
|
+
riskLimitValues = self.safe_dict(riskLimitsById, id, {})
|
|
961
1096
|
market = self.extend(market, riskLimitValues)
|
|
962
|
-
v1ProductsValues = self.
|
|
1097
|
+
v1ProductsValues = self.safe_dict(v1ProductsById, id, {})
|
|
963
1098
|
market = self.extend(market, v1ProductsValues)
|
|
964
1099
|
market = self.parse_swap_market(market)
|
|
965
1100
|
else:
|
|
966
1101
|
baseCurrency = self.safe_string(market, 'baseCurrency')
|
|
967
|
-
currencyValues = self.
|
|
1102
|
+
currencyValues = self.safe_dict(currenciesByCode, baseCurrency, {})
|
|
968
1103
|
valueScale = self.safe_string(currencyValues, 'valueScale', '8')
|
|
969
1104
|
market = self.extend(market, {'valueScale': valueScale})
|
|
970
1105
|
market = self.parse_spot_market(market)
|
|
@@ -998,9 +1133,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
998
1133
|
for i in range(0, len(currencies)):
|
|
999
1134
|
currency = currencies[i]
|
|
1000
1135
|
id = self.safe_string(currency, 'currency')
|
|
1001
|
-
name = self.safe_string(currency, 'name')
|
|
1002
1136
|
code = self.safe_currency_code(id)
|
|
1003
|
-
status = self.safe_string(currency, 'status')
|
|
1004
1137
|
valueScaleString = self.safe_string(currency, 'valueScale')
|
|
1005
1138
|
valueScale = int(valueScaleString)
|
|
1006
1139
|
minValueEv = self.safe_string(currency, 'minValueEv')
|
|
@@ -1013,12 +1146,12 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
1013
1146
|
precision = self.parse_number(precisionString)
|
|
1014
1147
|
minAmount = self.parse_number(Precise.string_mul(minValueEv, precisionString))
|
|
1015
1148
|
maxAmount = self.parse_number(Precise.string_mul(maxValueEv, precisionString))
|
|
1016
|
-
result[code] = {
|
|
1149
|
+
result[code] = self.safe_currency_structure({
|
|
1017
1150
|
'id': id,
|
|
1018
1151
|
'info': currency,
|
|
1019
1152
|
'code': code,
|
|
1020
|
-
'name': name,
|
|
1021
|
-
'active': status == 'Listed',
|
|
1153
|
+
'name': self.safe_string(currency, 'name'),
|
|
1154
|
+
'active': self.safe_string(currency, 'status') == 'Listed',
|
|
1022
1155
|
'deposit': None,
|
|
1023
1156
|
'withdraw': None,
|
|
1024
1157
|
'fee': None,
|
|
@@ -1034,8 +1167,9 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
1034
1167
|
},
|
|
1035
1168
|
},
|
|
1036
1169
|
'valueScale': valueScale,
|
|
1037
|
-
'networks':
|
|
1038
|
-
|
|
1170
|
+
'networks': None,
|
|
1171
|
+
'type': 'crypto',
|
|
1172
|
+
})
|
|
1039
1173
|
return result
|
|
1040
1174
|
|
|
1041
1175
|
def custom_parse_bid_ask(self, bidask, priceKey=0, amountKey=1, market: Market = None):
|
|
@@ -1071,7 +1205,9 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
1071
1205
|
async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
|
1072
1206
|
"""
|
|
1073
1207
|
fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
|
1074
|
-
|
|
1208
|
+
|
|
1209
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#queryorderbook
|
|
1210
|
+
|
|
1075
1211
|
:param str symbol: unified symbol of the market to fetch the order book for
|
|
1076
1212
|
:param int [limit]: the maximum amount of order book entries to return
|
|
1077
1213
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -1084,7 +1220,8 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
1084
1220
|
# 'id': 123456789, # optional request id
|
|
1085
1221
|
}
|
|
1086
1222
|
response = None
|
|
1087
|
-
|
|
1223
|
+
isStableSettled = (market['settle'] == 'USDT') or (market['settle'] == 'USDC')
|
|
1224
|
+
if market['linear'] and isStableSettled:
|
|
1088
1225
|
response = await self.v2GetMdV2Orderbook(self.extend(request, params))
|
|
1089
1226
|
else:
|
|
1090
1227
|
if (limit is not None) and (limit <= 30):
|
|
@@ -1129,7 +1266,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
1129
1266
|
precise.decimals = precise.decimals - scale
|
|
1130
1267
|
precise.reduce()
|
|
1131
1268
|
preciseString = str(precise)
|
|
1132
|
-
return self.
|
|
1269
|
+
return self.parse_to_numeric(preciseString)
|
|
1133
1270
|
|
|
1134
1271
|
def to_ev(self, amount, market: Market = None):
|
|
1135
1272
|
if (amount is None) or (market is None):
|
|
@@ -1142,7 +1279,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
1142
1279
|
return self.to_en(price, market['priceScale'])
|
|
1143
1280
|
|
|
1144
1281
|
def from_en(self, en, scale):
|
|
1145
|
-
if en is None:
|
|
1282
|
+
if en is None or scale is None:
|
|
1146
1283
|
return None
|
|
1147
1284
|
precise = Precise(en)
|
|
1148
1285
|
precise.decimals = self.sum(precise.decimals, scale)
|
|
@@ -1195,8 +1332,10 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
1195
1332
|
async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
|
1196
1333
|
"""
|
|
1197
1334
|
fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
|
1198
|
-
|
|
1199
|
-
|
|
1335
|
+
|
|
1336
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#querykline
|
|
1337
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md#query-kline
|
|
1338
|
+
|
|
1200
1339
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
|
1201
1340
|
:param str timeframe: the length of time each candle represents
|
|
1202
1341
|
:param int [since]: *only used for USDT settled contracts, otherwise is emulated and not supported by the exchange* timestamp in ms of the earliest candle to fetch
|
|
@@ -1214,7 +1353,8 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
1214
1353
|
}
|
|
1215
1354
|
until = self.safe_integer_2(params, 'until', 'to')
|
|
1216
1355
|
params = self.omit(params, ['until'])
|
|
1217
|
-
|
|
1356
|
+
isStableSettled = (market['settle'] == 'USDT') or (market['settle'] == 'USDC')
|
|
1357
|
+
usesSpecialFromToEndpoint = ((market['linear'] or isStableSettled)) and ((since is not None) or (until is not None))
|
|
1218
1358
|
maxLimit = 1000
|
|
1219
1359
|
if usesSpecialFromToEndpoint:
|
|
1220
1360
|
maxLimit = 2000
|
|
@@ -1222,7 +1362,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
1222
1362
|
limit = maxLimit
|
|
1223
1363
|
request['limit'] = min(limit, maxLimit)
|
|
1224
1364
|
response = None
|
|
1225
|
-
if market['linear'] or
|
|
1365
|
+
if market['linear'] or isStableSettled:
|
|
1226
1366
|
if (until is not None) or (since is not None):
|
|
1227
1367
|
candleDuration = self.parse_timeframe(timeframe)
|
|
1228
1368
|
if since is not None:
|
|
@@ -1359,7 +1499,9 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
1359
1499
|
async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
|
|
1360
1500
|
"""
|
|
1361
1501
|
fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
|
1362
|
-
|
|
1502
|
+
|
|
1503
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#query24hrsticker
|
|
1504
|
+
|
|
1363
1505
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
|
1364
1506
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1365
1507
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
@@ -1428,9 +1570,11 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
1428
1570
|
async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
|
1429
1571
|
"""
|
|
1430
1572
|
fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1573
|
+
|
|
1574
|
+
https://phemex-docs.github.io/#query-24-hours-ticker-for-all-symbols-2 # spot
|
|
1575
|
+
https://phemex-docs.github.io/#query-24-ticker-for-all-symbols # linear
|
|
1576
|
+
https://phemex-docs.github.io/#query-24-hours-ticker-for-all-symbols # inverse
|
|
1577
|
+
|
|
1434
1578
|
:param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
|
1435
1579
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1436
1580
|
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
|
@@ -1458,7 +1602,9 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
1458
1602
|
async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
|
1459
1603
|
"""
|
|
1460
1604
|
get the list of most recent trades for a particular symbol
|
|
1461
|
-
|
|
1605
|
+
|
|
1606
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#querytrades
|
|
1607
|
+
|
|
1462
1608
|
:param str symbol: unified symbol of the market to fetch trades for
|
|
1463
1609
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
|
1464
1610
|
:param int [limit]: the maximum amount of trades to fetch
|
|
@@ -1472,7 +1618,8 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
1472
1618
|
# 'id': 123456789, # optional request id
|
|
1473
1619
|
}
|
|
1474
1620
|
response = None
|
|
1475
|
-
|
|
1621
|
+
isStableSettled = (market['settle'] == 'USDT') or (market['settle'] == 'USDC')
|
|
1622
|
+
if market['linear'] and isStableSettled:
|
|
1476
1623
|
response = await self.v2GetMdV2Trade(self.extend(request, params))
|
|
1477
1624
|
else:
|
|
1478
1625
|
response = await self.v1GetMdTrade(self.extend(request, params))
|
|
@@ -1711,7 +1858,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
1711
1858
|
timestamp = self.safe_integer(trade, 'createdAt')
|
|
1712
1859
|
id = self.safe_string_2(trade, 'execId', 'execID')
|
|
1713
1860
|
orderId = self.safe_string(trade, 'orderID')
|
|
1714
|
-
if market['settle'] == 'USDT':
|
|
1861
|
+
if market['settle'] == 'USDT' or market['settle'] == 'USDC':
|
|
1715
1862
|
sideId = self.safe_string_lower(trade, 'side')
|
|
1716
1863
|
if (sideId == 'buy') or (sideId == 'sell'):
|
|
1717
1864
|
side = sideId
|
|
@@ -1881,9 +2028,11 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
1881
2028
|
async def fetch_balance(self, params={}) -> Balances:
|
|
1882
2029
|
"""
|
|
1883
2030
|
query for balance and get the amount of funds available for trading or funds locked in orders
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
2031
|
+
|
|
2032
|
+
https://phemex-docs.github.io/#query-wallets
|
|
2033
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#query-account-positions
|
|
2034
|
+
https://phemex-docs.github.io/#query-trading-account-and-positions
|
|
2035
|
+
|
|
1887
2036
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
1888
2037
|
:param str [params.type]: spot or swap
|
|
1889
2038
|
:param str [params.code]: *swap only* currency code of the balance to query(USD, USDT, etc), default is USDT
|
|
@@ -2037,8 +2186,9 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2037
2186
|
# }
|
|
2038
2187
|
# }
|
|
2039
2188
|
#
|
|
2040
|
-
|
|
2041
|
-
|
|
2189
|
+
if type == 'swap':
|
|
2190
|
+
return self.parse_swap_balance(response)
|
|
2191
|
+
return self.parse_spot_balance(response)
|
|
2042
2192
|
|
|
2043
2193
|
def parse_order_status(self, status: Str):
|
|
2044
2194
|
statuses: dict = {
|
|
@@ -2051,6 +2201,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2051
2201
|
'PartiallyFilled': 'open',
|
|
2052
2202
|
'Filled': 'closed',
|
|
2053
2203
|
'Canceled': 'canceled',
|
|
2204
|
+
'Suspended': 'canceled',
|
|
2054
2205
|
'1': 'open',
|
|
2055
2206
|
'2': 'canceled',
|
|
2056
2207
|
'3': 'closed',
|
|
@@ -2170,7 +2321,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2170
2321
|
'currency': self.safe_currency_code(self.safe_string(order, 'feeCurrency')),
|
|
2171
2322
|
}
|
|
2172
2323
|
timeInForce = self.parse_time_in_force(self.safe_string(order, 'timeInForce'))
|
|
2173
|
-
|
|
2324
|
+
triggerPrice = self.parse_number(self.omit_zero(self.from_ep(self.safe_string(order, 'stopPxEp'))))
|
|
2174
2325
|
postOnly = (timeInForce == 'PO')
|
|
2175
2326
|
return self.safe_order({
|
|
2176
2327
|
'info': order,
|
|
@@ -2185,8 +2336,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2185
2336
|
'postOnly': postOnly,
|
|
2186
2337
|
'side': side,
|
|
2187
2338
|
'price': price,
|
|
2188
|
-
'
|
|
2189
|
-
'triggerPrice': stopPrice,
|
|
2339
|
+
'triggerPrice': triggerPrice,
|
|
2190
2340
|
'amount': amount,
|
|
2191
2341
|
'cost': cost,
|
|
2192
2342
|
'average': average,
|
|
@@ -2330,7 +2480,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2330
2480
|
if lastTradeTimestamp == 0:
|
|
2331
2481
|
lastTradeTimestamp = None
|
|
2332
2482
|
timeInForce = self.parse_time_in_force(self.safe_string(order, 'timeInForce'))
|
|
2333
|
-
|
|
2483
|
+
triggerPrice = self.omit_zero(self.safe_string_2(order, 'stopPx', 'stopPxRp'))
|
|
2334
2484
|
postOnly = (timeInForce == 'PO')
|
|
2335
2485
|
reduceOnly = self.safe_value(order, 'reduceOnly')
|
|
2336
2486
|
execInst = self.safe_string(order, 'execInst')
|
|
@@ -2365,8 +2515,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2365
2515
|
'reduceOnly': reduceOnly,
|
|
2366
2516
|
'side': side,
|
|
2367
2517
|
'price': price,
|
|
2368
|
-
'
|
|
2369
|
-
'triggerPrice': stopPrice,
|
|
2518
|
+
'triggerPrice': triggerPrice,
|
|
2370
2519
|
'takeProfitPrice': takeProfit,
|
|
2371
2520
|
'stopLossPrice': stopLoss,
|
|
2372
2521
|
'amount': amount,
|
|
@@ -2389,26 +2538,29 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2389
2538
|
async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
|
2390
2539
|
"""
|
|
2391
2540
|
create a trade order
|
|
2392
|
-
|
|
2393
|
-
|
|
2541
|
+
|
|
2542
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#place-order
|
|
2543
|
+
https://phemex-docs.github.io/#place-order-http-put-prefered-3
|
|
2544
|
+
|
|
2394
2545
|
:param str symbol: unified symbol of the market to create an order in
|
|
2395
2546
|
:param str type: 'market' or 'limit'
|
|
2396
2547
|
:param str side: 'buy' or 'sell'
|
|
2397
2548
|
:param float amount: how much of currency you want to trade in units of base currency
|
|
2398
|
-
:param float [price]: the price at which the order is to be
|
|
2549
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
2399
2550
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
2400
2551
|
:param float [params.trigger]: trigger price for conditional orders
|
|
2401
2552
|
:param dict [params.takeProfit]: *swap only* *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered(perpetual swap markets only)
|
|
2402
2553
|
:param float [params.takeProfit.triggerPrice]: take profit trigger price
|
|
2403
2554
|
:param dict [params.stopLoss]: *swap only* *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered(perpetual swap markets only)
|
|
2404
2555
|
:param float [params.stopLoss.triggerPrice]: stop loss trigger price
|
|
2556
|
+
:param str [params.posSide]: *swap only* "Merged" for one way mode, "Long" for buy side of hedged mode, "Short" for sell side of hedged mode
|
|
2557
|
+
:param bool [params.hedged]: *swap only* True for hedged mode, False for one way mode, default is False
|
|
2405
2558
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
2406
2559
|
"""
|
|
2407
2560
|
await self.load_markets()
|
|
2408
2561
|
market = self.market(symbol)
|
|
2409
2562
|
requestSide = self.capitalize(side)
|
|
2410
2563
|
type = self.capitalize(type)
|
|
2411
|
-
reduceOnly = self.safe_bool(params, 'reduceOnly')
|
|
2412
2564
|
request: dict = {
|
|
2413
2565
|
# common
|
|
2414
2566
|
'symbol': market['id'],
|
|
@@ -2442,6 +2594,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2442
2594
|
stopLossDefined = (stopLoss is not None)
|
|
2443
2595
|
takeProfit = self.safe_value(params, 'takeProfit')
|
|
2444
2596
|
takeProfitDefined = (takeProfit is not None)
|
|
2597
|
+
isStableSettled = (market['settle'] == 'USDT') or (market['settle'] == 'USDC')
|
|
2445
2598
|
if clientOrderId is None:
|
|
2446
2599
|
brokerId = self.safe_string(self.options, 'brokerId', 'CCXT123456')
|
|
2447
2600
|
if brokerId is not None:
|
|
@@ -2451,7 +2604,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2451
2604
|
params = self.omit(params, ['clOrdID', 'clientOrderId'])
|
|
2452
2605
|
triggerPrice = self.safe_string_n(params, ['stopPx', 'stopPrice', 'triggerPrice'])
|
|
2453
2606
|
if triggerPrice is not None:
|
|
2454
|
-
if
|
|
2607
|
+
if isStableSettled:
|
|
2455
2608
|
request['stopPxRp'] = self.price_to_precision(symbol, triggerPrice)
|
|
2456
2609
|
else:
|
|
2457
2610
|
request['stopPxEp'] = self.to_ep(triggerPrice, market)
|
|
@@ -2486,78 +2639,94 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2486
2639
|
amountString = self.number_to_string(amount)
|
|
2487
2640
|
request['baseQtyEv'] = self.to_ev(amountString, market)
|
|
2488
2641
|
elif market['swap']:
|
|
2642
|
+
hedged = self.safe_bool(params, 'hedged', False)
|
|
2643
|
+
params = self.omit(params, 'hedged')
|
|
2489
2644
|
posSide = self.safe_string_lower(params, 'posSide')
|
|
2490
2645
|
if posSide is None:
|
|
2491
|
-
|
|
2646
|
+
if hedged:
|
|
2647
|
+
reduceOnly = self.safe_bool(params, 'reduceOnly')
|
|
2648
|
+
if reduceOnly:
|
|
2649
|
+
side = 'sell' if (side == 'buy') else 'buy'
|
|
2650
|
+
params = self.omit(params, 'reduceOnly')
|
|
2651
|
+
posSide = 'Long' if (side == 'buy') else 'Short'
|
|
2652
|
+
else:
|
|
2653
|
+
posSide = 'Merged'
|
|
2492
2654
|
posSide = self.capitalize(posSide)
|
|
2493
2655
|
request['posSide'] = posSide
|
|
2494
|
-
if
|
|
2495
|
-
request['reduceOnly'] = reduceOnly
|
|
2496
|
-
if market['settle'] == 'USDT':
|
|
2656
|
+
if isStableSettled:
|
|
2497
2657
|
request['orderQtyRq'] = amount
|
|
2498
2658
|
else:
|
|
2499
2659
|
request['orderQty'] = self.parse_to_int(amount)
|
|
2500
2660
|
if triggerPrice is not None:
|
|
2501
2661
|
triggerType = self.safe_string(params, 'triggerType', 'ByMarkPrice')
|
|
2502
2662
|
request['triggerType'] = triggerType
|
|
2663
|
+
# set direction & exchange specific order type
|
|
2664
|
+
triggerDirection = None
|
|
2665
|
+
triggerDirection, params = self.handle_param_string(params, 'triggerDirection')
|
|
2666
|
+
if triggerDirection is None:
|
|
2667
|
+
raise ArgumentsRequired(self.id + " createOrder() also requires a 'triggerDirection' parameter with either 'ascending' or 'descending' value")
|
|
2668
|
+
# the flow defined per https://phemex-docs.github.io/#more-order-type-examples
|
|
2669
|
+
if triggerDirection == 'ascending' or triggerDirection == 'up':
|
|
2670
|
+
if side == 'sell':
|
|
2671
|
+
request['ordType'] = 'MarketIfTouched' if (type == 'Market') else 'LimitIfTouched'
|
|
2672
|
+
elif side == 'buy':
|
|
2673
|
+
request['ordType'] = 'Stop' if (type == 'Market') else 'StopLimit'
|
|
2674
|
+
elif triggerDirection == 'descending' or triggerDirection == 'down':
|
|
2675
|
+
if side == 'sell':
|
|
2676
|
+
request['ordType'] = 'Stop' if (type == 'Market') else 'StopLimit'
|
|
2677
|
+
elif side == 'buy':
|
|
2678
|
+
request['ordType'] = 'MarketIfTouched' if (type == 'Market') else 'LimitIfTouched'
|
|
2503
2679
|
if stopLossDefined or takeProfitDefined:
|
|
2504
2680
|
if stopLossDefined:
|
|
2505
2681
|
stopLossTriggerPrice = self.safe_value_2(stopLoss, 'triggerPrice', 'stopPrice')
|
|
2506
2682
|
if stopLossTriggerPrice is None:
|
|
2507
|
-
raise InvalidOrder(self.id + ' createOrder() requires a trigger price in params["stopLoss"]["triggerPrice"]
|
|
2508
|
-
if
|
|
2683
|
+
raise InvalidOrder(self.id + ' createOrder() requires a trigger price in params["stopLoss"]["triggerPrice"] for a stop loss order')
|
|
2684
|
+
if isStableSettled:
|
|
2509
2685
|
request['stopLossRp'] = self.price_to_precision(symbol, stopLossTriggerPrice)
|
|
2510
2686
|
else:
|
|
2511
2687
|
request['stopLossEp'] = self.to_ep(stopLossTriggerPrice, market)
|
|
2512
2688
|
stopLossTriggerPriceType = self.safe_string_2(stopLoss, 'triggerPriceType', 'slTrigger')
|
|
2513
2689
|
if stopLossTriggerPriceType is not None:
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2518
|
-
if (stopLossTriggerPriceType != 'ByMarkPrice') and (stopLossTriggerPriceType != 'ByLastPrice'):
|
|
2519
|
-
raise InvalidOrder(self.id + ' createOrder() take profit trigger price type must be one of "ByMarkPrice", or "ByLastPrice"')
|
|
2520
|
-
request['slTrigger'] = stopLossTriggerPriceType
|
|
2690
|
+
request['slTrigger'] = self.safe_string(self.options['triggerPriceTypesMap'], stopLossTriggerPriceType, stopLossTriggerPriceType)
|
|
2691
|
+
slLimitPrice = self.safe_string(stopLoss, 'price')
|
|
2692
|
+
if slLimitPrice is not None:
|
|
2693
|
+
request['slPxRp'] = self.price_to_precision(symbol, slLimitPrice)
|
|
2521
2694
|
if takeProfitDefined:
|
|
2522
2695
|
takeProfitTriggerPrice = self.safe_value_2(takeProfit, 'triggerPrice', 'stopPrice')
|
|
2523
2696
|
if takeProfitTriggerPrice is None:
|
|
2524
|
-
raise InvalidOrder(self.id + ' createOrder() requires a trigger price in params["takeProfit"]["triggerPrice"]
|
|
2525
|
-
if
|
|
2697
|
+
raise InvalidOrder(self.id + ' createOrder() requires a trigger price in params["takeProfit"]["triggerPrice"] for a take profit order')
|
|
2698
|
+
if isStableSettled:
|
|
2526
2699
|
request['takeProfitRp'] = self.price_to_precision(symbol, takeProfitTriggerPrice)
|
|
2527
2700
|
else:
|
|
2528
2701
|
request['takeProfitEp'] = self.to_ep(takeProfitTriggerPrice, market)
|
|
2529
|
-
takeProfitTriggerPriceType = self.safe_string_2(
|
|
2702
|
+
takeProfitTriggerPriceType = self.safe_string_2(takeProfit, 'triggerPriceType', 'tpTrigger')
|
|
2530
2703
|
if takeProfitTriggerPriceType is not None:
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
if (takeProfitTriggerPriceType != 'ByMarkPrice') and (takeProfitTriggerPriceType != 'ByLastPrice'):
|
|
2536
|
-
raise InvalidOrder(self.id + ' createOrder() take profit trigger price type must be one of "ByMarkPrice", or "ByLastPrice"')
|
|
2537
|
-
request['tpTrigger'] = takeProfitTriggerPriceType
|
|
2704
|
+
request['tpTrigger'] = self.safe_string(self.options['triggerPriceTypesMap'], takeProfitTriggerPriceType, takeProfitTriggerPriceType)
|
|
2705
|
+
tpLimitPrice = self.safe_string(takeProfit, 'price')
|
|
2706
|
+
if tpLimitPrice is not None:
|
|
2707
|
+
request['tpPxRp'] = self.price_to_precision(symbol, tpLimitPrice)
|
|
2538
2708
|
if (type == 'Limit') or (type == 'StopLimit') or (type == 'LimitIfTouched'):
|
|
2539
|
-
if
|
|
2709
|
+
if isStableSettled:
|
|
2540
2710
|
request['priceRp'] = self.price_to_precision(symbol, price)
|
|
2541
2711
|
else:
|
|
2542
2712
|
priceString = self.number_to_string(price)
|
|
2543
2713
|
request['priceEp'] = self.to_ep(priceString, market)
|
|
2544
2714
|
takeProfitPrice = self.safe_string(params, 'takeProfitPrice')
|
|
2545
2715
|
if takeProfitPrice is not None:
|
|
2546
|
-
if
|
|
2716
|
+
if isStableSettled:
|
|
2547
2717
|
request['takeProfitRp'] = self.price_to_precision(symbol, takeProfitPrice)
|
|
2548
2718
|
else:
|
|
2549
2719
|
request['takeProfitEp'] = self.to_ep(takeProfitPrice, market)
|
|
2550
2720
|
params = self.omit(params, 'takeProfitPrice')
|
|
2551
2721
|
stopLossPrice = self.safe_string(params, 'stopLossPrice')
|
|
2552
2722
|
if stopLossPrice is not None:
|
|
2553
|
-
if
|
|
2723
|
+
if isStableSettled:
|
|
2554
2724
|
request['stopLossRp'] = self.price_to_precision(symbol, stopLossPrice)
|
|
2555
2725
|
else:
|
|
2556
2726
|
request['stopLossEp'] = self.to_ep(stopLossPrice, market)
|
|
2557
2727
|
params = self.omit(params, 'stopLossPrice')
|
|
2558
|
-
params = self.omit(params, 'reduceOnly')
|
|
2559
2728
|
response = None
|
|
2560
|
-
if
|
|
2729
|
+
if isStableSettled:
|
|
2561
2730
|
response = await self.privatePostGOrders(self.extend(request, params))
|
|
2562
2731
|
elif market['contract']:
|
|
2563
2732
|
response = await self.privatePostOrders(self.extend(request, params))
|
|
@@ -2642,16 +2811,18 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2642
2811
|
data = self.safe_dict(response, 'data', {})
|
|
2643
2812
|
return self.parse_order(data, market)
|
|
2644
2813
|
|
|
2645
|
-
async def edit_order(self, id: str, symbol: str, type: OrderType
|
|
2814
|
+
async def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
|
|
2646
2815
|
"""
|
|
2647
2816
|
edit a trade order
|
|
2648
|
-
|
|
2817
|
+
|
|
2818
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#amend-order-by-orderid
|
|
2819
|
+
|
|
2649
2820
|
:param str id: cancel order id
|
|
2650
2821
|
:param str symbol: unified symbol of the market to create an order in
|
|
2651
2822
|
:param str type: 'market' or 'limit'
|
|
2652
2823
|
:param str side: 'buy' or 'sell'
|
|
2653
2824
|
:param float amount: how much of currency you want to trade in units of base currency
|
|
2654
|
-
:param float [price]: the price at which the order is to be
|
|
2825
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
|
2655
2826
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
2656
2827
|
:param str [params.posSide]: either 'Merged' or 'Long' or 'Short'
|
|
2657
2828
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
@@ -2663,13 +2834,13 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2663
2834
|
}
|
|
2664
2835
|
clientOrderId = self.safe_string_2(params, 'clientOrderId', 'clOrdID')
|
|
2665
2836
|
params = self.omit(params, ['clientOrderId', 'clOrdID'])
|
|
2666
|
-
|
|
2837
|
+
isStableSettled = (market['settle'] == 'USDT') or (market['settle'] == 'USDC')
|
|
2667
2838
|
if clientOrderId is not None:
|
|
2668
2839
|
request['clOrdID'] = clientOrderId
|
|
2669
2840
|
else:
|
|
2670
2841
|
request['orderID'] = id
|
|
2671
2842
|
if price is not None:
|
|
2672
|
-
if
|
|
2843
|
+
if isStableSettled:
|
|
2673
2844
|
request['priceRp'] = self.price_to_precision(market['symbol'], price)
|
|
2674
2845
|
else:
|
|
2675
2846
|
request['priceEp'] = self.to_ep(price, market)
|
|
@@ -2679,19 +2850,19 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2679
2850
|
if finalQty is not None:
|
|
2680
2851
|
request['baseQtyEV'] = finalQty
|
|
2681
2852
|
elif amount is not None:
|
|
2682
|
-
if
|
|
2853
|
+
if isStableSettled:
|
|
2683
2854
|
request['orderQtyRq'] = self.amount_to_precision(market['symbol'], amount)
|
|
2684
2855
|
else:
|
|
2685
2856
|
request['baseQtyEV'] = self.to_ev(amount, market)
|
|
2686
|
-
|
|
2687
|
-
if
|
|
2688
|
-
if
|
|
2689
|
-
request['stopPxRp'] = self.price_to_precision(symbol,
|
|
2857
|
+
triggerPrice = self.safe_string_n(params, ['triggerPrice', 'stopPx', 'stopPrice'])
|
|
2858
|
+
if triggerPrice is not None:
|
|
2859
|
+
if isStableSettled:
|
|
2860
|
+
request['stopPxRp'] = self.price_to_precision(symbol, triggerPrice)
|
|
2690
2861
|
else:
|
|
2691
|
-
request['stopPxEp'] = self.to_ep(
|
|
2692
|
-
params = self.omit(params, ['stopPx', 'stopPrice'])
|
|
2862
|
+
request['stopPxEp'] = self.to_ep(triggerPrice, market)
|
|
2863
|
+
params = self.omit(params, ['triggerPrice', 'stopPx', 'stopPrice'])
|
|
2693
2864
|
response = None
|
|
2694
|
-
if
|
|
2865
|
+
if isStableSettled:
|
|
2695
2866
|
posSide = self.safe_string(params, 'posSide')
|
|
2696
2867
|
if posSide is None:
|
|
2697
2868
|
request['posSide'] = 'Merged'
|
|
@@ -2706,7 +2877,9 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2706
2877
|
async def cancel_order(self, id: str, symbol: Str = None, params={}):
|
|
2707
2878
|
"""
|
|
2708
2879
|
cancels an open order
|
|
2709
|
-
|
|
2880
|
+
|
|
2881
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#cancel-single-order-by-orderid
|
|
2882
|
+
|
|
2710
2883
|
:param str id: order id
|
|
2711
2884
|
:param str symbol: unified symbol of the market the order was made in
|
|
2712
2885
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -2727,7 +2900,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2727
2900
|
else:
|
|
2728
2901
|
request['orderID'] = id
|
|
2729
2902
|
response = None
|
|
2730
|
-
if market['settle'] == 'USDT':
|
|
2903
|
+
if market['settle'] == 'USDT' or market['settle'] == 'USDC':
|
|
2731
2904
|
posSide = self.safe_string(params, 'posSide')
|
|
2732
2905
|
if posSide is None:
|
|
2733
2906
|
request['posSide'] = 'Merged'
|
|
@@ -2742,7 +2915,9 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2742
2915
|
async def cancel_all_orders(self, symbol: Str = None, params={}):
|
|
2743
2916
|
"""
|
|
2744
2917
|
cancel all open orders in a market
|
|
2745
|
-
|
|
2918
|
+
|
|
2919
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#cancelall
|
|
2920
|
+
|
|
2746
2921
|
:param str symbol: unified market symbol of the market to cancel orders in
|
|
2747
2922
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
2748
2923
|
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
|
@@ -2751,28 +2926,58 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2751
2926
|
raise ArgumentsRequired(self.id + ' cancelAllOrders() requires a symbol argument')
|
|
2752
2927
|
await self.load_markets()
|
|
2753
2928
|
market = self.market(symbol)
|
|
2754
|
-
|
|
2755
|
-
params = self.omit(params, 'stop', 'trigger')
|
|
2929
|
+
trigger = self.safe_value_2(params, 'stop', 'trigger', False)
|
|
2930
|
+
params = self.omit(params, ['stop', 'trigger'])
|
|
2756
2931
|
request: dict = {
|
|
2757
2932
|
'symbol': market['id'],
|
|
2758
2933
|
# 'untriggerred': False, # False to cancel non-conditional orders, True to cancel conditional orders
|
|
2759
2934
|
# 'text': 'up to 40 characters max',
|
|
2760
2935
|
}
|
|
2761
|
-
if
|
|
2762
|
-
request['untriggerred'] =
|
|
2936
|
+
if trigger:
|
|
2937
|
+
request['untriggerred'] = trigger
|
|
2763
2938
|
response = None
|
|
2764
|
-
if market['settle'] == 'USDT':
|
|
2939
|
+
if market['settle'] == 'USDT' or market['settle'] == 'USDC':
|
|
2765
2940
|
response = await self.privateDeleteGOrdersAll(self.extend(request, params))
|
|
2941
|
+
#
|
|
2942
|
+
# {
|
|
2943
|
+
# code: '0',
|
|
2944
|
+
# msg: '',
|
|
2945
|
+
# data: '1'
|
|
2946
|
+
# }
|
|
2947
|
+
#
|
|
2766
2948
|
elif market['swap']:
|
|
2767
2949
|
response = await self.privateDeleteOrdersAll(self.extend(request, params))
|
|
2950
|
+
#
|
|
2951
|
+
# {
|
|
2952
|
+
# code: '0',
|
|
2953
|
+
# msg: '',
|
|
2954
|
+
# data: '1'
|
|
2955
|
+
# }
|
|
2956
|
+
#
|
|
2768
2957
|
else:
|
|
2769
2958
|
response = await self.privateDeleteSpotOrdersAll(self.extend(request, params))
|
|
2770
|
-
|
|
2959
|
+
#
|
|
2960
|
+
# {
|
|
2961
|
+
# code: '0',
|
|
2962
|
+
# msg: '',
|
|
2963
|
+
# data: {
|
|
2964
|
+
# total: '1'
|
|
2965
|
+
# }
|
|
2966
|
+
# }
|
|
2967
|
+
#
|
|
2968
|
+
return [
|
|
2969
|
+
self.safe_order({
|
|
2970
|
+
'info': response,
|
|
2971
|
+
}),
|
|
2972
|
+
]
|
|
2771
2973
|
|
|
2772
2974
|
async def fetch_order(self, id: str, symbol: Str = None, params={}):
|
|
2773
2975
|
"""
|
|
2774
|
-
|
|
2976
|
+
|
|
2977
|
+
https://phemex-docs.github.io/#query-orders-by-ids
|
|
2978
|
+
|
|
2775
2979
|
fetches information on an order made by the user
|
|
2980
|
+
:param str id: the order id
|
|
2776
2981
|
:param str symbol: unified symbol of the market the order was made in
|
|
2777
2982
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
2778
2983
|
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
|
@@ -2791,10 +2996,10 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2791
2996
|
else:
|
|
2792
2997
|
request['orderID'] = id
|
|
2793
2998
|
response = None
|
|
2794
|
-
if market['settle'] == 'USDT':
|
|
2999
|
+
if market['settle'] == 'USDT' or market['settle'] == 'USDC':
|
|
2795
3000
|
response = await self.privateGetApiDataGFuturesOrdersByOrderId(self.extend(request, params))
|
|
2796
3001
|
elif market['spot']:
|
|
2797
|
-
response = await self.
|
|
3002
|
+
response = await self.privateGetApiDataSpotsOrdersByOrderId(self.extend(request, params))
|
|
2798
3003
|
else:
|
|
2799
3004
|
response = await self.privateGetExchangeOrder(self.extend(request, params))
|
|
2800
3005
|
data = self.safe_value(response, 'data', {})
|
|
@@ -2806,13 +3011,18 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2806
3011
|
raise OrderNotFound(self.id + ' fetchOrder() ' + symbol + ' order with clientOrderId ' + clientOrderId + ' not found')
|
|
2807
3012
|
else:
|
|
2808
3013
|
raise OrderNotFound(self.id + ' fetchOrder() ' + symbol + ' order with id ' + id + ' not found')
|
|
2809
|
-
order = self.
|
|
3014
|
+
order = self.safe_dict(data, 0, {})
|
|
3015
|
+
elif market['spot']:
|
|
3016
|
+
rows = self.safe_list(data, 'rows', [])
|
|
3017
|
+
order = self.safe_dict(rows, 0, {})
|
|
2810
3018
|
return self.parse_order(order, market)
|
|
2811
3019
|
|
|
2812
3020
|
async def fetch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
|
2813
3021
|
"""
|
|
2814
3022
|
fetches information on multiple orders made by the user
|
|
2815
|
-
|
|
3023
|
+
|
|
3024
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#queryorder
|
|
3025
|
+
|
|
2816
3026
|
:param str symbol: unified market symbol of the market orders were made in
|
|
2817
3027
|
:param int [since]: the earliest time in ms to fetch orders for
|
|
2818
3028
|
:param int [limit]: the maximum number of order structures to retrieve
|
|
@@ -2831,13 +3041,13 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2831
3041
|
if limit is not None:
|
|
2832
3042
|
request['limit'] = limit
|
|
2833
3043
|
response = None
|
|
2834
|
-
if market['settle'] == 'USDT':
|
|
3044
|
+
if market['settle'] == 'USDT' or market['settle'] == 'USDC':
|
|
2835
3045
|
request['currency'] = market['settle']
|
|
2836
3046
|
response = await self.privateGetExchangeOrderV2OrderList(self.extend(request, params))
|
|
2837
3047
|
elif market['swap']:
|
|
2838
3048
|
response = await self.privateGetExchangeOrderList(self.extend(request, params))
|
|
2839
3049
|
else:
|
|
2840
|
-
response = await self.
|
|
3050
|
+
response = await self.privateGetApiDataSpotsOrders(self.extend(request, params))
|
|
2841
3051
|
data = self.safe_value(response, 'data', {})
|
|
2842
3052
|
rows = self.safe_list(data, 'rows', data)
|
|
2843
3053
|
return self.parse_orders(rows, market, since, limit)
|
|
@@ -2845,9 +3055,11 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2845
3055
|
async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
|
2846
3056
|
"""
|
|
2847
3057
|
fetch all unfilled currently open orders
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
3058
|
+
|
|
3059
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#queryopenorder
|
|
3060
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md
|
|
3061
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Spot-API-en.md#spotListAllOpenOrder
|
|
3062
|
+
|
|
2851
3063
|
:param str symbol: unified market symbol
|
|
2852
3064
|
:param int [since]: the earliest time in ms to fetch open orders for
|
|
2853
3065
|
:param int [limit]: the maximum number of open order structures to retrieve
|
|
@@ -2864,7 +3076,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2864
3076
|
}
|
|
2865
3077
|
response = None
|
|
2866
3078
|
try:
|
|
2867
|
-
if market['settle'] == 'USDT':
|
|
3079
|
+
if market['settle'] == 'USDT' or market['settle'] == 'USDC':
|
|
2868
3080
|
response = await self.privateGetGOrdersActiveList(self.extend(request, params))
|
|
2869
3081
|
elif market['swap']:
|
|
2870
3082
|
response = await self.privateGetOrdersActiveList(self.extend(request, params))
|
|
@@ -2884,10 +3096,12 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2884
3096
|
async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
|
2885
3097
|
"""
|
|
2886
3098
|
fetches information on multiple closed orders made by the user
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
3099
|
+
|
|
3100
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#queryorder
|
|
3101
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md#queryorder
|
|
3102
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedgedd-Perpetual-API.md#query-closed-orders-by-symbol
|
|
3103
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Spot-API-en.md#spotDataOrdersByIds
|
|
3104
|
+
|
|
2891
3105
|
:param str symbol: unified market symbol of the market orders were made in
|
|
2892
3106
|
:param int [since]: the earliest time in ms to fetch orders for
|
|
2893
3107
|
:param int [limit]: the maximum number of order structures to retrieve
|
|
@@ -2961,9 +3175,11 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
2961
3175
|
async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
|
2962
3176
|
"""
|
|
2963
3177
|
fetch all trades made by the user
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
3178
|
+
|
|
3179
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md#query-user-trade
|
|
3180
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#query-user-trade
|
|
3181
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Spot-API-en.md#spotDataTradesHist
|
|
3182
|
+
|
|
2967
3183
|
:param str symbol: unified market symbol
|
|
2968
3184
|
:param int [since]: the earliest time in ms to fetch trades for
|
|
2969
3185
|
:param int [limit]: the maximum number of trades structures to retrieve
|
|
@@ -3107,11 +3323,12 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
3107
3323
|
data = self.safe_value(data, 'rows', [])
|
|
3108
3324
|
return self.parse_trades(data, market, since, limit)
|
|
3109
3325
|
|
|
3110
|
-
async def fetch_deposit_address(self, code: str, params={}):
|
|
3326
|
+
async def fetch_deposit_address(self, code: str, params={}) -> DepositAddress:
|
|
3111
3327
|
"""
|
|
3112
3328
|
fetch the deposit address for a currency associated with self account
|
|
3113
3329
|
:param str code: unified currency code
|
|
3114
3330
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
3331
|
+
:param str [params.network]: the chain name to fetch the deposit address e.g. ETH, TRX, EOS, SOL, etc.
|
|
3115
3332
|
:returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
|
|
3116
3333
|
"""
|
|
3117
3334
|
await self.load_markets()
|
|
@@ -3119,23 +3336,29 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
3119
3336
|
request: dict = {
|
|
3120
3337
|
'currency': currency['id'],
|
|
3121
3338
|
}
|
|
3122
|
-
defaultNetworks = self.
|
|
3339
|
+
defaultNetworks = self.safe_dict(self.options, 'defaultNetworks')
|
|
3123
3340
|
defaultNetwork = self.safe_string_upper(defaultNetworks, code)
|
|
3124
|
-
networks = self.
|
|
3125
|
-
network = self.
|
|
3341
|
+
networks = self.safe_dict(self.options, 'networks', {})
|
|
3342
|
+
network = self.safe_string_upper_2(params, 'network', 'chainName', defaultNetwork)
|
|
3126
3343
|
network = self.safe_string(networks, network, network)
|
|
3127
3344
|
if network is None:
|
|
3128
|
-
|
|
3345
|
+
raise ArgumentsRequired(self.id + ' fetchDepositAddress() requires a network parameter')
|
|
3129
3346
|
else:
|
|
3130
3347
|
request['chainName'] = network
|
|
3131
3348
|
params = self.omit(params, 'network')
|
|
3132
|
-
response = await self.
|
|
3349
|
+
response = await self.privateGetExchangeWalletsV2DepositAddress(self.extend(request, params))
|
|
3350
|
+
#
|
|
3133
3351
|
# {
|
|
3134
|
-
# "code":0,
|
|
3135
|
-
# "msg":"OK",
|
|
3136
|
-
# "data":{
|
|
3137
|
-
# "address":"
|
|
3138
|
-
# "tag":
|
|
3352
|
+
# "code": 0,
|
|
3353
|
+
# "msg": "OK",
|
|
3354
|
+
# "data": {
|
|
3355
|
+
# "address": "tb1qxel5wq5gumt",
|
|
3356
|
+
# "tag": "",
|
|
3357
|
+
# "notice": False,
|
|
3358
|
+
# "accountType": 1,
|
|
3359
|
+
# "contractName": null,
|
|
3360
|
+
# "chainTokenUrl": null,
|
|
3361
|
+
# "sign": null
|
|
3139
3362
|
# }
|
|
3140
3363
|
# }
|
|
3141
3364
|
#
|
|
@@ -3144,11 +3367,11 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
3144
3367
|
tag = self.safe_string(data, 'tag')
|
|
3145
3368
|
self.check_address(address)
|
|
3146
3369
|
return {
|
|
3370
|
+
'info': response,
|
|
3147
3371
|
'currency': code,
|
|
3372
|
+
'network': None,
|
|
3148
3373
|
'address': address,
|
|
3149
3374
|
'tag': tag,
|
|
3150
|
-
'network': None,
|
|
3151
|
-
'info': response,
|
|
3152
3375
|
}
|
|
3153
3376
|
|
|
3154
3377
|
async def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
|
|
@@ -3360,21 +3583,25 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
3360
3583
|
'fee': fee,
|
|
3361
3584
|
}
|
|
3362
3585
|
|
|
3363
|
-
async def fetch_positions(self, symbols: Strings = None, params={}):
|
|
3586
|
+
async def fetch_positions(self, symbols: Strings = None, params={}) -> List[Position]:
|
|
3364
3587
|
"""
|
|
3365
3588
|
fetch all open positions
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3589
|
+
|
|
3590
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md#query-trading-account-and-positions
|
|
3591
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#query-account-positions
|
|
3592
|
+
https://phemex-docs.github.io/#query-account-positions-with-unrealized-pnl
|
|
3593
|
+
|
|
3369
3594
|
:param str[] [symbols]: list of unified market symbols
|
|
3370
3595
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
3371
|
-
:param str [
|
|
3596
|
+
:param str [params.code]: the currency code to fetch positions for, USD, BTC or USDT, USDT is the default
|
|
3597
|
+
:param str [params.method]: *USDT contracts only* 'privateGetGAccountsAccountPositions' or 'privateGetAccountsPositions' default is 'privateGetGAccountsAccountPositions'
|
|
3372
3598
|
:returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
|
|
3373
3599
|
"""
|
|
3374
3600
|
await self.load_markets()
|
|
3375
3601
|
symbols = self.market_symbols(symbols)
|
|
3376
3602
|
subType = None
|
|
3377
|
-
code = self.
|
|
3603
|
+
code = self.safe_string_2(params, 'currency', 'code', 'USDT')
|
|
3604
|
+
params = self.omit(params, ['currency', 'code'])
|
|
3378
3605
|
settle = None
|
|
3379
3606
|
market = None
|
|
3380
3607
|
firstSymbol = self.safe_string(symbols, 0)
|
|
@@ -3383,15 +3610,15 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
3383
3610
|
settle = market['settle']
|
|
3384
3611
|
code = market['settle']
|
|
3385
3612
|
else:
|
|
3386
|
-
settle, params = self.handle_option_and_params(params, 'fetchPositions', 'settle',
|
|
3613
|
+
settle, params = self.handle_option_and_params(params, 'fetchPositions', 'settle', code)
|
|
3387
3614
|
subType, params = self.handle_sub_type_and_params('fetchPositions', market, params)
|
|
3388
3615
|
isUSDTSettled = settle == 'USDT'
|
|
3389
3616
|
if isUSDTSettled:
|
|
3390
3617
|
code = 'USDT'
|
|
3618
|
+
elif settle == 'BTC':
|
|
3619
|
+
code = 'BTC'
|
|
3391
3620
|
elif code is None:
|
|
3392
3621
|
code = 'USD' if (subType == 'linear') else 'BTC'
|
|
3393
|
-
else:
|
|
3394
|
-
params = self.omit(params, 'code')
|
|
3395
3622
|
currency = self.currency(code)
|
|
3396
3623
|
request: dict = {
|
|
3397
3624
|
'currency': currency['id'],
|
|
@@ -3631,7 +3858,9 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
3631
3858
|
async def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
|
3632
3859
|
"""
|
|
3633
3860
|
fetch the history of funding payments paid and received on self account
|
|
3634
|
-
|
|
3861
|
+
|
|
3862
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#futureDataFundingFeesHist
|
|
3863
|
+
|
|
3635
3864
|
:param str symbol: unified market symbol
|
|
3636
3865
|
:param int [since]: the earliest time in ms to fetch funding history for
|
|
3637
3866
|
:param int [limit]: the maximum number of funding history structures to retrieve
|
|
@@ -3652,8 +3881,8 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
3652
3881
|
raise BadRequest(self.id + ' fetchFundingHistory() limit argument cannot exceed 200')
|
|
3653
3882
|
request['limit'] = limit
|
|
3654
3883
|
response = None
|
|
3655
|
-
|
|
3656
|
-
if
|
|
3884
|
+
isStableSettled = market['settle'] == 'USDT' or market['settle'] == 'USDC'
|
|
3885
|
+
if isStableSettled:
|
|
3657
3886
|
response = await self.privateGetApiDataGFuturesFundingFees(self.extend(request, params))
|
|
3658
3887
|
else:
|
|
3659
3888
|
response = await self.privateGetApiDataFuturesFundingFees(self.extend(request, params))
|
|
@@ -3702,15 +3931,15 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
3702
3931
|
if value is None or currencyCode is None:
|
|
3703
3932
|
return value
|
|
3704
3933
|
# it was confirmed by phemex support, that USDT contracts use direct amounts in funding fees, while USD & INVERSE needs 'valueScale'
|
|
3705
|
-
|
|
3706
|
-
if not
|
|
3934
|
+
isStableSettled = market['settle'] == 'USDT' or market['settle'] == 'USDC'
|
|
3935
|
+
if not isStableSettled:
|
|
3707
3936
|
currency = self.safe_currency(currencyCode)
|
|
3708
3937
|
scale = self.safe_string(currency['info'], 'valueScale')
|
|
3709
3938
|
tickPrecision = self.parse_precision(scale)
|
|
3710
3939
|
value = Precise.string_mul(value, tickPrecision)
|
|
3711
3940
|
return value
|
|
3712
3941
|
|
|
3713
|
-
async def fetch_funding_rate(self, symbol: str, params={}):
|
|
3942
|
+
async def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
|
|
3714
3943
|
"""
|
|
3715
3944
|
fetch the current funding rate
|
|
3716
3945
|
:param str symbol: unified market symbol
|
|
@@ -3755,7 +3984,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
3755
3984
|
result = self.safe_value(response, 'result', {})
|
|
3756
3985
|
return self.parse_funding_rate(result, market)
|
|
3757
3986
|
|
|
3758
|
-
def parse_funding_rate(self, contract, market: Market = None):
|
|
3987
|
+
def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
|
|
3759
3988
|
#
|
|
3760
3989
|
# {
|
|
3761
3990
|
# "askEp": 2332500,
|
|
@@ -3796,30 +4025,37 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
3796
4025
|
marketId = self.safe_string(contract, 'symbol')
|
|
3797
4026
|
symbol = self.safe_symbol(marketId, market)
|
|
3798
4027
|
timestamp = self.safe_integer_product(contract, 'timestamp', 0.000001)
|
|
4028
|
+
markEp = self.from_ep(self.safe_string(contract, 'markEp'), market)
|
|
4029
|
+
indexEp = self.from_ep(self.safe_string(contract, 'indexEp'), market)
|
|
4030
|
+
fundingRateEr = self.from_er(self.safe_string(contract, 'fundingRateEr'), market)
|
|
4031
|
+
nextFundingRateEr = self.from_er(self.safe_string(contract, 'predFundingRateEr'), market)
|
|
3799
4032
|
return {
|
|
3800
4033
|
'info': contract,
|
|
3801
4034
|
'symbol': symbol,
|
|
3802
|
-
'markPrice': self.
|
|
3803
|
-
'indexPrice': self.
|
|
4035
|
+
'markPrice': self.safe_number(contract, 'markPriceRp', markEp),
|
|
4036
|
+
'indexPrice': self.safe_number(contract, 'indexPriceRp', indexEp),
|
|
3804
4037
|
'interestRate': None,
|
|
3805
4038
|
'estimatedSettlePrice': None,
|
|
3806
4039
|
'timestamp': timestamp,
|
|
3807
4040
|
'datetime': self.iso8601(timestamp),
|
|
3808
|
-
'fundingRate': self.
|
|
4041
|
+
'fundingRate': self.safe_number(contract, 'fundingRateRr', fundingRateEr),
|
|
3809
4042
|
'fundingTimestamp': None,
|
|
3810
4043
|
'fundingDatetime': None,
|
|
3811
|
-
'nextFundingRate': self.
|
|
4044
|
+
'nextFundingRate': self.safe_number(contract, 'predFundingRateRr', nextFundingRateEr),
|
|
3812
4045
|
'nextFundingTimestamp': None,
|
|
3813
4046
|
'nextFundingDatetime': None,
|
|
3814
4047
|
'previousFundingRate': None,
|
|
3815
4048
|
'previousFundingTimestamp': None,
|
|
3816
4049
|
'previousFundingDatetime': None,
|
|
4050
|
+
'interval': None,
|
|
3817
4051
|
}
|
|
3818
4052
|
|
|
3819
4053
|
async def set_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
|
|
3820
4054
|
"""
|
|
3821
4055
|
Either adds or reduces margin in an isolated position in order to set the margin to a specific value
|
|
3822
|
-
|
|
4056
|
+
|
|
4057
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md#assign-position-balance-in-isolated-marign-mode
|
|
4058
|
+
|
|
3823
4059
|
:param str symbol: unified market symbol of the market to set margin in
|
|
3824
4060
|
:param float amount: the amount to set the margin to
|
|
3825
4061
|
:param dict [params]: parameters specific to the exchange API endpoint
|
|
@@ -3876,6 +4112,9 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
3876
4112
|
async def set_margin_mode(self, marginMode: str, symbol: Str = None, params={}):
|
|
3877
4113
|
"""
|
|
3878
4114
|
set margin mode to 'cross' or 'isolated'
|
|
4115
|
+
|
|
4116
|
+
https://phemex-docs.github.io/#set-leverage
|
|
4117
|
+
|
|
3879
4118
|
:param str marginMode: 'cross' or 'isolated'
|
|
3880
4119
|
:param str symbol: unified market symbol
|
|
3881
4120
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -3885,8 +4124,8 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
3885
4124
|
raise ArgumentsRequired(self.id + ' setMarginMode() requires a symbol argument')
|
|
3886
4125
|
await self.load_markets()
|
|
3887
4126
|
market = self.market(symbol)
|
|
3888
|
-
if not market['swap'] or market['settle'] == 'USDT':
|
|
3889
|
-
raise BadSymbol(self.id + ' setMarginMode() supports swap(non USDT based) contracts only')
|
|
4127
|
+
if not market['swap'] or market['settle'] == 'USDT' or market['settle'] == 'USDC':
|
|
4128
|
+
raise BadSymbol(self.id + ' setMarginMode() supports swap(non USDT/USDC based) contracts only')
|
|
3890
4129
|
marginMode = marginMode.lower()
|
|
3891
4130
|
if marginMode != 'isolated' and marginMode != 'cross':
|
|
3892
4131
|
raise BadRequest(self.id + ' setMarginMode() marginMode argument should be isolated or cross')
|
|
@@ -3904,7 +4143,9 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
3904
4143
|
async def set_position_mode(self, hedged: bool, symbol: Str = None, params={}):
|
|
3905
4144
|
"""
|
|
3906
4145
|
set hedged to True or False for a market
|
|
3907
|
-
|
|
4146
|
+
|
|
4147
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#switch-position-mode-synchronously
|
|
4148
|
+
|
|
3908
4149
|
:param bool hedged: set to True to use dualSidePosition
|
|
3909
4150
|
:param str symbol: not used by binance setPositionMode()
|
|
3910
4151
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -4036,7 +4277,8 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
4036
4277
|
# ]
|
|
4037
4278
|
# },
|
|
4038
4279
|
#
|
|
4039
|
-
|
|
4280
|
+
marketId = self.safe_string(info, 'symbol')
|
|
4281
|
+
market = self.safe_market(marketId, market)
|
|
4040
4282
|
riskLimits = (market['info']['riskLimits'])
|
|
4041
4283
|
tiers = []
|
|
4042
4284
|
minNotional = 0
|
|
@@ -4045,6 +4287,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
4045
4287
|
maxNotional = self.safe_integer(tier, 'limit')
|
|
4046
4288
|
tiers.append({
|
|
4047
4289
|
'tier': self.sum(i, 1),
|
|
4290
|
+
'symbol': self.safe_symbol(marketId, market),
|
|
4048
4291
|
'currency': market['settle'],
|
|
4049
4292
|
'minNotional': minNotional,
|
|
4050
4293
|
'maxNotional': maxNotional,
|
|
@@ -4089,10 +4332,12 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
4089
4332
|
url = self.implode_hostname(self.urls['api'][api]) + url
|
|
4090
4333
|
return {'url': url, 'method': method, 'body': body, 'headers': headers}
|
|
4091
4334
|
|
|
4092
|
-
async def set_leverage(self, leverage:
|
|
4335
|
+
async def set_leverage(self, leverage: int, symbol: Str = None, params={}):
|
|
4093
4336
|
"""
|
|
4094
4337
|
set the level of leverage for a market
|
|
4095
|
-
|
|
4338
|
+
|
|
4339
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#set-leverage
|
|
4340
|
+
|
|
4096
4341
|
:param float leverage: the rate of leverage, 100 > leverage > -100 excluding numbers between -1 to 1
|
|
4097
4342
|
:param str symbol: unified market symbol
|
|
4098
4343
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
@@ -4116,7 +4361,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
4116
4361
|
'symbol': market['id'],
|
|
4117
4362
|
}
|
|
4118
4363
|
response = None
|
|
4119
|
-
if market['settle'] == 'USDT':
|
|
4364
|
+
if market['settle'] == 'USDT' or market['settle'] == 'USDC':
|
|
4120
4365
|
if not isHedged and longLeverageRr is None and shortLeverageRr is None:
|
|
4121
4366
|
request['leverageRr'] = leverage
|
|
4122
4367
|
else:
|
|
@@ -4133,6 +4378,10 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
4133
4378
|
async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
|
|
4134
4379
|
"""
|
|
4135
4380
|
transfer currency internally between wallets on the same account
|
|
4381
|
+
|
|
4382
|
+
https://phemex-docs.github.io/#transfer-between-spot-and-futures
|
|
4383
|
+
https://phemex-docs.github.io/#universal-transfer-main-account-only-transfer-between-sub-to-main-main-to-sub-or-sub-to-sub
|
|
4384
|
+
|
|
4136
4385
|
:param str code: unified currency code
|
|
4137
4386
|
:param float amount: amount to transfer
|
|
4138
4387
|
:param str fromAccount: account to transfer from
|
|
@@ -4206,9 +4455,12 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
4206
4455
|
transfer['currency'] = code
|
|
4207
4456
|
return transfer
|
|
4208
4457
|
|
|
4209
|
-
async def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}) ->
|
|
4458
|
+
async def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[TransferEntry]:
|
|
4210
4459
|
"""
|
|
4211
4460
|
fetch a history of internal transfers made on an account
|
|
4461
|
+
|
|
4462
|
+
https://phemex-docs.github.io/#query-transfer-history
|
|
4463
|
+
|
|
4212
4464
|
:param str code: unified currency code of the currency transferred
|
|
4213
4465
|
:param int [since]: the earliest time in ms to fetch transfers for
|
|
4214
4466
|
:param int [limit]: the maximum number of transfers structures to retrieve
|
|
@@ -4317,7 +4569,9 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
4317
4569
|
async def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
|
4318
4570
|
"""
|
|
4319
4571
|
fetches historical funding rate prices
|
|
4320
|
-
|
|
4572
|
+
|
|
4573
|
+
https://phemex-docs.github.io/#query-funding-rate-history-2
|
|
4574
|
+
|
|
4321
4575
|
:param str symbol: unified symbol of the market to fetch the funding rate history for
|
|
4322
4576
|
:param int [since]: timestamp in ms of the earliest funding rate to fetch
|
|
4323
4577
|
:param int [limit]: the maximum amount of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>` to fetch
|
|
@@ -4330,7 +4584,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
4330
4584
|
raise ArgumentsRequired(self.id + ' fetchFundingRateHistory() requires a symbol argument')
|
|
4331
4585
|
await self.load_markets()
|
|
4332
4586
|
market = self.market(symbol)
|
|
4333
|
-
isUsdtSettled = market['settle'] == 'USDT'
|
|
4587
|
+
isUsdtSettled = market['settle'] == 'USDT' or market['settle'] == 'USDC'
|
|
4334
4588
|
if not market['swap']:
|
|
4335
4589
|
raise BadRequest(self.id + ' fetchFundingRateHistory() supports swap contracts only')
|
|
4336
4590
|
paginate = False
|
|
@@ -4387,10 +4641,12 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
4387
4641
|
sorted = self.sort_by(result, 'timestamp')
|
|
4388
4642
|
return self.filter_by_symbol_since_limit(sorted, symbol, since, limit)
|
|
4389
4643
|
|
|
4390
|
-
async def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
|
|
4644
|
+
async def withdraw(self, code: str, amount: float, address: str, tag: Str = None, params={}) -> Transaction:
|
|
4391
4645
|
"""
|
|
4392
4646
|
make a withdrawal
|
|
4393
|
-
|
|
4647
|
+
|
|
4648
|
+
https://phemex-docs.github.io/#create-withdraw-request
|
|
4649
|
+
|
|
4394
4650
|
:param str code: unified currency code
|
|
4395
4651
|
:param float amount: the amount to withdraw
|
|
4396
4652
|
:param str address: the address to withdraw to
|
|
@@ -4453,6 +4709,291 @@ class phemex(Exchange, ImplicitAPI):
|
|
|
4453
4709
|
data = self.safe_dict(response, 'data', {})
|
|
4454
4710
|
return self.parse_transaction(data, currency)
|
|
4455
4711
|
|
|
4712
|
+
async def fetch_open_interest(self, symbol: str, params={}):
|
|
4713
|
+
"""
|
|
4714
|
+
retrieves the open interest of a trading pair
|
|
4715
|
+
|
|
4716
|
+
https://phemex-docs.github.io/#query-24-hours-ticker
|
|
4717
|
+
|
|
4718
|
+
:param str symbol: unified CCXT market symbol
|
|
4719
|
+
:param dict [params]: exchange specific parameters
|
|
4720
|
+
:returns dict} an open interest structure{@link https://docs.ccxt.com/#/?id=open-interest-structure:
|
|
4721
|
+
"""
|
|
4722
|
+
await self.load_markets()
|
|
4723
|
+
market = self.market(symbol)
|
|
4724
|
+
if not market['contract']:
|
|
4725
|
+
raise BadRequest(self.id + ' fetchOpenInterest is only supported for contract markets.')
|
|
4726
|
+
request: dict = {
|
|
4727
|
+
'symbol': market['id'],
|
|
4728
|
+
}
|
|
4729
|
+
response = await self.v2GetMdV2Ticker24hr(self.extend(request, params))
|
|
4730
|
+
#
|
|
4731
|
+
# {
|
|
4732
|
+
# error: null,
|
|
4733
|
+
# id: '0',
|
|
4734
|
+
# result: {
|
|
4735
|
+
# closeRp: '67550.1',
|
|
4736
|
+
# fundingRateRr: '0.0001',
|
|
4737
|
+
# highRp: '68400',
|
|
4738
|
+
# indexPriceRp: '67567.15389794',
|
|
4739
|
+
# lowRp: '66096.4',
|
|
4740
|
+
# markPriceRp: '67550.1',
|
|
4741
|
+
# openInterestRv: '1848.1144186',
|
|
4742
|
+
# openRp: '66330',
|
|
4743
|
+
# predFundingRateRr: '0.0001',
|
|
4744
|
+
# symbol: 'BTCUSDT',
|
|
4745
|
+
# timestamp: '1729114315443343001',
|
|
4746
|
+
# turnoverRv: '228863389.3237532',
|
|
4747
|
+
# volumeRq: '3388.5600312'
|
|
4748
|
+
# }
|
|
4749
|
+
# }
|
|
4750
|
+
#
|
|
4751
|
+
result = self.safe_dict(response, 'result')
|
|
4752
|
+
return self.parse_open_interest(result, market)
|
|
4753
|
+
|
|
4754
|
+
def parse_open_interest(self, interest, market: Market = None):
|
|
4755
|
+
#
|
|
4756
|
+
# {
|
|
4757
|
+
# closeRp: '67550.1',
|
|
4758
|
+
# fundingRateRr: '0.0001',
|
|
4759
|
+
# highRp: '68400',
|
|
4760
|
+
# indexPriceRp: '67567.15389794',
|
|
4761
|
+
# lowRp: '66096.4',
|
|
4762
|
+
# markPriceRp: '67550.1',
|
|
4763
|
+
# openInterestRv: '1848.1144186',
|
|
4764
|
+
# openRp: '66330',
|
|
4765
|
+
# predFundingRateRr: '0.0001',
|
|
4766
|
+
# symbol: 'BTCUSDT',
|
|
4767
|
+
# timestamp: '1729114315443343001',
|
|
4768
|
+
# turnoverRv: '228863389.3237532',
|
|
4769
|
+
# volumeRq: '3388.5600312'
|
|
4770
|
+
# }
|
|
4771
|
+
#
|
|
4772
|
+
timestamp = self.safe_integer(interest, 'timestamp') / 1000000
|
|
4773
|
+
id = self.safe_string(interest, 'symbol')
|
|
4774
|
+
return self.safe_open_interest({
|
|
4775
|
+
'info': interest,
|
|
4776
|
+
'symbol': self.safe_symbol(id, market),
|
|
4777
|
+
'baseVolume': self.safe_string(interest, 'volumeRq'),
|
|
4778
|
+
'quoteVolume': None, # deprecated
|
|
4779
|
+
'openInterestAmount': self.safe_string(interest, 'openInterestRv'),
|
|
4780
|
+
'openInterestValue': None,
|
|
4781
|
+
'timestamp': timestamp,
|
|
4782
|
+
'datetime': self.iso8601(timestamp),
|
|
4783
|
+
}, market)
|
|
4784
|
+
|
|
4785
|
+
async def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
|
|
4786
|
+
"""
|
|
4787
|
+
fetch a quote for converting from one currency to another
|
|
4788
|
+
|
|
4789
|
+
https://phemex-docs.github.io/#rfq-quote
|
|
4790
|
+
|
|
4791
|
+
:param str fromCode: the currency that you want to sell and convert from
|
|
4792
|
+
:param str toCode: the currency that you want to buy and convert into
|
|
4793
|
+
:param float amount: how much you want to trade in units of the from currency
|
|
4794
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
4795
|
+
:returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
|
|
4796
|
+
"""
|
|
4797
|
+
await self.load_markets()
|
|
4798
|
+
fromCurrency = self.currency(fromCode)
|
|
4799
|
+
toCurrency = self.currency(toCode)
|
|
4800
|
+
valueScale = self.safe_integer(fromCurrency, 'valueScale')
|
|
4801
|
+
request: dict = {
|
|
4802
|
+
'fromCurrency': fromCode,
|
|
4803
|
+
'toCurrency': toCode,
|
|
4804
|
+
'fromAmountEv': self.to_en(amount, valueScale),
|
|
4805
|
+
}
|
|
4806
|
+
response = await self.privateGetAssetsQuote(self.extend(request, params))
|
|
4807
|
+
#
|
|
4808
|
+
# {
|
|
4809
|
+
# "code": 0,
|
|
4810
|
+
# "msg": "OK",
|
|
4811
|
+
# "data": {
|
|
4812
|
+
# "code": "GIF...AAA",
|
|
4813
|
+
# "quoteArgs": {
|
|
4814
|
+
# "origin": 10,
|
|
4815
|
+
# "price": "0.00000939",
|
|
4816
|
+
# "proceeds": "0.00000000",
|
|
4817
|
+
# "ttlMs": 7000,
|
|
4818
|
+
# "expireAt": 1739875826009,
|
|
4819
|
+
# "requestAt": 1739875818009,
|
|
4820
|
+
# "quoteAt": 1739875816594
|
|
4821
|
+
# }
|
|
4822
|
+
# }
|
|
4823
|
+
# }
|
|
4824
|
+
#
|
|
4825
|
+
data = self.safe_dict(response, 'data', {})
|
|
4826
|
+
return self.parse_conversion(data, fromCurrency, toCurrency)
|
|
4827
|
+
|
|
4828
|
+
async def create_convert_trade(self, id: str, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
|
|
4829
|
+
"""
|
|
4830
|
+
convert from one currency to another
|
|
4831
|
+
|
|
4832
|
+
https://phemex-docs.github.io/#convert
|
|
4833
|
+
|
|
4834
|
+
:param str id: the id of the trade that you want to make
|
|
4835
|
+
:param str fromCode: the currency that you want to sell and convert from
|
|
4836
|
+
:param str toCode: the currency that you want to buy and convert into
|
|
4837
|
+
:param float [amount]: how much you want to trade in units of the from currency
|
|
4838
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
4839
|
+
:returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
|
|
4840
|
+
"""
|
|
4841
|
+
await self.load_markets()
|
|
4842
|
+
fromCurrency = self.currency(fromCode)
|
|
4843
|
+
toCurrency = self.currency(toCode)
|
|
4844
|
+
valueScale = self.safe_integer(fromCurrency, 'valueScale')
|
|
4845
|
+
request: dict = {
|
|
4846
|
+
'code': id,
|
|
4847
|
+
'fromCurrency': fromCode,
|
|
4848
|
+
'toCurrency': toCode,
|
|
4849
|
+
}
|
|
4850
|
+
if amount is not None:
|
|
4851
|
+
request['fromAmountEv'] = self.to_en(amount, valueScale)
|
|
4852
|
+
response = await self.privatePostAssetsConvert(self.extend(request, params))
|
|
4853
|
+
#
|
|
4854
|
+
# {
|
|
4855
|
+
# "code": 0,
|
|
4856
|
+
# "msg": "OK",
|
|
4857
|
+
# "data": {
|
|
4858
|
+
# "moveOp": 0,
|
|
4859
|
+
# "fromCurrency": "USDT",
|
|
4860
|
+
# "toCurrency": "BTC",
|
|
4861
|
+
# "fromAmountEv": 4000000000,
|
|
4862
|
+
# "toAmountEv": 41511,
|
|
4863
|
+
# "linkKey": "45c8ed8e-d3f4-472d-8262-e464e8c46247",
|
|
4864
|
+
# "status": 10
|
|
4865
|
+
# }
|
|
4866
|
+
# }
|
|
4867
|
+
#
|
|
4868
|
+
data = self.safe_dict(response, 'data', {})
|
|
4869
|
+
fromCurrencyId = self.safe_string(data, 'fromCurrency')
|
|
4870
|
+
fromResult = self.safe_currency(fromCurrencyId, fromCurrency)
|
|
4871
|
+
toCurrencyId = self.safe_string(data, 'toCurrency')
|
|
4872
|
+
to = self.safe_currency(toCurrencyId, toCurrency)
|
|
4873
|
+
return self.parse_conversion(data, fromResult, to)
|
|
4874
|
+
|
|
4875
|
+
async def fetch_convert_trade_history(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Conversion]:
|
|
4876
|
+
"""
|
|
4877
|
+
fetch the users history of conversion trades
|
|
4878
|
+
|
|
4879
|
+
https://phemex-docs.github.io/#query-convert-history
|
|
4880
|
+
|
|
4881
|
+
:param str [code]: the unified currency code
|
|
4882
|
+
:param int [since]: the earliest time in ms to fetch conversions for
|
|
4883
|
+
:param int [limit]: the maximum number of conversion structures to retrieve, default 20, max 200
|
|
4884
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
|
4885
|
+
:param str [params.until]: the end time in ms
|
|
4886
|
+
:param str [params.fromCurrency]: the currency that you sold and converted from
|
|
4887
|
+
:param str [params.toCurrency]: the currency that you bought and converted into
|
|
4888
|
+
:returns dict[]: a list of `conversion structures <https://docs.ccxt.com/#/?id=conversion-structure>`
|
|
4889
|
+
"""
|
|
4890
|
+
await self.load_markets()
|
|
4891
|
+
request: dict = {}
|
|
4892
|
+
if code is not None:
|
|
4893
|
+
request['fromCurrency'] = code
|
|
4894
|
+
if since is not None:
|
|
4895
|
+
request['startTime'] = since
|
|
4896
|
+
if limit is not None:
|
|
4897
|
+
request['limit'] = limit
|
|
4898
|
+
request, params = self.handle_until_option('endTime', request, params)
|
|
4899
|
+
response = await self.privateGetAssetsConvert(self.extend(request, params))
|
|
4900
|
+
#
|
|
4901
|
+
# {
|
|
4902
|
+
# "code": 0,
|
|
4903
|
+
# "msg": "OK",
|
|
4904
|
+
# "data": {
|
|
4905
|
+
# "total": 2,
|
|
4906
|
+
# "rows": [
|
|
4907
|
+
# {
|
|
4908
|
+
# "linkKey": "45c8ed8e-d3f4-472d-8262-e464e8c46247",
|
|
4909
|
+
# "createTime": 1739882294000,
|
|
4910
|
+
# "fromCurrency": "USDT",
|
|
4911
|
+
# "toCurrency": "BTC",
|
|
4912
|
+
# "fromAmountEv": 4000000000,
|
|
4913
|
+
# "toAmountEv": 41511,
|
|
4914
|
+
# "status": 10,
|
|
4915
|
+
# "conversionRate": 1037,
|
|
4916
|
+
# "errorCode": 0
|
|
4917
|
+
# },
|
|
4918
|
+
# ]
|
|
4919
|
+
# }
|
|
4920
|
+
# }
|
|
4921
|
+
#
|
|
4922
|
+
data = self.safe_dict(response, 'data', {})
|
|
4923
|
+
rows = self.safe_list(data, 'rows', [])
|
|
4924
|
+
return self.parse_conversions(rows, code, 'fromCurrency', 'toCurrency', since, limit)
|
|
4925
|
+
|
|
4926
|
+
def parse_conversion(self, conversion: dict, fromCurrency: Currency = None, toCurrency: Currency = None) -> Conversion:
|
|
4927
|
+
#
|
|
4928
|
+
# fetchConvertQuote
|
|
4929
|
+
#
|
|
4930
|
+
# {
|
|
4931
|
+
# "code": "GIF...AAA",
|
|
4932
|
+
# "quoteArgs": {
|
|
4933
|
+
# "origin": 10,
|
|
4934
|
+
# "price": "0.00000939",
|
|
4935
|
+
# "proceeds": "0.00000000",
|
|
4936
|
+
# "ttlMs": 7000,
|
|
4937
|
+
# "expireAt": 1739875826009,
|
|
4938
|
+
# "requestAt": 1739875818009,
|
|
4939
|
+
# "quoteAt": 1739875816594
|
|
4940
|
+
# }
|
|
4941
|
+
# }
|
|
4942
|
+
#
|
|
4943
|
+
# createConvertTrade
|
|
4944
|
+
#
|
|
4945
|
+
# {
|
|
4946
|
+
# "moveOp": 0,
|
|
4947
|
+
# "fromCurrency": "USDT",
|
|
4948
|
+
# "toCurrency": "BTC",
|
|
4949
|
+
# "fromAmountEv": 4000000000,
|
|
4950
|
+
# "toAmountEv": 41511,
|
|
4951
|
+
# "linkKey": "45c8ed8e-d3f4-472d-8262-e464e8c46247",
|
|
4952
|
+
# "status": 10
|
|
4953
|
+
# }
|
|
4954
|
+
#
|
|
4955
|
+
# fetchConvertTradeHistory
|
|
4956
|
+
#
|
|
4957
|
+
# {
|
|
4958
|
+
# "linkKey": "45c8ed8e-d3f4-472d-8262-e464e8c46247",
|
|
4959
|
+
# "createTime": 1739882294000,
|
|
4960
|
+
# "fromCurrency": "USDT",
|
|
4961
|
+
# "toCurrency": "BTC",
|
|
4962
|
+
# "fromAmountEv": 4000000000,
|
|
4963
|
+
# "toAmountEv": 41511,
|
|
4964
|
+
# "status": 10,
|
|
4965
|
+
# "conversionRate": 1037,
|
|
4966
|
+
# "errorCode": 0
|
|
4967
|
+
# }
|
|
4968
|
+
#
|
|
4969
|
+
quoteArgs = self.safe_dict(conversion, 'quoteArgs', {})
|
|
4970
|
+
requestTime = self.safe_integer(quoteArgs, 'requestAt')
|
|
4971
|
+
timestamp = self.safe_integer(conversion, 'createTime', requestTime)
|
|
4972
|
+
fromCoin = self.safe_string(conversion, 'fromCurrency', self.safe_string(fromCurrency, 'code'))
|
|
4973
|
+
fromCode = self.safe_currency_code(fromCoin, fromCurrency)
|
|
4974
|
+
toCoin = self.safe_string(conversion, 'toCurrency', self.safe_string(toCurrency, 'code'))
|
|
4975
|
+
toCode = self.safe_currency_code(toCoin, toCurrency)
|
|
4976
|
+
fromValueScale = self.safe_integer(fromCurrency, 'valueScale')
|
|
4977
|
+
toValueScale = self.safe_integer(toCurrency, 'valueScale')
|
|
4978
|
+
fromAmount = self.from_en(self.safe_string(conversion, 'fromAmountEv'), fromValueScale)
|
|
4979
|
+
if fromAmount is None and quoteArgs is not None:
|
|
4980
|
+
fromAmount = self.from_en(self.safe_string(quoteArgs, 'origin'), fromValueScale)
|
|
4981
|
+
toAmount = self.from_en(self.safe_string(conversion, 'toAmountEv'), toValueScale)
|
|
4982
|
+
if toAmount is None and quoteArgs is not None:
|
|
4983
|
+
toAmount = self.from_en(self.safe_string(quoteArgs, 'proceeds'), toValueScale)
|
|
4984
|
+
return {
|
|
4985
|
+
'info': conversion,
|
|
4986
|
+
'timestamp': timestamp,
|
|
4987
|
+
'datetime': self.iso8601(timestamp),
|
|
4988
|
+
'id': self.safe_string(conversion, 'code'),
|
|
4989
|
+
'fromCurrency': fromCode,
|
|
4990
|
+
'fromAmount': self.parse_number(fromAmount),
|
|
4991
|
+
'toCurrency': toCode,
|
|
4992
|
+
'toAmount': self.parse_number(toAmount),
|
|
4993
|
+
'price': self.safe_number(quoteArgs, 'price'),
|
|
4994
|
+
'fee': None,
|
|
4995
|
+
}
|
|
4996
|
+
|
|
4456
4997
|
def handle_errors(self, httpCode: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
|
|
4457
4998
|
if response is None:
|
|
4458
4999
|
return None # fallback to default error handler
|