ccxt 4.2.76__py2.py3-none-any.whl → 4.4.48__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 +36 -14
- ccxt/abstract/alpaca.py +4 -0
- ccxt/abstract/bigone.py +1 -1
- ccxt/abstract/binance.py +112 -48
- ccxt/abstract/binancecoinm.py +112 -48
- ccxt/abstract/binanceus.py +147 -83
- ccxt/abstract/binanceusdm.py +112 -48
- ccxt/abstract/bingx.py +133 -78
- ccxt/abstract/bitbank.py +5 -0
- ccxt/abstract/bitfinex.py +136 -65
- ccxt/abstract/bitfinex1.py +69 -0
- ccxt/abstract/bitflyer.py +1 -0
- ccxt/abstract/bitget.py +8 -1
- ccxt/abstract/bitmart.py +13 -1
- ccxt/abstract/bitopro.py +1 -0
- ccxt/abstract/bitpanda.py +0 -12
- ccxt/abstract/bitrue.py +3 -3
- ccxt/abstract/bitstamp.py +26 -3
- ccxt/abstract/blofin.py +24 -0
- ccxt/abstract/btcbox.py +1 -0
- ccxt/abstract/bybit.py +29 -14
- ccxt/abstract/cex.py +28 -29
- ccxt/abstract/coinbase.py +6 -0
- ccxt/abstract/coinbaseadvanced.py +94 -0
- ccxt/abstract/{coinbasepro.py → coinbaseexchange.py} +1 -0
- ccxt/abstract/coinbaseinternational.py +1 -1
- ccxt/abstract/coincatch.py +94 -0
- ccxt/abstract/coinex.py +233 -123
- ccxt/abstract/coinmetro.py +1 -0
- ccxt/abstract/cryptocom.py +14 -0
- ccxt/abstract/defx.py +69 -0
- ccxt/abstract/deribit.py +1 -0
- ccxt/abstract/digifinex.py +1 -0
- ccxt/abstract/ellipx.py +25 -0
- ccxt/abstract/gate.py +20 -0
- ccxt/abstract/gateio.py +20 -0
- ccxt/abstract/gemini.py +1 -0
- ccxt/abstract/hashkey.py +67 -0
- ccxt/abstract/hyperliquid.py +1 -1
- ccxt/abstract/independentreserve.py +6 -0
- ccxt/abstract/kraken.py +4 -3
- ccxt/abstract/krakenfutures.py +4 -0
- ccxt/abstract/kucoin.py +25 -0
- ccxt/abstract/kucoinfutures.py +35 -0
- ccxt/abstract/luno.py +2 -0
- ccxt/abstract/mexc.py +4 -0
- ccxt/abstract/myokx.py +340 -0
- ccxt/abstract/oceanex.py +5 -0
- ccxt/abstract/okx.py +30 -0
- ccxt/abstract/onetrading.py +0 -12
- ccxt/abstract/oxfun.py +34 -0
- ccxt/abstract/paradex.py +40 -0
- ccxt/abstract/phemex.py +1 -0
- ccxt/abstract/upbit.py +4 -0
- ccxt/abstract/vertex.py +19 -0
- ccxt/abstract/whitebit.py +31 -1
- ccxt/abstract/woo.py +6 -2
- ccxt/abstract/woofipro.py +119 -0
- ccxt/abstract/xt.py +153 -0
- ccxt/abstract/zonda.py +6 -0
- ccxt/ace.py +164 -60
- ccxt/alpaca.py +727 -63
- ccxt/ascendex.py +395 -249
- ccxt/async_support/__init__.py +36 -14
- ccxt/async_support/ace.py +164 -60
- ccxt/async_support/alpaca.py +727 -63
- ccxt/async_support/ascendex.py +396 -249
- ccxt/async_support/base/exchange.py +531 -155
- ccxt/async_support/base/ws/aiohttp_client.py +28 -5
- ccxt/async_support/base/ws/cache.py +3 -2
- ccxt/async_support/base/ws/client.py +26 -5
- ccxt/async_support/base/ws/fast_client.py +4 -3
- ccxt/async_support/base/ws/functions.py +1 -1
- ccxt/async_support/base/ws/future.py +40 -31
- ccxt/async_support/base/ws/order_book_side.py +3 -0
- ccxt/async_support/bequant.py +1 -1
- ccxt/async_support/bigone.py +329 -202
- ccxt/async_support/binance.py +3513 -1511
- ccxt/async_support/binancecoinm.py +2 -1
- ccxt/async_support/binanceus.py +12 -1
- ccxt/async_support/binanceusdm.py +3 -1
- ccxt/async_support/bingx.py +3105 -881
- ccxt/async_support/bit2c.py +119 -38
- ccxt/async_support/bitbank.py +215 -76
- ccxt/async_support/bitbns.py +124 -53
- ccxt/async_support/bitfinex.py +3236 -1078
- ccxt/async_support/bitfinex1.py +1711 -0
- ccxt/async_support/bitflyer.py +239 -50
- ccxt/async_support/bitget.py +1513 -563
- ccxt/async_support/bithumb.py +201 -67
- ccxt/async_support/bitmart.py +1320 -435
- ccxt/async_support/bitmex.py +308 -111
- ccxt/async_support/bitopro.py +256 -96
- ccxt/async_support/bitrue.py +365 -233
- ccxt/async_support/bitso.py +201 -89
- ccxt/async_support/bitstamp.py +438 -269
- ccxt/async_support/bitteam.py +179 -73
- ccxt/async_support/bitvavo.py +180 -70
- ccxt/async_support/bl3p.py +92 -25
- ccxt/async_support/blockchaincom.py +193 -79
- ccxt/async_support/blofin.py +403 -150
- ccxt/async_support/btcalpha.py +161 -55
- ccxt/async_support/btcbox.py +250 -34
- ccxt/async_support/btcmarkets.py +232 -85
- ccxt/async_support/btcturk.py +159 -60
- ccxt/async_support/bybit.py +2326 -1255
- ccxt/async_support/cex.py +1409 -1329
- ccxt/async_support/coinbase.py +1455 -288
- ccxt/async_support/coinbaseadvanced.py +17 -0
- ccxt/async_support/{coinbasepro.py → coinbaseexchange.py} +233 -99
- ccxt/async_support/coinbaseinternational.py +428 -88
- ccxt/async_support/coincatch.py +5152 -0
- ccxt/async_support/coincheck.py +121 -38
- ccxt/async_support/coinex.py +4020 -3339
- ccxt/async_support/coinlist.py +273 -116
- ccxt/async_support/coinmate.py +204 -97
- ccxt/async_support/coinmetro.py +203 -110
- ccxt/async_support/coinone.py +142 -68
- ccxt/async_support/coinsph.py +206 -89
- ccxt/async_support/coinspot.py +137 -62
- ccxt/async_support/cryptocom.py +515 -185
- ccxt/async_support/currencycom.py +203 -85
- ccxt/async_support/defx.py +2066 -0
- ccxt/async_support/delta.py +467 -158
- ccxt/async_support/deribit.py +558 -324
- ccxt/async_support/digifinex.py +340 -223
- ccxt/async_support/ellipx.py +1826 -0
- ccxt/async_support/exmo.py +259 -128
- ccxt/async_support/gate.py +1473 -464
- ccxt/async_support/gemini.py +206 -84
- ccxt/async_support/hashkey.py +4164 -0
- ccxt/async_support/hitbtc.py +334 -178
- ccxt/async_support/hollaex.py +134 -83
- ccxt/async_support/htx.py +1095 -563
- ccxt/async_support/huobijp.py +105 -56
- ccxt/async_support/hyperliquid.py +1634 -269
- ccxt/async_support/idex.py +148 -95
- ccxt/async_support/independentreserve.py +236 -31
- ccxt/async_support/indodax.py +165 -62
- ccxt/async_support/kraken.py +871 -354
- ccxt/async_support/krakenfutures.py +324 -100
- ccxt/async_support/kucoin.py +1050 -355
- ccxt/async_support/kucoinfutures.py +1004 -149
- ccxt/async_support/kuna.py +138 -106
- ccxt/async_support/latoken.py +135 -79
- ccxt/async_support/lbank.py +290 -113
- ccxt/async_support/luno.py +112 -62
- ccxt/async_support/lykke.py +104 -55
- ccxt/async_support/mercado.py +36 -29
- ccxt/async_support/mexc.py +995 -429
- ccxt/async_support/myokx.py +43 -0
- ccxt/async_support/ndax.py +163 -82
- ccxt/async_support/novadax.py +121 -75
- ccxt/async_support/oceanex.py +175 -59
- ccxt/async_support/okcoin.py +222 -163
- ccxt/async_support/okx.py +1777 -455
- ccxt/async_support/onetrading.py +132 -414
- ccxt/async_support/oxfun.py +2832 -0
- ccxt/async_support/p2b.py +79 -51
- ccxt/async_support/paradex.py +2017 -0
- ccxt/async_support/paymium.py +56 -32
- ccxt/async_support/phemex.py +572 -196
- ccxt/async_support/poloniex.py +218 -95
- ccxt/async_support/poloniexfutures.py +260 -92
- ccxt/async_support/probit.py +143 -110
- ccxt/async_support/timex.py +123 -70
- ccxt/async_support/tokocrypto.py +129 -93
- ccxt/async_support/tradeogre.py +39 -25
- ccxt/async_support/upbit.py +322 -113
- ccxt/async_support/vertex.py +2983 -0
- ccxt/async_support/wavesexchange.py +227 -173
- ccxt/async_support/wazirx.py +145 -65
- ccxt/async_support/whitebit.py +533 -138
- ccxt/async_support/woo.py +1155 -295
- ccxt/async_support/woofipro.py +2716 -0
- ccxt/async_support/xt.py +4628 -0
- ccxt/async_support/yobit.py +160 -92
- ccxt/async_support/zaif.py +80 -33
- ccxt/async_support/zonda.py +140 -69
- ccxt/base/errors.py +51 -20
- ccxt/base/exchange.py +1729 -482
- ccxt/base/precise.py +10 -0
- ccxt/base/types.py +223 -4
- ccxt/bequant.py +1 -1
- ccxt/bigone.py +329 -202
- ccxt/binance.py +3513 -1511
- ccxt/binancecoinm.py +2 -1
- ccxt/binanceus.py +12 -1
- ccxt/binanceusdm.py +3 -1
- ccxt/bingx.py +3105 -881
- ccxt/bit2c.py +119 -38
- ccxt/bitbank.py +215 -76
- ccxt/bitbns.py +124 -53
- ccxt/bitfinex.py +3235 -1078
- ccxt/bitfinex1.py +1710 -0
- ccxt/bitflyer.py +239 -50
- ccxt/bitget.py +1513 -563
- ccxt/bithumb.py +200 -67
- ccxt/bitmart.py +1320 -435
- ccxt/bitmex.py +308 -111
- ccxt/bitopro.py +256 -96
- ccxt/bitrue.py +365 -233
- ccxt/bitso.py +201 -89
- ccxt/bitstamp.py +438 -269
- ccxt/bitteam.py +179 -73
- ccxt/bitvavo.py +180 -70
- ccxt/bl3p.py +92 -25
- ccxt/blockchaincom.py +193 -79
- ccxt/blofin.py +403 -150
- ccxt/btcalpha.py +161 -55
- ccxt/btcbox.py +250 -34
- ccxt/btcmarkets.py +232 -85
- ccxt/btcturk.py +159 -60
- ccxt/bybit.py +2326 -1255
- ccxt/cex.py +1408 -1329
- ccxt/coinbase.py +1455 -288
- ccxt/coinbaseadvanced.py +17 -0
- ccxt/{coinbasepro.py → coinbaseexchange.py} +233 -99
- ccxt/coinbaseinternational.py +428 -88
- ccxt/coincatch.py +5152 -0
- ccxt/coincheck.py +121 -38
- ccxt/coinex.py +4020 -3339
- ccxt/coinlist.py +273 -116
- ccxt/coinmate.py +204 -97
- ccxt/coinmetro.py +203 -110
- ccxt/coinone.py +142 -68
- ccxt/coinsph.py +206 -89
- ccxt/coinspot.py +137 -62
- ccxt/cryptocom.py +515 -185
- ccxt/currencycom.py +203 -85
- ccxt/defx.py +2065 -0
- ccxt/delta.py +467 -158
- ccxt/deribit.py +558 -324
- ccxt/digifinex.py +340 -223
- ccxt/ellipx.py +1826 -0
- ccxt/exmo.py +259 -128
- ccxt/gate.py +1473 -464
- ccxt/gemini.py +206 -84
- ccxt/hashkey.py +4164 -0
- ccxt/hitbtc.py +334 -178
- ccxt/hollaex.py +134 -83
- ccxt/htx.py +1095 -563
- ccxt/huobijp.py +105 -56
- ccxt/hyperliquid.py +1633 -269
- ccxt/idex.py +148 -95
- ccxt/independentreserve.py +235 -31
- ccxt/indodax.py +165 -62
- ccxt/kraken.py +871 -354
- ccxt/krakenfutures.py +324 -100
- ccxt/kucoin.py +1050 -355
- ccxt/kucoinfutures.py +1004 -149
- ccxt/kuna.py +138 -106
- ccxt/latoken.py +135 -79
- ccxt/lbank.py +290 -113
- ccxt/luno.py +112 -62
- ccxt/lykke.py +104 -55
- ccxt/mercado.py +36 -29
- ccxt/mexc.py +994 -429
- ccxt/myokx.py +43 -0
- ccxt/ndax.py +163 -82
- ccxt/novadax.py +121 -75
- ccxt/oceanex.py +175 -59
- ccxt/okcoin.py +222 -163
- ccxt/okx.py +1777 -455
- ccxt/onetrading.py +132 -414
- ccxt/oxfun.py +2831 -0
- ccxt/p2b.py +79 -51
- ccxt/paradex.py +2017 -0
- ccxt/paymium.py +56 -32
- ccxt/phemex.py +572 -196
- ccxt/poloniex.py +218 -95
- ccxt/poloniexfutures.py +260 -92
- ccxt/pro/__init__.py +29 -5
- ccxt/pro/alpaca.py +32 -17
- ccxt/pro/ascendex.py +63 -15
- ccxt/pro/bequant.py +4 -0
- ccxt/pro/binance.py +1596 -329
- ccxt/pro/binancecoinm.py +1 -0
- ccxt/pro/binanceus.py +2 -9
- ccxt/pro/binanceusdm.py +2 -0
- ccxt/pro/bingx.py +527 -134
- ccxt/pro/bitcoincom.py +4 -1
- ccxt/pro/bitfinex.py +731 -266
- ccxt/pro/bitfinex1.py +635 -0
- ccxt/pro/bitget.py +726 -357
- ccxt/pro/bithumb.py +380 -0
- ccxt/pro/bitmart.py +138 -39
- ccxt/pro/bitmex.py +199 -40
- ccxt/pro/bitopro.py +25 -13
- ccxt/pro/bitrue.py +31 -32
- ccxt/pro/bitstamp.py +7 -6
- ccxt/pro/bitvavo.py +204 -82
- ccxt/pro/blockchaincom.py +30 -17
- ccxt/pro/blofin.py +692 -0
- ccxt/pro/bybit.py +791 -82
- ccxt/pro/cex.py +99 -51
- ccxt/pro/coinbase.py +220 -30
- ccxt/{async_support/hitbtc3.py → pro/coinbaseadvanced.py} +5 -5
- ccxt/pro/{coinbasepro.py → coinbaseexchange.py} +19 -19
- ccxt/pro/coinbaseinternational.py +193 -30
- ccxt/pro/coincatch.py +1464 -0
- ccxt/pro/coincheck.py +11 -6
- ccxt/pro/coinex.py +967 -661
- ccxt/pro/coinone.py +17 -10
- ccxt/pro/cryptocom.py +446 -66
- ccxt/pro/currencycom.py +11 -10
- ccxt/pro/defx.py +832 -0
- ccxt/pro/deribit.py +168 -32
- ccxt/pro/exmo.py +253 -21
- ccxt/pro/gate.py +729 -64
- ccxt/pro/gemini.py +44 -26
- ccxt/pro/hashkey.py +802 -0
- ccxt/pro/hitbtc.py +208 -103
- ccxt/pro/hollaex.py +25 -9
- ccxt/pro/htx.py +83 -39
- ccxt/pro/huobijp.py +17 -16
- ccxt/pro/hyperliquid.py +502 -31
- ccxt/pro/idex.py +28 -13
- ccxt/pro/independentreserve.py +21 -16
- ccxt/pro/kraken.py +298 -51
- ccxt/pro/krakenfutures.py +166 -75
- ccxt/pro/kucoin.py +395 -77
- ccxt/pro/kucoinfutures.py +400 -99
- ccxt/pro/lbank.py +52 -31
- ccxt/pro/luno.py +12 -10
- ccxt/pro/mexc.py +400 -50
- ccxt/pro/myokx.py +28 -0
- ccxt/pro/ndax.py +25 -12
- ccxt/pro/okcoin.py +28 -9
- ccxt/pro/okx.py +935 -124
- ccxt/pro/onetrading.py +41 -24
- ccxt/pro/oxfun.py +1054 -0
- ccxt/pro/p2b.py +100 -24
- ccxt/pro/paradex.py +352 -0
- ccxt/pro/phemex.py +93 -34
- ccxt/pro/poloniex.py +129 -50
- ccxt/pro/poloniexfutures.py +53 -32
- ccxt/pro/probit.py +93 -86
- ccxt/pro/upbit.py +401 -8
- ccxt/pro/vertex.py +943 -0
- ccxt/pro/wazirx.py +46 -28
- ccxt/pro/whitebit.py +65 -12
- ccxt/pro/woo.py +486 -70
- ccxt/pro/woofipro.py +1271 -0
- ccxt/pro/xt.py +1067 -0
- ccxt/probit.py +143 -110
- ccxt/static_dependencies/__init__.py +1 -1
- ccxt/static_dependencies/lark/__init__.py +38 -0
- ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
- ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
- ccxt/static_dependencies/lark/ast_utils.py +59 -0
- ccxt/static_dependencies/lark/common.py +86 -0
- ccxt/static_dependencies/lark/exceptions.py +292 -0
- ccxt/static_dependencies/lark/grammar.py +130 -0
- ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
- ccxt/static_dependencies/lark/indenter.py +143 -0
- ccxt/static_dependencies/lark/lark.py +658 -0
- ccxt/static_dependencies/lark/lexer.py +678 -0
- ccxt/static_dependencies/lark/load_grammar.py +1428 -0
- ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
- ccxt/static_dependencies/lark/parser_frontends.py +257 -0
- ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
- ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
- ccxt/static_dependencies/lark/parsers/earley.py +314 -0
- ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
- ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
- ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
- ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
- ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
- ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
- ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
- ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
- ccxt/static_dependencies/lark/py.typed +0 -0
- ccxt/static_dependencies/lark/reconstruct.py +107 -0
- ccxt/static_dependencies/lark/tools/__init__.py +70 -0
- ccxt/static_dependencies/lark/tools/nearley.py +202 -0
- ccxt/static_dependencies/lark/tools/serialize.py +32 -0
- ccxt/static_dependencies/lark/tools/standalone.py +196 -0
- ccxt/static_dependencies/lark/tree.py +267 -0
- ccxt/static_dependencies/lark/tree_matcher.py +186 -0
- ccxt/static_dependencies/lark/tree_templates.py +180 -0
- ccxt/static_dependencies/lark/utils.py +343 -0
- ccxt/static_dependencies/lark/visitors.py +596 -0
- ccxt/static_dependencies/marshmallow/__init__.py +81 -0
- ccxt/static_dependencies/marshmallow/base.py +65 -0
- ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
- ccxt/static_dependencies/marshmallow/decorators.py +231 -0
- ccxt/static_dependencies/marshmallow/error_store.py +60 -0
- ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
- ccxt/static_dependencies/marshmallow/fields.py +2114 -0
- ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
- ccxt/static_dependencies/marshmallow/py.typed +0 -0
- ccxt/static_dependencies/marshmallow/schema.py +1228 -0
- ccxt/static_dependencies/marshmallow/types.py +12 -0
- ccxt/static_dependencies/marshmallow/utils.py +378 -0
- ccxt/static_dependencies/marshmallow/validate.py +678 -0
- ccxt/static_dependencies/marshmallow/warnings.py +2 -0
- ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
- ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
- ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
- ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
- ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
- ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
- ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
- ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
- ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
- ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
- ccxt/static_dependencies/starknet/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
- ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
- ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
- ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
- ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
- ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
- ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
- ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
- ccxt/static_dependencies/starknet/common.py +15 -0
- ccxt/static_dependencies/starknet/constants.py +39 -0
- ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
- ccxt/static_dependencies/starknet/hash/address.py +79 -0
- ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
- ccxt/static_dependencies/starknet/hash/selector.py +16 -0
- ccxt/static_dependencies/starknet/hash/storage.py +12 -0
- ccxt/static_dependencies/starknet/hash/utils.py +78 -0
- ccxt/static_dependencies/starknet/models/__init__.py +0 -0
- ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
- ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
- ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
- ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
- ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
- ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
- ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
- ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
- ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
- ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
- ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
- ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
- ccxt/static_dependencies/starknet/utils/schema.py +13 -0
- ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
- ccxt/static_dependencies/starkware/__init__.py +0 -0
- ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
- ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
- ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
- ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
- ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
- ccxt/static_dependencies/sympy/__init__.py +0 -0
- ccxt/static_dependencies/sympy/core/__init__.py +0 -0
- ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
- ccxt/static_dependencies/sympy/external/__init__.py +0 -0
- ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
- ccxt/static_dependencies/sympy/external/importtools.py +187 -0
- ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
- ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
- ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
- ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
- ccxt/test/{test_async.py → tests_async.py} +465 -407
- ccxt/test/tests_helpers.py +285 -0
- ccxt/test/tests_init.py +39 -0
- ccxt/test/{test_sync.py → tests_sync.py} +465 -409
- ccxt/timex.py +123 -70
- ccxt/tokocrypto.py +129 -93
- ccxt/tradeogre.py +39 -25
- ccxt/upbit.py +322 -113
- ccxt/vertex.py +2983 -0
- ccxt/wavesexchange.py +227 -173
- ccxt/wazirx.py +145 -65
- ccxt/whitebit.py +533 -138
- ccxt/woo.py +1155 -295
- ccxt/woofipro.py +2716 -0
- ccxt/xt.py +4627 -0
- ccxt/yobit.py +159 -92
- ccxt/zaif.py +80 -33
- ccxt/zonda.py +140 -69
- ccxt-4.4.48.dist-info/LICENSE.txt +21 -0
- ccxt-4.4.48.dist-info/METADATA +646 -0
- ccxt-4.4.48.dist-info/RECORD +669 -0
- {ccxt-4.2.76.dist-info → ccxt-4.4.48.dist-info}/WHEEL +1 -1
- ccxt/abstract/bitbay.py +0 -47
- ccxt/abstract/bitfinex2.py +0 -139
- ccxt/abstract/hitbtc3.py +0 -115
- ccxt/async_support/bitbay.py +0 -17
- ccxt/async_support/bitfinex2.py +0 -3496
- ccxt/async_support/flowbtc.py +0 -34
- ccxt/bitbay.py +0 -17
- ccxt/bitfinex2.py +0 -3496
- ccxt/flowbtc.py +0 -34
- ccxt/hitbtc3.py +0 -16
- ccxt/pro/bitfinex2.py +0 -1081
- ccxt/test/base/__init__.py +0 -28
- 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 -103
- 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 -32
- 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_margin_mode.py +0 -24
- ccxt/test/base/test_margin_modification.py +0 -35
- ccxt/test/base/test_market.py +0 -190
- ccxt/test/base/test_number.py +0 -411
- ccxt/test/base/test_ohlcv.py +0 -32
- 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 -63
- ccxt/test/base/test_position.py +0 -60
- ccxt/test/base/test_shared_methods.py +0 -345
- ccxt/test/base/test_status.py +0 -24
- ccxt/test/base/test_throttle.py +0 -126
- ccxt/test/base/test_ticker.py +0 -86
- 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-4.2.76.dist-info/METADATA +0 -626
- ccxt-4.2.76.dist-info/RECORD +0 -534
- {ccxt-4.2.76.dist-info → ccxt-4.4.48.dist-info}/top_level.txt +0 -0
ccxt/async_support/phemex.py
CHANGED
@@ -7,9 +7,10 @@ from ccxt.async_support.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, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
10
|
+
from ccxt.base.types import Balances, Currencies, Currency, DepositAddress, Int, LeverageTier, LeverageTiers, MarginModification, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, Trade, Transaction, TransferEntry
|
11
11
|
from typing import List
|
12
12
|
from ccxt.base.errors import ExchangeError
|
13
|
+
from ccxt.base.errors import AuthenticationError
|
13
14
|
from ccxt.base.errors import PermissionDenied
|
14
15
|
from ccxt.base.errors import AccountSuspended
|
15
16
|
from ccxt.base.errors import ArgumentsRequired
|
@@ -18,12 +19,10 @@ from ccxt.base.errors import BadSymbol
|
|
18
19
|
from ccxt.base.errors import InsufficientFunds
|
19
20
|
from ccxt.base.errors import InvalidOrder
|
20
21
|
from ccxt.base.errors import OrderNotFound
|
21
|
-
from ccxt.base.errors import CancelPending
|
22
22
|
from ccxt.base.errors import DuplicateOrderId
|
23
|
-
from ccxt.base.errors import NotSupported
|
24
23
|
from ccxt.base.errors import DDoSProtection
|
25
24
|
from ccxt.base.errors import RateLimitExceeded
|
26
|
-
from ccxt.base.errors import
|
25
|
+
from ccxt.base.errors import CancelPending
|
27
26
|
from ccxt.base.decimal_to_precision import TICK_SIZE
|
28
27
|
from ccxt.base.precise import Precise
|
29
28
|
|
@@ -65,6 +64,8 @@ class phemex(Exchange, ImplicitAPI):
|
|
65
64
|
'fetchCrossBorrowRates': False,
|
66
65
|
'fetchCurrencies': True,
|
67
66
|
'fetchDepositAddress': True,
|
67
|
+
'fetchDepositAddresses': False,
|
68
|
+
'fetchDepositAddressesByNetwork': False,
|
68
69
|
'fetchDeposits': True,
|
69
70
|
'fetchFundingHistory': True,
|
70
71
|
'fetchFundingRate': True,
|
@@ -81,6 +82,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
81
82
|
'fetchMarkOHLCV': False,
|
82
83
|
'fetchMyTrades': True,
|
83
84
|
'fetchOHLCV': True,
|
85
|
+
'fetchOpenInterest': True,
|
84
86
|
'fetchOpenOrders': True,
|
85
87
|
'fetchOrder': True,
|
86
88
|
'fetchOrderBook': True,
|
@@ -96,6 +98,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
96
98
|
'fetchTransfers': True,
|
97
99
|
'fetchWithdrawals': True,
|
98
100
|
'reduceMargin': False,
|
101
|
+
'sandbox': True,
|
99
102
|
'setLeverage': True,
|
100
103
|
'setMargin': True,
|
101
104
|
'setMarginMode': True,
|
@@ -118,7 +121,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
118
121
|
'private': 'https://{hostname}',
|
119
122
|
},
|
120
123
|
'www': 'https://phemex.com',
|
121
|
-
'doc': 'https://
|
124
|
+
'doc': 'https://phemex-docs.github.io/#overview',
|
122
125
|
'fees': 'https://phemex.com/fees-conditions',
|
123
126
|
'referral': {
|
124
127
|
'url': 'https://phemex.com/register?referralCode=EDNVJ',
|
@@ -176,6 +179,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
176
179
|
'v2': {
|
177
180
|
'get': {
|
178
181
|
'public/products': 5,
|
182
|
+
'public/products-plus': 5,
|
179
183
|
'md/v2/orderbook': 5, # ?symbol=<symbol>&id=<id>
|
180
184
|
'md/v2/trade': 5, # ?symbol=<symbol>&id=<id>
|
181
185
|
'md/v2/ticker/24hr': 5, # ?symbol=<symbol>&id=<id>
|
@@ -302,6 +306,109 @@ class phemex(Exchange, ImplicitAPI):
|
|
302
306
|
'maker': self.parse_number('0.001'),
|
303
307
|
},
|
304
308
|
},
|
309
|
+
'features': {
|
310
|
+
'default': {
|
311
|
+
'sandbox': True,
|
312
|
+
'createOrder': {
|
313
|
+
'marginMode': False,
|
314
|
+
'triggerPrice': True,
|
315
|
+
# todo
|
316
|
+
'triggerPriceType': {
|
317
|
+
'mark': True,
|
318
|
+
'last': True,
|
319
|
+
'index': True,
|
320
|
+
},
|
321
|
+
'triggerDirection': False,
|
322
|
+
'stopLossPrice': False, # todo
|
323
|
+
'takeProfitPrice': False, # todo
|
324
|
+
'attachedStopLossTakeProfit': None,
|
325
|
+
'timeInForce': {
|
326
|
+
'IOC': True,
|
327
|
+
'FOK': True,
|
328
|
+
'PO': True,
|
329
|
+
'GTD': False,
|
330
|
+
},
|
331
|
+
'hedged': False,
|
332
|
+
'leverage': False,
|
333
|
+
'marketBuyByCost': True,
|
334
|
+
'marketBuyRequiresPrice': False,
|
335
|
+
'selfTradePrevention': False,
|
336
|
+
'trailing': False,
|
337
|
+
'iceberg': False,
|
338
|
+
},
|
339
|
+
'createOrders': None,
|
340
|
+
'fetchMyTrades': {
|
341
|
+
'marginMode': False,
|
342
|
+
'limit': 200,
|
343
|
+
'daysBack': 100000,
|
344
|
+
'untilDays': 2, # todo implement
|
345
|
+
},
|
346
|
+
'fetchOrder': {
|
347
|
+
'marginMode': False,
|
348
|
+
'trigger': False,
|
349
|
+
'trailing': False,
|
350
|
+
},
|
351
|
+
'fetchOpenOrders': {
|
352
|
+
'marginMode': False,
|
353
|
+
'limit': None,
|
354
|
+
'trigger': False,
|
355
|
+
'trailing': False,
|
356
|
+
},
|
357
|
+
'fetchOrders': {
|
358
|
+
'marginMode': False,
|
359
|
+
'limit': None,
|
360
|
+
'daysBack': None,
|
361
|
+
'untilDays': None,
|
362
|
+
'trigger': False,
|
363
|
+
'trailing': False,
|
364
|
+
},
|
365
|
+
'fetchClosedOrders': {
|
366
|
+
'marginMode': False,
|
367
|
+
'limit': 200,
|
368
|
+
'daysBack': 100000,
|
369
|
+
'daysBackCanceled': 100000,
|
370
|
+
'untilDays': 2,
|
371
|
+
'trigger': False,
|
372
|
+
'trailing': False,
|
373
|
+
},
|
374
|
+
'fetchOHLCV': {
|
375
|
+
'limit': 1000,
|
376
|
+
},
|
377
|
+
},
|
378
|
+
'spot': {
|
379
|
+
'extends': 'default',
|
380
|
+
},
|
381
|
+
'forDerivatives': {
|
382
|
+
'extends': 'default',
|
383
|
+
'createOrder': {
|
384
|
+
'triggerDirection': True,
|
385
|
+
'attachedStopLossTakeProfit': {
|
386
|
+
'triggerPriceType': {
|
387
|
+
'mark': True,
|
388
|
+
'last': True,
|
389
|
+
'index': True,
|
390
|
+
},
|
391
|
+
'price': True,
|
392
|
+
},
|
393
|
+
'hedged': True,
|
394
|
+
},
|
395
|
+
'fetchOHLCV': {
|
396
|
+
'limit': 2000,
|
397
|
+
},
|
398
|
+
},
|
399
|
+
'swap': {
|
400
|
+
'linear': {
|
401
|
+
'extends': 'forDerivatives',
|
402
|
+
},
|
403
|
+
'inverse': {
|
404
|
+
'extends': 'forDerivatives',
|
405
|
+
},
|
406
|
+
},
|
407
|
+
'future': {
|
408
|
+
'linear': None,
|
409
|
+
'inverse': None,
|
410
|
+
},
|
411
|
+
},
|
305
412
|
'requiredCredentials': {
|
306
413
|
'apiKey': True,
|
307
414
|
'secret': True,
|
@@ -500,6 +607,13 @@ class phemex(Exchange, ImplicitAPI):
|
|
500
607
|
'transfer': {
|
501
608
|
'fillResponseFromRequest': True,
|
502
609
|
},
|
610
|
+
'triggerPriceTypesMap': {
|
611
|
+
'last': 'ByLastPrice',
|
612
|
+
'mark': 'ByMarkPrice',
|
613
|
+
'index': 'ByIndexPrice',
|
614
|
+
'ask': 'ByAskPrice',
|
615
|
+
'bid': 'ByBidPrice',
|
616
|
+
},
|
503
617
|
},
|
504
618
|
})
|
505
619
|
|
@@ -511,10 +625,10 @@ class phemex(Exchange, ImplicitAPI):
|
|
511
625
|
parts = value.split(' ')
|
512
626
|
return self.safe_number(parts, 0)
|
513
627
|
|
514
|
-
def parse_swap_market(self, market):
|
628
|
+
def parse_swap_market(self, market: dict):
|
515
629
|
#
|
516
630
|
# {
|
517
|
-
# "symbol":"BTCUSD",
|
631
|
+
# "symbol":"BTCUSD", #
|
518
632
|
# "code":"1",
|
519
633
|
# "type":"Perpetual",
|
520
634
|
# "displaySymbol":"BTC / USD",
|
@@ -522,7 +636,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
522
636
|
# "markSymbol":".MBTC",
|
523
637
|
# "fundingRateSymbol":".BTCFR",
|
524
638
|
# "fundingRate8hSymbol":".BTCFR8H",
|
525
|
-
# "contractUnderlyingAssets":"USD",
|
639
|
+
# "contractUnderlyingAssets":"USD", # or eg. `1000 SHIB`
|
526
640
|
# "settleCurrency":"BTC",
|
527
641
|
# "quoteCurrency":"USD",
|
528
642
|
# "contractSize":"1 USD",
|
@@ -566,6 +680,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
566
680
|
quoteId = self.safe_string(market, 'quoteCurrency')
|
567
681
|
settleId = self.safe_string(market, 'settleCurrency')
|
568
682
|
base = self.safe_currency_code(baseId)
|
683
|
+
base = base.replace(' ', '') # replace space for junction codes, eg. `1000 SHIB`
|
569
684
|
quote = self.safe_currency_code(quoteId)
|
570
685
|
settle = self.safe_currency_code(settleId)
|
571
686
|
inverse = False
|
@@ -646,7 +761,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
646
761
|
'info': market,
|
647
762
|
})
|
648
763
|
|
649
|
-
def parse_spot_market(self, market):
|
764
|
+
def parse_spot_market(self, market: dict):
|
650
765
|
#
|
651
766
|
# {
|
652
767
|
# "symbol":"sBTCUSDT",
|
@@ -743,13 +858,16 @@ class phemex(Exchange, ImplicitAPI):
|
|
743
858
|
'max': self.parse_safe_number(self.safe_string(market, 'maxOrderValue')),
|
744
859
|
},
|
745
860
|
},
|
746
|
-
'created':
|
861
|
+
'created': self.safe_integer(market, 'listTime'),
|
747
862
|
'info': market,
|
748
863
|
})
|
749
864
|
|
750
|
-
async def fetch_markets(self, params={}):
|
865
|
+
async def fetch_markets(self, params={}) -> List[Market]:
|
751
866
|
"""
|
752
867
|
retrieves data on all markets for phemex
|
868
|
+
|
869
|
+
https://phemex-docs.github.io/#query-product-information-3
|
870
|
+
|
753
871
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
754
872
|
:returns dict[]: an array of objects representing market data
|
755
873
|
"""
|
@@ -971,7 +1089,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
971
1089
|
result.append(market)
|
972
1090
|
return result
|
973
1091
|
|
974
|
-
async def fetch_currencies(self, params={}):
|
1092
|
+
async def fetch_currencies(self, params={}) -> Currencies:
|
975
1093
|
"""
|
976
1094
|
fetches all available currencies on an exchange
|
977
1095
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -994,7 +1112,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
994
1112
|
# }
|
995
1113
|
data = self.safe_value(response, 'data', {})
|
996
1114
|
currencies = self.safe_value(data, 'currencies', [])
|
997
|
-
result = {}
|
1115
|
+
result: dict = {}
|
998
1116
|
for i in range(0, len(currencies)):
|
999
1117
|
currency = currencies[i]
|
1000
1118
|
id = self.safe_string(currency, 'currency')
|
@@ -1050,7 +1168,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
1050
1168
|
]
|
1051
1169
|
|
1052
1170
|
def custom_parse_order_book(self, orderbook, symbol, timestamp=None, bidsKey='bids', asksKey='asks', priceKey=0, amountKey=1, market: Market = None):
|
1053
|
-
result = {
|
1171
|
+
result: dict = {
|
1054
1172
|
'symbol': symbol,
|
1055
1173
|
'timestamp': timestamp,
|
1056
1174
|
'datetime': self.iso8601(timestamp),
|
@@ -1071,7 +1189,9 @@ class phemex(Exchange, ImplicitAPI):
|
|
1071
1189
|
async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
1072
1190
|
"""
|
1073
1191
|
fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
1074
|
-
|
1192
|
+
|
1193
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#queryorderbook
|
1194
|
+
|
1075
1195
|
:param str symbol: unified symbol of the market to fetch the order book for
|
1076
1196
|
:param int [limit]: the maximum amount of order book entries to return
|
1077
1197
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1079,7 +1199,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
1079
1199
|
"""
|
1080
1200
|
await self.load_markets()
|
1081
1201
|
market = self.market(symbol)
|
1082
|
-
request = {
|
1202
|
+
request: dict = {
|
1083
1203
|
'symbol': market['id'],
|
1084
1204
|
# 'id': 123456789, # optional request id
|
1085
1205
|
}
|
@@ -1195,8 +1315,10 @@ class phemex(Exchange, ImplicitAPI):
|
|
1195
1315
|
async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
1196
1316
|
"""
|
1197
1317
|
fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
1198
|
-
|
1199
|
-
|
1318
|
+
|
1319
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#querykline
|
1320
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md#query-kline
|
1321
|
+
|
1200
1322
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
1201
1323
|
:param str timeframe: the length of time each candle represents
|
1202
1324
|
: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
|
@@ -1208,7 +1330,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
1208
1330
|
await self.load_markets()
|
1209
1331
|
market = self.market(symbol)
|
1210
1332
|
userLimit = limit
|
1211
|
-
request = {
|
1333
|
+
request: dict = {
|
1212
1334
|
'symbol': market['id'],
|
1213
1335
|
'resolution': self.safe_string(self.timeframes, timeframe, timeframe),
|
1214
1336
|
}
|
@@ -1266,10 +1388,10 @@ class phemex(Exchange, ImplicitAPI):
|
|
1266
1388
|
# }
|
1267
1389
|
#
|
1268
1390
|
data = self.safe_value(response, 'data', {})
|
1269
|
-
rows = self.
|
1391
|
+
rows = self.safe_list(data, 'rows', [])
|
1270
1392
|
return self.parse_ohlcvs(rows, market, timeframe, since, userLimit)
|
1271
1393
|
|
1272
|
-
def parse_ticker(self, ticker, market: Market = None) -> Ticker:
|
1394
|
+
def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
|
1273
1395
|
#
|
1274
1396
|
# spot
|
1275
1397
|
#
|
@@ -1359,14 +1481,16 @@ class phemex(Exchange, ImplicitAPI):
|
|
1359
1481
|
async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
|
1360
1482
|
"""
|
1361
1483
|
fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
1362
|
-
|
1484
|
+
|
1485
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#query24hrsticker
|
1486
|
+
|
1363
1487
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
1364
1488
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1365
1489
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
1366
1490
|
"""
|
1367
1491
|
await self.load_markets()
|
1368
1492
|
market = self.market(symbol)
|
1369
|
-
request = {
|
1493
|
+
request: dict = {
|
1370
1494
|
'symbol': market['id'],
|
1371
1495
|
# 'id': 123456789, # optional request id
|
1372
1496
|
}
|
@@ -1422,15 +1546,17 @@ class phemex(Exchange, ImplicitAPI):
|
|
1422
1546
|
# }
|
1423
1547
|
# }
|
1424
1548
|
#
|
1425
|
-
result = self.
|
1549
|
+
result = self.safe_dict(response, 'result', {})
|
1426
1550
|
return self.parse_ticker(result, market)
|
1427
1551
|
|
1428
1552
|
async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
1429
1553
|
"""
|
1430
1554
|
fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
1431
|
-
|
1432
|
-
|
1433
|
-
|
1555
|
+
|
1556
|
+
https://phemex-docs.github.io/#query-24-hours-ticker-for-all-symbols-2 # spot
|
1557
|
+
https://phemex-docs.github.io/#query-24-ticker-for-all-symbols # linear
|
1558
|
+
https://phemex-docs.github.io/#query-24-hours-ticker-for-all-symbols # inverse
|
1559
|
+
|
1434
1560
|
:param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
1435
1561
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1436
1562
|
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
@@ -1452,13 +1578,15 @@ class phemex(Exchange, ImplicitAPI):
|
|
1452
1578
|
response = await self.v1GetMdTicker24hrAll(query)
|
1453
1579
|
else:
|
1454
1580
|
response = await self.v2GetMdV2Ticker24hrAll(query)
|
1455
|
-
result = self.
|
1581
|
+
result = self.safe_list(response, 'result', [])
|
1456
1582
|
return self.parse_tickers(result, symbols)
|
1457
1583
|
|
1458
1584
|
async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
1459
1585
|
"""
|
1460
1586
|
get the list of most recent trades for a particular symbol
|
1461
|
-
|
1587
|
+
|
1588
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#querytrades
|
1589
|
+
|
1462
1590
|
:param str symbol: unified symbol of the market to fetch trades for
|
1463
1591
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
1464
1592
|
:param int [limit]: the maximum amount of trades to fetch
|
@@ -1467,7 +1595,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
1467
1595
|
"""
|
1468
1596
|
await self.load_markets()
|
1469
1597
|
market = self.market(symbol)
|
1470
|
-
request = {
|
1598
|
+
request: dict = {
|
1471
1599
|
'symbol': market['id'],
|
1472
1600
|
# 'id': 123456789, # optional request id
|
1473
1601
|
}
|
@@ -1496,7 +1624,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
1496
1624
|
trades = self.safe_value_2(result, 'trades', 'trades_p', [])
|
1497
1625
|
return self.parse_trades(trades, market, since, limit)
|
1498
1626
|
|
1499
|
-
def parse_trade(self, trade, market: Market = None) -> Trade:
|
1627
|
+
def parse_trade(self, trade: dict, market: Market = None) -> Trade:
|
1500
1628
|
#
|
1501
1629
|
# fetchTrades(public) spot & contract
|
1502
1630
|
#
|
@@ -1657,6 +1785,26 @@ class phemex(Exchange, ImplicitAPI):
|
|
1657
1785
|
# "execId": "8718cae",
|
1658
1786
|
# "execStatus": 6
|
1659
1787
|
# }
|
1788
|
+
# spot with fees paid using PT token
|
1789
|
+
# "createdAt": "1714990724076",
|
1790
|
+
# "symbol": "BTCUSDT",
|
1791
|
+
# "currency": "USDT",
|
1792
|
+
# "action": "1",
|
1793
|
+
# "tradeType": "1",
|
1794
|
+
# "execQtyRq": "0.003",
|
1795
|
+
# "execPriceRp": "64935",
|
1796
|
+
# "side": "2",
|
1797
|
+
# "orderQtyRq": "0.003",
|
1798
|
+
# "priceRp": "51600",
|
1799
|
+
# "execValueRv": "194.805",
|
1800
|
+
# "feeRateRr": "0.000495",
|
1801
|
+
# "execFeeRv": "0",
|
1802
|
+
# "ordType": "3",
|
1803
|
+
# "execId": "XXXXXX",
|
1804
|
+
# "execStatus": "7",
|
1805
|
+
# "posSide": "1",
|
1806
|
+
# "ptFeeRv": "0.110012249248",
|
1807
|
+
# "ptPriceRp": "0.876524893"
|
1660
1808
|
#
|
1661
1809
|
priceString: Str
|
1662
1810
|
amountString: Str
|
@@ -1705,10 +1853,16 @@ class phemex(Exchange, ImplicitAPI):
|
|
1705
1853
|
priceString = self.safe_string(trade, 'execPriceRp')
|
1706
1854
|
amountString = self.safe_string(trade, 'execQtyRq')
|
1707
1855
|
costString = self.safe_string(trade, 'execValueRv')
|
1708
|
-
feeCostString = self.safe_string(trade, 'execFeeRv')
|
1856
|
+
feeCostString = self.omit_zero(self.safe_string(trade, 'execFeeRv'))
|
1709
1857
|
feeRateString = self.safe_string(trade, 'feeRateRr')
|
1710
|
-
|
1711
|
-
|
1858
|
+
if feeCostString is not None:
|
1859
|
+
currencyId = self.safe_string(trade, 'currency')
|
1860
|
+
feeCurrencyCode = self.safe_currency_code(currencyId)
|
1861
|
+
else:
|
1862
|
+
ptFeeRv = self.omit_zero(self.safe_string(trade, 'ptFeeRv'))
|
1863
|
+
if ptFeeRv is not None:
|
1864
|
+
feeCostString = ptFeeRv
|
1865
|
+
feeCurrencyCode = 'PT'
|
1712
1866
|
else:
|
1713
1867
|
side = self.safe_string_lower(trade, 'side')
|
1714
1868
|
type = self.parse_order_type(self.safe_string(trade, 'ordType'))
|
@@ -1719,7 +1873,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
1719
1873
|
amountString = self.from_ev(self.safe_string(trade, 'execBaseQtyEv'), market)
|
1720
1874
|
amountString = self.safe_string(trade, 'execQty', amountString)
|
1721
1875
|
costString = self.from_er(self.safe_string_2(trade, 'execQuoteQtyEv', 'execValueEv'), market)
|
1722
|
-
feeCostString = self.from_er(self.safe_string(trade, 'execFeeEv'), market)
|
1876
|
+
feeCostString = self.from_er(self.omit_zero(self.safe_string(trade, 'execFeeEv')), market)
|
1723
1877
|
if feeCostString is not None:
|
1724
1878
|
feeRateString = self.from_er(self.safe_string(trade, 'feeRateEr'), market)
|
1725
1879
|
if market['spot']:
|
@@ -1729,6 +1883,10 @@ class phemex(Exchange, ImplicitAPI):
|
|
1729
1883
|
if info is not None:
|
1730
1884
|
settlementCurrencyId = self.safe_string(info, 'settlementCurrency')
|
1731
1885
|
feeCurrencyCode = self.safe_currency_code(settlementCurrencyId)
|
1886
|
+
else:
|
1887
|
+
feeCostString = self.safe_string(trade, 'ptFeeRv')
|
1888
|
+
if feeCostString is not None:
|
1889
|
+
feeCurrencyCode = 'PT'
|
1732
1890
|
fee = {
|
1733
1891
|
'cost': feeCostString,
|
1734
1892
|
'rate': feeRateString,
|
@@ -1776,7 +1934,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
1776
1934
|
# }
|
1777
1935
|
#
|
1778
1936
|
timestamp = None
|
1779
|
-
result = {'info': response}
|
1937
|
+
result: dict = {'info': response}
|
1780
1938
|
data = self.safe_value(response, 'data', [])
|
1781
1939
|
for i in range(0, len(data)):
|
1782
1940
|
balance = data[i]
|
@@ -1832,7 +1990,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
1832
1990
|
# }
|
1833
1991
|
# }
|
1834
1992
|
#
|
1835
|
-
result = {'info': response}
|
1993
|
+
result: dict = {'info': response}
|
1836
1994
|
data = self.safe_value(response, 'data', {})
|
1837
1995
|
balance = self.safe_value(data, 'account', {})
|
1838
1996
|
currencyId = self.safe_string(balance, 'currency')
|
@@ -1851,9 +2009,11 @@ class phemex(Exchange, ImplicitAPI):
|
|
1851
2009
|
async def fetch_balance(self, params={}) -> Balances:
|
1852
2010
|
"""
|
1853
2011
|
query for balance and get the amount of funds available for trading or funds locked in orders
|
1854
|
-
|
1855
|
-
|
1856
|
-
|
2012
|
+
|
2013
|
+
https://phemex-docs.github.io/#query-wallets
|
2014
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#query-account-positions
|
2015
|
+
https://phemex-docs.github.io/#query-trading-account-and-positions
|
2016
|
+
|
1857
2017
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1858
2018
|
:param str [params.type]: spot or swap
|
1859
2019
|
:param str [params.code]: *swap only* currency code of the balance to query(USD, USDT, etc), default is USDT
|
@@ -1865,7 +2025,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
1865
2025
|
code = self.safe_string(params, 'code')
|
1866
2026
|
params = self.omit(params, ['code'])
|
1867
2027
|
response = None
|
1868
|
-
request = {}
|
2028
|
+
request: dict = {}
|
1869
2029
|
if (type != 'spot') and (type != 'swap'):
|
1870
2030
|
raise BadRequest(self.id + ' does not support ' + type + ' markets, only spot and swap')
|
1871
2031
|
if type == 'swap':
|
@@ -2010,8 +2170,8 @@ class phemex(Exchange, ImplicitAPI):
|
|
2010
2170
|
result = self.parse_swap_balance(response) if (type == 'swap') else self.parse_spot_balance(response)
|
2011
2171
|
return result
|
2012
2172
|
|
2013
|
-
def parse_order_status(self, status):
|
2014
|
-
statuses = {
|
2173
|
+
def parse_order_status(self, status: Str):
|
2174
|
+
statuses: dict = {
|
2015
2175
|
'Created': 'open',
|
2016
2176
|
'Untriggered': 'open',
|
2017
2177
|
'Deactivated': 'closed',
|
@@ -2021,6 +2181,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2021
2181
|
'PartiallyFilled': 'open',
|
2022
2182
|
'Filled': 'closed',
|
2023
2183
|
'Canceled': 'canceled',
|
2184
|
+
'Suspended': 'canceled',
|
2024
2185
|
'1': 'open',
|
2025
2186
|
'2': 'canceled',
|
2026
2187
|
'3': 'closed',
|
@@ -2032,8 +2193,8 @@ class phemex(Exchange, ImplicitAPI):
|
|
2032
2193
|
}
|
2033
2194
|
return self.safe_string(statuses, status, status)
|
2034
2195
|
|
2035
|
-
def parse_order_type(self, type):
|
2036
|
-
types = {
|
2196
|
+
def parse_order_type(self, type: Str):
|
2197
|
+
types: dict = {
|
2037
2198
|
'1': 'market',
|
2038
2199
|
'2': 'limit',
|
2039
2200
|
'3': 'stop',
|
@@ -2049,8 +2210,8 @@ class phemex(Exchange, ImplicitAPI):
|
|
2049
2210
|
}
|
2050
2211
|
return self.safe_string(types, type, type)
|
2051
2212
|
|
2052
|
-
def parse_time_in_force(self, timeInForce):
|
2053
|
-
timeInForces = {
|
2213
|
+
def parse_time_in_force(self, timeInForce: Str):
|
2214
|
+
timeInForces: dict = {
|
2054
2215
|
'GoodTillCancel': 'GTC',
|
2055
2216
|
'PostOnly': 'PO',
|
2056
2217
|
'ImmediateOrCancel': 'IOC',
|
@@ -2058,7 +2219,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2058
2219
|
}
|
2059
2220
|
return self.safe_string(timeInForces, timeInForce, timeInForce)
|
2060
2221
|
|
2061
|
-
def parse_spot_order(self, order, market: Market = None):
|
2222
|
+
def parse_spot_order(self, order: dict, market: Market = None):
|
2062
2223
|
#
|
2063
2224
|
# spot
|
2064
2225
|
#
|
@@ -2137,10 +2298,10 @@ class phemex(Exchange, ImplicitAPI):
|
|
2137
2298
|
if feeCost is not None:
|
2138
2299
|
fee = {
|
2139
2300
|
'cost': feeCost,
|
2140
|
-
'currency':
|
2301
|
+
'currency': self.safe_currency_code(self.safe_string(order, 'feeCurrency')),
|
2141
2302
|
}
|
2142
2303
|
timeInForce = self.parse_time_in_force(self.safe_string(order, 'timeInForce'))
|
2143
|
-
|
2304
|
+
triggerPrice = self.parse_number(self.omit_zero(self.from_ep(self.safe_string(order, 'stopPxEp'))))
|
2144
2305
|
postOnly = (timeInForce == 'PO')
|
2145
2306
|
return self.safe_order({
|
2146
2307
|
'info': order,
|
@@ -2155,8 +2316,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2155
2316
|
'postOnly': postOnly,
|
2156
2317
|
'side': side,
|
2157
2318
|
'price': price,
|
2158
|
-
'
|
2159
|
-
'triggerPrice': stopPrice,
|
2319
|
+
'triggerPrice': triggerPrice,
|
2160
2320
|
'amount': amount,
|
2161
2321
|
'cost': cost,
|
2162
2322
|
'average': average,
|
@@ -2168,7 +2328,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2168
2328
|
}, market)
|
2169
2329
|
|
2170
2330
|
def parse_order_side(self, side):
|
2171
|
-
sides = {
|
2331
|
+
sides: dict = {
|
2172
2332
|
'1': 'buy',
|
2173
2333
|
'2': 'sell',
|
2174
2334
|
}
|
@@ -2282,6 +2442,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2282
2442
|
clientOrderId = None
|
2283
2443
|
marketId = self.safe_string(order, 'symbol')
|
2284
2444
|
symbol = self.safe_symbol(marketId, market)
|
2445
|
+
market = self.safe_market(marketId, market)
|
2285
2446
|
status = self.parse_order_status(self.safe_string(order, 'ordStatus'))
|
2286
2447
|
side = self.parse_order_side(self.safe_string_lower(order, 'side'))
|
2287
2448
|
type = self.parse_order_type(self.safe_string(order, 'orderType'))
|
@@ -2299,7 +2460,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2299
2460
|
if lastTradeTimestamp == 0:
|
2300
2461
|
lastTradeTimestamp = None
|
2301
2462
|
timeInForce = self.parse_time_in_force(self.safe_string(order, 'timeInForce'))
|
2302
|
-
|
2463
|
+
triggerPrice = self.omit_zero(self.safe_string_2(order, 'stopPx', 'stopPxRp'))
|
2303
2464
|
postOnly = (timeInForce == 'PO')
|
2304
2465
|
reduceOnly = self.safe_value(order, 'reduceOnly')
|
2305
2466
|
execInst = self.safe_string(order, 'execInst')
|
@@ -2307,6 +2468,19 @@ class phemex(Exchange, ImplicitAPI):
|
|
2307
2468
|
reduceOnly = True
|
2308
2469
|
takeProfit = self.safe_string(order, 'takeProfitRp')
|
2309
2470
|
stopLoss = self.safe_string(order, 'stopLossRp')
|
2471
|
+
feeValue = self.omit_zero(self.safe_string(order, 'execFeeRv'))
|
2472
|
+
ptFeeRv = self.omit_zero(self.safe_string(order, 'ptFeeRv'))
|
2473
|
+
fee = None
|
2474
|
+
if feeValue is not None:
|
2475
|
+
fee = {
|
2476
|
+
'cost': feeValue,
|
2477
|
+
'currency': market['quote'],
|
2478
|
+
}
|
2479
|
+
elif ptFeeRv is not None:
|
2480
|
+
fee = {
|
2481
|
+
'cost': ptFeeRv,
|
2482
|
+
'currency': 'PT',
|
2483
|
+
}
|
2310
2484
|
return self.safe_order({
|
2311
2485
|
'info': order,
|
2312
2486
|
'id': id,
|
@@ -2321,8 +2495,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2321
2495
|
'reduceOnly': reduceOnly,
|
2322
2496
|
'side': side,
|
2323
2497
|
'price': price,
|
2324
|
-
'
|
2325
|
-
'triggerPrice': stopPrice,
|
2498
|
+
'triggerPrice': triggerPrice,
|
2326
2499
|
'takeProfitPrice': takeProfit,
|
2327
2500
|
'stopLossPrice': stopLoss,
|
2328
2501
|
'amount': amount,
|
@@ -2331,11 +2504,11 @@ class phemex(Exchange, ImplicitAPI):
|
|
2331
2504
|
'cost': cost,
|
2332
2505
|
'average': None,
|
2333
2506
|
'status': status,
|
2334
|
-
'fee':
|
2507
|
+
'fee': fee,
|
2335
2508
|
'trades': None,
|
2336
2509
|
})
|
2337
2510
|
|
2338
|
-
def parse_order(self, order, market: Market = None) -> Order:
|
2511
|
+
def parse_order(self, order: dict, market: Market = None) -> Order:
|
2339
2512
|
isSwap = self.safe_bool(market, 'swap', False)
|
2340
2513
|
hasPnl = ('closedPnl' in order) or ('closedPnlRv' in order) or ('totalPnlRv' in order)
|
2341
2514
|
if isSwap or hasPnl:
|
@@ -2345,25 +2518,31 @@ class phemex(Exchange, ImplicitAPI):
|
|
2345
2518
|
async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
2346
2519
|
"""
|
2347
2520
|
create a trade order
|
2348
|
-
|
2521
|
+
|
2522
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#place-order
|
2523
|
+
https://phemex-docs.github.io/#place-order-http-put-prefered-3
|
2524
|
+
|
2349
2525
|
:param str symbol: unified symbol of the market to create an order in
|
2350
2526
|
:param str type: 'market' or 'limit'
|
2351
2527
|
:param str side: 'buy' or 'sell'
|
2352
2528
|
:param float amount: how much of currency you want to trade in units of base currency
|
2353
|
-
:param float [price]: the price at which the order is to be
|
2529
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
2354
2530
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2531
|
+
:param float [params.trigger]: trigger price for conditional orders
|
2355
2532
|
: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)
|
2356
2533
|
:param float [params.takeProfit.triggerPrice]: take profit trigger price
|
2357
2534
|
: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)
|
2358
2535
|
:param float [params.stopLoss.triggerPrice]: stop loss trigger price
|
2536
|
+
: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
|
2537
|
+
:param bool [params.hedged]: *swap only* True for hedged mode, False for one way mode, default is False
|
2359
2538
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2360
2539
|
"""
|
2361
2540
|
await self.load_markets()
|
2362
2541
|
market = self.market(symbol)
|
2363
2542
|
requestSide = self.capitalize(side)
|
2364
2543
|
type = self.capitalize(type)
|
2365
|
-
reduceOnly = self.
|
2366
|
-
request = {
|
2544
|
+
reduceOnly = self.safe_bool(params, 'reduceOnly')
|
2545
|
+
request: dict = {
|
2367
2546
|
# common
|
2368
2547
|
'symbol': market['id'],
|
2369
2548
|
'side': requestSide, # Sell, Buy
|
@@ -2403,18 +2582,24 @@ class phemex(Exchange, ImplicitAPI):
|
|
2403
2582
|
else:
|
2404
2583
|
request['clOrdID'] = clientOrderId
|
2405
2584
|
params = self.omit(params, ['clOrdID', 'clientOrderId'])
|
2406
|
-
|
2407
|
-
if
|
2585
|
+
triggerPrice = self.safe_string_n(params, ['stopPx', 'stopPrice', 'triggerPrice'])
|
2586
|
+
if triggerPrice is not None:
|
2408
2587
|
if market['settle'] == 'USDT':
|
2409
|
-
request['stopPxRp'] = self.price_to_precision(symbol,
|
2588
|
+
request['stopPxRp'] = self.price_to_precision(symbol, triggerPrice)
|
2410
2589
|
else:
|
2411
|
-
request['stopPxEp'] = self.to_ep(
|
2590
|
+
request['stopPxEp'] = self.to_ep(triggerPrice, market)
|
2412
2591
|
params = self.omit(params, ['stopPx', 'stopPrice', 'stopLoss', 'takeProfit', 'triggerPrice'])
|
2413
2592
|
if market['spot']:
|
2414
2593
|
qtyType = self.safe_value(params, 'qtyType', 'ByBase')
|
2415
2594
|
if (type == 'Market') or (type == 'Stop') or (type == 'MarketIfTouched'):
|
2416
2595
|
if price is not None:
|
2417
2596
|
qtyType = 'ByQuote'
|
2597
|
+
if triggerPrice is not None:
|
2598
|
+
if type == 'Limit':
|
2599
|
+
request['ordType'] = 'StopLimit'
|
2600
|
+
elif type == 'Market':
|
2601
|
+
request['ordType'] = 'Stop'
|
2602
|
+
request['trigger'] = 'ByLastPrice'
|
2418
2603
|
request['qtyType'] = qtyType
|
2419
2604
|
if qtyType == 'ByQuote':
|
2420
2605
|
cost = self.safe_number(params, 'cost')
|
@@ -2434,55 +2619,70 @@ class phemex(Exchange, ImplicitAPI):
|
|
2434
2619
|
amountString = self.number_to_string(amount)
|
2435
2620
|
request['baseQtyEv'] = self.to_ev(amountString, market)
|
2436
2621
|
elif market['swap']:
|
2622
|
+
hedged = self.safe_bool(params, 'hedged', False)
|
2623
|
+
params = self.omit(params, 'hedged')
|
2437
2624
|
posSide = self.safe_string_lower(params, 'posSide')
|
2438
2625
|
if posSide is None:
|
2439
|
-
|
2626
|
+
if hedged:
|
2627
|
+
if reduceOnly:
|
2628
|
+
side = 'sell' if (side == 'buy') else 'buy'
|
2629
|
+
posSide = 'Long' if (side == 'buy') else 'Short'
|
2630
|
+
else:
|
2631
|
+
posSide = 'Merged'
|
2440
2632
|
posSide = self.capitalize(posSide)
|
2441
2633
|
request['posSide'] = posSide
|
2442
|
-
if reduceOnly is not None:
|
2443
|
-
request['reduceOnly'] = reduceOnly
|
2444
2634
|
if market['settle'] == 'USDT':
|
2445
2635
|
request['orderQtyRq'] = amount
|
2446
2636
|
else:
|
2447
2637
|
request['orderQty'] = self.parse_to_int(amount)
|
2448
|
-
if
|
2638
|
+
if triggerPrice is not None:
|
2449
2639
|
triggerType = self.safe_string(params, 'triggerType', 'ByMarkPrice')
|
2450
2640
|
request['triggerType'] = triggerType
|
2641
|
+
# set direction & exchange specific order type
|
2642
|
+
triggerDirection = None
|
2643
|
+
triggerDirection, params = self.handle_param_string(params, 'triggerDirection')
|
2644
|
+
if triggerDirection is None:
|
2645
|
+
raise ArgumentsRequired(self.id + " createOrder() also requires a 'triggerDirection' parameter with either 'up' or 'down' value")
|
2646
|
+
# the flow defined per https://phemex-docs.github.io/#more-order-type-examples
|
2647
|
+
if triggerDirection == 'up':
|
2648
|
+
if side == 'sell':
|
2649
|
+
request['ordType'] = 'MarketIfTouched' if (type == 'Market') else 'LimitIfTouched'
|
2650
|
+
elif side == 'buy':
|
2651
|
+
request['ordType'] = 'Stop' if (type == 'Market') else 'StopLimit'
|
2652
|
+
elif triggerDirection == 'down':
|
2653
|
+
if side == 'sell':
|
2654
|
+
request['ordType'] = 'Stop' if (type == 'Market') else 'StopLimit'
|
2655
|
+
elif side == 'buy':
|
2656
|
+
request['ordType'] = 'MarketIfTouched' if (type == 'Market') else 'LimitIfTouched'
|
2451
2657
|
if stopLossDefined or takeProfitDefined:
|
2452
2658
|
if stopLossDefined:
|
2453
2659
|
stopLossTriggerPrice = self.safe_value_2(stopLoss, 'triggerPrice', 'stopPrice')
|
2454
2660
|
if stopLossTriggerPrice is None:
|
2455
|
-
raise InvalidOrder(self.id + ' createOrder() requires a trigger price in params["stopLoss"]["triggerPrice"]
|
2661
|
+
raise InvalidOrder(self.id + ' createOrder() requires a trigger price in params["stopLoss"]["triggerPrice"] for a stop loss order')
|
2456
2662
|
if market['settle'] == 'USDT':
|
2457
2663
|
request['stopLossRp'] = self.price_to_precision(symbol, stopLossTriggerPrice)
|
2458
2664
|
else:
|
2459
2665
|
request['stopLossEp'] = self.to_ep(stopLossTriggerPrice, market)
|
2460
2666
|
stopLossTriggerPriceType = self.safe_string_2(stopLoss, 'triggerPriceType', 'slTrigger')
|
2461
2667
|
if stopLossTriggerPriceType is not None:
|
2462
|
-
|
2463
|
-
|
2464
|
-
|
2465
|
-
|
2466
|
-
if (stopLossTriggerPriceType != 'ByMarkPrice') and (stopLossTriggerPriceType != 'ByLastPrice'):
|
2467
|
-
raise InvalidOrder(self.id + ' createOrder() take profit trigger price type must be one of "ByMarkPrice", or "ByLastPrice"')
|
2468
|
-
request['slTrigger'] = stopLossTriggerPriceType
|
2668
|
+
request['slTrigger'] = self.safe_string(self.options['triggerPriceTypesMap'], stopLossTriggerPriceType, stopLossTriggerPriceType)
|
2669
|
+
slLimitPrice = self.safe_string(stopLoss, 'price')
|
2670
|
+
if slLimitPrice is not None:
|
2671
|
+
request['slPxRp'] = self.price_to_precision(symbol, slLimitPrice)
|
2469
2672
|
if takeProfitDefined:
|
2470
2673
|
takeProfitTriggerPrice = self.safe_value_2(takeProfit, 'triggerPrice', 'stopPrice')
|
2471
2674
|
if takeProfitTriggerPrice is None:
|
2472
|
-
raise InvalidOrder(self.id + ' createOrder() requires a trigger price in params["takeProfit"]["triggerPrice"]
|
2675
|
+
raise InvalidOrder(self.id + ' createOrder() requires a trigger price in params["takeProfit"]["triggerPrice"] for a take profit order')
|
2473
2676
|
if market['settle'] == 'USDT':
|
2474
2677
|
request['takeProfitRp'] = self.price_to_precision(symbol, takeProfitTriggerPrice)
|
2475
2678
|
else:
|
2476
2679
|
request['takeProfitEp'] = self.to_ep(takeProfitTriggerPrice, market)
|
2477
|
-
takeProfitTriggerPriceType = self.safe_string_2(
|
2680
|
+
takeProfitTriggerPriceType = self.safe_string_2(takeProfit, 'triggerPriceType', 'tpTrigger')
|
2478
2681
|
if takeProfitTriggerPriceType is not None:
|
2479
|
-
|
2480
|
-
|
2481
|
-
|
2482
|
-
|
2483
|
-
if (takeProfitTriggerPriceType != 'ByMarkPrice') and (takeProfitTriggerPriceType != 'ByLastPrice'):
|
2484
|
-
raise InvalidOrder(self.id + ' createOrder() take profit trigger price type must be one of "ByMarkPrice", or "ByLastPrice"')
|
2485
|
-
request['tpTrigger'] = takeProfitTriggerPriceType
|
2682
|
+
request['tpTrigger'] = self.safe_string(self.options['triggerPriceTypesMap'], takeProfitTriggerPriceType, takeProfitTriggerPriceType)
|
2683
|
+
tpLimitPrice = self.safe_string(takeProfit, 'price')
|
2684
|
+
if tpLimitPrice is not None:
|
2685
|
+
request['tpPxRp'] = self.price_to_precision(symbol, tpLimitPrice)
|
2486
2686
|
if (type == 'Limit') or (type == 'StopLimit') or (type == 'LimitIfTouched'):
|
2487
2687
|
if market['settle'] == 'USDT':
|
2488
2688
|
request['priceRp'] = self.price_to_precision(symbol, price)
|
@@ -2587,26 +2787,28 @@ class phemex(Exchange, ImplicitAPI):
|
|
2587
2787
|
# }
|
2588
2788
|
# }
|
2589
2789
|
#
|
2590
|
-
data = self.
|
2790
|
+
data = self.safe_dict(response, 'data', {})
|
2591
2791
|
return self.parse_order(data, market)
|
2592
2792
|
|
2593
2793
|
async def edit_order(self, id: str, symbol: str, type: OrderType = None, side: OrderSide = None, amount: Num = None, price: Num = None, params={}):
|
2594
2794
|
"""
|
2595
2795
|
edit a trade order
|
2596
|
-
|
2796
|
+
|
2797
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#amend-order-by-orderid
|
2798
|
+
|
2597
2799
|
:param str id: cancel order id
|
2598
2800
|
:param str symbol: unified symbol of the market to create an order in
|
2599
2801
|
:param str type: 'market' or 'limit'
|
2600
2802
|
:param str side: 'buy' or 'sell'
|
2601
2803
|
:param float amount: how much of currency you want to trade in units of base currency
|
2602
|
-
:param float [price]: the price at which the order is to be
|
2804
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
2603
2805
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2604
2806
|
:param str [params.posSide]: either 'Merged' or 'Long' or 'Short'
|
2605
2807
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2606
2808
|
"""
|
2607
2809
|
await self.load_markets()
|
2608
2810
|
market = self.market(symbol)
|
2609
|
-
request = {
|
2811
|
+
request: dict = {
|
2610
2812
|
'symbol': market['id'],
|
2611
2813
|
}
|
2612
2814
|
clientOrderId = self.safe_string_2(params, 'clientOrderId', 'clOrdID')
|
@@ -2631,13 +2833,13 @@ class phemex(Exchange, ImplicitAPI):
|
|
2631
2833
|
request['orderQtyRq'] = self.amount_to_precision(market['symbol'], amount)
|
2632
2834
|
else:
|
2633
2835
|
request['baseQtyEV'] = self.to_ev(amount, market)
|
2634
|
-
|
2635
|
-
if
|
2836
|
+
triggerPrice = self.safe_string_n(params, ['triggerPrice', 'stopPx', 'stopPrice'])
|
2837
|
+
if triggerPrice is not None:
|
2636
2838
|
if isUSDTSettled:
|
2637
|
-
request['stopPxRp'] = self.price_to_precision(symbol,
|
2839
|
+
request['stopPxRp'] = self.price_to_precision(symbol, triggerPrice)
|
2638
2840
|
else:
|
2639
|
-
request['stopPxEp'] = self.to_ep(
|
2640
|
-
params = self.omit(params, ['stopPx', 'stopPrice'])
|
2841
|
+
request['stopPxEp'] = self.to_ep(triggerPrice, market)
|
2842
|
+
params = self.omit(params, ['triggerPrice', 'stopPx', 'stopPrice'])
|
2641
2843
|
response = None
|
2642
2844
|
if isUSDTSettled:
|
2643
2845
|
posSide = self.safe_string(params, 'posSide')
|
@@ -2648,13 +2850,15 @@ class phemex(Exchange, ImplicitAPI):
|
|
2648
2850
|
response = await self.privatePutOrdersReplace(self.extend(request, params))
|
2649
2851
|
else:
|
2650
2852
|
response = await self.privatePutSpotOrders(self.extend(request, params))
|
2651
|
-
data = self.
|
2853
|
+
data = self.safe_dict(response, 'data', {})
|
2652
2854
|
return self.parse_order(data, market)
|
2653
2855
|
|
2654
2856
|
async def cancel_order(self, id: str, symbol: Str = None, params={}):
|
2655
2857
|
"""
|
2656
2858
|
cancels an open order
|
2657
|
-
|
2859
|
+
|
2860
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#cancel-single-order-by-orderid
|
2861
|
+
|
2658
2862
|
:param str id: order id
|
2659
2863
|
:param str symbol: unified symbol of the market the order was made in
|
2660
2864
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -2665,7 +2869,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2665
2869
|
raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol argument')
|
2666
2870
|
await self.load_markets()
|
2667
2871
|
market = self.market(symbol)
|
2668
|
-
request = {
|
2872
|
+
request: dict = {
|
2669
2873
|
'symbol': market['id'],
|
2670
2874
|
}
|
2671
2875
|
clientOrderId = self.safe_string_2(params, 'clientOrderId', 'clOrdID')
|
@@ -2684,13 +2888,15 @@ class phemex(Exchange, ImplicitAPI):
|
|
2684
2888
|
response = await self.privateDeleteOrdersCancel(self.extend(request, params))
|
2685
2889
|
else:
|
2686
2890
|
response = await self.privateDeleteSpotOrders(self.extend(request, params))
|
2687
|
-
data = self.
|
2891
|
+
data = self.safe_dict(response, 'data', {})
|
2688
2892
|
return self.parse_order(data, market)
|
2689
2893
|
|
2690
2894
|
async def cancel_all_orders(self, symbol: Str = None, params={}):
|
2691
2895
|
"""
|
2692
2896
|
cancel all open orders in a market
|
2693
|
-
|
2897
|
+
|
2898
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#cancelall
|
2899
|
+
|
2694
2900
|
:param str symbol: unified market symbol of the market to cancel orders in
|
2695
2901
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2696
2902
|
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
@@ -2699,23 +2905,58 @@ class phemex(Exchange, ImplicitAPI):
|
|
2699
2905
|
raise ArgumentsRequired(self.id + ' cancelAllOrders() requires a symbol argument')
|
2700
2906
|
await self.load_markets()
|
2701
2907
|
market = self.market(symbol)
|
2702
|
-
|
2908
|
+
trigger = self.safe_value_2(params, 'stop', 'trigger', False)
|
2909
|
+
params = self.omit(params, ['stop', 'trigger'])
|
2910
|
+
request: dict = {
|
2703
2911
|
'symbol': market['id'],
|
2704
2912
|
# 'untriggerred': False, # False to cancel non-conditional orders, True to cancel conditional orders
|
2705
2913
|
# 'text': 'up to 40 characters max',
|
2706
2914
|
}
|
2915
|
+
if trigger:
|
2916
|
+
request['untriggerred'] = trigger
|
2707
2917
|
response = None
|
2708
2918
|
if market['settle'] == 'USDT':
|
2709
2919
|
response = await self.privateDeleteGOrdersAll(self.extend(request, params))
|
2920
|
+
#
|
2921
|
+
# {
|
2922
|
+
# code: '0',
|
2923
|
+
# msg: '',
|
2924
|
+
# data: '1'
|
2925
|
+
# }
|
2926
|
+
#
|
2710
2927
|
elif market['swap']:
|
2711
2928
|
response = await self.privateDeleteOrdersAll(self.extend(request, params))
|
2929
|
+
#
|
2930
|
+
# {
|
2931
|
+
# code: '0',
|
2932
|
+
# msg: '',
|
2933
|
+
# data: '1'
|
2934
|
+
# }
|
2935
|
+
#
|
2712
2936
|
else:
|
2713
2937
|
response = await self.privateDeleteSpotOrdersAll(self.extend(request, params))
|
2714
|
-
|
2938
|
+
#
|
2939
|
+
# {
|
2940
|
+
# code: '0',
|
2941
|
+
# msg: '',
|
2942
|
+
# data: {
|
2943
|
+
# total: '1'
|
2944
|
+
# }
|
2945
|
+
# }
|
2946
|
+
#
|
2947
|
+
return [
|
2948
|
+
self.safe_order({
|
2949
|
+
'info': response,
|
2950
|
+
}),
|
2951
|
+
]
|
2715
2952
|
|
2716
2953
|
async def fetch_order(self, id: str, symbol: Str = None, params={}):
|
2717
2954
|
"""
|
2955
|
+
|
2956
|
+
https://phemex-docs.github.io/#query-orders-by-ids
|
2957
|
+
|
2718
2958
|
fetches information on an order made by the user
|
2959
|
+
:param str id: the order id
|
2719
2960
|
:param str symbol: unified symbol of the market the order was made in
|
2720
2961
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2721
2962
|
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
@@ -2724,9 +2965,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2724
2965
|
raise ArgumentsRequired(self.id + ' fetchOrder() requires a symbol argument')
|
2725
2966
|
await self.load_markets()
|
2726
2967
|
market = self.market(symbol)
|
2727
|
-
|
2728
|
-
raise NotSupported(self.id + 'fetchOrder() is not supported yet for USDT settled swap markets') # https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#query-user-order-by-orderid-or-query-user-order-by-client-order-id
|
2729
|
-
request = {
|
2968
|
+
request: dict = {
|
2730
2969
|
'symbol': market['id'],
|
2731
2970
|
}
|
2732
2971
|
clientOrderId = self.safe_string_2(params, 'clientOrderId', 'clOrdID')
|
@@ -2736,8 +2975,10 @@ class phemex(Exchange, ImplicitAPI):
|
|
2736
2975
|
else:
|
2737
2976
|
request['orderID'] = id
|
2738
2977
|
response = None
|
2739
|
-
if market['
|
2740
|
-
response = await self.
|
2978
|
+
if market['settle'] == 'USDT':
|
2979
|
+
response = await self.privateGetApiDataGFuturesOrdersByOrderId(self.extend(request, params))
|
2980
|
+
elif market['spot']:
|
2981
|
+
response = await self.privateGetApiDataSpotsOrdersByOrderId(self.extend(request, params))
|
2741
2982
|
else:
|
2742
2983
|
response = await self.privateGetExchangeOrder(self.extend(request, params))
|
2743
2984
|
data = self.safe_value(response, 'data', {})
|
@@ -2749,13 +2990,18 @@ class phemex(Exchange, ImplicitAPI):
|
|
2749
2990
|
raise OrderNotFound(self.id + ' fetchOrder() ' + symbol + ' order with clientOrderId ' + clientOrderId + ' not found')
|
2750
2991
|
else:
|
2751
2992
|
raise OrderNotFound(self.id + ' fetchOrder() ' + symbol + ' order with id ' + id + ' not found')
|
2752
|
-
order = self.
|
2993
|
+
order = self.safe_dict(data, 0, {})
|
2994
|
+
elif market['spot']:
|
2995
|
+
rows = self.safe_list(data, 'rows', [])
|
2996
|
+
order = self.safe_dict(rows, 0, {})
|
2753
2997
|
return self.parse_order(order, market)
|
2754
2998
|
|
2755
2999
|
async def fetch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
2756
3000
|
"""
|
2757
3001
|
fetches information on multiple orders made by the user
|
2758
|
-
|
3002
|
+
|
3003
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#queryorder
|
3004
|
+
|
2759
3005
|
:param str symbol: unified market symbol of the market orders were made in
|
2760
3006
|
:param int [since]: the earliest time in ms to fetch orders for
|
2761
3007
|
:param int [limit]: the maximum number of order structures to retrieve
|
@@ -2766,7 +3012,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2766
3012
|
raise ArgumentsRequired(self.id + ' fetchOrders() requires a symbol argument')
|
2767
3013
|
await self.load_markets()
|
2768
3014
|
market = self.market(symbol)
|
2769
|
-
request = {
|
3015
|
+
request: dict = {
|
2770
3016
|
'symbol': market['id'],
|
2771
3017
|
}
|
2772
3018
|
if since is not None:
|
@@ -2780,17 +3026,19 @@ class phemex(Exchange, ImplicitAPI):
|
|
2780
3026
|
elif market['swap']:
|
2781
3027
|
response = await self.privateGetExchangeOrderList(self.extend(request, params))
|
2782
3028
|
else:
|
2783
|
-
response = await self.
|
3029
|
+
response = await self.privateGetApiDataSpotsOrders(self.extend(request, params))
|
2784
3030
|
data = self.safe_value(response, 'data', {})
|
2785
|
-
rows = self.
|
3031
|
+
rows = self.safe_list(data, 'rows', data)
|
2786
3032
|
return self.parse_orders(rows, market, since, limit)
|
2787
3033
|
|
2788
3034
|
async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
2789
3035
|
"""
|
2790
3036
|
fetch all unfilled currently open orders
|
2791
|
-
|
2792
|
-
|
2793
|
-
|
3037
|
+
|
3038
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#queryopenorder
|
3039
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md
|
3040
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Spot-API-en.md#spotListAllOpenOrder
|
3041
|
+
|
2794
3042
|
:param str symbol: unified market symbol
|
2795
3043
|
:param int [since]: the earliest time in ms to fetch open orders for
|
2796
3044
|
:param int [limit]: the maximum number of open order structures to retrieve
|
@@ -2802,7 +3050,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2802
3050
|
raise ArgumentsRequired(self.id + ' fetchOpenOrders() requires a symbol argument')
|
2803
3051
|
await self.load_markets()
|
2804
3052
|
market = self.market(symbol)
|
2805
|
-
request = {
|
3053
|
+
request: dict = {
|
2806
3054
|
'symbol': market['id'],
|
2807
3055
|
}
|
2808
3056
|
response = None
|
@@ -2821,16 +3069,18 @@ class phemex(Exchange, ImplicitAPI):
|
|
2821
3069
|
if isinstance(data, list):
|
2822
3070
|
return self.parse_orders(data, market, since, limit)
|
2823
3071
|
else:
|
2824
|
-
rows = self.
|
3072
|
+
rows = self.safe_list(data, 'rows', [])
|
2825
3073
|
return self.parse_orders(rows, market, since, limit)
|
2826
3074
|
|
2827
3075
|
async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
2828
3076
|
"""
|
2829
3077
|
fetches information on multiple closed orders made by the user
|
2830
|
-
|
2831
|
-
|
2832
|
-
|
2833
|
-
|
3078
|
+
|
3079
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#queryorder
|
3080
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md#queryorder
|
3081
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedgedd-Perpetual-API.md#query-closed-orders-by-symbol
|
3082
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Spot-API-en.md#spotDataOrdersByIds
|
3083
|
+
|
2834
3084
|
:param str symbol: unified market symbol of the market orders were made in
|
2835
3085
|
:param int [since]: the earliest time in ms to fetch orders for
|
2836
3086
|
:param int [limit]: the maximum number of order structures to retrieve
|
@@ -2842,7 +3092,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2842
3092
|
market = None
|
2843
3093
|
if symbol is not None:
|
2844
3094
|
market = self.market(symbol)
|
2845
|
-
request = {
|
3095
|
+
request: dict = {
|
2846
3096
|
}
|
2847
3097
|
if market is not None:
|
2848
3098
|
request['symbol'] = market['id']
|
@@ -2898,15 +3148,17 @@ class phemex(Exchange, ImplicitAPI):
|
|
2898
3148
|
if isinstance(data, list):
|
2899
3149
|
return self.parse_orders(data, market, since, limit)
|
2900
3150
|
else:
|
2901
|
-
rows = self.
|
3151
|
+
rows = self.safe_list(data, 'rows', [])
|
2902
3152
|
return self.parse_orders(rows, market, since, limit)
|
2903
3153
|
|
2904
3154
|
async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
2905
3155
|
"""
|
2906
3156
|
fetch all trades made by the user
|
2907
|
-
|
2908
|
-
|
2909
|
-
|
3157
|
+
|
3158
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md#query-user-trade
|
3159
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#query-user-trade
|
3160
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Spot-API-en.md#spotDataTradesHist
|
3161
|
+
|
2910
3162
|
:param str symbol: unified market symbol
|
2911
3163
|
:param int [since]: the earliest time in ms to fetch trades for
|
2912
3164
|
:param int [limit]: the maximum number of trades structures to retrieve
|
@@ -2917,7 +3169,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
2917
3169
|
market = None
|
2918
3170
|
if symbol is not None:
|
2919
3171
|
market = self.market(symbol)
|
2920
|
-
request = {}
|
3172
|
+
request: dict = {}
|
2921
3173
|
if limit is not None:
|
2922
3174
|
limit = min(200, limit)
|
2923
3175
|
request['limit'] = limit
|
@@ -3050,7 +3302,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
3050
3302
|
data = self.safe_value(data, 'rows', [])
|
3051
3303
|
return self.parse_trades(data, market, since, limit)
|
3052
3304
|
|
3053
|
-
async def fetch_deposit_address(self, code: str, params={}):
|
3305
|
+
async def fetch_deposit_address(self, code: str, params={}) -> DepositAddress:
|
3054
3306
|
"""
|
3055
3307
|
fetch the deposit address for a currency associated with self account
|
3056
3308
|
:param str code: unified currency code
|
@@ -3059,12 +3311,12 @@ class phemex(Exchange, ImplicitAPI):
|
|
3059
3311
|
"""
|
3060
3312
|
await self.load_markets()
|
3061
3313
|
currency = self.currency(code)
|
3062
|
-
request = {
|
3314
|
+
request: dict = {
|
3063
3315
|
'currency': currency['id'],
|
3064
3316
|
}
|
3065
|
-
defaultNetworks = self.
|
3317
|
+
defaultNetworks = self.safe_dict(self.options, 'defaultNetworks')
|
3066
3318
|
defaultNetwork = self.safe_string_upper(defaultNetworks, code)
|
3067
|
-
networks = self.
|
3319
|
+
networks = self.safe_dict(self.options, 'networks', {})
|
3068
3320
|
network = self.safe_string_upper(params, 'network', defaultNetwork)
|
3069
3321
|
network = self.safe_string(networks, network, network)
|
3070
3322
|
if network is None:
|
@@ -3087,11 +3339,11 @@ class phemex(Exchange, ImplicitAPI):
|
|
3087
3339
|
tag = self.safe_string(data, 'tag')
|
3088
3340
|
self.check_address(address)
|
3089
3341
|
return {
|
3342
|
+
'info': response,
|
3090
3343
|
'currency': code,
|
3344
|
+
'network': None,
|
3091
3345
|
'address': address,
|
3092
3346
|
'tag': tag,
|
3093
|
-
'network': None,
|
3094
|
-
'info': response,
|
3095
3347
|
}
|
3096
3348
|
|
3097
3349
|
async def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
|
@@ -3168,8 +3420,8 @@ class phemex(Exchange, ImplicitAPI):
|
|
3168
3420
|
data = self.safe_list(response, 'data', [])
|
3169
3421
|
return self.parse_transactions(data, currency, since, limit)
|
3170
3422
|
|
3171
|
-
def parse_transaction_status(self, status):
|
3172
|
-
statuses = {
|
3423
|
+
def parse_transaction_status(self, status: Str):
|
3424
|
+
statuses: dict = {
|
3173
3425
|
'Success': 'ok',
|
3174
3426
|
'Succeed': 'ok',
|
3175
3427
|
'Rejected': 'failed',
|
@@ -3188,7 +3440,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
3188
3440
|
}
|
3189
3441
|
return self.safe_string(statuses, status, status)
|
3190
3442
|
|
3191
|
-
def parse_transaction(self, transaction, currency: Currency = None) -> Transaction:
|
3443
|
+
def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
|
3192
3444
|
#
|
3193
3445
|
# withdraw
|
3194
3446
|
#
|
@@ -3306,18 +3558,22 @@ class phemex(Exchange, ImplicitAPI):
|
|
3306
3558
|
async def fetch_positions(self, symbols: Strings = None, params={}):
|
3307
3559
|
"""
|
3308
3560
|
fetch all open positions
|
3309
|
-
|
3310
|
-
|
3311
|
-
|
3561
|
+
|
3562
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md#query-trading-account-and-positions
|
3563
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#query-account-positions
|
3564
|
+
https://phemex-docs.github.io/#query-account-positions-with-unrealized-pnl
|
3565
|
+
|
3312
3566
|
:param str[] [symbols]: list of unified market symbols
|
3313
3567
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3314
|
-
:param str [
|
3568
|
+
:param str [params.code]: the currency code to fetch positions for, USD, BTC or USDT, USD is the default
|
3569
|
+
:param str [params.method]: *USDT contracts only* 'privateGetGAccountsAccountPositions' or 'privateGetAccountsPositions' default is 'privateGetGAccountsAccountPositions'
|
3315
3570
|
:returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
|
3316
3571
|
"""
|
3317
3572
|
await self.load_markets()
|
3318
3573
|
symbols = self.market_symbols(symbols)
|
3319
3574
|
subType = None
|
3320
|
-
code = self.
|
3575
|
+
code = self.safe_string_2(params, 'currency', 'code', 'USD')
|
3576
|
+
params = self.omit(params, ['currency', 'code'])
|
3321
3577
|
settle = None
|
3322
3578
|
market = None
|
3323
3579
|
firstSymbol = self.safe_string(symbols, 0)
|
@@ -3326,17 +3582,17 @@ class phemex(Exchange, ImplicitAPI):
|
|
3326
3582
|
settle = market['settle']
|
3327
3583
|
code = market['settle']
|
3328
3584
|
else:
|
3329
|
-
settle, params = self.handle_option_and_params(params, 'fetchPositions', 'settle',
|
3585
|
+
settle, params = self.handle_option_and_params(params, 'fetchPositions', 'settle', code)
|
3330
3586
|
subType, params = self.handle_sub_type_and_params('fetchPositions', market, params)
|
3331
3587
|
isUSDTSettled = settle == 'USDT'
|
3332
3588
|
if isUSDTSettled:
|
3333
3589
|
code = 'USDT'
|
3590
|
+
elif settle == 'BTC':
|
3591
|
+
code = 'BTC'
|
3334
3592
|
elif code is None:
|
3335
3593
|
code = 'USD' if (subType == 'linear') else 'BTC'
|
3336
|
-
else:
|
3337
|
-
params = self.omit(params, 'code')
|
3338
3594
|
currency = self.currency(code)
|
3339
|
-
request = {
|
3595
|
+
request: dict = {
|
3340
3596
|
'currency': currency['id'],
|
3341
3597
|
}
|
3342
3598
|
response = None
|
@@ -3433,7 +3689,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
3433
3689
|
result.append(self.parse_position(position))
|
3434
3690
|
return self.filter_by_array_positions(result, 'symbol', symbols, False)
|
3435
3691
|
|
3436
|
-
def parse_position(self, position, market: Market = None):
|
3692
|
+
def parse_position(self, position: dict, market: Market = None):
|
3437
3693
|
#
|
3438
3694
|
# {
|
3439
3695
|
# "userID": "811370",
|
@@ -3574,7 +3830,9 @@ class phemex(Exchange, ImplicitAPI):
|
|
3574
3830
|
async def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
3575
3831
|
"""
|
3576
3832
|
fetch the history of funding payments paid and received on self account
|
3577
|
-
|
3833
|
+
|
3834
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#futureDataFundingFeesHist
|
3835
|
+
|
3578
3836
|
:param str symbol: unified market symbol
|
3579
3837
|
:param int [since]: the earliest time in ms to fetch funding history for
|
3580
3838
|
:param int [limit]: the maximum number of funding history structures to retrieve
|
@@ -3585,7 +3843,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
3585
3843
|
raise ArgumentsRequired(self.id + ' fetchFundingHistory() requires a symbol argument')
|
3586
3844
|
await self.load_markets()
|
3587
3845
|
market = self.market(symbol)
|
3588
|
-
request = {
|
3846
|
+
request: dict = {
|
3589
3847
|
'symbol': market['id'],
|
3590
3848
|
# 'limit': 20, # Page size default 20, max 200
|
3591
3849
|
# 'offset': 0, # Page start default 0
|
@@ -3595,7 +3853,8 @@ class phemex(Exchange, ImplicitAPI):
|
|
3595
3853
|
raise BadRequest(self.id + ' fetchFundingHistory() limit argument cannot exceed 200')
|
3596
3854
|
request['limit'] = limit
|
3597
3855
|
response = None
|
3598
|
-
|
3856
|
+
isUsdt = market['settle'] == 'USDT'
|
3857
|
+
if isUsdt:
|
3599
3858
|
response = await self.privateGetApiDataGFuturesFundingFees(self.extend(request, params))
|
3600
3859
|
else:
|
3601
3860
|
response = await self.privateGetApiDataFuturesFundingFees(self.extend(request, params))
|
@@ -3608,13 +3867,13 @@ class phemex(Exchange, ImplicitAPI):
|
|
3608
3867
|
# {
|
3609
3868
|
# "symbol": "BTCUSD",
|
3610
3869
|
# "currency": "BTC",
|
3611
|
-
# "execQty": 18,
|
3870
|
+
# "execQty": 18, # "execQty" regular, but "execQtyRq" in hedge
|
3612
3871
|
# "side": "Buy",
|
3613
|
-
# "execPriceEp": 360086455,
|
3614
|
-
# "execValueEv": 49987,
|
3615
|
-
# "fundingRateEr": 10000,
|
3616
|
-
# "feeRateEr": 10000,
|
3617
|
-
# "execFeeEv": 5,
|
3872
|
+
# "execPriceEp": 360086455, # "execPriceEp" regular, but "execPriceRp" in hedge
|
3873
|
+
# "execValueEv": 49987, # "execValueEv" regular, but "execValueRv" in hedge
|
3874
|
+
# "fundingRateEr": 10000, # "fundingRateEr" regular, but "fundingRateRr" in hedge
|
3875
|
+
# "feeRateEr": 10000, # "feeRateEr" regular, but "feeRateRr" in hedge
|
3876
|
+
# "execFeeEv": 5, # "execFeeEv" regular, but "execFeeRv" in hedge
|
3618
3877
|
# "createTime": 1651881600000
|
3619
3878
|
# }
|
3620
3879
|
# ]
|
@@ -3627,18 +3886,32 @@ class phemex(Exchange, ImplicitAPI):
|
|
3627
3886
|
for i in range(0, len(rows)):
|
3628
3887
|
entry = rows[i]
|
3629
3888
|
timestamp = self.safe_integer(entry, 'createTime')
|
3889
|
+
execFee = self.safe_string_2(entry, 'execFeeEv', 'execFeeRv')
|
3890
|
+
currencyCode = self.safe_currency_code(self.safe_string(entry, 'currency'))
|
3630
3891
|
result.append({
|
3631
3892
|
'info': entry,
|
3632
3893
|
'symbol': self.safe_string(entry, 'symbol'),
|
3633
|
-
'code':
|
3894
|
+
'code': currencyCode,
|
3634
3895
|
'timestamp': timestamp,
|
3635
3896
|
'datetime': self.iso8601(timestamp),
|
3636
3897
|
'id': None,
|
3637
|
-
'amount': self.
|
3898
|
+
'amount': self.parse_funding_fee_to_precision(execFee, market, currencyCode),
|
3638
3899
|
})
|
3639
3900
|
return result
|
3640
3901
|
|
3641
|
-
|
3902
|
+
def parse_funding_fee_to_precision(self, value, market: Market = None, currencyCode: Str = None):
|
3903
|
+
if value is None or currencyCode is None:
|
3904
|
+
return value
|
3905
|
+
# it was confirmed by phemex support, that USDT contracts use direct amounts in funding fees, while USD & INVERSE needs 'valueScale'
|
3906
|
+
isUsdt = market['settle'] == 'USDT'
|
3907
|
+
if not isUsdt:
|
3908
|
+
currency = self.safe_currency(currencyCode)
|
3909
|
+
scale = self.safe_string(currency['info'], 'valueScale')
|
3910
|
+
tickPrecision = self.parse_precision(scale)
|
3911
|
+
value = Precise.string_mul(value, tickPrecision)
|
3912
|
+
return value
|
3913
|
+
|
3914
|
+
async def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
|
3642
3915
|
"""
|
3643
3916
|
fetch the current funding rate
|
3644
3917
|
:param str symbol: unified market symbol
|
@@ -3649,10 +3922,10 @@ class phemex(Exchange, ImplicitAPI):
|
|
3649
3922
|
market = self.market(symbol)
|
3650
3923
|
if not market['swap']:
|
3651
3924
|
raise BadSymbol(self.id + ' fetchFundingRate() supports swap contracts only')
|
3652
|
-
request = {
|
3925
|
+
request: dict = {
|
3653
3926
|
'symbol': market['id'],
|
3654
3927
|
}
|
3655
|
-
response = {}
|
3928
|
+
response: dict = {}
|
3656
3929
|
if not market['linear']:
|
3657
3930
|
response = await self.v1GetMdTicker24hr(self.extend(request, params))
|
3658
3931
|
else:
|
@@ -3683,7 +3956,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
3683
3956
|
result = self.safe_value(response, 'result', {})
|
3684
3957
|
return self.parse_funding_rate(result, market)
|
3685
3958
|
|
3686
|
-
def parse_funding_rate(self, contract, market: Market = None):
|
3959
|
+
def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
|
3687
3960
|
#
|
3688
3961
|
# {
|
3689
3962
|
# "askEp": 2332500,
|
@@ -3724,30 +3997,37 @@ class phemex(Exchange, ImplicitAPI):
|
|
3724
3997
|
marketId = self.safe_string(contract, 'symbol')
|
3725
3998
|
symbol = self.safe_symbol(marketId, market)
|
3726
3999
|
timestamp = self.safe_integer_product(contract, 'timestamp', 0.000001)
|
4000
|
+
markEp = self.from_ep(self.safe_string(contract, 'markEp'), market)
|
4001
|
+
indexEp = self.from_ep(self.safe_string(contract, 'indexEp'), market)
|
4002
|
+
fundingRateEr = self.from_er(self.safe_string(contract, 'fundingRateEr'), market)
|
4003
|
+
nextFundingRateEr = self.from_er(self.safe_string(contract, 'predFundingRateEr'), market)
|
3727
4004
|
return {
|
3728
4005
|
'info': contract,
|
3729
4006
|
'symbol': symbol,
|
3730
|
-
'markPrice': self.
|
3731
|
-
'indexPrice': self.
|
4007
|
+
'markPrice': self.safe_number(contract, 'markPriceRp', markEp),
|
4008
|
+
'indexPrice': self.safe_number(contract, 'indexPriceRp', indexEp),
|
3732
4009
|
'interestRate': None,
|
3733
4010
|
'estimatedSettlePrice': None,
|
3734
4011
|
'timestamp': timestamp,
|
3735
4012
|
'datetime': self.iso8601(timestamp),
|
3736
|
-
'fundingRate': self.
|
4013
|
+
'fundingRate': self.safe_number(contract, 'fundingRateRr', fundingRateEr),
|
3737
4014
|
'fundingTimestamp': None,
|
3738
4015
|
'fundingDatetime': None,
|
3739
|
-
'nextFundingRate': self.
|
4016
|
+
'nextFundingRate': self.safe_number(contract, 'predFundingRateRr', nextFundingRateEr),
|
3740
4017
|
'nextFundingTimestamp': None,
|
3741
4018
|
'nextFundingDatetime': None,
|
3742
4019
|
'previousFundingRate': None,
|
3743
4020
|
'previousFundingTimestamp': None,
|
3744
4021
|
'previousFundingDatetime': None,
|
4022
|
+
'interval': None,
|
3745
4023
|
}
|
3746
4024
|
|
3747
|
-
async def set_margin(self, symbol: str, amount: float, params={}):
|
4025
|
+
async def set_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
|
3748
4026
|
"""
|
3749
4027
|
Either adds or reduces margin in an isolated position in order to set the margin to a specific value
|
3750
|
-
|
4028
|
+
|
4029
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Contract-API-en.md#assign-position-balance-in-isolated-marign-mode
|
4030
|
+
|
3751
4031
|
:param str symbol: unified market symbol of the market to set margin in
|
3752
4032
|
:param float amount: the amount to set the margin to
|
3753
4033
|
:param dict [params]: parameters specific to the exchange API endpoint
|
@@ -3755,7 +4035,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
3755
4035
|
"""
|
3756
4036
|
await self.load_markets()
|
3757
4037
|
market = self.market(symbol)
|
3758
|
-
request = {
|
4038
|
+
request: dict = {
|
3759
4039
|
'symbol': market['id'],
|
3760
4040
|
'posBalanceEv': self.to_ev(amount, market),
|
3761
4041
|
}
|
@@ -3772,12 +4052,12 @@ class phemex(Exchange, ImplicitAPI):
|
|
3772
4052
|
})
|
3773
4053
|
|
3774
4054
|
def parse_margin_status(self, status):
|
3775
|
-
statuses = {
|
4055
|
+
statuses: dict = {
|
3776
4056
|
'0': 'ok',
|
3777
4057
|
}
|
3778
4058
|
return self.safe_string(statuses, status, status)
|
3779
4059
|
|
3780
|
-
def parse_margin_modification(self, data, market: Market = None):
|
4060
|
+
def parse_margin_modification(self, data: dict, market: Market = None) -> MarginModification:
|
3781
4061
|
#
|
3782
4062
|
# {
|
3783
4063
|
# "code": 0,
|
@@ -3790,17 +4070,23 @@ class phemex(Exchange, ImplicitAPI):
|
|
3790
4070
|
codeCurrency = 'base' if inverse else 'quote'
|
3791
4071
|
return {
|
3792
4072
|
'info': data,
|
4073
|
+
'symbol': self.safe_symbol(None, market),
|
3793
4074
|
'type': 'set',
|
4075
|
+
'marginMode': 'isolated',
|
3794
4076
|
'amount': None,
|
3795
4077
|
'total': None,
|
3796
4078
|
'code': market[codeCurrency],
|
3797
|
-
'symbol': self.safe_symbol(None, market),
|
3798
4079
|
'status': self.parse_margin_status(self.safe_string(data, 'code')),
|
4080
|
+
'timestamp': None,
|
4081
|
+
'datetime': None,
|
3799
4082
|
}
|
3800
4083
|
|
3801
4084
|
async def set_margin_mode(self, marginMode: str, symbol: Str = None, params={}):
|
3802
4085
|
"""
|
3803
4086
|
set margin mode to 'cross' or 'isolated'
|
4087
|
+
|
4088
|
+
https://phemex-docs.github.io/#set-leverage
|
4089
|
+
|
3804
4090
|
:param str marginMode: 'cross' or 'isolated'
|
3805
4091
|
:param str symbol: unified market symbol
|
3806
4092
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -3820,7 +4106,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
3820
4106
|
leverage = 0
|
3821
4107
|
if leverage is None:
|
3822
4108
|
raise ArgumentsRequired(self.id + ' setMarginMode() requires a leverage parameter')
|
3823
|
-
request = {
|
4109
|
+
request: dict = {
|
3824
4110
|
'symbol': market['id'],
|
3825
4111
|
'leverage': leverage,
|
3826
4112
|
}
|
@@ -3829,7 +4115,9 @@ class phemex(Exchange, ImplicitAPI):
|
|
3829
4115
|
async def set_position_mode(self, hedged: bool, symbol: Str = None, params={}):
|
3830
4116
|
"""
|
3831
4117
|
set hedged to True or False for a market
|
3832
|
-
|
4118
|
+
|
4119
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#switch-position-mode-synchronously
|
4120
|
+
|
3833
4121
|
:param bool hedged: set to True to use dualSidePosition
|
3834
4122
|
:param str symbol: not used by binance setPositionMode()
|
3835
4123
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -3840,7 +4128,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
3840
4128
|
market = self.market(symbol)
|
3841
4129
|
if market['settle'] != 'USDT':
|
3842
4130
|
raise BadSymbol(self.id + ' setPositionMode() supports USDT settled markets only')
|
3843
|
-
request = {
|
4131
|
+
request: dict = {
|
3844
4132
|
'symbol': market['id'],
|
3845
4133
|
}
|
3846
4134
|
if hedged:
|
@@ -3849,7 +4137,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
3849
4137
|
request['targetPosMode'] = 'OneWay'
|
3850
4138
|
return await self.privatePutGPositionsSwitchPosModeSync(self.extend(request, params))
|
3851
4139
|
|
3852
|
-
async def fetch_leverage_tiers(self, symbols: Strings = None, params={}):
|
4140
|
+
async def fetch_leverage_tiers(self, symbols: Strings = None, params={}) -> LeverageTiers:
|
3853
4141
|
"""
|
3854
4142
|
retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes
|
3855
4143
|
:param str[]|None symbols: list of unified market symbols
|
@@ -3942,10 +4230,10 @@ class phemex(Exchange, ImplicitAPI):
|
|
3942
4230
|
#
|
3943
4231
|
#
|
3944
4232
|
data = self.safe_value(response, 'data', {})
|
3945
|
-
riskLimits = self.
|
4233
|
+
riskLimits = self.safe_list(data, 'riskLimits')
|
3946
4234
|
return self.parse_leverage_tiers(riskLimits, symbols, 'symbol')
|
3947
4235
|
|
3948
|
-
def parse_market_leverage_tiers(self, info, market: Market = None):
|
4236
|
+
def parse_market_leverage_tiers(self, info, market: Market = None) -> List[LeverageTier]:
|
3949
4237
|
"""
|
3950
4238
|
:param dict info: Exchange market response for 1 market
|
3951
4239
|
:param dict market: CCXT market
|
@@ -3961,7 +4249,8 @@ class phemex(Exchange, ImplicitAPI):
|
|
3961
4249
|
# ]
|
3962
4250
|
# },
|
3963
4251
|
#
|
3964
|
-
|
4252
|
+
marketId = self.safe_string(info, 'symbol')
|
4253
|
+
market = self.safe_market(marketId, market)
|
3965
4254
|
riskLimits = (market['info']['riskLimits'])
|
3966
4255
|
tiers = []
|
3967
4256
|
minNotional = 0
|
@@ -3970,6 +4259,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
3970
4259
|
maxNotional = self.safe_integer(tier, 'limit')
|
3971
4260
|
tiers.append({
|
3972
4261
|
'tier': self.sum(i, 1),
|
4262
|
+
'symbol': self.safe_symbol(marketId, market),
|
3973
4263
|
'currency': market['settle'],
|
3974
4264
|
'minNotional': minNotional,
|
3975
4265
|
'maxNotional': maxNotional,
|
@@ -4017,7 +4307,9 @@ class phemex(Exchange, ImplicitAPI):
|
|
4017
4307
|
async def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
|
4018
4308
|
"""
|
4019
4309
|
set the level of leverage for a market
|
4020
|
-
|
4310
|
+
|
4311
|
+
https://github.com/phemex/phemex-api-docs/blob/master/Public-Hedged-Perpetual-API.md#set-leverage
|
4312
|
+
|
4021
4313
|
:param float leverage: the rate of leverage, 100 > leverage > -100 excluding numbers between -1 to 1
|
4022
4314
|
:param str symbol: unified market symbol
|
4023
4315
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -4037,7 +4329,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
4037
4329
|
longLeverageRr = self.safe_integer(params, 'longLeverageRr')
|
4038
4330
|
shortLeverageRr = self.safe_integer(params, 'shortLeverageRr')
|
4039
4331
|
market = self.market(symbol)
|
4040
|
-
request = {
|
4332
|
+
request: dict = {
|
4041
4333
|
'symbol': market['id'],
|
4042
4334
|
}
|
4043
4335
|
response = None
|
@@ -4058,6 +4350,10 @@ class phemex(Exchange, ImplicitAPI):
|
|
4058
4350
|
async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
|
4059
4351
|
"""
|
4060
4352
|
transfer currency internally between wallets on the same account
|
4353
|
+
|
4354
|
+
https://phemex-docs.github.io/#transfer-between-spot-and-futures
|
4355
|
+
https://phemex-docs.github.io/#universal-transfer-main-account-only-transfer-between-sub-to-main-main-to-sub-or-sub-to-sub
|
4356
|
+
|
4061
4357
|
:param str code: unified currency code
|
4062
4358
|
:param float amount: amount to transfer
|
4063
4359
|
:param str fromAccount: account to transfer from
|
@@ -4079,7 +4375,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
4079
4375
|
elif fromId == 'future' and toId == 'spot':
|
4080
4376
|
direction = 1
|
4081
4377
|
if direction is not None:
|
4082
|
-
request = {
|
4378
|
+
request: dict = {
|
4083
4379
|
'currency': currency['id'],
|
4084
4380
|
'moveOp': direction,
|
4085
4381
|
'amountEv': scaledAmmount,
|
@@ -4102,7 +4398,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
4102
4398
|
data = self.safe_value(response, 'data', {})
|
4103
4399
|
transfer = self.parse_transfer(data, currency)
|
4104
4400
|
else: # sub account transfer
|
4105
|
-
request = {
|
4401
|
+
request: dict = {
|
4106
4402
|
'fromUserId': fromId,
|
4107
4403
|
'toUserId': toId,
|
4108
4404
|
'amountEv': scaledAmmount,
|
@@ -4131,9 +4427,12 @@ class phemex(Exchange, ImplicitAPI):
|
|
4131
4427
|
transfer['currency'] = code
|
4132
4428
|
return transfer
|
4133
4429
|
|
4134
|
-
async def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
|
4430
|
+
async def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[TransferEntry]:
|
4135
4431
|
"""
|
4136
4432
|
fetch a history of internal transfers made on an account
|
4433
|
+
|
4434
|
+
https://phemex-docs.github.io/#query-transfer-history
|
4435
|
+
|
4137
4436
|
:param str code: unified currency code of the currency transferred
|
4138
4437
|
:param int [since]: the earliest time in ms to fetch transfers for
|
4139
4438
|
:param int [limit]: the maximum number of transfers structures to retrieve
|
@@ -4144,7 +4443,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
4144
4443
|
if code is None:
|
4145
4444
|
raise ArgumentsRequired(self.id + ' fetchTransfers() requires a code argument')
|
4146
4445
|
currency = self.currency(code)
|
4147
|
-
request = {
|
4446
|
+
request: dict = {
|
4148
4447
|
'currency': currency['id'],
|
4149
4448
|
}
|
4150
4449
|
if since is not None:
|
@@ -4173,10 +4472,10 @@ class phemex(Exchange, ImplicitAPI):
|
|
4173
4472
|
# }
|
4174
4473
|
#
|
4175
4474
|
data = self.safe_value(response, 'data', {})
|
4176
|
-
transfers = self.
|
4475
|
+
transfers = self.safe_list(data, 'rows', [])
|
4177
4476
|
return self.parse_transfers(transfers, currency, since, limit)
|
4178
4477
|
|
4179
|
-
def parse_transfer(self, transfer, currency: Currency = None):
|
4478
|
+
def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
|
4180
4479
|
#
|
4181
4480
|
# transfer
|
4182
4481
|
#
|
@@ -4230,8 +4529,8 @@ class phemex(Exchange, ImplicitAPI):
|
|
4230
4529
|
'status': self.parse_transfer_status(status),
|
4231
4530
|
}
|
4232
4531
|
|
4233
|
-
def parse_transfer_status(self, status):
|
4234
|
-
statuses = {
|
4532
|
+
def parse_transfer_status(self, status: Str) -> Str:
|
4533
|
+
statuses: dict = {
|
4235
4534
|
'3': 'rejected', # 'Rejected',
|
4236
4535
|
'6': 'canceled', # 'Got error and wait for recovery',
|
4237
4536
|
'10': 'ok', # 'Success',
|
@@ -4242,7 +4541,9 @@ class phemex(Exchange, ImplicitAPI):
|
|
4242
4541
|
async def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
4243
4542
|
"""
|
4244
4543
|
fetches historical funding rate prices
|
4245
|
-
|
4544
|
+
|
4545
|
+
https://phemex-docs.github.io/#query-funding-rate-history-2
|
4546
|
+
|
4246
4547
|
:param str symbol: unified symbol of the market to fetch the funding rate history for
|
4247
4548
|
:param int [since]: timestamp in ms of the earliest funding rate to fetch
|
4248
4549
|
:param int [limit]: the maximum amount of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>` to fetch
|
@@ -4267,7 +4568,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
4267
4568
|
customSymbol = '.' + market['id'] + 'FR8H' # phemex requires a custom symbol for funding rate history
|
4268
4569
|
else:
|
4269
4570
|
customSymbol = '.' + market['baseId'] + 'FR8H'
|
4270
|
-
request = {
|
4571
|
+
request: dict = {
|
4271
4572
|
'symbol': customSymbol,
|
4272
4573
|
}
|
4273
4574
|
if since is not None:
|
@@ -4312,10 +4613,12 @@ class phemex(Exchange, ImplicitAPI):
|
|
4312
4613
|
sorted = self.sort_by(result, 'timestamp')
|
4313
4614
|
return self.filter_by_symbol_since_limit(sorted, symbol, since, limit)
|
4314
4615
|
|
4315
|
-
async def withdraw(self, code: str, amount: float, address, tag=None, params={}):
|
4616
|
+
async def withdraw(self, code: str, amount: float, address: str, tag=None, params={}) -> Transaction:
|
4316
4617
|
"""
|
4317
4618
|
make a withdrawal
|
4318
|
-
|
4619
|
+
|
4620
|
+
https://phemex-docs.github.io/#create-withdraw-request
|
4621
|
+
|
4319
4622
|
:param str code: unified currency code
|
4320
4623
|
:param float amount: the amount to withdraw
|
4321
4624
|
:param str address: the address to withdraw to
|
@@ -4339,7 +4642,7 @@ class phemex(Exchange, ImplicitAPI):
|
|
4339
4642
|
networkId = currency['id']
|
4340
4643
|
else:
|
4341
4644
|
raise ArgumentsRequired(self.id + ' withdraw() requires an extra argument params["network"]')
|
4342
|
-
request = {
|
4645
|
+
request: dict = {
|
4343
4646
|
'currency': currency['id'],
|
4344
4647
|
'address': address,
|
4345
4648
|
'amount': amount,
|
@@ -4375,10 +4678,83 @@ class phemex(Exchange, ImplicitAPI):
|
|
4375
4678
|
# }
|
4376
4679
|
# }
|
4377
4680
|
#
|
4378
|
-
data = self.
|
4681
|
+
data = self.safe_dict(response, 'data', {})
|
4379
4682
|
return self.parse_transaction(data, currency)
|
4380
4683
|
|
4381
|
-
def
|
4684
|
+
async def fetch_open_interest(self, symbol: str, params={}):
|
4685
|
+
"""
|
4686
|
+
retrieves the open interest of a trading pair
|
4687
|
+
|
4688
|
+
https://phemex-docs.github.io/#query-24-hours-ticker
|
4689
|
+
|
4690
|
+
:param str symbol: unified CCXT market symbol
|
4691
|
+
:param dict [params]: exchange specific parameters
|
4692
|
+
:returns dict} an open interest structure{@link https://docs.ccxt.com/#/?id=open-interest-structure:
|
4693
|
+
"""
|
4694
|
+
await self.load_markets()
|
4695
|
+
market = self.market(symbol)
|
4696
|
+
if not market['contract']:
|
4697
|
+
raise BadRequest(self.id + ' fetchOpenInterest is only supported for contract markets.')
|
4698
|
+
request: dict = {
|
4699
|
+
'symbol': market['id'],
|
4700
|
+
}
|
4701
|
+
response = await self.v2GetMdV2Ticker24hr(self.extend(request, params))
|
4702
|
+
#
|
4703
|
+
# {
|
4704
|
+
# error: null,
|
4705
|
+
# id: '0',
|
4706
|
+
# result: {
|
4707
|
+
# closeRp: '67550.1',
|
4708
|
+
# fundingRateRr: '0.0001',
|
4709
|
+
# highRp: '68400',
|
4710
|
+
# indexPriceRp: '67567.15389794',
|
4711
|
+
# lowRp: '66096.4',
|
4712
|
+
# markPriceRp: '67550.1',
|
4713
|
+
# openInterestRv: '1848.1144186',
|
4714
|
+
# openRp: '66330',
|
4715
|
+
# predFundingRateRr: '0.0001',
|
4716
|
+
# symbol: 'BTCUSDT',
|
4717
|
+
# timestamp: '1729114315443343001',
|
4718
|
+
# turnoverRv: '228863389.3237532',
|
4719
|
+
# volumeRq: '3388.5600312'
|
4720
|
+
# }
|
4721
|
+
# }
|
4722
|
+
#
|
4723
|
+
result = self.safe_dict(response, 'result')
|
4724
|
+
return self.parse_open_interest(result, market)
|
4725
|
+
|
4726
|
+
def parse_open_interest(self, interest, market: Market = None):
|
4727
|
+
#
|
4728
|
+
# {
|
4729
|
+
# closeRp: '67550.1',
|
4730
|
+
# fundingRateRr: '0.0001',
|
4731
|
+
# highRp: '68400',
|
4732
|
+
# indexPriceRp: '67567.15389794',
|
4733
|
+
# lowRp: '66096.4',
|
4734
|
+
# markPriceRp: '67550.1',
|
4735
|
+
# openInterestRv: '1848.1144186',
|
4736
|
+
# openRp: '66330',
|
4737
|
+
# predFundingRateRr: '0.0001',
|
4738
|
+
# symbol: 'BTCUSDT',
|
4739
|
+
# timestamp: '1729114315443343001',
|
4740
|
+
# turnoverRv: '228863389.3237532',
|
4741
|
+
# volumeRq: '3388.5600312'
|
4742
|
+
# }
|
4743
|
+
#
|
4744
|
+
timestamp = self.safe_integer(interest, 'timestamp') / 1000000
|
4745
|
+
id = self.safe_string(interest, 'symbol')
|
4746
|
+
return self.safe_open_interest({
|
4747
|
+
'info': interest,
|
4748
|
+
'symbol': self.safe_symbol(id, market),
|
4749
|
+
'baseVolume': self.safe_string(interest, 'volumeRq'),
|
4750
|
+
'quoteVolume': None, # deprecated
|
4751
|
+
'openInterestAmount': self.safe_string(interest, 'openInterestRv'),
|
4752
|
+
'openInterestValue': None,
|
4753
|
+
'timestamp': timestamp,
|
4754
|
+
'datetime': self.iso8601(timestamp),
|
4755
|
+
}, market)
|
4756
|
+
|
4757
|
+
def handle_errors(self, httpCode: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
|
4382
4758
|
if response is None:
|
4383
4759
|
return None # fallback to default error handler
|
4384
4760
|
#
|