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