ccxt 4.2.77__py2.py3-none-any.whl → 4.4.49__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 +24 -0
- ccxt/abstract/kucoinfutures.py +34 -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 +3030 -1087
- 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 +3205 -937
- 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 +238 -49
- ccxt/async_support/bitget.py +1525 -573
- ccxt/async_support/bithumb.py +199 -65
- 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 +392 -148
- 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 +2231 -1193
- ccxt/async_support/cex.py +1409 -1329
- ccxt/async_support/coinbase.py +1454 -287
- 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 +223 -97
- 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 +404 -109
- ccxt/async_support/deribit.py +639 -323
- ccxt/async_support/digifinex.py +465 -233
- ccxt/async_support/ellipx.py +1887 -0
- ccxt/async_support/exmo.py +317 -128
- ccxt/async_support/gate.py +1472 -463
- ccxt/async_support/gemini.py +206 -84
- ccxt/async_support/hashkey.py +4164 -0
- ccxt/async_support/hitbtc.py +433 -178
- ccxt/async_support/hollaex.py +207 -83
- ccxt/async_support/htx.py +1095 -563
- ccxt/async_support/huobijp.py +178 -56
- ccxt/async_support/hyperliquid.py +1678 -292
- ccxt/async_support/idex.py +219 -95
- ccxt/async_support/independentreserve.py +300 -31
- ccxt/async_support/indodax.py +226 -62
- ccxt/async_support/kraken.py +871 -354
- ccxt/async_support/krakenfutures.py +324 -100
- ccxt/async_support/kucoin.py +917 -357
- ccxt/async_support/kucoinfutures.py +1004 -149
- ccxt/async_support/kuna.py +198 -107
- ccxt/async_support/latoken.py +199 -79
- ccxt/async_support/lbank.py +360 -113
- ccxt/async_support/luno.py +185 -62
- ccxt/async_support/lykke.py +168 -55
- ccxt/async_support/mercado.py +101 -29
- ccxt/async_support/mexc.py +995 -429
- ccxt/async_support/myokx.py +53 -0
- ccxt/async_support/ndax.py +234 -82
- ccxt/async_support/novadax.py +195 -75
- ccxt/async_support/oceanex.py +244 -59
- ccxt/async_support/okcoin.py +301 -165
- ccxt/async_support/okx.py +1776 -454
- ccxt/async_support/onetrading.py +198 -414
- ccxt/async_support/oxfun.py +2898 -0
- ccxt/async_support/p2b.py +142 -52
- ccxt/async_support/paradex.py +2085 -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 +1137 -296
- 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 +1722 -480
- 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 +3030 -1087
- ccxt/binancecoinm.py +2 -1
- ccxt/binanceus.py +12 -1
- ccxt/binanceusdm.py +3 -1
- ccxt/bingx.py +3205 -937
- 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 +238 -49
- ccxt/bitget.py +1525 -573
- ccxt/bithumb.py +198 -65
- 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 +392 -148
- ccxt/btcalpha.py +161 -55
- ccxt/btcbox.py +250 -34
- ccxt/btcmarkets.py +232 -85
- ccxt/btcturk.py +159 -60
- ccxt/bybit.py +2231 -1193
- ccxt/cex.py +1408 -1329
- ccxt/coinbase.py +1454 -287
- 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 +223 -97
- ccxt/coinspot.py +137 -62
- ccxt/cryptocom.py +515 -185
- ccxt/currencycom.py +203 -85
- ccxt/defx.py +2065 -0
- ccxt/delta.py +404 -109
- ccxt/deribit.py +639 -323
- ccxt/digifinex.py +465 -233
- ccxt/ellipx.py +1887 -0
- ccxt/exmo.py +317 -128
- ccxt/gate.py +1472 -463
- ccxt/gemini.py +206 -84
- ccxt/hashkey.py +4164 -0
- ccxt/hitbtc.py +433 -178
- ccxt/hollaex.py +207 -83
- ccxt/htx.py +1095 -563
- ccxt/huobijp.py +178 -56
- ccxt/hyperliquid.py +1677 -292
- ccxt/idex.py +219 -95
- ccxt/independentreserve.py +299 -31
- ccxt/indodax.py +226 -62
- ccxt/kraken.py +871 -354
- ccxt/krakenfutures.py +324 -100
- ccxt/kucoin.py +917 -357
- ccxt/kucoinfutures.py +1004 -149
- ccxt/kuna.py +198 -107
- ccxt/latoken.py +199 -79
- ccxt/lbank.py +360 -113
- ccxt/luno.py +185 -62
- ccxt/lykke.py +168 -55
- ccxt/mercado.py +101 -29
- ccxt/mexc.py +994 -429
- ccxt/myokx.py +53 -0
- ccxt/ndax.py +234 -82
- ccxt/novadax.py +195 -75
- ccxt/oceanex.py +244 -59
- ccxt/okcoin.py +301 -165
- ccxt/okx.py +1776 -454
- ccxt/onetrading.py +198 -414
- ccxt/oxfun.py +2897 -0
- ccxt/p2b.py +142 -52
- ccxt/paradex.py +2085 -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 +62 -14
- 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 +143 -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 +203 -81
- 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 +965 -665
- 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 +167 -31
- ccxt/pro/exmo.py +252 -20
- 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 +92 -33
- ccxt/pro/poloniex.py +128 -49
- ccxt/pro/poloniexfutures.py +53 -32
- ccxt/pro/probit.py +92 -85
- 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 +437 -65
- 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} +456 -391
- ccxt/test/tests_helpers.py +285 -0
- ccxt/test/tests_init.py +39 -0
- ccxt/test/{test_sync.py → tests_sync.py} +456 -393
- 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 +1137 -296
- 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.49.dist-info/LICENSE.txt +21 -0
- ccxt-4.4.49.dist-info/METADATA +646 -0
- ccxt-4.4.49.dist-info/RECORD +669 -0
- {ccxt-4.2.77.dist-info → ccxt-4.4.49.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.77.dist-info/METADATA +0 -626
- ccxt-4.2.77.dist-info/RECORD +0 -534
- {ccxt-4.2.77.dist-info → ccxt-4.4.49.dist-info}/top_level.txt +0 -0
ccxt/bitmart.py
CHANGED
@@ -6,9 +6,10 @@
|
|
6
6
|
from ccxt.base.exchange import Exchange
|
7
7
|
from ccxt.abstract.bitmart import ImplicitAPI
|
8
8
|
import hashlib
|
9
|
-
from ccxt.base.types import Balances, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, Transaction, TransferEntry
|
9
|
+
from ccxt.base.types import Balances, BorrowInterest, Currencies, Currency, DepositAddress, FundingHistory, Int, IsolatedBorrowRate, IsolatedBorrowRates, LedgerEntry, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Str, Strings, Ticker, Tickers, FundingRate, Trade, TradingFeeInterface, Transaction, TransferEntry
|
10
10
|
from typing import List
|
11
11
|
from ccxt.base.errors import ExchangeError
|
12
|
+
from ccxt.base.errors import AuthenticationError
|
12
13
|
from ccxt.base.errors import PermissionDenied
|
13
14
|
from ccxt.base.errors import AccountSuspended
|
14
15
|
from ccxt.base.errors import ArgumentsRequired
|
@@ -24,7 +25,6 @@ from ccxt.base.errors import RateLimitExceeded
|
|
24
25
|
from ccxt.base.errors import ExchangeNotAvailable
|
25
26
|
from ccxt.base.errors import OnMaintenance
|
26
27
|
from ccxt.base.errors import InvalidNonce
|
27
|
-
from ccxt.base.errors import AuthenticationError
|
28
28
|
from ccxt.base.decimal_to_precision import TRUNCATE
|
29
29
|
from ccxt.base.decimal_to_precision import TICK_SIZE
|
30
30
|
from ccxt.base.precise import Precise
|
@@ -54,11 +54,12 @@ class bitmart(Exchange, ImplicitAPI):
|
|
54
54
|
'borrowIsolatedMargin': True,
|
55
55
|
'cancelAllOrders': True,
|
56
56
|
'cancelOrder': True,
|
57
|
-
'cancelOrders':
|
57
|
+
'cancelOrders': True,
|
58
58
|
'createMarketBuyOrderWithCost': True,
|
59
59
|
'createMarketOrderWithCost': False,
|
60
60
|
'createMarketSellOrderWithCost': False,
|
61
61
|
'createOrder': True,
|
62
|
+
'createOrders': True,
|
62
63
|
'createPostOnlyOrder': True,
|
63
64
|
'createStopLimitOrder': False,
|
64
65
|
'createStopMarketOrder': False,
|
@@ -80,12 +81,13 @@ class bitmart(Exchange, ImplicitAPI):
|
|
80
81
|
'fetchDeposits': True,
|
81
82
|
'fetchDepositWithdrawFee': True,
|
82
83
|
'fetchDepositWithdrawFees': False,
|
83
|
-
'fetchFundingHistory':
|
84
|
+
'fetchFundingHistory': True,
|
84
85
|
'fetchFundingRate': True,
|
85
86
|
'fetchFundingRateHistory': False,
|
86
87
|
'fetchFundingRates': False,
|
87
88
|
'fetchIsolatedBorrowRate': True,
|
88
89
|
'fetchIsolatedBorrowRates': True,
|
90
|
+
'fetchLedger': True,
|
89
91
|
'fetchLiquidations': False,
|
90
92
|
'fetchMarginMode': False,
|
91
93
|
'fetchMarkets': True,
|
@@ -126,9 +128,10 @@ class bitmart(Exchange, ImplicitAPI):
|
|
126
128
|
},
|
127
129
|
'hostname': 'bitmart.com', # bitmart.info, bitmart.news for Hong Kong users
|
128
130
|
'urls': {
|
129
|
-
'logo': 'https://
|
131
|
+
'logo': 'https://github.com/user-attachments/assets/0623e9c4-f50e-48c9-82bd-65c3908c3a14',
|
130
132
|
'api': {
|
131
|
-
'
|
133
|
+
'spot': 'https://api-cloud.{hostname}',
|
134
|
+
'swap': 'https://api-cloud-v2.{hostname}', # bitmart.info for Hong Kong users
|
132
135
|
},
|
133
136
|
'www': 'https://www.bitmart.com/',
|
134
137
|
'doc': 'https://developer-pro.bitmart.com/',
|
@@ -171,6 +174,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
171
174
|
'contract/public/depth': 5,
|
172
175
|
'contract/public/open-interest': 30,
|
173
176
|
'contract/public/funding-rate': 30,
|
177
|
+
'contract/public/funding-rate-history': 30,
|
174
178
|
'contract/public/kline': 6, # should be 5 but errors
|
175
179
|
'account/v1/currencies': 30,
|
176
180
|
},
|
@@ -198,7 +202,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
198
202
|
'spot/v2/orders': 5,
|
199
203
|
'spot/v1/trades': 5,
|
200
204
|
# newer order endpoint
|
201
|
-
'spot/v2/trades':
|
205
|
+
'spot/v2/trades': 4,
|
202
206
|
'spot/v3/orders': 5,
|
203
207
|
'spot/v2/order_detail': 1,
|
204
208
|
# margin
|
@@ -218,6 +222,10 @@ class bitmart(Exchange, ImplicitAPI):
|
|
218
222
|
'contract/private/get-open-orders': 1.2,
|
219
223
|
'contract/private/current-plan-order': 1.2,
|
220
224
|
'contract/private/trades': 10,
|
225
|
+
'contract/private/position-risk': 10,
|
226
|
+
'contract/private/affilate/rebate-list': 10,
|
227
|
+
'contract/private/affilate/trade-list': 10,
|
228
|
+
'contract/private/transaction-history': 10,
|
221
229
|
},
|
222
230
|
'post': {
|
223
231
|
# sub-account endpoints
|
@@ -242,6 +250,9 @@ class bitmart(Exchange, ImplicitAPI):
|
|
242
250
|
'spot/v4/query/history-orders': 5, # 12 times/2 sec = 6/s => 30/6 = 5
|
243
251
|
'spot/v4/query/trades': 5, # 12 times/2 sec = 6/s => 30/6 = 5
|
244
252
|
'spot/v4/query/order-trades': 5, # 12 times/2 sec = 6/s => 30/6 = 5
|
253
|
+
'spot/v4/cancel_orders': 3,
|
254
|
+
'spot/v4/cancel_all': 90,
|
255
|
+
'spot/v4/batch_orders': 3,
|
245
256
|
# newer endpoint
|
246
257
|
'spot/v3/cancel_order': 1,
|
247
258
|
'spot/v2/batch_orders': 1,
|
@@ -260,6 +271,10 @@ class bitmart(Exchange, ImplicitAPI):
|
|
260
271
|
'contract/private/submit-plan-order': 2.5,
|
261
272
|
'contract/private/cancel-plan-order': 1.5,
|
262
273
|
'contract/private/submit-leverage': 2.5,
|
274
|
+
'contract/private/submit-tp-sl-order': 2.5,
|
275
|
+
'contract/private/modify-plan-order': 2.5,
|
276
|
+
'contract/private/modify-preset-plan-order': 2.5,
|
277
|
+
'contract/private/modify-tp-sl-order': 2.5,
|
263
278
|
},
|
264
279
|
},
|
265
280
|
},
|
@@ -509,8 +524,8 @@ class bitmart(Exchange, ImplicitAPI):
|
|
509
524
|
'40045': InvalidOrder, # 400, The order open type is invalid
|
510
525
|
'40046': PermissionDenied, # 403, The account is not opened futures
|
511
526
|
'40047': PermissionDenied, # 403, Services is not available in you countries and areas
|
512
|
-
'40048':
|
513
|
-
'40049':
|
527
|
+
'40048': InvalidOrder, # 403, ClientOrderId only allows a combination of numbers and letters
|
528
|
+
'40049': InvalidOrder, # 403, The maximum length of clientOrderId cannot exceed 32
|
514
529
|
'40050': InvalidOrder, # 403, Client OrderId duplicated with existing orders
|
515
530
|
},
|
516
531
|
'broad': {},
|
@@ -530,6 +545,8 @@ class bitmart(Exchange, ImplicitAPI):
|
|
530
545
|
'defaultNetworks': {
|
531
546
|
'USDT': 'ERC20',
|
532
547
|
},
|
548
|
+
'timeDifference': 0, # the difference between system clock and exchange clock
|
549
|
+
'adjustForTimeDifference': False, # controls the adjustment logic upon instantiation
|
533
550
|
'networks': {
|
534
551
|
'ERC20': 'ERC20',
|
535
552
|
'SOL': 'SOL',
|
@@ -692,6 +709,148 @@ class bitmart(Exchange, ImplicitAPI):
|
|
692
709
|
'createMarketBuyOrderRequiresPrice': True,
|
693
710
|
'brokerId': 'CCXTxBitmart000',
|
694
711
|
},
|
712
|
+
'features': {
|
713
|
+
'default': {
|
714
|
+
'sandbox': False,
|
715
|
+
'createOrder': {
|
716
|
+
'marginMode': True,
|
717
|
+
'triggerPrice': False,
|
718
|
+
'triggerPriceType': None,
|
719
|
+
'triggerDirection': False,
|
720
|
+
'stopLossPrice': False,
|
721
|
+
'takeProfitPrice': False,
|
722
|
+
'attachedStopLossTakeProfit': None,
|
723
|
+
'timeInForce': {
|
724
|
+
'IOC': True,
|
725
|
+
'FOK': False,
|
726
|
+
'PO': True,
|
727
|
+
'GTD': False,
|
728
|
+
},
|
729
|
+
'hedged': False,
|
730
|
+
'trailing': False,
|
731
|
+
'marketBuyRequiresPrice': False, # todo: https://developer-pro.bitmart.com/en/spot/#new-order-v2-signed
|
732
|
+
'marketBuyByCost': True,
|
733
|
+
'leverage': True, # todo: implement
|
734
|
+
'selfTradePrevention': False,
|
735
|
+
'iceberg': False,
|
736
|
+
},
|
737
|
+
'createOrders': {
|
738
|
+
'max': 10,
|
739
|
+
},
|
740
|
+
'fetchMyTrades': {
|
741
|
+
'marginMode': True,
|
742
|
+
'limit': 200,
|
743
|
+
'daysBack': None,
|
744
|
+
'untilDays': 99999,
|
745
|
+
},
|
746
|
+
'fetchOrder': {
|
747
|
+
'marginMode': False,
|
748
|
+
'trigger': False,
|
749
|
+
'trailing': False,
|
750
|
+
},
|
751
|
+
'fetchOpenOrders': {
|
752
|
+
'marginMode': True,
|
753
|
+
'limit': 200,
|
754
|
+
'trigger': False,
|
755
|
+
'trailing': False,
|
756
|
+
},
|
757
|
+
'fetchOrders': None,
|
758
|
+
'fetchClosedOrders': {
|
759
|
+
'marginMode': True,
|
760
|
+
'limit': 200,
|
761
|
+
'daysBack': None,
|
762
|
+
'daysBackCanceled': None,
|
763
|
+
'untilDays': None,
|
764
|
+
'trigger': False,
|
765
|
+
'trailing': False,
|
766
|
+
},
|
767
|
+
'fetchOHLCV': {
|
768
|
+
'limit': 1000, # variable timespans for recent endpoint, 200 for historical
|
769
|
+
},
|
770
|
+
},
|
771
|
+
'forDerivatives': {
|
772
|
+
'extends': 'default',
|
773
|
+
'createOrder': {
|
774
|
+
'marginMode': True,
|
775
|
+
'triggerPrice': True,
|
776
|
+
'triggerPriceType': {
|
777
|
+
'last': True,
|
778
|
+
'mark': True,
|
779
|
+
'index': False,
|
780
|
+
},
|
781
|
+
'triggerDirection': True, # todo: implementation broken
|
782
|
+
'stopLossPrice': True,
|
783
|
+
'takeProfitPrice': True,
|
784
|
+
'attachedStopLossTakeProfit': {
|
785
|
+
'triggerPriceType': {
|
786
|
+
'last': True,
|
787
|
+
'mark': True,
|
788
|
+
'index': False,
|
789
|
+
},
|
790
|
+
'price': False,
|
791
|
+
},
|
792
|
+
'timeInForce': {
|
793
|
+
'IOC': True,
|
794
|
+
'FOK': True,
|
795
|
+
'PO': True,
|
796
|
+
'GTD': False,
|
797
|
+
},
|
798
|
+
'hedged': False,
|
799
|
+
'trailing': True,
|
800
|
+
'marketBuyRequiresPrice': True,
|
801
|
+
'marketBuyByCost': True,
|
802
|
+
# exchange-supported features
|
803
|
+
# 'selfTradePrevention': True,
|
804
|
+
# 'twap': False,
|
805
|
+
# 'iceberg': False,
|
806
|
+
# 'oco': False,
|
807
|
+
},
|
808
|
+
'fetchMyTrades': {
|
809
|
+
'marginMode': True,
|
810
|
+
'limit': None,
|
811
|
+
'daysBack': None,
|
812
|
+
'untilDays': 99999,
|
813
|
+
},
|
814
|
+
'fetchOrder': {
|
815
|
+
'marginMode': False,
|
816
|
+
'trigger': False,
|
817
|
+
'trailing': True,
|
818
|
+
},
|
819
|
+
'fetchOpenOrders': {
|
820
|
+
'marginMode': False,
|
821
|
+
'limit': 100,
|
822
|
+
'trigger': True,
|
823
|
+
'trailing': False,
|
824
|
+
},
|
825
|
+
'fetchClosedOrders': {
|
826
|
+
'marginMode': True,
|
827
|
+
'limit': 200,
|
828
|
+
'daysBack': None,
|
829
|
+
'daysBackCanceled': None,
|
830
|
+
'untilDays': None,
|
831
|
+
'trigger': False,
|
832
|
+
'trailing': False,
|
833
|
+
},
|
834
|
+
'fetchOHLCV': {
|
835
|
+
'limit': 500,
|
836
|
+
},
|
837
|
+
},
|
838
|
+
'spot': {
|
839
|
+
'extends': 'default',
|
840
|
+
},
|
841
|
+
'swap': {
|
842
|
+
'linear': {
|
843
|
+
'extends': 'forDerivatives',
|
844
|
+
},
|
845
|
+
'inverse': {
|
846
|
+
'extends': 'forDerivatives',
|
847
|
+
},
|
848
|
+
},
|
849
|
+
'future': {
|
850
|
+
'linear': None,
|
851
|
+
'inverse': None,
|
852
|
+
},
|
853
|
+
},
|
695
854
|
})
|
696
855
|
|
697
856
|
def fetch_time(self, params={}):
|
@@ -711,7 +870,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
711
870
|
# }
|
712
871
|
# }
|
713
872
|
#
|
714
|
-
data = self.
|
873
|
+
data = self.safe_dict(response, 'data', {})
|
715
874
|
return self.safe_integer(data, 'server_time')
|
716
875
|
|
717
876
|
def fetch_status(self, params={}):
|
@@ -720,7 +879,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
720
879
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
721
880
|
:returns dict: a `status structure <https://docs.ccxt.com/#/?id=exchange-status-structure>`
|
722
881
|
"""
|
723
|
-
options = self.
|
882
|
+
options = self.safe_dict(self.options, 'fetchStatus', {})
|
724
883
|
defaultType = self.safe_string(self.options, 'defaultType')
|
725
884
|
type = self.safe_string(options, 'type', defaultType)
|
726
885
|
type = self.safe_string(params, 'type', type)
|
@@ -751,12 +910,12 @@ class bitmart(Exchange, ImplicitAPI):
|
|
751
910
|
# }
|
752
911
|
# }
|
753
912
|
#
|
754
|
-
data = self.
|
755
|
-
services = self.
|
913
|
+
data = self.safe_dict(response, 'data', {})
|
914
|
+
services = self.safe_list(data, 'service', [])
|
756
915
|
servicesByType = self.index_by(services, 'service_type')
|
757
916
|
if type == 'swap':
|
758
917
|
type = 'contract'
|
759
|
-
service = self.
|
918
|
+
service = self.safe_string(servicesByType, type)
|
760
919
|
status = None
|
761
920
|
eta = None
|
762
921
|
if service is not None:
|
@@ -802,8 +961,8 @@ class bitmart(Exchange, ImplicitAPI):
|
|
802
961
|
# }
|
803
962
|
# }
|
804
963
|
#
|
805
|
-
data = self.
|
806
|
-
symbols = self.
|
964
|
+
data = self.safe_dict(response, 'data', {})
|
965
|
+
symbols = self.safe_list(data, 'symbols', [])
|
807
966
|
result = []
|
808
967
|
for i in range(0, len(symbols)):
|
809
968
|
market = symbols[i]
|
@@ -874,38 +1033,45 @@ class bitmart(Exchange, ImplicitAPI):
|
|
874
1033
|
response = self.publicGetContractPublicDetails(params)
|
875
1034
|
#
|
876
1035
|
# {
|
877
|
-
#
|
878
|
-
#
|
879
|
-
#
|
880
|
-
#
|
881
|
-
#
|
882
|
-
#
|
883
|
-
#
|
884
|
-
#
|
885
|
-
#
|
886
|
-
#
|
887
|
-
#
|
888
|
-
#
|
889
|
-
#
|
890
|
-
#
|
891
|
-
#
|
892
|
-
#
|
893
|
-
#
|
894
|
-
#
|
895
|
-
#
|
896
|
-
#
|
897
|
-
#
|
898
|
-
#
|
899
|
-
#
|
900
|
-
#
|
901
|
-
#
|
902
|
-
#
|
903
|
-
#
|
904
|
-
#
|
1036
|
+
# "code": 1000,
|
1037
|
+
# "message": "Ok",
|
1038
|
+
# "data": {
|
1039
|
+
# "symbols": [
|
1040
|
+
# {
|
1041
|
+
# "symbol": "BTCUSDT",
|
1042
|
+
# "product_type": 1,
|
1043
|
+
# "open_timestamp": 1645977600000,
|
1044
|
+
# "expire_timestamp": 0,
|
1045
|
+
# "settle_timestamp": 0,
|
1046
|
+
# "base_currency": "BTC",
|
1047
|
+
# "quote_currency": "USDT",
|
1048
|
+
# "last_price": "63547.4",
|
1049
|
+
# "volume_24h": "110938430",
|
1050
|
+
# "turnover_24h": "7004836342.6944",
|
1051
|
+
# "index_price": "63587.85404255",
|
1052
|
+
# "index_name": "BTCUSDT",
|
1053
|
+
# "contract_size": "0.001",
|
1054
|
+
# "min_leverage": "1",
|
1055
|
+
# "max_leverage": "100",
|
1056
|
+
# "price_precision": "0.1",
|
1057
|
+
# "vol_precision": "1",
|
1058
|
+
# "max_volume": "1000000",
|
1059
|
+
# "min_volume": "1",
|
1060
|
+
# "funding_rate": "0.0000801",
|
1061
|
+
# "expected_funding_rate": "-0.0000035",
|
1062
|
+
# "open_interest": "278214",
|
1063
|
+
# "open_interest_value": "17555316.9355496",
|
1064
|
+
# "high_24h": "64109.4",
|
1065
|
+
# "low_24h": "61857.6",
|
1066
|
+
# "change_24h": "0.0239264900886327",
|
1067
|
+
# "funding_time": 1726819200000
|
1068
|
+
# },
|
1069
|
+
# ]
|
1070
|
+
# }
|
905
1071
|
# }
|
906
1072
|
#
|
907
|
-
data = self.
|
908
|
-
symbols = self.
|
1073
|
+
data = self.safe_dict(response, 'data', {})
|
1074
|
+
symbols = self.safe_list(data, 'symbols', [])
|
909
1075
|
result = []
|
910
1076
|
for i in range(0, len(symbols)):
|
911
1077
|
market = symbols[i]
|
@@ -975,17 +1141,22 @@ class bitmart(Exchange, ImplicitAPI):
|
|
975
1141
|
})
|
976
1142
|
return result
|
977
1143
|
|
978
|
-
def fetch_markets(self, params={}):
|
1144
|
+
def fetch_markets(self, params={}) -> List[Market]:
|
979
1145
|
"""
|
1146
|
+
|
1147
|
+
https://developer-pro.bitmart.com/en/futuresv2/#get-contract-details
|
1148
|
+
|
980
1149
|
retrieves data on all markets for bitmart
|
981
1150
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
982
1151
|
:returns dict[]: an array of objects representing market data
|
983
1152
|
"""
|
1153
|
+
if self.options['adjustForTimeDifference']:
|
1154
|
+
self.load_time_difference()
|
984
1155
|
spot = self.fetch_spot_markets(params)
|
985
1156
|
contract = self.fetch_contract_markets(params)
|
986
1157
|
return self.array_concat(spot, contract)
|
987
1158
|
|
988
|
-
def fetch_currencies(self, params={}):
|
1159
|
+
def fetch_currencies(self, params={}) -> Currencies:
|
989
1160
|
"""
|
990
1161
|
fetches all available currencies on an exchange
|
991
1162
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1006,16 +1177,16 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1006
1177
|
# }
|
1007
1178
|
# }
|
1008
1179
|
#
|
1009
|
-
data = self.
|
1010
|
-
currencies = self.
|
1011
|
-
result = {}
|
1180
|
+
data = self.safe_dict(response, 'data', {})
|
1181
|
+
currencies = self.safe_list(data, 'currencies', [])
|
1182
|
+
result: dict = {}
|
1012
1183
|
for i in range(0, len(currencies)):
|
1013
1184
|
currency = currencies[i]
|
1014
1185
|
id = self.safe_string(currency, 'id')
|
1015
1186
|
code = self.safe_currency_code(id)
|
1016
1187
|
name = self.safe_string(currency, 'name')
|
1017
|
-
withdrawEnabled = self.
|
1018
|
-
depositEnabled = self.
|
1188
|
+
withdrawEnabled = self.safe_bool(currency, 'withdraw_enabled')
|
1189
|
+
depositEnabled = self.safe_bool(currency, 'deposit_enabled')
|
1019
1190
|
active = withdrawEnabled and depositEnabled
|
1020
1191
|
result[code] = {
|
1021
1192
|
'id': id,
|
@@ -1036,7 +1207,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1036
1207
|
|
1037
1208
|
def fetch_transaction_fee(self, code: str, params={}):
|
1038
1209
|
"""
|
1039
|
-
|
1210
|
+
@deprecated
|
1040
1211
|
please use fetchDepositWithdrawFee instead
|
1041
1212
|
:param str code: unified currency code
|
1042
1213
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1044,7 +1215,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1044
1215
|
"""
|
1045
1216
|
self.load_markets()
|
1046
1217
|
currency = self.currency(code)
|
1047
|
-
request = {
|
1218
|
+
request: dict = {
|
1048
1219
|
'currency': currency['id'],
|
1049
1220
|
}
|
1050
1221
|
response = self.privateGetAccountV1WithdrawCharge(self.extend(request, params))
|
@@ -1062,7 +1233,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1062
1233
|
# }
|
1063
1234
|
#
|
1064
1235
|
data = response['data']
|
1065
|
-
withdrawFees = {}
|
1236
|
+
withdrawFees: dict = {}
|
1066
1237
|
withdrawFees[code] = self.safe_number(data, 'withdraw_fee')
|
1067
1238
|
return {
|
1068
1239
|
'info': response,
|
@@ -1101,7 +1272,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1101
1272
|
"""
|
1102
1273
|
self.load_markets()
|
1103
1274
|
currency = self.currency(code)
|
1104
|
-
request = {
|
1275
|
+
request: dict = {
|
1105
1276
|
'currency': currency['id'],
|
1106
1277
|
}
|
1107
1278
|
response = self.privateGetAccountV1WithdrawCharge(self.extend(request, params))
|
@@ -1121,29 +1292,48 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1121
1292
|
data = response['data']
|
1122
1293
|
return self.parse_deposit_withdraw_fee(data)
|
1123
1294
|
|
1124
|
-
def parse_ticker(self, ticker, market: Market = None) -> Ticker:
|
1295
|
+
def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
|
1125
1296
|
#
|
1126
|
-
# spot(REST)
|
1297
|
+
# spot(REST) fetchTickers
|
1127
1298
|
#
|
1128
|
-
#
|
1129
|
-
#
|
1130
|
-
#
|
1131
|
-
#
|
1132
|
-
#
|
1133
|
-
#
|
1134
|
-
#
|
1135
|
-
#
|
1136
|
-
#
|
1137
|
-
#
|
1138
|
-
#
|
1139
|
-
#
|
1140
|
-
#
|
1141
|
-
#
|
1142
|
-
#
|
1143
|
-
#
|
1144
|
-
#
|
1299
|
+
# {
|
1300
|
+
# 'result': [
|
1301
|
+
# "AFIN_USDT", # symbol
|
1302
|
+
# "0.001047", # last
|
1303
|
+
# "11110", # v_24h
|
1304
|
+
# "11.632170", # qv_24h
|
1305
|
+
# "0.001048", # open_24h
|
1306
|
+
# "0.001048", # high_24h
|
1307
|
+
# "0.001047", # low_24h
|
1308
|
+
# "-0.00095", # price_change_24h
|
1309
|
+
# "0.001029", # bid_px
|
1310
|
+
# "5555", # bid_sz
|
1311
|
+
# "0.001041", # ask_px
|
1312
|
+
# "5297", # ask_sz
|
1313
|
+
# "1717122550482" # timestamp
|
1314
|
+
# ]
|
1315
|
+
# }
|
1316
|
+
#
|
1317
|
+
# spot(REST) fetchTicker
|
1318
|
+
#
|
1319
|
+
# {
|
1320
|
+
# "symbol": "BTC_USDT",
|
1321
|
+
# "last": "68500.00",
|
1322
|
+
# "v_24h": "10491.65490",
|
1323
|
+
# "qv_24h": "717178990.42",
|
1324
|
+
# "open_24h": "68149.75",
|
1325
|
+
# "high_24h": "69499.99",
|
1326
|
+
# "low_24h": "67132.40",
|
1327
|
+
# "fluctuation": "0.00514",
|
1328
|
+
# "bid_px": "68500",
|
1329
|
+
# "bid_sz": "0.00162",
|
1330
|
+
# "ask_px": "68500.01",
|
1331
|
+
# "ask_sz": "0.01722",
|
1332
|
+
# "ts": "1717131391671"
|
1333
|
+
# }
|
1145
1334
|
#
|
1146
1335
|
# spot(WS)
|
1336
|
+
#
|
1147
1337
|
# {
|
1148
1338
|
# "symbol":"BTC_USDT",
|
1149
1339
|
# "last_price":"146.24",
|
@@ -1156,37 +1346,74 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1156
1346
|
#
|
1157
1347
|
# swap
|
1158
1348
|
#
|
1159
|
-
#
|
1160
|
-
#
|
1161
|
-
#
|
1162
|
-
#
|
1163
|
-
#
|
1164
|
-
#
|
1165
|
-
#
|
1166
|
-
#
|
1167
|
-
#
|
1168
|
-
#
|
1169
|
-
#
|
1170
|
-
#
|
1349
|
+
# {
|
1350
|
+
# "symbol": "BTCUSDT",
|
1351
|
+
# "product_type": 1,
|
1352
|
+
# "open_timestamp": 1645977600000,
|
1353
|
+
# "expire_timestamp": 0,
|
1354
|
+
# "settle_timestamp": 0,
|
1355
|
+
# "base_currency": "BTC",
|
1356
|
+
# "quote_currency": "USDT",
|
1357
|
+
# "last_price": "63547.4",
|
1358
|
+
# "volume_24h": "110938430",
|
1359
|
+
# "turnover_24h": "7004836342.6944",
|
1360
|
+
# "index_price": "63587.85404255",
|
1361
|
+
# "index_name": "BTCUSDT",
|
1362
|
+
# "contract_size": "0.001",
|
1363
|
+
# "min_leverage": "1",
|
1364
|
+
# "max_leverage": "100",
|
1365
|
+
# "price_precision": "0.1",
|
1366
|
+
# "vol_precision": "1",
|
1367
|
+
# "max_volume": "1000000",
|
1368
|
+
# "min_volume": "1",
|
1369
|
+
# "funding_rate": "0.0000801",
|
1370
|
+
# "expected_funding_rate": "-0.0000035",
|
1371
|
+
# "open_interest": "278214",
|
1372
|
+
# "open_interest_value": "17555316.9355496",
|
1373
|
+
# "high_24h": "64109.4",
|
1374
|
+
# "low_24h": "61857.6",
|
1375
|
+
# "change_24h": "0.0239264900886327",
|
1376
|
+
# "funding_time": 1726819200000
|
1377
|
+
# }
|
1171
1378
|
#
|
1172
|
-
|
1173
|
-
|
1174
|
-
# ticker from WS has a different field(in seconds)
|
1175
|
-
timestamp = self.safe_integer_product(ticker, 's_t', 1000)
|
1379
|
+
result = self.safe_list(ticker, 'result', [])
|
1380
|
+
average = self.safe_string_2(ticker, 'avg_price', 'index_price')
|
1176
1381
|
marketId = self.safe_string_2(ticker, 'symbol', 'contract_symbol')
|
1382
|
+
timestamp = self.safe_integer_2(ticker, 'timestamp', 'ts')
|
1383
|
+
last = self.safe_string_2(ticker, 'last_price', 'last')
|
1384
|
+
percentage = self.safe_string_2(ticker, 'price_change_percent_24h', 'change_24h')
|
1385
|
+
change = self.safe_string(ticker, 'fluctuation')
|
1386
|
+
high = self.safe_string_2(ticker, 'high_24h', 'high_price')
|
1387
|
+
low = self.safe_string_2(ticker, 'low_24h', 'low_price')
|
1388
|
+
bid = self.safe_string_2(ticker, 'best_bid', 'bid_px')
|
1389
|
+
bidVolume = self.safe_string_2(ticker, 'best_bid_size', 'bid_sz')
|
1390
|
+
ask = self.safe_string_2(ticker, 'best_ask', 'ask_px')
|
1391
|
+
askVolume = self.safe_string_2(ticker, 'best_ask_size', 'ask_sz')
|
1392
|
+
open = self.safe_string(ticker, 'open_24h')
|
1393
|
+
baseVolume = self.safe_string_n(ticker, ['base_volume_24h', 'v_24h', 'volume_24h'])
|
1394
|
+
quoteVolume = self.safe_string_lower_n(ticker, ['quote_volume_24h', 'qv_24h', 'turnover_24h'])
|
1395
|
+
listMarketId = self.safe_string(result, 0)
|
1396
|
+
if listMarketId is not None:
|
1397
|
+
marketId = listMarketId
|
1398
|
+
timestamp = self.safe_integer(result, 12)
|
1399
|
+
high = self.safe_string(result, 5)
|
1400
|
+
low = self.safe_string(result, 6)
|
1401
|
+
bid = self.safe_string(result, 8)
|
1402
|
+
bidVolume = self.safe_string(result, 9)
|
1403
|
+
ask = self.safe_string(result, 10)
|
1404
|
+
askVolume = self.safe_string(result, 11)
|
1405
|
+
open = self.safe_string(result, 4)
|
1406
|
+
last = self.safe_string(result, 1)
|
1407
|
+
change = self.safe_string(result, 7)
|
1408
|
+
baseVolume = self.safe_string(result, 2)
|
1409
|
+
quoteVolume = self.safe_string_lower(result, 3)
|
1177
1410
|
market = self.safe_market(marketId, market)
|
1178
1411
|
symbol = market['symbol']
|
1179
|
-
|
1180
|
-
|
1412
|
+
if timestamp is None:
|
1413
|
+
# ticker from WS has a different field(in seconds)
|
1414
|
+
timestamp = self.safe_integer_product(ticker, 's_t', 1000)
|
1181
1415
|
if percentage is None:
|
1182
|
-
|
1183
|
-
if (percentageRaw is not None) and (percentageRaw != '0'): # a few tickers show strictly '0' in fluctuation field
|
1184
|
-
direction = percentageRaw[0]
|
1185
|
-
percentage = direction + Precise.string_mul(percentageRaw.replace(direction, ''), '100')
|
1186
|
-
elif percentageRaw == '0':
|
1187
|
-
percentage = '0'
|
1188
|
-
baseVolume = self.safe_string(ticker, 'base_volume_24h')
|
1189
|
-
quoteVolume = self.safe_string(ticker, 'quote_volume_24h')
|
1416
|
+
percentage = Precise.string_mul(change, '100')
|
1190
1417
|
if quoteVolume is None:
|
1191
1418
|
if baseVolume is None:
|
1192
1419
|
# self is swap
|
@@ -1196,21 +1423,18 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1196
1423
|
# contrary to name and documentation, base_volume_24h is actually the quote volume
|
1197
1424
|
quoteVolume = baseVolume
|
1198
1425
|
baseVolume = None
|
1199
|
-
average = self.safe_string_2(ticker, 'avg_price', 'index_price')
|
1200
|
-
high = self.safe_string_2(ticker, 'high_24h', 'high_price')
|
1201
|
-
low = self.safe_string_2(ticker, 'low_24h', 'low_price')
|
1202
1426
|
return self.safe_ticker({
|
1203
1427
|
'symbol': symbol,
|
1204
1428
|
'timestamp': timestamp,
|
1205
1429
|
'datetime': self.iso8601(timestamp),
|
1206
1430
|
'high': high,
|
1207
1431
|
'low': low,
|
1208
|
-
'bid':
|
1209
|
-
'bidVolume':
|
1210
|
-
'ask':
|
1211
|
-
'askVolume':
|
1432
|
+
'bid': bid,
|
1433
|
+
'bidVolume': bidVolume,
|
1434
|
+
'ask': ask,
|
1435
|
+
'askVolume': askVolume,
|
1212
1436
|
'vwap': None,
|
1213
|
-
'open':
|
1437
|
+
'open': open,
|
1214
1438
|
'close': last,
|
1215
1439
|
'last': last,
|
1216
1440
|
'previousClose': None,
|
@@ -1219,96 +1443,112 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1219
1443
|
'average': average,
|
1220
1444
|
'baseVolume': baseVolume,
|
1221
1445
|
'quoteVolume': quoteVolume,
|
1446
|
+
'indexPrice': self.safe_string(ticker, 'index_price'),
|
1222
1447
|
'info': ticker,
|
1223
1448
|
}, market)
|
1224
1449
|
|
1225
1450
|
def fetch_ticker(self, symbol: str, params={}) -> Ticker:
|
1226
1451
|
"""
|
1227
1452
|
fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
|
1453
|
+
|
1454
|
+
https://developer-pro.bitmart.com/en/spot/#get-ticker-of-a-trading-pair-v3
|
1455
|
+
https://developer-pro.bitmart.com/en/futuresv2/#get-contract-details
|
1456
|
+
|
1228
1457
|
:param str symbol: unified symbol of the market to fetch the ticker for
|
1229
1458
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1230
1459
|
:returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
|
1231
1460
|
"""
|
1232
1461
|
self.load_markets()
|
1233
1462
|
market = self.market(symbol)
|
1234
|
-
request = {}
|
1463
|
+
request: dict = {}
|
1235
1464
|
response = None
|
1236
1465
|
if market['swap']:
|
1237
|
-
request['
|
1238
|
-
response = self.
|
1466
|
+
request['symbol'] = market['id']
|
1467
|
+
response = self.publicGetContractPublicDetails(self.extend(request, params))
|
1468
|
+
#
|
1469
|
+
# {
|
1470
|
+
# "code": 1000,
|
1471
|
+
# "message": "Ok",
|
1472
|
+
# "data": {
|
1473
|
+
# "symbols": [
|
1474
|
+
# {
|
1475
|
+
# "symbol": "BTCUSDT",
|
1476
|
+
# "product_type": 1,
|
1477
|
+
# "open_timestamp": 1645977600000,
|
1478
|
+
# "expire_timestamp": 0,
|
1479
|
+
# "settle_timestamp": 0,
|
1480
|
+
# "base_currency": "BTC",
|
1481
|
+
# "quote_currency": "USDT",
|
1482
|
+
# "last_price": "63547.4",
|
1483
|
+
# "volume_24h": "110938430",
|
1484
|
+
# "turnover_24h": "7004836342.6944",
|
1485
|
+
# "index_price": "63587.85404255",
|
1486
|
+
# "index_name": "BTCUSDT",
|
1487
|
+
# "contract_size": "0.001",
|
1488
|
+
# "min_leverage": "1",
|
1489
|
+
# "max_leverage": "100",
|
1490
|
+
# "price_precision": "0.1",
|
1491
|
+
# "vol_precision": "1",
|
1492
|
+
# "max_volume": "1000000",
|
1493
|
+
# "min_volume": "1",
|
1494
|
+
# "funding_rate": "0.0000801",
|
1495
|
+
# "expected_funding_rate": "-0.0000035",
|
1496
|
+
# "open_interest": "278214",
|
1497
|
+
# "open_interest_value": "17555316.9355496",
|
1498
|
+
# "high_24h": "64109.4",
|
1499
|
+
# "low_24h": "61857.6",
|
1500
|
+
# "change_24h": "0.0239264900886327",
|
1501
|
+
# "funding_time": 1726819200000
|
1502
|
+
# },
|
1503
|
+
# ]
|
1504
|
+
# }
|
1505
|
+
# }
|
1506
|
+
#
|
1239
1507
|
elif market['spot']:
|
1240
1508
|
request['symbol'] = market['id']
|
1241
|
-
response = self.
|
1509
|
+
response = self.publicGetSpotQuotationV3Ticker(self.extend(request, params))
|
1510
|
+
#
|
1511
|
+
# {
|
1512
|
+
# "code": 1000,
|
1513
|
+
# "trace": "f2194c2c202d2.99.1717535",
|
1514
|
+
# "message": "success",
|
1515
|
+
# "data": {
|
1516
|
+
# "symbol": "BTC_USDT",
|
1517
|
+
# "last": "68500.00",
|
1518
|
+
# "v_24h": "10491.65490",
|
1519
|
+
# "qv_24h": "717178990.42",
|
1520
|
+
# "open_24h": "68149.75",
|
1521
|
+
# "high_24h": "69499.99",
|
1522
|
+
# "low_24h": "67132.40",
|
1523
|
+
# "fluctuation": "0.00514",
|
1524
|
+
# "bid_px": "68500",
|
1525
|
+
# "bid_sz": "0.00162",
|
1526
|
+
# "ask_px": "68500.01",
|
1527
|
+
# "ask_sz": "0.01722",
|
1528
|
+
# "ts": "1717131391671"
|
1529
|
+
# }
|
1530
|
+
# }
|
1531
|
+
#
|
1242
1532
|
else:
|
1243
1533
|
raise NotSupported(self.id + ' fetchTicker() does not support ' + market['type'] + ' markets, only spot and swap markets are accepted')
|
1244
|
-
#
|
1245
|
-
# spot
|
1246
|
-
#
|
1247
|
-
# {
|
1248
|
-
# "message":"OK",
|
1249
|
-
# "code":1000,
|
1250
|
-
# "trace":"6aa5b923-2f57-46e3-876d-feca190e0b82",
|
1251
|
-
# "data":{
|
1252
|
-
# "tickers":[
|
1253
|
-
# {
|
1254
|
-
# "symbol":"ETH_BTC",
|
1255
|
-
# "last_price":"0.036037",
|
1256
|
-
# "quote_volume_24h":"4380.6660000000",
|
1257
|
-
# "base_volume_24h":"159.3582006712",
|
1258
|
-
# "high_24h":"0.036972",
|
1259
|
-
# "low_24h":"0.035524",
|
1260
|
-
# "open_24h":"0.036561",
|
1261
|
-
# "close_24h":"0.036037",
|
1262
|
-
# "best_ask":"0.036077",
|
1263
|
-
# "best_ask_size":"9.9500",
|
1264
|
-
# "best_bid":"0.035983",
|
1265
|
-
# "best_bid_size":"4.2792",
|
1266
|
-
# "fluctuation":"-0.0143",
|
1267
|
-
# "url":"https://www.bitmart.com/trade?symbol=ETH_BTC"
|
1268
|
-
# }
|
1269
|
-
# ]
|
1270
|
-
# }
|
1271
|
-
# }
|
1272
|
-
#
|
1273
|
-
# swap
|
1274
|
-
#
|
1275
|
-
# {
|
1276
|
-
# "message":"OK",
|
1277
|
-
# "code":1000,
|
1278
|
-
# "trace":"4a0ebceb-d3f7-45a3-8feb-f61e230e24cd",
|
1279
|
-
# "data":{
|
1280
|
-
# "tickers":[
|
1281
|
-
# {
|
1282
|
-
# "contract_symbol":"DOGEUSDT",
|
1283
|
-
# "last_price":"0.130180",
|
1284
|
-
# "index_price":"0.13028635",
|
1285
|
-
# "last_funding_rate":"0.00002025",
|
1286
|
-
# "price_change_percent_24h":"-2.326",
|
1287
|
-
# "volume_24h":"116789313.01797258",
|
1288
|
-
# "url":"https://futures.bitmart.com/en?symbol=DOGEUSDT",
|
1289
|
-
# "high_price":"0.134520",
|
1290
|
-
# "low_price":"0.128570",
|
1291
|
-
# "legal_coin_price":"0.13017401"
|
1292
|
-
# }
|
1293
|
-
# ]
|
1294
|
-
# }
|
1295
|
-
# }
|
1296
|
-
#
|
1297
|
-
data = self.safe_value(response, 'data', {})
|
1298
|
-
tickers = self.safe_value(data, 'tickers', [])
|
1299
1534
|
# fails in naming for contract tickers 'contract_symbol'
|
1300
|
-
|
1535
|
+
tickers = []
|
1536
|
+
ticker: dict = {}
|
1301
1537
|
if market['spot']:
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
1305
|
-
|
1538
|
+
ticker = self.safe_dict(response, 'data', {})
|
1539
|
+
else:
|
1540
|
+
data = self.safe_dict(response, 'data', {})
|
1541
|
+
tickers = self.safe_list(data, 'symbols', [])
|
1542
|
+
ticker = self.safe_dict(tickers, 0, {})
|
1306
1543
|
return self.parse_ticker(ticker, market)
|
1307
1544
|
|
1308
1545
|
def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
|
1309
1546
|
"""
|
1310
1547
|
fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
|
1311
|
-
|
1548
|
+
|
1549
|
+
https://developer-pro.bitmart.com/en/spot/#get-ticker-of-all-pairs-v3
|
1550
|
+
https://developer-pro.bitmart.com/en/futuresv2/#get-contract-details
|
1551
|
+
|
1312
1552
|
:param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
|
1313
1553
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1314
1554
|
:returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
|
@@ -1318,21 +1558,92 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1318
1558
|
type = None
|
1319
1559
|
market = None
|
1320
1560
|
if symbols is not None:
|
1321
|
-
symbol = self.
|
1561
|
+
symbol = self.safe_string(symbols, 0)
|
1322
1562
|
market = self.market(symbol)
|
1323
1563
|
type, params = self.handle_market_type_and_params('fetchTickers', market, params)
|
1324
1564
|
response = None
|
1325
1565
|
if type == 'spot':
|
1326
|
-
response = self.
|
1566
|
+
response = self.publicGetSpotQuotationV3Tickers(params)
|
1567
|
+
#
|
1568
|
+
# {
|
1569
|
+
# "code": 1000,
|
1570
|
+
# "trace": "17c5e5d9ac49f9b71efca2bed55f1a.105.171225637482393",
|
1571
|
+
# "message": "success",
|
1572
|
+
# "data": [
|
1573
|
+
# [
|
1574
|
+
# "AFIN_USDT",
|
1575
|
+
# "0.001047",
|
1576
|
+
# "11110",
|
1577
|
+
# "11.632170",
|
1578
|
+
# "0.001048",
|
1579
|
+
# "0.001048",
|
1580
|
+
# "0.001047",
|
1581
|
+
# "-0.00095",
|
1582
|
+
# "0.001029",
|
1583
|
+
# "5555",
|
1584
|
+
# "0.001041",
|
1585
|
+
# "5297",
|
1586
|
+
# "1717122550482"
|
1587
|
+
# ],
|
1588
|
+
# ]
|
1589
|
+
# }
|
1590
|
+
#
|
1327
1591
|
elif type == 'swap':
|
1328
|
-
response = self.
|
1592
|
+
response = self.publicGetContractPublicDetails(params)
|
1593
|
+
#
|
1594
|
+
# {
|
1595
|
+
# "code": 1000,
|
1596
|
+
# "message": "Ok",
|
1597
|
+
# "data": {
|
1598
|
+
# "symbols": [
|
1599
|
+
# {
|
1600
|
+
# "symbol": "BTCUSDT",
|
1601
|
+
# "product_type": 1,
|
1602
|
+
# "open_timestamp": 1645977600000,
|
1603
|
+
# "expire_timestamp": 0,
|
1604
|
+
# "settle_timestamp": 0,
|
1605
|
+
# "base_currency": "BTC",
|
1606
|
+
# "quote_currency": "USDT",
|
1607
|
+
# "last_price": "63547.4",
|
1608
|
+
# "volume_24h": "110938430",
|
1609
|
+
# "turnover_24h": "7004836342.6944",
|
1610
|
+
# "index_price": "63587.85404255",
|
1611
|
+
# "index_name": "BTCUSDT",
|
1612
|
+
# "contract_size": "0.001",
|
1613
|
+
# "min_leverage": "1",
|
1614
|
+
# "max_leverage": "100",
|
1615
|
+
# "price_precision": "0.1",
|
1616
|
+
# "vol_precision": "1",
|
1617
|
+
# "max_volume": "1000000",
|
1618
|
+
# "min_volume": "1",
|
1619
|
+
# "funding_rate": "0.0000801",
|
1620
|
+
# "expected_funding_rate": "-0.0000035",
|
1621
|
+
# "open_interest": "278214",
|
1622
|
+
# "open_interest_value": "17555316.9355496",
|
1623
|
+
# "high_24h": "64109.4",
|
1624
|
+
# "low_24h": "61857.6",
|
1625
|
+
# "change_24h": "0.0239264900886327",
|
1626
|
+
# "funding_time": 1726819200000
|
1627
|
+
# },
|
1628
|
+
# ]
|
1629
|
+
# }
|
1630
|
+
# }
|
1631
|
+
#
|
1329
1632
|
else:
|
1330
1633
|
raise NotSupported(self.id + ' fetchTickers() does not support ' + type + ' markets, only spot and swap markets are accepted')
|
1331
|
-
|
1332
|
-
|
1333
|
-
|
1634
|
+
tickers = []
|
1635
|
+
if type == 'spot':
|
1636
|
+
tickers = self.safe_list(response, 'data', [])
|
1637
|
+
else:
|
1638
|
+
data = self.safe_dict(response, 'data', {})
|
1639
|
+
tickers = self.safe_list(data, 'symbols', [])
|
1640
|
+
result: dict = {}
|
1334
1641
|
for i in range(0, len(tickers)):
|
1335
|
-
ticker =
|
1642
|
+
ticker: dict = {}
|
1643
|
+
if type == 'spot':
|
1644
|
+
ticker = self.parse_ticker({'result': tickers[i]})
|
1645
|
+
else:
|
1646
|
+
ticker = self.parse_ticker(tickers[i])
|
1336
1647
|
symbol = ticker['symbol']
|
1337
1648
|
result[symbol] = ticker
|
1338
1649
|
return self.filter_by_array_tickers(result, 'symbol', symbols)
|
@@ -1340,8 +1651,11 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1340
1651
|
def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
|
1341
1652
|
"""
|
1342
1653
|
fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
|
1343
|
-
|
1344
|
-
|
1654
|
+
|
1655
|
+
https://developer-pro.bitmart.com/en/spot/#get-depth-v3
|
1656
|
+
https://developer-pro.bitmart.com/en/futures/#get-market-depth
|
1657
|
+
https://developer-pro.bitmart.com/en/futuresv2/#get-market-depth
|
1658
|
+
|
1345
1659
|
:param str symbol: unified symbol of the market to fetch the order book for
|
1346
1660
|
:param int [limit]: the maximum amount of order book entries to return
|
1347
1661
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -1349,7 +1663,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1349
1663
|
"""
|
1350
1664
|
self.load_markets()
|
1351
1665
|
market = self.market(symbol)
|
1352
|
-
request = {
|
1666
|
+
request: dict = {
|
1353
1667
|
'symbol': market['id'],
|
1354
1668
|
}
|
1355
1669
|
response = None
|
@@ -1406,21 +1720,21 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1406
1720
|
# "trace": "4cad855074664097ac6ba5258c47305d.72.16952643834721135"
|
1407
1721
|
# }
|
1408
1722
|
#
|
1409
|
-
data = self.
|
1723
|
+
data = self.safe_dict(response, 'data', {})
|
1410
1724
|
timestamp = self.safe_integer_2(data, 'ts', 'timestamp')
|
1411
1725
|
return self.parse_order_book(data, market['symbol'], timestamp)
|
1412
1726
|
|
1413
|
-
def parse_trade(self, trade, market: Market = None) -> Trade:
|
1727
|
+
def parse_trade(self, trade: dict, market: Market = None) -> Trade:
|
1414
1728
|
#
|
1415
1729
|
# public fetchTrades spot( amount = count * price )
|
1416
1730
|
#
|
1417
|
-
#
|
1418
|
-
#
|
1419
|
-
#
|
1420
|
-
#
|
1421
|
-
#
|
1422
|
-
#
|
1423
|
-
#
|
1731
|
+
# [
|
1732
|
+
# "BTC_USDT", # symbol
|
1733
|
+
# "1717212457302", # timestamp
|
1734
|
+
# "67643.11", # price
|
1735
|
+
# "0.00106", # size
|
1736
|
+
# "sell" # side
|
1737
|
+
# ]
|
1424
1738
|
#
|
1425
1739
|
# spot: fetchMyTrades
|
1426
1740
|
#
|
@@ -1467,22 +1781,23 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1467
1781
|
# 'lastTradeID': 6802340762
|
1468
1782
|
# }
|
1469
1783
|
#
|
1470
|
-
timestamp = self.safe_integer_n(trade, ['
|
1471
|
-
|
1784
|
+
timestamp = self.safe_integer_n(trade, ['createTime', 'create_time', 1])
|
1785
|
+
isPublic = self.safe_string(trade, 0)
|
1786
|
+
isPublicTrade = (isPublic is not None)
|
1472
1787
|
amount = None
|
1473
1788
|
cost = None
|
1474
1789
|
type = None
|
1475
1790
|
side = None
|
1476
1791
|
if isPublicTrade:
|
1477
|
-
amount = self.
|
1792
|
+
amount = self.safe_string_2(trade, 'count', 3)
|
1478
1793
|
cost = self.safe_string(trade, 'amount')
|
1479
|
-
side = self.
|
1794
|
+
side = self.safe_string_2(trade, 'type', 4)
|
1480
1795
|
else:
|
1481
1796
|
amount = self.safe_string_n(trade, ['size', 'vol', 'fillQty'])
|
1482
1797
|
cost = self.safe_string(trade, 'notional')
|
1483
1798
|
type = self.safe_string(trade, 'type')
|
1484
1799
|
side = self.parse_order_side(self.safe_string(trade, 'side'))
|
1485
|
-
marketId = self.
|
1800
|
+
marketId = self.safe_string_2(trade, 'symbol', 0)
|
1486
1801
|
market = self.safe_market(marketId, market)
|
1487
1802
|
feeCostString = self.safe_string_2(trade, 'fee', 'paid_fees')
|
1488
1803
|
fee = None
|
@@ -1504,7 +1819,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1504
1819
|
'symbol': market['symbol'],
|
1505
1820
|
'type': type,
|
1506
1821
|
'side': side,
|
1507
|
-
'price': self.
|
1822
|
+
'price': self.safe_string_n(trade, ['price', 'fillPrice', 2]),
|
1508
1823
|
'amount': amount,
|
1509
1824
|
'cost': cost,
|
1510
1825
|
'takerOrMaker': self.safe_string_lower_2(trade, 'tradeRole', 'exec_type'),
|
@@ -1513,10 +1828,13 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1513
1828
|
|
1514
1829
|
def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
|
1515
1830
|
"""
|
1516
|
-
get
|
1831
|
+
get a list of the most recent trades for a particular symbol
|
1832
|
+
|
1833
|
+
https://developer-pro.bitmart.com/en/spot/#get-recent-trades-v3
|
1834
|
+
|
1517
1835
|
:param str symbol: unified symbol of the market to fetch trades for
|
1518
1836
|
:param int [since]: timestamp in ms of the earliest trade to fetch
|
1519
|
-
:param int [limit]: the maximum
|
1837
|
+
:param int [limit]: the maximum number of trades to fetch
|
1520
1838
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1521
1839
|
:returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
|
1522
1840
|
"""
|
@@ -1524,33 +1842,30 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1524
1842
|
market = self.market(symbol)
|
1525
1843
|
if not market['spot']:
|
1526
1844
|
raise NotSupported(self.id + ' fetchTrades() does not support ' + market['type'] + ' orders, only spot orders are accepted')
|
1527
|
-
request = {
|
1845
|
+
request: dict = {
|
1528
1846
|
'symbol': market['id'],
|
1529
1847
|
}
|
1530
|
-
|
1531
|
-
|
1532
|
-
|
1848
|
+
if limit is not None:
|
1849
|
+
request['limit'] = limit
|
1850
|
+
response = self.publicGetSpotQuotationV3Trades(self.extend(request, params))
|
1533
1851
|
#
|
1534
1852
|
# {
|
1535
|
-
# "
|
1536
|
-
# "
|
1537
|
-
# "
|
1538
|
-
# "data":
|
1539
|
-
#
|
1540
|
-
#
|
1541
|
-
#
|
1542
|
-
#
|
1543
|
-
#
|
1544
|
-
#
|
1545
|
-
#
|
1546
|
-
#
|
1547
|
-
# ]
|
1548
|
-
# }
|
1853
|
+
# "code": 1000,
|
1854
|
+
# "trace": "58031f9a5bd.111.17117",
|
1855
|
+
# "message": "success",
|
1856
|
+
# "data": [
|
1857
|
+
# [
|
1858
|
+
# "BTC_USDT",
|
1859
|
+
# "1717212457302",
|
1860
|
+
# "67643.11",
|
1861
|
+
# "0.00106",
|
1862
|
+
# "sell"
|
1863
|
+
# ],
|
1864
|
+
# ]
|
1549
1865
|
# }
|
1550
1866
|
#
|
1551
|
-
data = self.
|
1552
|
-
|
1553
|
-
return self.parse_trades(trades, market, since, limit)
|
1867
|
+
data = self.safe_list(response, 'data', [])
|
1868
|
+
return self.parse_trades(data, market, since, limit)
|
1554
1869
|
|
1555
1870
|
def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
|
1556
1871
|
#
|
@@ -1617,8 +1932,10 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1617
1932
|
def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
|
1618
1933
|
"""
|
1619
1934
|
fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
|
1620
|
-
|
1621
|
-
|
1935
|
+
|
1936
|
+
https://developer-pro.bitmart.com/en/spot/#get-history-k-line-v3
|
1937
|
+
https://developer-pro.bitmart.com/en/futuresv2/#get-k-line
|
1938
|
+
|
1622
1939
|
:param str symbol: unified symbol of the market to fetch OHLCV data for
|
1623
1940
|
:param str timeframe: the length of time each candle represents
|
1624
1941
|
:param int [since]: timestamp in ms of the earliest candle to fetch
|
@@ -1636,7 +1953,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1636
1953
|
market = self.market(symbol)
|
1637
1954
|
duration = self.parse_timeframe(timeframe)
|
1638
1955
|
parsedTimeframe = self.safe_integer(self.timeframes, timeframe)
|
1639
|
-
request = {
|
1956
|
+
request: dict = {
|
1640
1957
|
'symbol': market['id'],
|
1641
1958
|
}
|
1642
1959
|
if parsedTimeframe is not None:
|
@@ -1650,7 +1967,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1650
1967
|
if since is not None:
|
1651
1968
|
request['after'] = self.parse_to_int((since / 1000)) - 1
|
1652
1969
|
else:
|
1653
|
-
maxLimit =
|
1970
|
+
maxLimit = 500
|
1654
1971
|
if limit is None:
|
1655
1972
|
limit = maxLimit
|
1656
1973
|
limit = min(maxLimit, limit)
|
@@ -1703,13 +2020,15 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1703
2020
|
# "trace": "96c989db-e0f5-46f5-bba6-60cfcbde699b"
|
1704
2021
|
# }
|
1705
2022
|
#
|
1706
|
-
ohlcv = self.
|
2023
|
+
ohlcv = self.safe_list(response, 'data', [])
|
1707
2024
|
return self.parse_ohlcvs(ohlcv, market, timeframe, since, limit)
|
1708
2025
|
|
1709
2026
|
def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
1710
2027
|
"""
|
1711
|
-
|
1712
|
-
|
2028
|
+
|
2029
|
+
https://developer-pro.bitmart.com/en/spot/#account-trade-list-v4-signed
|
2030
|
+
https://developer-pro.bitmart.com/en/futures/#get-order-trade-keyed
|
2031
|
+
|
1713
2032
|
fetch all trades made by the user
|
1714
2033
|
:param str symbol: unified market symbol
|
1715
2034
|
:param int [since]: the earliest time in ms to fetch trades for
|
@@ -1721,7 +2040,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1721
2040
|
"""
|
1722
2041
|
self.load_markets()
|
1723
2042
|
market = None
|
1724
|
-
request = {}
|
2043
|
+
request: dict = {}
|
1725
2044
|
if symbol is not None:
|
1726
2045
|
market = self.market(symbol)
|
1727
2046
|
request['symbol'] = market['id']
|
@@ -1735,11 +2054,12 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1735
2054
|
marginMode, params = self.handle_margin_mode_and_params('fetchMyTrades', params)
|
1736
2055
|
if marginMode == 'isolated':
|
1737
2056
|
request['orderMode'] = 'iso_margin'
|
1738
|
-
options = self.
|
1739
|
-
|
2057
|
+
options = self.safe_dict(self.options, 'fetchMyTrades', {})
|
2058
|
+
maxLimit = 200
|
2059
|
+
defaultLimit = self.safe_integer(options, 'limit', maxLimit)
|
1740
2060
|
if limit is None:
|
1741
2061
|
limit = defaultLimit
|
1742
|
-
request['limit'] = limit
|
2062
|
+
request['limit'] = min(limit, maxLimit)
|
1743
2063
|
if since is not None:
|
1744
2064
|
request['startTime'] = since
|
1745
2065
|
if until is not None:
|
@@ -1806,12 +2126,14 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1806
2126
|
# "trace": "4cad855074634097ac6ba5257c47305d.62.16959616054873723"
|
1807
2127
|
# }
|
1808
2128
|
#
|
1809
|
-
data = self.
|
2129
|
+
data = self.safe_list(response, 'data', [])
|
1810
2130
|
return self.parse_trades(data, market, since, limit)
|
1811
2131
|
|
1812
2132
|
def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
1813
2133
|
"""
|
1814
|
-
|
2134
|
+
|
2135
|
+
https://developer-pro.bitmart.com/en/spot/#order-trade-list-v4-signed
|
2136
|
+
|
1815
2137
|
fetch all the trades made from a single order
|
1816
2138
|
:param str id: order id
|
1817
2139
|
:param str symbol: unified market symbol
|
@@ -1821,33 +2143,33 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1821
2143
|
:returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
|
1822
2144
|
"""
|
1823
2145
|
self.load_markets()
|
1824
|
-
request = {
|
2146
|
+
request: dict = {
|
1825
2147
|
'orderId': id,
|
1826
2148
|
}
|
1827
2149
|
response = self.privatePostSpotV4QueryOrderTrades(self.extend(request, params))
|
1828
|
-
data = self.
|
2150
|
+
data = self.safe_list(response, 'data', [])
|
1829
2151
|
return self.parse_trades(data, None, since, limit)
|
1830
2152
|
|
1831
2153
|
def custom_parse_balance(self, response, marketType) -> Balances:
|
1832
|
-
data = self.
|
2154
|
+
data = self.safe_dict(response, 'data', {})
|
1833
2155
|
wallet = None
|
1834
2156
|
if marketType == 'swap':
|
1835
|
-
wallet = self.
|
2157
|
+
wallet = self.safe_list(response, 'data', [])
|
1836
2158
|
elif marketType == 'margin':
|
1837
|
-
wallet = self.
|
2159
|
+
wallet = self.safe_list(data, 'symbols', [])
|
1838
2160
|
else:
|
1839
|
-
wallet = self.
|
2161
|
+
wallet = self.safe_list(data, 'wallet', [])
|
1840
2162
|
result = {'info': response}
|
1841
2163
|
if marketType == 'margin':
|
1842
2164
|
for i in range(0, len(wallet)):
|
1843
2165
|
entry = wallet[i]
|
1844
2166
|
marketId = self.safe_string(entry, 'symbol')
|
1845
2167
|
symbol = self.safe_symbol(marketId, None, '_')
|
1846
|
-
base = self.
|
1847
|
-
quote = self.
|
2168
|
+
base = self.safe_dict(entry, 'base', {})
|
2169
|
+
quote = self.safe_dict(entry, 'quote', {})
|
1848
2170
|
baseCode = self.safe_currency_code(self.safe_string(base, 'currency'))
|
1849
2171
|
quoteCode = self.safe_currency_code(self.safe_string(quote, 'currency'))
|
1850
|
-
subResult = {}
|
2172
|
+
subResult: dict = {}
|
1851
2173
|
subResult[baseCode] = self.parse_balance_helper(base)
|
1852
2174
|
subResult[quoteCode] = self.parse_balance_helper(quote)
|
1853
2175
|
result[symbol] = self.safe_balance(subResult)
|
@@ -1877,10 +2199,13 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1877
2199
|
def fetch_balance(self, params={}) -> Balances:
|
1878
2200
|
"""
|
1879
2201
|
query for balance and get the amount of funds available for trading or funds locked in orders
|
1880
|
-
|
1881
|
-
|
1882
|
-
|
1883
|
-
|
2202
|
+
|
2203
|
+
https://developer-pro.bitmart.com/en/spot/#get-spot-wallet-balance
|
2204
|
+
https://developer-pro.bitmart.com/en/futures/#get-contract-assets-detail
|
2205
|
+
https://developer-pro.bitmart.com/en/futuresv2/#get-contract-assets-keyed
|
2206
|
+
https://developer-pro.bitmart.com/en/spot/#get-account-balance
|
2207
|
+
https://developer-pro.bitmart.com/en/spot/#get-margin-account-details-isolated
|
2208
|
+
|
1884
2209
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
1885
2210
|
:returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
|
1886
2211
|
"""
|
@@ -1999,7 +2324,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
1999
2324
|
#
|
2000
2325
|
return self.custom_parse_balance(response, marketType)
|
2001
2326
|
|
2002
|
-
def parse_trading_fee(self, fee, market: Market = None):
|
2327
|
+
def parse_trading_fee(self, fee: dict, market: Market = None) -> TradingFeeInterface:
|
2003
2328
|
#
|
2004
2329
|
# {
|
2005
2330
|
# "symbol": "ETH_USDT",
|
@@ -2014,9 +2339,11 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2014
2339
|
'symbol': symbol,
|
2015
2340
|
'maker': self.safe_number(fee, 'maker_fee_rate'),
|
2016
2341
|
'taker': self.safe_number(fee, 'taker_fee_rate'),
|
2342
|
+
'percentage': None,
|
2343
|
+
'tierBased': None,
|
2017
2344
|
}
|
2018
2345
|
|
2019
|
-
def fetch_trading_fee(self, symbol: str, params={}):
|
2346
|
+
def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
|
2020
2347
|
"""
|
2021
2348
|
fetch the trading fees for a market
|
2022
2349
|
:param str symbol: unified market symbol
|
@@ -2027,7 +2354,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2027
2354
|
market = self.market(symbol)
|
2028
2355
|
if not market['spot']:
|
2029
2356
|
raise NotSupported(self.id + ' fetchTradingFee() does not support ' + market['type'] + ' orders, only spot orders are accepted')
|
2030
|
-
request = {
|
2357
|
+
request: dict = {
|
2031
2358
|
'symbol': market['id'],
|
2032
2359
|
}
|
2033
2360
|
response = self.privateGetSpotV1TradeFee(self.extend(request, params))
|
@@ -2043,12 +2370,12 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2043
2370
|
# }
|
2044
2371
|
# }
|
2045
2372
|
#
|
2046
|
-
data = self.
|
2373
|
+
data = self.safe_dict(response, 'data', {})
|
2047
2374
|
return self.parse_trading_fee(data)
|
2048
2375
|
|
2049
|
-
def parse_order(self, order, market: Market = None) -> Order:
|
2376
|
+
def parse_order(self, order: dict, market: Market = None) -> Order:
|
2050
2377
|
#
|
2051
|
-
# createOrder
|
2378
|
+
# createOrder, editOrder
|
2052
2379
|
#
|
2053
2380
|
# {
|
2054
2381
|
# "order_id": 2707217580
|
@@ -2148,7 +2475,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2148
2475
|
trailingActivationPrice = self.safe_number(order, 'activation_price')
|
2149
2476
|
return self.safe_order({
|
2150
2477
|
'id': id,
|
2151
|
-
'clientOrderId': self.
|
2478
|
+
'clientOrderId': self.safe_string_2(order, 'client_order_id', 'clientOrderId'),
|
2152
2479
|
'info': order,
|
2153
2480
|
'timestamp': timestamp,
|
2154
2481
|
'datetime': self.iso8601(timestamp),
|
@@ -2159,7 +2486,6 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2159
2486
|
'postOnly': postOnly,
|
2160
2487
|
'side': self.parse_order_side(self.safe_string(order, 'side')),
|
2161
2488
|
'price': self.omit_zero(priceString),
|
2162
|
-
'stopPrice': trailingActivationPrice,
|
2163
2489
|
'triggerPrice': trailingActivationPrice,
|
2164
2490
|
'amount': self.omit_zero(self.safe_string(order, 'size')),
|
2165
2491
|
'cost': self.safe_string_2(order, 'filled_notional', 'filledNotional'),
|
@@ -2172,7 +2498,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2172
2498
|
}, market)
|
2173
2499
|
|
2174
2500
|
def parse_order_side(self, side):
|
2175
|
-
sides = {
|
2501
|
+
sides: dict = {
|
2176
2502
|
'1': 'buy',
|
2177
2503
|
'2': 'buy',
|
2178
2504
|
'3': 'sell',
|
@@ -2181,7 +2507,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2181
2507
|
return self.safe_string(sides, side, side)
|
2182
2508
|
|
2183
2509
|
def parse_order_status_by_type(self, type, status):
|
2184
|
-
statusesByType = {
|
2510
|
+
statusesByType: dict = {
|
2185
2511
|
'spot': {
|
2186
2512
|
'1': 'rejected', # Order failure
|
2187
2513
|
'2': 'open', # Placing order
|
@@ -2202,13 +2528,15 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2202
2528
|
'4': 'closed', # Completed
|
2203
2529
|
},
|
2204
2530
|
}
|
2205
|
-
statuses = self.
|
2531
|
+
statuses = self.safe_dict(statusesByType, type, {})
|
2206
2532
|
return self.safe_string(statuses, status, status)
|
2207
2533
|
|
2208
2534
|
def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
|
2209
2535
|
"""
|
2210
2536
|
create a market buy order by providing the symbol and cost
|
2211
|
-
|
2537
|
+
|
2538
|
+
https://developer-pro.bitmart.com/en/spot/#new-order-v2-signed
|
2539
|
+
|
2212
2540
|
:param str symbol: unified symbol of the market to create an order in
|
2213
2541
|
:param float cost: how much you want to trade in units of the quote currency
|
2214
2542
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -2224,15 +2552,19 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2224
2552
|
def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
2225
2553
|
"""
|
2226
2554
|
create a trade order
|
2227
|
-
|
2228
|
-
|
2229
|
-
|
2230
|
-
|
2555
|
+
|
2556
|
+
https://developer-pro.bitmart.com/en/spot/#new-order-v2-signed
|
2557
|
+
https://developer-pro.bitmart.com/en/spot/#place-margin-order
|
2558
|
+
https://developer-pro.bitmart.com/en/futures/#submit-order-signed
|
2559
|
+
https://developer-pro.bitmart.com/en/futures/#submit-plan-order-signed
|
2560
|
+
https://developer-pro.bitmart.com/en/futuresv2/#submit-plan-order-signed
|
2561
|
+
https://developer-pro.bitmart.com/en/futuresv2/#submit-tp-or-sl-order-signed
|
2562
|
+
|
2231
2563
|
:param str symbol: unified symbol of the market to create an order in
|
2232
2564
|
:param str type: 'market', 'limit' or 'trailing' for swap markets only
|
2233
2565
|
:param str side: 'buy' or 'sell'
|
2234
2566
|
:param float amount: how much of currency you want to trade in units of base currency
|
2235
|
-
:param float [price]: the price at which the order is to be
|
2567
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
2236
2568
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2237
2569
|
:param str [params.marginMode]: 'cross' or 'isolated'
|
2238
2570
|
:param str [params.leverage]: *swap only* leverage level
|
@@ -2245,6 +2577,9 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2245
2577
|
:param int [params.activation_price_type]: *swap trailing order only* 1: last price, 2: fair price, default is 1
|
2246
2578
|
:param str [params.trailingPercent]: *swap only* the percent to trail away from the current market price, min 0.1 max 5
|
2247
2579
|
:param str [params.trailingTriggerPrice]: *swap only* the price to trigger a trailing order, default uses the price argument
|
2580
|
+
:param str [params.stopLossPrice]: *swap only* the price to trigger a stop-loss order
|
2581
|
+
:param str [params.takeProfitPrice]: *swap only* the price to trigger a take-profit order
|
2582
|
+
:param int [params.plan_category]: *swap tp/sl only* 1: tp/sl, 2: position tp/sl, default is 1
|
2248
2583
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2249
2584
|
"""
|
2250
2585
|
self.load_markets()
|
@@ -2252,6 +2587,10 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2252
2587
|
result = self.handle_margin_mode_and_params('createOrder', params)
|
2253
2588
|
marginMode = self.safe_string(result, 0)
|
2254
2589
|
triggerPrice = self.safe_string_n(params, ['triggerPrice', 'stopPrice', 'trigger_price'])
|
2590
|
+
stopLossPrice = self.safe_string(params, 'stopLossPrice')
|
2591
|
+
takeProfitPrice = self.safe_string(params, 'takeProfitPrice')
|
2592
|
+
isStopLoss = stopLossPrice is not None
|
2593
|
+
isTakeProfit = takeProfitPrice is not None
|
2255
2594
|
isTriggerOrder = triggerPrice is not None
|
2256
2595
|
response = None
|
2257
2596
|
if market['spot']:
|
@@ -2264,6 +2603,8 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2264
2603
|
swapRequest = self.create_swap_order_request(symbol, type, side, amount, price, params)
|
2265
2604
|
if isTriggerOrder:
|
2266
2605
|
response = self.privatePostContractPrivateSubmitPlanOrder(swapRequest)
|
2606
|
+
elif isStopLoss or isTakeProfit:
|
2607
|
+
response = self.privatePostContractPrivateSubmitTpSlOrder(swapRequest)
|
2267
2608
|
else:
|
2268
2609
|
response = self.privatePostContractPrivateSubmitOrder(swapRequest)
|
2269
2610
|
#
|
@@ -2281,7 +2622,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2281
2622
|
# swap
|
2282
2623
|
# {"code":1000,"message":"Ok","data":{"order_id":231116359426639,"price":"market price"},"trace":"7f9c94e10f9d4513bc08a7bfc2a5559a.62.16996369620521911"}
|
2283
2624
|
#
|
2284
|
-
data = self.
|
2625
|
+
data = self.safe_dict(response, 'data', {})
|
2285
2626
|
order = self.parse_order(data, market)
|
2286
2627
|
order['type'] = type
|
2287
2628
|
order['side'] = side
|
@@ -2289,17 +2630,82 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2289
2630
|
order['price'] = price
|
2290
2631
|
return order
|
2291
2632
|
|
2633
|
+
def create_orders(self, orders: List[OrderRequest], params={}):
|
2634
|
+
"""
|
2635
|
+
create a list of trade orders
|
2636
|
+
|
2637
|
+
https://developer-pro.bitmart.com/en/spot/#new-batch-order-v4-signed
|
2638
|
+
|
2639
|
+
:param Array orders: list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
|
2640
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2641
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2642
|
+
"""
|
2643
|
+
self.load_markets()
|
2644
|
+
ordersRequests = []
|
2645
|
+
symbol = None
|
2646
|
+
market = None
|
2647
|
+
for i in range(0, len(orders)):
|
2648
|
+
rawOrder = orders[i]
|
2649
|
+
marketId = self.safe_string(rawOrder, 'symbol')
|
2650
|
+
market = self.market(marketId)
|
2651
|
+
if not market['spot']:
|
2652
|
+
raise NotSupported(self.id + ' createOrders() supports spot orders only')
|
2653
|
+
if symbol is None:
|
2654
|
+
symbol = marketId
|
2655
|
+
else:
|
2656
|
+
if symbol != marketId:
|
2657
|
+
raise BadRequest(self.id + ' createOrders() requires all orders to have the same symbol')
|
2658
|
+
type = self.safe_string(rawOrder, 'type')
|
2659
|
+
side = self.safe_string(rawOrder, 'side')
|
2660
|
+
amount = self.safe_value(rawOrder, 'amount')
|
2661
|
+
price = self.safe_value(rawOrder, 'price')
|
2662
|
+
orderParams = self.safe_dict(rawOrder, 'params', {})
|
2663
|
+
orderRequest = self.create_spot_order_request(marketId, type, side, amount, price, orderParams)
|
2664
|
+
orderRequest = self.omit(orderRequest, ['symbol']) # not needed because it goes in the outter object
|
2665
|
+
ordersRequests.append(orderRequest)
|
2666
|
+
request: dict = {
|
2667
|
+
'symbol': market['id'],
|
2668
|
+
'orderParams': ordersRequests,
|
2669
|
+
}
|
2670
|
+
response = self.privatePostSpotV4BatchOrders(request)
|
2671
|
+
#
|
2672
|
+
# {
|
2673
|
+
# "message": "OK",
|
2674
|
+
# "code": 1000,
|
2675
|
+
# "trace": "5fc697fb817a4b5396284786a9b2609a.263.17022620476480263",
|
2676
|
+
# "data": {
|
2677
|
+
# "code": 0,
|
2678
|
+
# "msg": "success",
|
2679
|
+
# "data": {
|
2680
|
+
# "orderIds": [
|
2681
|
+
# "212751308355553320"
|
2682
|
+
# ]
|
2683
|
+
# }
|
2684
|
+
# }
|
2685
|
+
# }
|
2686
|
+
#
|
2687
|
+
data = self.safe_dict(response, 'data', {})
|
2688
|
+
innderData = self.safe_dict(data, 'data', {})
|
2689
|
+
orderIds = self.safe_list(innderData, 'orderIds', [])
|
2690
|
+
parsedOrders = []
|
2691
|
+
for i in range(0, len(orderIds)):
|
2692
|
+
orderId = orderIds[i]
|
2693
|
+
order = self.safe_order({'id': orderId}, market)
|
2694
|
+
parsedOrders.append(order)
|
2695
|
+
return parsedOrders
|
2696
|
+
|
2292
2697
|
def create_swap_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
2293
2698
|
"""
|
2294
|
-
|
2699
|
+
@ignore
|
2295
2700
|
create a trade order
|
2296
|
-
|
2297
|
-
|
2701
|
+
https://developer-pro.bitmart.com/en/futuresv2/#submit-order-signed
|
2702
|
+
https://developer-pro.bitmart.com/en/futuresv2/#submit-plan-order-signed
|
2703
|
+
https://developer-pro.bitmart.com/en/futuresv2/#submit-tp-or-sl-order-signed
|
2298
2704
|
:param str symbol: unified symbol of the market to create an order in
|
2299
|
-
:param str type: 'market', 'limit' or '
|
2705
|
+
:param str type: 'market', 'limit', 'trailing', 'stop_loss', or 'take_profit'
|
2300
2706
|
:param str side: 'buy' or 'sell'
|
2301
2707
|
:param float amount: how much of currency you want to trade in units of base currency
|
2302
|
-
:param float [price]: the price at which the order is to be
|
2708
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
2303
2709
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2304
2710
|
:param int [params.leverage]: leverage level
|
2305
2711
|
:param boolean [params.reduceOnly]: *swap only* reduce only
|
@@ -2311,10 +2717,21 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2311
2717
|
:param int [params.activation_price_type]: *swap trailing order only* 1: last price, 2: fair price, default is 1
|
2312
2718
|
:param str [params.trailingPercent]: *swap only* the percent to trail away from the current market price, min 0.1 max 5
|
2313
2719
|
:param str [params.trailingTriggerPrice]: *swap only* the price to trigger a trailing order, default uses the price argument
|
2720
|
+
:param str [params.stopLossPrice]: *swap only* the price to trigger a stop-loss order
|
2721
|
+
:param str [params.takeProfitPrice]: *swap only* the price to trigger a take-profit order
|
2722
|
+
:param int [params.plan_category]: *swap tp/sl only* 1: tp/sl, 2: position tp/sl, default is 1
|
2314
2723
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2315
2724
|
"""
|
2316
2725
|
market = self.market(symbol)
|
2317
|
-
|
2726
|
+
stopLossPrice = self.safe_string(params, 'stopLossPrice')
|
2727
|
+
takeProfitPrice = self.safe_string(params, 'takeProfitPrice')
|
2728
|
+
isStopLoss = stopLossPrice is not None
|
2729
|
+
isTakeProfit = takeProfitPrice is not None
|
2730
|
+
if isStopLoss:
|
2731
|
+
type = 'stop_loss'
|
2732
|
+
elif isTakeProfit:
|
2733
|
+
type = 'take_profit'
|
2734
|
+
request: dict = {
|
2318
2735
|
'symbol': market['id'],
|
2319
2736
|
'type': type,
|
2320
2737
|
'size': int(self.amount_to_precision(symbol, amount)),
|
@@ -2323,7 +2740,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2323
2740
|
mode = self.safe_integer(params, 'mode') # only for swap
|
2324
2741
|
isMarketOrder = type == 'market'
|
2325
2742
|
postOnly = None
|
2326
|
-
reduceOnly = self.
|
2743
|
+
reduceOnly = self.safe_bool(params, 'reduceOnly')
|
2327
2744
|
isExchangeSpecificPo = (mode == 4)
|
2328
2745
|
postOnly, params = self.handle_post_only(isMarketOrder, isExchangeSpecificPo, params)
|
2329
2746
|
ioc = ((timeInForce == 'IOC') or (mode == 3))
|
@@ -2348,7 +2765,8 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2348
2765
|
request['activation_price'] = self.price_to_precision(symbol, trailingTriggerPrice)
|
2349
2766
|
request['activation_price_type'] = self.safe_integer(params, 'activation_price_type', 1)
|
2350
2767
|
if isTriggerOrder:
|
2351
|
-
|
2768
|
+
if isLimitOrder or price is not None:
|
2769
|
+
request['executive_price'] = self.price_to_precision(symbol, price)
|
2352
2770
|
request['trigger_price'] = self.price_to_precision(symbol, triggerPrice)
|
2353
2771
|
request['price_type'] = self.safe_integer(params, 'price_type', 1)
|
2354
2772
|
if side == 'buy':
|
@@ -2361,6 +2779,18 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2361
2779
|
request['price_way'] = 1
|
2362
2780
|
else:
|
2363
2781
|
request['price_way'] = 2
|
2782
|
+
marginMode = None
|
2783
|
+
marginMode, params = self.handle_margin_mode_and_params('createOrder', params, 'cross')
|
2784
|
+
if isStopLoss or isTakeProfit:
|
2785
|
+
reduceOnly = True
|
2786
|
+
request['price_type'] = self.safe_integer(params, 'price_type', 1)
|
2787
|
+
request['executive_price'] = self.price_to_precision(symbol, price)
|
2788
|
+
if isStopLoss:
|
2789
|
+
request['trigger_price'] = self.price_to_precision(symbol, stopLossPrice)
|
2790
|
+
else:
|
2791
|
+
request['trigger_price'] = self.price_to_precision(symbol, takeProfitPrice)
|
2792
|
+
else:
|
2793
|
+
request['open_type'] = marginMode
|
2364
2794
|
if side == 'buy':
|
2365
2795
|
if reduceOnly:
|
2366
2796
|
request['side'] = 2 # buy close short
|
@@ -2371,35 +2801,35 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2371
2801
|
request['side'] = 3 # sell close long
|
2372
2802
|
else:
|
2373
2803
|
request['side'] = 4 # sell open short
|
2374
|
-
marginMode = None
|
2375
|
-
marginMode, params = self.handle_margin_mode_and_params('createOrder', params, 'cross')
|
2376
|
-
request['open_type'] = marginMode
|
2377
2804
|
clientOrderId = self.safe_string(params, 'clientOrderId')
|
2378
2805
|
if clientOrderId is not None:
|
2379
2806
|
params = self.omit(params, 'clientOrderId')
|
2380
2807
|
request['client_order_id'] = clientOrderId
|
2381
|
-
leverage = self.safe_integer(params, 'leverage'
|
2382
|
-
params = self.omit(params, ['timeInForce', 'postOnly', 'reduceOnly', 'leverage', 'trailingTriggerPrice', 'trailingPercent', 'triggerPrice', 'stopPrice'])
|
2383
|
-
|
2808
|
+
leverage = self.safe_integer(params, 'leverage')
|
2809
|
+
params = self.omit(params, ['timeInForce', 'postOnly', 'reduceOnly', 'leverage', 'trailingTriggerPrice', 'trailingPercent', 'triggerPrice', 'stopPrice', 'stopLossPrice', 'takeProfitPrice'])
|
2810
|
+
if leverage is not None:
|
2811
|
+
request['leverage'] = self.number_to_string(leverage)
|
2812
|
+
elif isTriggerOrder:
|
2813
|
+
request['leverage'] = '1' # for plan orders leverage is required, if not available default to 1
|
2384
2814
|
return self.extend(request, params)
|
2385
2815
|
|
2386
2816
|
def create_spot_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
|
2387
2817
|
"""
|
2388
|
-
|
2818
|
+
@ignore
|
2389
2819
|
create a spot order request
|
2390
|
-
|
2391
|
-
|
2820
|
+
https://developer-pro.bitmart.com/en/spot/#place-spot-order
|
2821
|
+
https://developer-pro.bitmart.com/en/spot/#place-margin-order
|
2392
2822
|
:param str symbol: unified symbol of the market to create an order in
|
2393
2823
|
:param str type: 'market' or 'limit'
|
2394
2824
|
:param str side: 'buy' or 'sell'
|
2395
2825
|
:param float amount: how much of currency you want to trade in units of base currency
|
2396
|
-
:param float [price]: the price at which the order is to be
|
2826
|
+
:param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
|
2397
2827
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2398
2828
|
:param str [params.marginMode]: 'cross' or 'isolated'
|
2399
2829
|
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2400
2830
|
"""
|
2401
2831
|
market = self.market(symbol)
|
2402
|
-
request = {
|
2832
|
+
request: dict = {
|
2403
2833
|
'symbol': market['id'],
|
2404
2834
|
'side': side,
|
2405
2835
|
'type': type,
|
@@ -2422,7 +2852,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2422
2852
|
elif isMarketOrder:
|
2423
2853
|
# for market buy it requires the amount of quote currency to spend
|
2424
2854
|
if side == 'buy':
|
2425
|
-
notional = self.
|
2855
|
+
notional = self.safe_string_2(params, 'cost', 'notional')
|
2426
2856
|
params = self.omit(params, 'cost')
|
2427
2857
|
createMarketBuyOrderRequiresPrice = True
|
2428
2858
|
createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', True)
|
@@ -2432,9 +2862,9 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2432
2862
|
else:
|
2433
2863
|
amountString = self.number_to_string(amount)
|
2434
2864
|
priceString = self.number_to_string(price)
|
2435
|
-
notional =
|
2865
|
+
notional = Precise.string_mul(amountString, priceString)
|
2436
2866
|
else:
|
2437
|
-
notional = amount if (notional is None) else notional
|
2867
|
+
notional = self.number_to_string(amount) if (notional is None) else notional
|
2438
2868
|
request['notional'] = self.decimal_to_precision(notional, TRUNCATE, market['precision']['price'], self.precisionMode)
|
2439
2869
|
elif side == 'sell':
|
2440
2870
|
request['size'] = self.amount_to_precision(symbol, amount)
|
@@ -2442,27 +2872,35 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2442
2872
|
request['type'] = 'limit_maker'
|
2443
2873
|
if ioc:
|
2444
2874
|
request['type'] = 'ioc'
|
2875
|
+
clientOrderId = self.safe_string(params, 'clientOrderId')
|
2876
|
+
if clientOrderId is not None:
|
2877
|
+
params = self.omit(params, 'clientOrderId')
|
2878
|
+
request['client_order_id'] = clientOrderId
|
2445
2879
|
return self.extend(request, params)
|
2446
2880
|
|
2447
2881
|
def cancel_order(self, id: str, symbol: Str = None, params={}):
|
2448
2882
|
"""
|
2449
2883
|
cancels an open order
|
2450
|
-
|
2451
|
-
|
2452
|
-
|
2453
|
-
|
2884
|
+
|
2885
|
+
https://developer-pro.bitmart.com/en/futures/#cancel-order-signed
|
2886
|
+
https://developer-pro.bitmart.com/en/spot/#cancel-order-v3-signed
|
2887
|
+
https://developer-pro.bitmart.com/en/futures/#cancel-plan-order-signed
|
2888
|
+
https://developer-pro.bitmart.com/en/futures/#cancel-plan-order-signed
|
2889
|
+
https://developer-pro.bitmart.com/en/futures/#cancel-order-signed
|
2890
|
+
https://developer-pro.bitmart.com/en/futures/#cancel-plan-order-signed
|
2891
|
+
|
2454
2892
|
:param str id: order id
|
2455
2893
|
:param str symbol: unified symbol of the market the order was made in
|
2456
2894
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2457
2895
|
:param str [params.clientOrderId]: *spot only* the client order id of the order to cancel
|
2458
|
-
:param boolean [params.
|
2896
|
+
:param boolean [params.trigger]: *swap only* whether the order is a trigger order
|
2459
2897
|
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2460
2898
|
"""
|
2461
2899
|
if symbol is None:
|
2462
2900
|
raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol argument')
|
2463
2901
|
self.load_markets()
|
2464
2902
|
market = self.market(symbol)
|
2465
|
-
request = {
|
2903
|
+
request: dict = {
|
2466
2904
|
'symbol': market['id'],
|
2467
2905
|
}
|
2468
2906
|
clientOrderId = self.safe_string_2(params, 'clientOrderId', 'client_order_id')
|
@@ -2475,9 +2913,9 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2475
2913
|
if market['spot']:
|
2476
2914
|
response = self.privatePostSpotV3CancelOrder(self.extend(request, params))
|
2477
2915
|
else:
|
2478
|
-
|
2916
|
+
trigger = self.safe_bool_2(params, 'stop', 'trigger')
|
2479
2917
|
params = self.omit(params, ['stop', 'trigger'])
|
2480
|
-
if not
|
2918
|
+
if not trigger:
|
2481
2919
|
response = self.privatePostContractPrivateCancelOrder(self.extend(request, params))
|
2482
2920
|
else:
|
2483
2921
|
response = self.privatePostContractPrivateCancelPlanOrder(self.extend(request, params))
|
@@ -2508,7 +2946,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2508
2946
|
return response
|
2509
2947
|
data = self.safe_value(response, 'data')
|
2510
2948
|
if data is True:
|
2511
|
-
return self.
|
2949
|
+
return self.safe_order({'id': id}, market)
|
2512
2950
|
succeeded = self.safe_value(data, 'succeed')
|
2513
2951
|
if succeeded is not None:
|
2514
2952
|
id = self.safe_string(succeeded, 0)
|
@@ -2518,21 +2956,81 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2518
2956
|
result = self.safe_value(data, 'result')
|
2519
2957
|
if not result:
|
2520
2958
|
raise InvalidOrder(self.id + ' cancelOrder() ' + symbol + ' order id ' + id + ' is filled or canceled')
|
2521
|
-
order = self.
|
2522
|
-
return
|
2959
|
+
order = self.safe_order({'id': id, 'symbol': market['symbol'], 'info': {}}, market)
|
2960
|
+
return order
|
2961
|
+
|
2962
|
+
def cancel_orders(self, ids: List[str], symbol: Str = None, params={}):
|
2963
|
+
"""
|
2964
|
+
cancel multiple orders
|
2965
|
+
|
2966
|
+
https://developer-pro.bitmart.com/en/spot/#cancel-batch-order-v4-signed
|
2967
|
+
|
2968
|
+
:param str[] ids: order ids
|
2969
|
+
:param str symbol: unified symbol of the market the order was made in
|
2970
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2971
|
+
:param str[] [params.clientOrderIds]: client order ids
|
2972
|
+
:returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
2973
|
+
"""
|
2974
|
+
if symbol is None:
|
2975
|
+
raise ArgumentsRequired(self.id + ' cancelOrders() requires a symbol argument')
|
2976
|
+
self.load_markets()
|
2977
|
+
market = self.market(symbol)
|
2978
|
+
if not market['spot']:
|
2979
|
+
raise NotSupported(self.id + ' cancelOrders() does not support ' + market['type'] + ' orders, only spot orders are accepted')
|
2980
|
+
clientOrderIds = self.safe_list(params, 'clientOrderIds')
|
2981
|
+
params = self.omit(params, ['clientOrderIds'])
|
2982
|
+
request: dict = {
|
2983
|
+
'symbol': market['id'],
|
2984
|
+
}
|
2985
|
+
if clientOrderIds is not None:
|
2986
|
+
request['clientOrderIds'] = clientOrderIds
|
2987
|
+
else:
|
2988
|
+
request['orderIds'] = ids
|
2989
|
+
response = self.privatePostSpotV4CancelOrders(self.extend(request, params))
|
2990
|
+
#
|
2991
|
+
# {
|
2992
|
+
# "message": "OK",
|
2993
|
+
# "code": 1000,
|
2994
|
+
# "trace": "c4edbce860164203954f7c3c81d60fc6.309.17022669632770001",
|
2995
|
+
# "data": {
|
2996
|
+
# "successIds": [
|
2997
|
+
# "213055379155243012"
|
2998
|
+
# ],
|
2999
|
+
# "failIds": [],
|
3000
|
+
# "totalCount": 1,
|
3001
|
+
# "successCount": 1,
|
3002
|
+
# "failedCount": 0
|
3003
|
+
# }
|
3004
|
+
# }
|
3005
|
+
#
|
3006
|
+
data = self.safe_dict(response, 'data', {})
|
3007
|
+
allOrders = []
|
3008
|
+
successIds = self.safe_list(data, 'successIds', [])
|
3009
|
+
for i in range(0, len(successIds)):
|
3010
|
+
id = successIds[i]
|
3011
|
+
allOrders.append(self.safe_order({'id': id, 'status': 'canceled'}, market))
|
3012
|
+
failIds = self.safe_list(data, 'failIds', [])
|
3013
|
+
for i in range(0, len(failIds)):
|
3014
|
+
id = failIds[i]
|
3015
|
+
allOrders.append(self.safe_order({'id': id, 'status': 'failed'}, market))
|
3016
|
+
return allOrders
|
2523
3017
|
|
2524
3018
|
def cancel_all_orders(self, symbol: Str = None, params={}):
|
2525
3019
|
"""
|
2526
3020
|
cancel all open orders in a market
|
2527
|
-
|
2528
|
-
|
3021
|
+
|
3022
|
+
https://developer-pro.bitmart.com/en/spot/#cancel-all-orders
|
3023
|
+
https://developer-pro.bitmart.com/en/spot/#new-batch-order-v4-signed
|
3024
|
+
https://developer-pro.bitmart.com/en/futures/#cancel-all-orders-signed
|
3025
|
+
https://developer-pro.bitmart.com/en/futuresv2/#cancel-all-orders-signed
|
3026
|
+
|
2529
3027
|
:param str symbol: unified market symbol of the market to cancel orders in
|
2530
3028
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2531
3029
|
:param str [params.side]: *spot only* 'buy' or 'sell'
|
2532
3030
|
:returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
|
2533
3031
|
"""
|
2534
3032
|
self.load_markets()
|
2535
|
-
request = {}
|
3033
|
+
request: dict = {}
|
2536
3034
|
market = None
|
2537
3035
|
if symbol is not None:
|
2538
3036
|
market = self.market(symbol)
|
@@ -2541,7 +3039,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2541
3039
|
type = None
|
2542
3040
|
type, params = self.handle_market_type_and_params('cancelAllOrders', market, params)
|
2543
3041
|
if type == 'spot':
|
2544
|
-
response = self.
|
3042
|
+
response = self.privatePostSpotV4CancelAll(self.extend(request, params))
|
2545
3043
|
elif type == 'swap':
|
2546
3044
|
if symbol is None:
|
2547
3045
|
raise ArgumentsRequired(self.id + ' cancelAllOrders() requires a symbol argument')
|
@@ -2573,7 +3071,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2573
3071
|
market = self.market(symbol)
|
2574
3072
|
if not market['spot']:
|
2575
3073
|
raise NotSupported(self.id + ' fetchOrdersByStatus() does not support ' + market['type'] + ' orders, only spot orders are accepted')
|
2576
|
-
request = {
|
3074
|
+
request: dict = {
|
2577
3075
|
'symbol': market['id'],
|
2578
3076
|
'offset': 1, # max offset * limit < 500
|
2579
3077
|
'N': 100, # max limit is 100
|
@@ -2615,15 +3113,17 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2615
3113
|
# }
|
2616
3114
|
# }
|
2617
3115
|
#
|
2618
|
-
data = self.
|
2619
|
-
orders = self.
|
3116
|
+
data = self.safe_dict(response, 'data', {})
|
3117
|
+
orders = self.safe_list(data, 'orders', [])
|
2620
3118
|
return self.parse_orders(orders, market, since, limit)
|
2621
3119
|
|
2622
3120
|
def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
2623
3121
|
"""
|
2624
|
-
|
2625
|
-
|
2626
|
-
|
3122
|
+
|
3123
|
+
https://developer-pro.bitmart.com/en/spot/#current-open-orders-v4-signed
|
3124
|
+
https://developer-pro.bitmart.com/en/futures/#get-all-open-orders-keyed
|
3125
|
+
https://developer-pro.bitmart.com/en/futures/#get-all-current-plan-orders-keyed
|
3126
|
+
|
2627
3127
|
fetch all unfilled currently open orders
|
2628
3128
|
:param str symbol: unified market symbol
|
2629
3129
|
:param int [since]: the earliest time in ms to fetch open orders for
|
@@ -2640,16 +3140,16 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2640
3140
|
"""
|
2641
3141
|
self.load_markets()
|
2642
3142
|
market = None
|
2643
|
-
request = {}
|
3143
|
+
request: dict = {}
|
2644
3144
|
if symbol is not None:
|
2645
3145
|
market = self.market(symbol)
|
2646
3146
|
request['symbol'] = market['id']
|
2647
|
-
if limit is not None:
|
2648
|
-
request['limit'] = limit
|
2649
3147
|
type = None
|
2650
3148
|
response = None
|
2651
3149
|
type, params = self.handle_market_type_and_params('fetchOpenOrders', market, params)
|
2652
3150
|
if type == 'spot':
|
3151
|
+
if limit is not None:
|
3152
|
+
request['limit'] = min(limit, 200)
|
2653
3153
|
marginMode = None
|
2654
3154
|
marginMode, params = self.handle_margin_mode_and_params('fetchOpenOrders', params)
|
2655
3155
|
if marginMode == 'isolated':
|
@@ -2662,9 +3162,11 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2662
3162
|
request['endTime'] = until
|
2663
3163
|
response = self.privatePostSpotV4QueryOpenOrders(self.extend(request, params))
|
2664
3164
|
elif type == 'swap':
|
2665
|
-
|
3165
|
+
if limit is not None:
|
3166
|
+
request['limit'] = min(limit, 100)
|
3167
|
+
isTrigger = self.safe_bool_2(params, 'stop', 'trigger')
|
2666
3168
|
params = self.omit(params, ['stop', 'trigger'])
|
2667
|
-
if
|
3169
|
+
if isTrigger:
|
2668
3170
|
response = self.privateGetContractPrivateCurrentPlanOrder(self.extend(request, params))
|
2669
3171
|
else:
|
2670
3172
|
trailing = self.safe_bool(params, 'trailing', False)
|
@@ -2731,13 +3233,16 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2731
3233
|
# "trace": "7f9d94g10f9d4513bc08a7rfc3a5559a.71.16957022303515933"
|
2732
3234
|
# }
|
2733
3235
|
#
|
2734
|
-
data = self.
|
3236
|
+
data = self.safe_list(response, 'data', [])
|
2735
3237
|
return self.parse_orders(data, market, since, limit)
|
2736
3238
|
|
2737
3239
|
def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
|
2738
3240
|
"""
|
2739
|
-
|
2740
|
-
|
3241
|
+
|
3242
|
+
https://developer-pro.bitmart.com/en/spot/#account-orders-v4-signed
|
3243
|
+
https://developer-pro.bitmart.com/en/futures/#get-order-history-keyed
|
3244
|
+
https://developer-pro.bitmart.com/en/futuresv2/#get-order-history-keyed
|
3245
|
+
|
2741
3246
|
fetches information on multiple closed orders made by the user
|
2742
3247
|
:param str symbol: unified market symbol of the market orders were made in
|
2743
3248
|
:param int [since]: the earliest time in ms to fetch orders for
|
@@ -2749,7 +3254,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2749
3254
|
"""
|
2750
3255
|
self.load_markets()
|
2751
3256
|
market = None
|
2752
|
-
request = {}
|
3257
|
+
request: dict = {}
|
2753
3258
|
if symbol is not None:
|
2754
3259
|
market = self.market(symbol)
|
2755
3260
|
request['symbol'] = market['id']
|
@@ -2758,12 +3263,8 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2758
3263
|
if type != 'spot':
|
2759
3264
|
if symbol is None:
|
2760
3265
|
raise ArgumentsRequired(self.id + ' fetchClosedOrders() requires a symbol argument')
|
2761
|
-
marginMode = None
|
2762
|
-
marginMode, params = self.handle_margin_mode_and_params('fetchClosedOrders', params)
|
2763
|
-
if marginMode == 'isolated':
|
2764
|
-
request['orderMode'] = 'iso_margin'
|
2765
|
-
startTimeKey = 'startTime' if (type == 'spot') else 'start_time'
|
2766
3266
|
if since is not None:
|
3267
|
+
startTimeKey = 'startTime' if (type == 'spot') else 'start_time'
|
2767
3268
|
request[startTimeKey] = since
|
2768
3269
|
endTimeKey = 'endTime' if (type == 'spot') else 'end_time'
|
2769
3270
|
until = self.safe_integer_2(params, 'until', endTimeKey)
|
@@ -2772,10 +3273,14 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2772
3273
|
request[endTimeKey] = until
|
2773
3274
|
response = None
|
2774
3275
|
if type == 'spot':
|
3276
|
+
marginMode = None
|
3277
|
+
marginMode, params = self.handle_margin_mode_and_params('fetchClosedOrders', params)
|
3278
|
+
if marginMode == 'isolated':
|
3279
|
+
request['orderMode'] = 'iso_margin'
|
2775
3280
|
response = self.privatePostSpotV4QueryHistoryOrders(self.extend(request, params))
|
2776
3281
|
else:
|
2777
3282
|
response = self.privateGetContractPrivateOrderHistory(self.extend(request, params))
|
2778
|
-
data = self.
|
3283
|
+
data = self.safe_list(response, 'data', [])
|
2779
3284
|
return self.parse_orders(data, market, since, limit)
|
2780
3285
|
|
2781
3286
|
def fetch_canceled_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
@@ -2792,9 +3297,12 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2792
3297
|
def fetch_order(self, id: str, symbol: Str = None, params={}):
|
2793
3298
|
"""
|
2794
3299
|
fetches information on an order made by the user
|
2795
|
-
|
2796
|
-
|
2797
|
-
|
3300
|
+
|
3301
|
+
https://developer-pro.bitmart.com/en/spot/#query-order-by-id-v4-signed
|
3302
|
+
https://developer-pro.bitmart.com/en/spot/#query-order-by-clientorderid-v4-signed
|
3303
|
+
https://developer-pro.bitmart.com/en/futures/#get-order-detail-keyed
|
3304
|
+
https://developer-pro.bitmart.com/en/futuresv2/#get-order-detail-keyed
|
3305
|
+
|
2798
3306
|
:param str id: the id of the order
|
2799
3307
|
:param str symbol: unified symbol of the market the order was made in
|
2800
3308
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -2804,7 +3312,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2804
3312
|
:returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
2805
3313
|
"""
|
2806
3314
|
self.load_markets()
|
2807
|
-
request = {}
|
3315
|
+
request: dict = {}
|
2808
3316
|
type = None
|
2809
3317
|
market = None
|
2810
3318
|
response = None
|
@@ -2882,26 +3390,28 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2882
3390
|
# "trace": "4cad855075664097af6ba5257c47605d.63.14957831547451715"
|
2883
3391
|
# }
|
2884
3392
|
#
|
2885
|
-
data = self.
|
3393
|
+
data = self.safe_dict(response, 'data', {})
|
2886
3394
|
return self.parse_order(data, market)
|
2887
3395
|
|
2888
|
-
def fetch_deposit_address(self, code: str, params={}):
|
3396
|
+
def fetch_deposit_address(self, code: str, params={}) -> DepositAddress:
|
2889
3397
|
"""
|
2890
3398
|
fetch the deposit address for a currency associated with self account
|
2891
|
-
|
3399
|
+
|
3400
|
+
https://developer-pro.bitmart.com/en/spot/#deposit-address-keyed
|
3401
|
+
|
2892
3402
|
:param str code: unified currency code
|
2893
3403
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
2894
3404
|
:returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
|
2895
3405
|
"""
|
2896
3406
|
self.load_markets()
|
2897
3407
|
currency = self.currency(code)
|
2898
|
-
request = {
|
3408
|
+
request: dict = {
|
2899
3409
|
'currency': currency['id'],
|
2900
3410
|
}
|
2901
3411
|
if code == 'USDT':
|
2902
3412
|
defaultNetworks = self.safe_value(self.options, 'defaultNetworks')
|
2903
3413
|
defaultNetwork = self.safe_string_upper(defaultNetworks, code)
|
2904
|
-
networks = self.
|
3414
|
+
networks = self.safe_dict(self.options, 'networks', {})
|
2905
3415
|
networkInner = self.safe_string_upper(params, 'network', defaultNetwork) # self line allows the user to specify either ERC20 or ETH
|
2906
3416
|
networkInner = self.safe_string(networks, networkInner, networkInner) # handle ERC20>ETH alias
|
2907
3417
|
if networkInner is not None:
|
@@ -2921,10 +3431,10 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2921
3431
|
# }
|
2922
3432
|
# }
|
2923
3433
|
#
|
2924
|
-
data = self.
|
3434
|
+
data = self.safe_dict(response, 'data', {})
|
2925
3435
|
return self.parse_deposit_address(data, currency)
|
2926
3436
|
|
2927
|
-
def parse_deposit_address(self, depositAddress, currency=None):
|
3437
|
+
def parse_deposit_address(self, depositAddress, currency=None) -> DepositAddress:
|
2928
3438
|
#
|
2929
3439
|
# {
|
2930
3440
|
# currency: 'ETH',
|
@@ -2942,24 +3452,20 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2942
3452
|
parts = chain.split('-')
|
2943
3453
|
partsLength = len(parts)
|
2944
3454
|
networkId = self.safe_string(parts, partsLength - 1)
|
2945
|
-
|
3455
|
+
if networkId == self.safe_string(currency, 'name'):
|
3456
|
+
network = self.safe_string(currency, 'code')
|
3457
|
+
else:
|
3458
|
+
network = self.network_id_to_code(networkId)
|
2946
3459
|
self.check_address(address)
|
2947
3460
|
return {
|
2948
3461
|
'info': depositAddress,
|
2949
3462
|
'currency': self.safe_string(currency, 'code'),
|
3463
|
+
'network': network,
|
2950
3464
|
'address': address,
|
2951
3465
|
'tag': self.safe_string(depositAddress, 'address_memo'),
|
2952
|
-
'network': network,
|
2953
3466
|
}
|
2954
3467
|
|
2955
|
-
def
|
2956
|
-
name = self.safe_string(currency, 'name')
|
2957
|
-
if networkId == name:
|
2958
|
-
code = self.safe_string(currency, 'code')
|
2959
|
-
return code
|
2960
|
-
return self.network_id_to_code(networkId)
|
2961
|
-
|
2962
|
-
def withdraw(self, code: str, amount: float, address, tag=None, params={}):
|
3468
|
+
def withdraw(self, code: str, amount: float, address: str, tag=None, params={}) -> Transaction:
|
2963
3469
|
"""
|
2964
3470
|
make a withdrawal
|
2965
3471
|
:param str code: unified currency code
|
@@ -2973,7 +3479,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2973
3479
|
self.check_address(address)
|
2974
3480
|
self.load_markets()
|
2975
3481
|
currency = self.currency(code)
|
2976
|
-
request = {
|
3482
|
+
request: dict = {
|
2977
3483
|
'currency': currency['id'],
|
2978
3484
|
'amount': amount,
|
2979
3485
|
'destination': 'To Digital Address', # To Digital Address, To Binance, To OKEX
|
@@ -2984,7 +3490,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
2984
3490
|
if code == 'USDT':
|
2985
3491
|
defaultNetworks = self.safe_value(self.options, 'defaultNetworks')
|
2986
3492
|
defaultNetwork = self.safe_string_upper(defaultNetworks, code)
|
2987
|
-
networks = self.
|
3493
|
+
networks = self.safe_dict(self.options, 'networks', {})
|
2988
3494
|
network = self.safe_string_upper(params, 'network', defaultNetwork) # self line allows the user to specify either ERC20 or ETH
|
2989
3495
|
network = self.safe_string(networks, network, network) # handle ERC20>ETH alias
|
2990
3496
|
if network is not None:
|
@@ -3001,7 +3507,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3001
3507
|
# }
|
3002
3508
|
# }
|
3003
3509
|
#
|
3004
|
-
data = self.
|
3510
|
+
data = self.safe_dict(response, 'data', {})
|
3005
3511
|
transaction = self.parse_transaction(data, currency)
|
3006
3512
|
return self.extend(transaction, {
|
3007
3513
|
'code': code,
|
@@ -3013,7 +3519,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3013
3519
|
self.load_markets()
|
3014
3520
|
if limit is None:
|
3015
3521
|
limit = 50 # max 50
|
3016
|
-
request = {
|
3522
|
+
request: dict = {
|
3017
3523
|
'operation_type': type, # deposit or withdraw
|
3018
3524
|
'offset': 1,
|
3019
3525
|
'N': limit,
|
@@ -3025,7 +3531,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3025
3531
|
if code == 'USDT':
|
3026
3532
|
defaultNetworks = self.safe_value(self.options, 'defaultNetworks')
|
3027
3533
|
defaultNetwork = self.safe_string_upper(defaultNetworks, code)
|
3028
|
-
networks = self.
|
3534
|
+
networks = self.safe_dict(self.options, 'networks', {})
|
3029
3535
|
network = self.safe_string_upper(params, 'network', defaultNetwork) # self line allows the user to specify either ERC20 or ETH
|
3030
3536
|
network = self.safe_string(networks, network, network) # handle ERC20>ETH alias
|
3031
3537
|
if network is not None:
|
@@ -3057,8 +3563,8 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3057
3563
|
# }
|
3058
3564
|
# }
|
3059
3565
|
#
|
3060
|
-
data = self.
|
3061
|
-
records = self.
|
3566
|
+
data = self.safe_dict(response, 'data', {})
|
3567
|
+
records = self.safe_list(data, 'records', [])
|
3062
3568
|
return self.parse_transactions(records, currency, since, limit)
|
3063
3569
|
|
3064
3570
|
def fetch_deposit(self, id: str, code: Str = None, params={}):
|
@@ -3070,7 +3576,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3070
3576
|
:returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
|
3071
3577
|
"""
|
3072
3578
|
self.load_markets()
|
3073
|
-
request = {
|
3579
|
+
request: dict = {
|
3074
3580
|
'id': id,
|
3075
3581
|
}
|
3076
3582
|
response = self.privateGetAccountV1DepositWithdrawDetail(self.extend(request, params))
|
@@ -3096,8 +3602,8 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3096
3602
|
# }
|
3097
3603
|
# }
|
3098
3604
|
#
|
3099
|
-
data = self.
|
3100
|
-
record = self.
|
3605
|
+
data = self.safe_dict(response, 'data', {})
|
3606
|
+
record = self.safe_dict(data, 'record', {})
|
3101
3607
|
return self.parse_transaction(record)
|
3102
3608
|
|
3103
3609
|
def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
|
@@ -3120,7 +3626,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3120
3626
|
:returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
|
3121
3627
|
"""
|
3122
3628
|
self.load_markets()
|
3123
|
-
request = {
|
3629
|
+
request: dict = {
|
3124
3630
|
'id': id,
|
3125
3631
|
}
|
3126
3632
|
response = self.privateGetAccountV1DepositWithdrawDetail(self.extend(request, params))
|
@@ -3146,8 +3652,8 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3146
3652
|
# }
|
3147
3653
|
# }
|
3148
3654
|
#
|
3149
|
-
data = self.
|
3150
|
-
record = self.
|
3655
|
+
data = self.safe_dict(response, 'data', {})
|
3656
|
+
record = self.safe_dict(data, 'record', {})
|
3151
3657
|
return self.parse_transaction(record)
|
3152
3658
|
|
3153
3659
|
def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
|
@@ -3161,8 +3667,8 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3161
3667
|
"""
|
3162
3668
|
return self.fetch_transactions_by_type('withdraw', code, since, limit, params)
|
3163
3669
|
|
3164
|
-
def parse_transaction_status(self, status):
|
3165
|
-
statuses = {
|
3670
|
+
def parse_transaction_status(self, status: Str):
|
3671
|
+
statuses: dict = {
|
3166
3672
|
'0': 'pending', # Create
|
3167
3673
|
'1': 'pending', # Submitted, waiting for withdrawal
|
3168
3674
|
'2': 'pending', # Processing
|
@@ -3172,7 +3678,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3172
3678
|
}
|
3173
3679
|
return self.safe_string(statuses, status, status)
|
3174
3680
|
|
3175
|
-
def parse_transaction(self, transaction, currency: Currency = None) -> Transaction:
|
3681
|
+
def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
|
3176
3682
|
#
|
3177
3683
|
# withdraw
|
3178
3684
|
#
|
@@ -3247,7 +3753,9 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3247
3753
|
def repay_isolated_margin(self, symbol: str, code: str, amount, params={}):
|
3248
3754
|
"""
|
3249
3755
|
repay borrowed margin and interest
|
3250
|
-
|
3756
|
+
|
3757
|
+
https://developer-pro.bitmart.com/en/spot/#margin-repay-isolated
|
3758
|
+
|
3251
3759
|
:param str symbol: unified market symbol
|
3252
3760
|
:param str code: unified currency code of the currency to repay
|
3253
3761
|
:param str amount: the amount to repay
|
@@ -3257,7 +3765,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3257
3765
|
self.load_markets()
|
3258
3766
|
market = self.market(symbol)
|
3259
3767
|
currency = self.currency(code)
|
3260
|
-
request = {
|
3768
|
+
request: dict = {
|
3261
3769
|
'symbol': market['id'],
|
3262
3770
|
'currency': currency['id'],
|
3263
3771
|
'amount': self.currency_to_precision(code, amount),
|
@@ -3273,7 +3781,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3273
3781
|
# }
|
3274
3782
|
# }
|
3275
3783
|
#
|
3276
|
-
data = self.
|
3784
|
+
data = self.safe_dict(response, 'data', {})
|
3277
3785
|
transaction = self.parse_margin_loan(data, currency)
|
3278
3786
|
return self.extend(transaction, {
|
3279
3787
|
'amount': amount,
|
@@ -3283,7 +3791,9 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3283
3791
|
def borrow_isolated_margin(self, symbol: str, code: str, amount: float, params={}):
|
3284
3792
|
"""
|
3285
3793
|
create a loan to borrow margin
|
3286
|
-
|
3794
|
+
|
3795
|
+
https://developer-pro.bitmart.com/en/spot/#margin-borrow-isolated
|
3796
|
+
|
3287
3797
|
:param str symbol: unified market symbol
|
3288
3798
|
:param str code: unified currency code of the currency to borrow
|
3289
3799
|
:param str amount: the amount to borrow
|
@@ -3293,7 +3803,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3293
3803
|
self.load_markets()
|
3294
3804
|
market = self.market(symbol)
|
3295
3805
|
currency = self.currency(code)
|
3296
|
-
request = {
|
3806
|
+
request: dict = {
|
3297
3807
|
'symbol': market['id'],
|
3298
3808
|
'currency': currency['id'],
|
3299
3809
|
'amount': self.currency_to_precision(code, amount),
|
@@ -3309,7 +3819,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3309
3819
|
# }
|
3310
3820
|
# }
|
3311
3821
|
#
|
3312
|
-
data = self.
|
3822
|
+
data = self.safe_dict(response, 'data', {})
|
3313
3823
|
transaction = self.parse_margin_loan(data, currency)
|
3314
3824
|
return self.extend(transaction, {
|
3315
3825
|
'amount': amount,
|
@@ -3340,17 +3850,19 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3340
3850
|
'info': info,
|
3341
3851
|
}
|
3342
3852
|
|
3343
|
-
def fetch_isolated_borrow_rate(self, symbol: str, params={}):
|
3853
|
+
def fetch_isolated_borrow_rate(self, symbol: str, params={}) -> IsolatedBorrowRate:
|
3344
3854
|
"""
|
3345
3855
|
fetch the rate of interest to borrow a currency for margin trading
|
3346
|
-
|
3856
|
+
|
3857
|
+
https://developer-pro.bitmart.com/en/spot/#get-trading-pair-borrowing-rate-and-amount-keyed
|
3858
|
+
|
3347
3859
|
:param str symbol: unified symbol of the market to fetch the borrow rate for
|
3348
3860
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3349
3861
|
:returns dict: an `isolated borrow rate structure <https://github.com/ccxt/ccxt/wiki/Manual#isolated-borrow-rate-structure>`
|
3350
3862
|
"""
|
3351
3863
|
self.load_markets()
|
3352
3864
|
market = self.market(symbol)
|
3353
|
-
request = {
|
3865
|
+
request: dict = {
|
3354
3866
|
'symbol': market['id'],
|
3355
3867
|
}
|
3356
3868
|
response = self.privateGetSpotV1MarginIsolatedPairs(self.extend(request, params))
|
@@ -3386,12 +3898,12 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3386
3898
|
# }
|
3387
3899
|
# }
|
3388
3900
|
#
|
3389
|
-
data = self.
|
3390
|
-
symbols = self.
|
3391
|
-
borrowRate = self.
|
3901
|
+
data = self.safe_dict(response, 'data', {})
|
3902
|
+
symbols = self.safe_list(data, 'symbols', [])
|
3903
|
+
borrowRate = self.safe_dict(symbols, 0, [])
|
3392
3904
|
return self.parse_isolated_borrow_rate(borrowRate, market)
|
3393
3905
|
|
3394
|
-
def parse_isolated_borrow_rate(self, info, market: Market = None):
|
3906
|
+
def parse_isolated_borrow_rate(self, info: dict, market: Market = None) -> IsolatedBorrowRate:
|
3395
3907
|
#
|
3396
3908
|
# {
|
3397
3909
|
# "symbol": "BTC_USDT",
|
@@ -3417,8 +3929,8 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3417
3929
|
#
|
3418
3930
|
marketId = self.safe_string(info, 'symbol')
|
3419
3931
|
symbol = self.safe_symbol(marketId, market)
|
3420
|
-
baseData = self.
|
3421
|
-
quoteData = self.
|
3932
|
+
baseData = self.safe_dict(info, 'base', {})
|
3933
|
+
quoteData = self.safe_dict(info, 'quote', {})
|
3422
3934
|
baseId = self.safe_string(baseData, 'currency')
|
3423
3935
|
quoteId = self.safe_string(quoteData, 'currency')
|
3424
3936
|
return {
|
@@ -3433,10 +3945,12 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3433
3945
|
'info': info,
|
3434
3946
|
}
|
3435
3947
|
|
3436
|
-
def fetch_isolated_borrow_rates(self, params={}):
|
3948
|
+
def fetch_isolated_borrow_rates(self, params={}) -> IsolatedBorrowRates:
|
3437
3949
|
"""
|
3438
3950
|
fetch the borrow interest rates of all currencies, currently only works for isolated margin
|
3439
|
-
|
3951
|
+
|
3952
|
+
https://developer-pro.bitmart.com/en/spot/#get-trading-pair-borrowing-rate-and-amount-keyed
|
3953
|
+
|
3440
3954
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3441
3955
|
:returns dict: a list of `isolated borrow rate structures <https://docs.ccxt.com/#/?id=isolated-borrow-rate-structure>`
|
3442
3956
|
"""
|
@@ -3474,19 +3988,18 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3474
3988
|
# }
|
3475
3989
|
# }
|
3476
3990
|
#
|
3477
|
-
data = self.
|
3478
|
-
symbols = self.
|
3479
|
-
|
3480
|
-
for i in range(0, len(symbols)):
|
3481
|
-
symbol = self.safe_value(symbols, i)
|
3482
|
-
result.append(self.parse_isolated_borrow_rate(symbol))
|
3483
|
-
return result
|
3991
|
+
data = self.safe_dict(response, 'data', {})
|
3992
|
+
symbols = self.safe_list(data, 'symbols', [])
|
3993
|
+
return self.parse_isolated_borrow_rates(symbols)
|
3484
3994
|
|
3485
3995
|
def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
|
3486
3996
|
"""
|
3487
3997
|
transfer currency internally between wallets on the same account, currently only supports transfer between spot and margin
|
3488
|
-
|
3489
|
-
|
3998
|
+
|
3999
|
+
https://developer-pro.bitmart.com/en/spot/#margin-asset-transfer-signed
|
4000
|
+
https://developer-pro.bitmart.com/en/futures/#transfer-signed
|
4001
|
+
https://developer-pro.bitmart.com/en/futuresv2/#transfer-signed
|
4002
|
+
|
3490
4003
|
:param str code: unified currency code
|
3491
4004
|
:param float amount: amount to transfer
|
3492
4005
|
:param str fromAccount: account to transfer from
|
@@ -3497,7 +4010,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3497
4010
|
self.load_markets()
|
3498
4011
|
currency = self.currency(code)
|
3499
4012
|
amountToPrecision = self.currency_to_precision(code, amount)
|
3500
|
-
request = {
|
4013
|
+
request: dict = {
|
3501
4014
|
'amount': amountToPrecision,
|
3502
4015
|
'currency': currency['id'],
|
3503
4016
|
}
|
@@ -3546,13 +4059,13 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3546
4059
|
# }
|
3547
4060
|
# }
|
3548
4061
|
#
|
3549
|
-
data = self.
|
4062
|
+
data = self.safe_dict(response, 'data', {})
|
3550
4063
|
return self.extend(self.parse_transfer(data, currency), {
|
3551
4064
|
'status': self.parse_transfer_status(self.safe_string_2(response, 'code', 'message')),
|
3552
4065
|
})
|
3553
4066
|
|
3554
|
-
def parse_transfer_status(self, status):
|
3555
|
-
statuses = {
|
4067
|
+
def parse_transfer_status(self, status: Str) -> Str:
|
4068
|
+
statuses: dict = {
|
3556
4069
|
'1000': 'ok',
|
3557
4070
|
'OK': 'ok',
|
3558
4071
|
'FINISHED': 'ok',
|
@@ -3560,20 +4073,20 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3560
4073
|
return self.safe_string(statuses, status, status)
|
3561
4074
|
|
3562
4075
|
def parse_transfer_to_account(self, type):
|
3563
|
-
types = {
|
4076
|
+
types: dict = {
|
3564
4077
|
'contract_to_spot': 'spot',
|
3565
4078
|
'spot_to_contract': 'swap',
|
3566
4079
|
}
|
3567
4080
|
return self.safe_string(types, type, type)
|
3568
4081
|
|
3569
4082
|
def parse_transfer_from_account(self, type):
|
3570
|
-
types = {
|
4083
|
+
types: dict = {
|
3571
4084
|
'contract_to_spot': 'swap',
|
3572
4085
|
'spot_to_contract': 'spot',
|
3573
4086
|
}
|
3574
4087
|
return self.safe_string(types, type, type)
|
3575
4088
|
|
3576
|
-
def parse_transfer(self, transfer, currency: Currency = None):
|
4089
|
+
def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
|
3577
4090
|
#
|
3578
4091
|
# margin
|
3579
4092
|
#
|
@@ -3612,10 +4125,12 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3612
4125
|
'status': self.parse_transfer_status(self.safe_string(transfer, 'state')),
|
3613
4126
|
}
|
3614
4127
|
|
3615
|
-
def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
|
4128
|
+
def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[TransferEntry]:
|
3616
4129
|
"""
|
3617
4130
|
fetch a history of internal transfers made on an account, only transfers between spot and swap are supported
|
3618
|
-
|
4131
|
+
|
4132
|
+
https://developer-pro.bitmart.com/en/futures/#get-transfer-list-signed
|
4133
|
+
|
3619
4134
|
:param str code: unified currency code of the currency transferred
|
3620
4135
|
:param int [since]: the earliest time in ms to fetch transfers for
|
3621
4136
|
:param int [limit]: the maximum number of transfer structures to retrieve
|
@@ -3627,7 +4142,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3627
4142
|
self.load_markets()
|
3628
4143
|
if limit is None:
|
3629
4144
|
limit = 10
|
3630
|
-
request = {
|
4145
|
+
request: dict = {
|
3631
4146
|
'page': self.safe_integer(params, 'page', 1), # default is 1, max is 1000
|
3632
4147
|
'limit': limit, # default is 10, max is 100
|
3633
4148
|
}
|
@@ -3639,9 +4154,9 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3639
4154
|
request['time_start'] = since
|
3640
4155
|
if limit is not None:
|
3641
4156
|
request['limit'] = limit
|
3642
|
-
until = self.
|
4157
|
+
until = self.safe_integer(params, 'until') # unified in milliseconds
|
3643
4158
|
endTime = self.safe_integer(params, 'time_end', until) # exchange-specific in milliseconds
|
3644
|
-
params = self.omit(params, ['
|
4159
|
+
params = self.omit(params, ['until'])
|
3645
4160
|
if endTime is not None:
|
3646
4161
|
request['time_end'] = endTime
|
3647
4162
|
response = self.privatePostAccountV1TransferContractList(self.extend(request, params))
|
@@ -3664,14 +4179,16 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3664
4179
|
# }
|
3665
4180
|
# }
|
3666
4181
|
#
|
3667
|
-
data = self.
|
3668
|
-
records = self.
|
4182
|
+
data = self.safe_dict(response, 'data', {})
|
4183
|
+
records = self.safe_list(data, 'records', [])
|
3669
4184
|
return self.parse_transfers(records, currency, since, limit)
|
3670
4185
|
|
3671
|
-
def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
4186
|
+
def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
|
3672
4187
|
"""
|
3673
4188
|
fetch the interest owed by the user for borrowing currency for margin trading
|
3674
|
-
|
4189
|
+
|
4190
|
+
https://developer-pro.bitmart.com/en/spot/#get-borrow-record-isolated
|
4191
|
+
|
3675
4192
|
:param str code: unified currency code
|
3676
4193
|
:param str symbol: unified market symbol when fetch interest in isolated markets
|
3677
4194
|
:param int [since]: the earliest time in ms to fetch borrrow interest for
|
@@ -3683,7 +4200,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3683
4200
|
raise ArgumentsRequired(self.id + ' fetchBorrowInterest() requires a symbol argument')
|
3684
4201
|
self.load_markets()
|
3685
4202
|
market = self.market(symbol)
|
3686
|
-
request = {
|
4203
|
+
request: dict = {
|
3687
4204
|
'symbol': market['id'],
|
3688
4205
|
}
|
3689
4206
|
if limit is not None:
|
@@ -3712,12 +4229,12 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3712
4229
|
# }
|
3713
4230
|
# }
|
3714
4231
|
#
|
3715
|
-
data = self.
|
3716
|
-
rows = self.
|
4232
|
+
data = self.safe_dict(response, 'data', {})
|
4233
|
+
rows = self.safe_list(data, 'records', [])
|
3717
4234
|
interest = self.parse_borrow_interests(rows, market)
|
3718
4235
|
return self.filter_by_currency_since_limit(interest, code, since, limit)
|
3719
4236
|
|
3720
|
-
def parse_borrow_interest(self, info, market: Market = None):
|
4237
|
+
def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
|
3721
4238
|
#
|
3722
4239
|
# {
|
3723
4240
|
# "borrow_id": "1657664327844Lk5eJJugXmdHHZoe",
|
@@ -3734,21 +4251,23 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3734
4251
|
market = self.safe_market(marketId, market)
|
3735
4252
|
timestamp = self.safe_integer(info, 'create_time')
|
3736
4253
|
return {
|
4254
|
+
'info': info,
|
3737
4255
|
'symbol': self.safe_string(market, 'symbol'),
|
3738
|
-
'marginMode': 'isolated',
|
3739
4256
|
'currency': self.safe_currency_code(self.safe_string(info, 'currency')),
|
3740
4257
|
'interest': self.safe_number(info, 'interest_amount'),
|
3741
4258
|
'interestRate': self.safe_number(info, 'hourly_interest'),
|
3742
4259
|
'amountBorrowed': self.safe_number(info, 'borrow_amount'),
|
4260
|
+
'marginMode': 'isolated',
|
3743
4261
|
'timestamp': timestamp, # borrow creation time
|
3744
4262
|
'datetime': self.iso8601(timestamp),
|
3745
|
-
'info': info,
|
3746
4263
|
}
|
3747
4264
|
|
3748
4265
|
def fetch_open_interest(self, symbol: str, params={}):
|
3749
4266
|
"""
|
3750
4267
|
Retrieves the open interest of a currency
|
3751
|
-
|
4268
|
+
|
4269
|
+
https://developer-pro.bitmart.com/en/futuresv2/#get-futures-openinterest
|
4270
|
+
|
3752
4271
|
:param str symbol: Unified CCXT market symbol
|
3753
4272
|
:param dict [params]: exchange specific parameters
|
3754
4273
|
:returns dict} an open interest structure{@link https://docs.ccxt.com/#/?id=open-interest-structure:
|
@@ -3757,7 +4276,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3757
4276
|
market = self.market(symbol)
|
3758
4277
|
if not market['contract']:
|
3759
4278
|
raise BadRequest(self.id + ' fetchOpenInterest() supports contract markets only')
|
3760
|
-
request = {
|
4279
|
+
request: dict = {
|
3761
4280
|
'symbol': market['id'],
|
3762
4281
|
}
|
3763
4282
|
response = self.publicGetContractPublicOpenInterest(self.extend(request, params))
|
@@ -3774,7 +4293,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3774
4293
|
# "trace": "7f9c94e10f9d4513bc08a7bfc2a5559a.72.16946575108274991"
|
3775
4294
|
# }
|
3776
4295
|
#
|
3777
|
-
data = self.
|
4296
|
+
data = self.safe_dict(response, 'data', {})
|
3778
4297
|
return self.parse_open_interest(data, market)
|
3779
4298
|
|
3780
4299
|
def parse_open_interest(self, interest, market: Market = None):
|
@@ -3800,7 +4319,10 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3800
4319
|
def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
|
3801
4320
|
"""
|
3802
4321
|
set the level of leverage for a market
|
3803
|
-
|
4322
|
+
|
4323
|
+
https://developer-pro.bitmart.com/en/futures/#submit-leverage-signed
|
4324
|
+
https://developer-pro.bitmart.com/en/futuresv2/#submit-leverage-signed
|
4325
|
+
|
3804
4326
|
:param float leverage: the rate of leverage
|
3805
4327
|
:param str symbol: unified market symbol
|
3806
4328
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
@@ -3816,17 +4338,19 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3816
4338
|
market = self.market(symbol)
|
3817
4339
|
if not market['swap']:
|
3818
4340
|
raise BadSymbol(self.id + ' setLeverage() supports swap contracts only')
|
3819
|
-
request = {
|
4341
|
+
request: dict = {
|
3820
4342
|
'symbol': market['id'],
|
3821
4343
|
'leverage': str(leverage),
|
3822
4344
|
'open_type': marginMode,
|
3823
4345
|
}
|
3824
4346
|
return self.privatePostContractPrivateSubmitLeverage(self.extend(request, params))
|
3825
4347
|
|
3826
|
-
def fetch_funding_rate(self, symbol: str, params={}):
|
4348
|
+
def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
|
3827
4349
|
"""
|
3828
4350
|
fetch the current funding rate
|
3829
|
-
|
4351
|
+
|
4352
|
+
https://developer-pro.bitmart.com/en/futuresv2/#get-current-funding-rate
|
4353
|
+
|
3830
4354
|
:param str symbol: unified market symbol
|
3831
4355
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3832
4356
|
:returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
|
@@ -3835,7 +4359,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3835
4359
|
market = self.market(symbol)
|
3836
4360
|
if not market['swap']:
|
3837
4361
|
raise BadSymbol(self.id + ' fetchFundingRate() supports swap contracts only')
|
3838
|
-
request = {
|
4362
|
+
request: dict = {
|
3839
4363
|
'symbol': market['id'],
|
3840
4364
|
}
|
3841
4365
|
response = self.publicGetContractPublicFundingRate(self.extend(request, params))
|
@@ -3852,10 +4376,66 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3852
4376
|
# "trace": "4cad855074654097ac7ba5257c47305d.54.16951844206655589"
|
3853
4377
|
# }
|
3854
4378
|
#
|
3855
|
-
data = self.
|
4379
|
+
data = self.safe_dict(response, 'data', {})
|
3856
4380
|
return self.parse_funding_rate(data, market)
|
3857
4381
|
|
3858
|
-
def
|
4382
|
+
def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
4383
|
+
"""
|
4384
|
+
fetches historical funding rate prices
|
4385
|
+
|
4386
|
+
https://developer-pro.bitmart.com/en/futuresv2/#get-funding-rate-history
|
4387
|
+
|
4388
|
+
:param str symbol: unified symbol of the market to fetch the funding rate history for
|
4389
|
+
:param int [since]: timestamp in ms of the earliest funding rate to fetch
|
4390
|
+
:param int [limit]: the maximum amount of funding rate structures to fetch
|
4391
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4392
|
+
:returns dict[]: a list of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>`
|
4393
|
+
"""
|
4394
|
+
if symbol is None:
|
4395
|
+
raise ArgumentsRequired(self.id + ' fetchFundingRateHistory() requires a symbol argument')
|
4396
|
+
self.load_markets()
|
4397
|
+
market = self.market(symbol)
|
4398
|
+
request: dict = {
|
4399
|
+
'symbol': market['id'],
|
4400
|
+
}
|
4401
|
+
if limit is not None:
|
4402
|
+
request['limit'] = limit
|
4403
|
+
response = self.publicGetContractPublicFundingRateHistory(self.extend(request, params))
|
4404
|
+
#
|
4405
|
+
# {
|
4406
|
+
# "code": 1000,
|
4407
|
+
# "message": "Ok",
|
4408
|
+
# "data": {
|
4409
|
+
# "list": [
|
4410
|
+
# {
|
4411
|
+
# "symbol": "BTCUSDT",
|
4412
|
+
# "funding_rate": "0.000091412174",
|
4413
|
+
# "funding_time": "1734336000000"
|
4414
|
+
# },
|
4415
|
+
# ]
|
4416
|
+
# },
|
4417
|
+
# "trace": "fg73d949fgfdf6a40c8fc7f5ae6738.54.345345345345"
|
4418
|
+
# }
|
4419
|
+
#
|
4420
|
+
data = self.safe_dict(response, 'data', {})
|
4421
|
+
result = self.safe_list(data, 'list', [])
|
4422
|
+
rates = []
|
4423
|
+
for i in range(0, len(result)):
|
4424
|
+
entry = result[i]
|
4425
|
+
marketId = self.safe_string(entry, 'symbol')
|
4426
|
+
symbolInner = self.safe_symbol(marketId, market, '-', 'swap')
|
4427
|
+
timestamp = self.safe_integer(entry, 'funding_time')
|
4428
|
+
rates.append({
|
4429
|
+
'info': entry,
|
4430
|
+
'symbol': symbolInner,
|
4431
|
+
'fundingRate': self.safe_number(entry, 'funding_rate'),
|
4432
|
+
'timestamp': timestamp,
|
4433
|
+
'datetime': self.iso8601(timestamp),
|
4434
|
+
})
|
4435
|
+
sorted = self.sort_by(rates, 'timestamp')
|
4436
|
+
return self.filter_by_symbol_since_limit(sorted, market['symbol'], since, limit)
|
4437
|
+
|
4438
|
+
def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
|
3859
4439
|
#
|
3860
4440
|
# {
|
3861
4441
|
# "timestamp": 1695184410697,
|
@@ -3884,19 +4464,23 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3884
4464
|
'previousFundingRate': self.safe_number(contract, 'rate_value'),
|
3885
4465
|
'previousFundingTimestamp': None,
|
3886
4466
|
'previousFundingDatetime': None,
|
4467
|
+
'interval': None,
|
3887
4468
|
}
|
3888
4469
|
|
3889
4470
|
def fetch_position(self, symbol: str, params={}):
|
3890
4471
|
"""
|
3891
4472
|
fetch data on a single open contract trade position
|
3892
|
-
|
4473
|
+
|
4474
|
+
https://developer-pro.bitmart.com/en/futures/#get-current-position-keyed
|
4475
|
+
https://developer-pro.bitmart.com/en/futuresv2/#get-current-position-risk-details-keyed
|
4476
|
+
|
3893
4477
|
:param str symbol: unified market symbol of the market the position is held in
|
3894
4478
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3895
4479
|
:returns dict: a `position structure <https://docs.ccxt.com/#/?id=position-structure>`
|
3896
4480
|
"""
|
3897
4481
|
self.load_markets()
|
3898
4482
|
market = self.market(symbol)
|
3899
|
-
request = {
|
4483
|
+
request: dict = {
|
3900
4484
|
'symbol': market['id'],
|
3901
4485
|
}
|
3902
4486
|
response = self.privateGetContractPrivatePosition(self.extend(request, params))
|
@@ -3929,14 +4513,17 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3929
4513
|
# "trace":"4cad855074664097ac5ba5257c47305d.67.16963925142065945"
|
3930
4514
|
# }
|
3931
4515
|
#
|
3932
|
-
data = self.
|
3933
|
-
first = self.
|
4516
|
+
data = self.safe_list(response, 'data', [])
|
4517
|
+
first = self.safe_dict(data, 0, {})
|
3934
4518
|
return self.parse_position(first, market)
|
3935
4519
|
|
3936
4520
|
def fetch_positions(self, symbols: Strings = None, params={}):
|
3937
4521
|
"""
|
3938
4522
|
fetch all open contract positions
|
3939
|
-
|
4523
|
+
|
4524
|
+
https://developer-pro.bitmart.com/en/futures/#get-current-position-keyed
|
4525
|
+
https://developer-pro.bitmart.com/en/futuresv2/#get-current-position-risk-details-keyed
|
4526
|
+
|
3940
4527
|
:param str[]|None symbols: list of unified market symbols
|
3941
4528
|
:param dict [params]: extra parameters specific to the exchange API endpoint
|
3942
4529
|
:returns dict[]: a list of `position structures <https://docs.ccxt.com/#/?id=position-structure>`
|
@@ -3948,7 +4535,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3948
4535
|
symbolsLength = len(symbols)
|
3949
4536
|
first = self.safe_string(symbols, 0)
|
3950
4537
|
market = self.market(first)
|
3951
|
-
request = {}
|
4538
|
+
request: dict = {}
|
3952
4539
|
if symbolsLength == 1:
|
3953
4540
|
# only supports symbols or sending one symbol
|
3954
4541
|
request['symbol'] = market['id']
|
@@ -3982,14 +4569,14 @@ class bitmart(Exchange, ImplicitAPI):
|
|
3982
4569
|
# "trace":"4cad855074664097ac5ba5257c47305d.67.16963925142065945"
|
3983
4570
|
# }
|
3984
4571
|
#
|
3985
|
-
positions = self.
|
4572
|
+
positions = self.safe_list(response, 'data', [])
|
3986
4573
|
result = []
|
3987
4574
|
for i in range(0, len(positions)):
|
3988
4575
|
result.append(self.parse_position(positions[i]))
|
3989
4576
|
symbols = self.market_symbols(symbols)
|
3990
4577
|
return self.filter_by_array_positions(result, 'symbol', symbols, False)
|
3991
4578
|
|
3992
|
-
def parse_position(self, position, market: Market = None):
|
4579
|
+
def parse_position(self, position: dict, market: Market = None):
|
3993
4580
|
#
|
3994
4581
|
# {
|
3995
4582
|
# "symbol": "BTCUSDT",
|
@@ -4056,7 +4643,9 @@ class bitmart(Exchange, ImplicitAPI):
|
|
4056
4643
|
def fetch_my_liquidations(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
4057
4644
|
"""
|
4058
4645
|
retrieves the users liquidated positions
|
4059
|
-
|
4646
|
+
|
4647
|
+
https://developer-pro.bitmart.com/en/futures/#get-order-history-keyed
|
4648
|
+
|
4060
4649
|
:param str symbol: unified CCXT market symbol
|
4061
4650
|
:param int [since]: the earliest time in ms to fetch liquidations for
|
4062
4651
|
:param int [limit]: the maximum number of liquidation structures to retrieve
|
@@ -4070,7 +4659,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
4070
4659
|
market = self.market(symbol)
|
4071
4660
|
if not market['swap']:
|
4072
4661
|
raise NotSupported(self.id + ' fetchMyLiquidations() supports swap markets only')
|
4073
|
-
request = {
|
4662
|
+
request: dict = {
|
4074
4663
|
'symbol': market['id'],
|
4075
4664
|
}
|
4076
4665
|
if since is not None:
|
@@ -4102,7 +4691,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
4102
4691
|
# "trace": "4cad855074664097ac6ba4257c47305d.71.16965658195443021"
|
4103
4692
|
# }
|
4104
4693
|
#
|
4105
|
-
data = self.
|
4694
|
+
data = self.safe_list(response, 'data', [])
|
4106
4695
|
result = []
|
4107
4696
|
for i in range(0, len(data)):
|
4108
4697
|
entry = data[i]
|
@@ -4149,11 +4738,307 @@ class bitmart(Exchange, ImplicitAPI):
|
|
4149
4738
|
'datetime': self.iso8601(timestamp),
|
4150
4739
|
})
|
4151
4740
|
|
4741
|
+
def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}) -> Order:
|
4742
|
+
"""
|
4743
|
+
edits an open order
|
4744
|
+
|
4745
|
+
https://developer-pro.bitmart.com/en/futuresv2/#modify-plan-order-signed
|
4746
|
+
https://developer-pro.bitmart.com/en/futuresv2/#modify-tp-sl-order-signed
|
4747
|
+
https://developer-pro.bitmart.com/en/futuresv2/#modify-preset-plan-order-signed
|
4748
|
+
|
4749
|
+
:param str id: order id
|
4750
|
+
:param str symbol: unified symbol of the market to edit an order in
|
4751
|
+
:param str type: 'market' or 'limit'
|
4752
|
+
:param str side: 'buy' or 'sell'
|
4753
|
+
:param float [amount]: how much you want to trade in units of the base currency
|
4754
|
+
:param float [price]: the price to fulfill the order, in units of the quote currency, ignored in market orders
|
4755
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4756
|
+
:param str [params.triggerPrice]: *swap only* the price to trigger a stop order
|
4757
|
+
:param str [params.stopLossPrice]: *swap only* the price to trigger a stop-loss order
|
4758
|
+
:param str [params.takeProfitPrice]: *swap only* the price to trigger a take-profit order
|
4759
|
+
:param str [params.stopLoss.triggerPrice]: *swap only* the price to trigger a preset stop-loss order
|
4760
|
+
:param str [params.takeProfit.triggerPrice]: *swap only* the price to trigger a preset take-profit order
|
4761
|
+
:param str [params.clientOrderId]: client order id of the order
|
4762
|
+
:param int [params.price_type]: *swap only* 1: last price, 2: fair price, default is 1
|
4763
|
+
:param int [params.plan_category]: *swap tp/sl only* 1: tp/sl, 2: position tp/sl, default is 1
|
4764
|
+
:returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
|
4765
|
+
"""
|
4766
|
+
self.load_markets()
|
4767
|
+
market = self.market(symbol)
|
4768
|
+
if not market['swap']:
|
4769
|
+
raise NotSupported(self.id + ' editOrder() does not support ' + market['type'] + ' markets, only swap markets are supported')
|
4770
|
+
stopLossPrice = self.safe_string(params, 'stopLossPrice')
|
4771
|
+
takeProfitPrice = self.safe_string(params, 'takeProfitPrice')
|
4772
|
+
triggerPrice = self.safe_string_n(params, ['triggerPrice', 'stopPrice', 'trigger_price'])
|
4773
|
+
stopLoss = self.safe_dict(params, 'stopLoss', {})
|
4774
|
+
takeProfit = self.safe_dict(params, 'takeProfit', {})
|
4775
|
+
presetStopLoss = self.safe_string(stopLoss, 'triggerPrice')
|
4776
|
+
presetTakeProfit = self.safe_string(takeProfit, 'triggerPrice')
|
4777
|
+
isTriggerOrder = triggerPrice is not None
|
4778
|
+
isStopLoss = stopLossPrice is not None
|
4779
|
+
isTakeProfit = takeProfitPrice is not None
|
4780
|
+
isPresetStopLoss = presetStopLoss is not None
|
4781
|
+
isPresetTakeProfit = presetTakeProfit is not None
|
4782
|
+
request: dict = {
|
4783
|
+
'symbol': market['id'],
|
4784
|
+
}
|
4785
|
+
clientOrderId = self.safe_string(params, 'clientOrderId')
|
4786
|
+
if clientOrderId is not None:
|
4787
|
+
params = self.omit(params, 'clientOrderId')
|
4788
|
+
request['client_order_id'] = clientOrderId
|
4789
|
+
if id is not None:
|
4790
|
+
request['order_id'] = id
|
4791
|
+
params = self.omit(params, ['triggerPrice', 'stopPrice', 'stopLossPrice', 'takeProfitPrice', 'stopLoss', 'takeProfit'])
|
4792
|
+
response = None
|
4793
|
+
if isTriggerOrder or isStopLoss or isTakeProfit:
|
4794
|
+
request['price_type'] = self.safe_integer(params, 'price_type', 1)
|
4795
|
+
if price is not None:
|
4796
|
+
request['executive_price'] = self.price_to_precision(symbol, price)
|
4797
|
+
if isTriggerOrder:
|
4798
|
+
request['type'] = type
|
4799
|
+
request['trigger_price'] = self.price_to_precision(symbol, triggerPrice)
|
4800
|
+
response = self.privatePostContractPrivateModifyPlanOrder(self.extend(request, params))
|
4801
|
+
#
|
4802
|
+
# {
|
4803
|
+
# "code": 1000,
|
4804
|
+
# "message": "Ok",
|
4805
|
+
# "data": {
|
4806
|
+
# "order_id": "3000023150003503"
|
4807
|
+
# },
|
4808
|
+
# "trace": "324523453245.108.1734567125596324575"
|
4809
|
+
# }
|
4810
|
+
#
|
4811
|
+
elif isStopLoss or isTakeProfit:
|
4812
|
+
request['category'] = type
|
4813
|
+
if isStopLoss:
|
4814
|
+
request['trigger_price'] = self.price_to_precision(symbol, stopLossPrice)
|
4815
|
+
else:
|
4816
|
+
request['trigger_price'] = self.price_to_precision(symbol, takeProfitPrice)
|
4817
|
+
response = self.privatePostContractPrivateModifyTpSlOrder(self.extend(request, params))
|
4818
|
+
#
|
4819
|
+
# {
|
4820
|
+
# "code": 1000,
|
4821
|
+
# "message": "Ok",
|
4822
|
+
# "data": {
|
4823
|
+
# "order_id": "3000023150003480"
|
4824
|
+
# },
|
4825
|
+
# "trace": "23452345.104.1724536582682345459"
|
4826
|
+
# }
|
4827
|
+
#
|
4828
|
+
elif isPresetStopLoss or isPresetTakeProfit:
|
4829
|
+
if isPresetStopLoss:
|
4830
|
+
request['preset_stop_loss_price_type'] = self.safe_integer(params, 'price_type', 1)
|
4831
|
+
request['preset_stop_loss_price'] = self.price_to_precision(symbol, presetStopLoss)
|
4832
|
+
else:
|
4833
|
+
request['preset_take_profit_price_type'] = self.safe_integer(params, 'price_type', 1)
|
4834
|
+
request['preset_take_profit_price'] = self.price_to_precision(symbol, presetTakeProfit)
|
4835
|
+
response = self.privatePostContractPrivateModifyPresetPlanOrder(self.extend(request, params))
|
4836
|
+
#
|
4837
|
+
# {
|
4838
|
+
# "code": 1000,
|
4839
|
+
# "message": "Ok",
|
4840
|
+
# "data": {
|
4841
|
+
# "order_id": "3000023150003496"
|
4842
|
+
# },
|
4843
|
+
# "trace": "a5c3234534534a836bc476a203.123452.172716624359200197"
|
4844
|
+
# }
|
4845
|
+
#
|
4846
|
+
else:
|
4847
|
+
raise NotSupported(self.id + ' editOrder() only supports trigger, stop loss and take profit orders')
|
4848
|
+
data = self.safe_dict(response, 'data', {})
|
4849
|
+
return self.parse_order(data, market)
|
4850
|
+
|
4851
|
+
def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
|
4852
|
+
"""
|
4853
|
+
fetch the history of changes, actions done by the user or operations that altered the balance of the user
|
4854
|
+
|
4855
|
+
https://developer-pro.bitmart.com/en/futuresv2/#get-transaction-history-keyed
|
4856
|
+
|
4857
|
+
:param str [code]: unified currency code
|
4858
|
+
:param int [since]: timestamp in ms of the earliest ledger entry
|
4859
|
+
:param int [limit]: max number of ledger entries to return
|
4860
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4861
|
+
:param int [params.until]: timestamp in ms of the latest ledger entry
|
4862
|
+
:returns dict[]: a list of `ledger structures <https://docs.ccxt.com/#/?id=ledger>`
|
4863
|
+
"""
|
4864
|
+
self.load_markets()
|
4865
|
+
currency = None
|
4866
|
+
if code is not None:
|
4867
|
+
currency = self.currency(code)
|
4868
|
+
request: dict = {}
|
4869
|
+
request, params = self.handle_until_option('end_time', request, params)
|
4870
|
+
transactionsRequest = self.fetch_transactions_request(0, None, since, limit, params)
|
4871
|
+
response = self.privateGetContractPrivateTransactionHistory(transactionsRequest)
|
4872
|
+
#
|
4873
|
+
# {
|
4874
|
+
# "code": 1000,
|
4875
|
+
# "message": "Ok",
|
4876
|
+
# "data": [
|
4877
|
+
# {
|
4878
|
+
# "time": "1734422402121",
|
4879
|
+
# "type": "Funding Fee",
|
4880
|
+
# "amount": "-0.00008253",
|
4881
|
+
# "asset": "USDT",
|
4882
|
+
# "symbol": "LTCUSDT",
|
4883
|
+
# "tran_id": "1734422402121",
|
4884
|
+
# "flow_type": 3
|
4885
|
+
# },
|
4886
|
+
# ],
|
4887
|
+
# "trace": "4cd11f83c71egfhfgh842790f07241e.23.173442343427772866"
|
4888
|
+
# }
|
4889
|
+
#
|
4890
|
+
data = self.safe_list(response, 'data', [])
|
4891
|
+
return self.parse_ledger(data, currency, since, limit)
|
4892
|
+
|
4893
|
+
def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
|
4894
|
+
#
|
4895
|
+
# {
|
4896
|
+
# "time": "1734422402121",
|
4897
|
+
# "type": "Funding Fee",
|
4898
|
+
# "amount": "-0.00008253",
|
4899
|
+
# "asset": "USDT",
|
4900
|
+
# "symbol": "LTCUSDT",
|
4901
|
+
# "tran_id": "1734422402121",
|
4902
|
+
# "flow_type": 3
|
4903
|
+
# }
|
4904
|
+
#
|
4905
|
+
amount = self.safe_string(item, 'amount')
|
4906
|
+
direction = None
|
4907
|
+
if Precise.string_le(amount, '0'):
|
4908
|
+
direction = 'out'
|
4909
|
+
amount = Precise.string_mul('-1', amount)
|
4910
|
+
else:
|
4911
|
+
direction = 'in'
|
4912
|
+
currencyId = self.safe_string(item, 'asset')
|
4913
|
+
timestamp = self.safe_integer(item, 'time')
|
4914
|
+
type = self.safe_string(item, 'type')
|
4915
|
+
return self.safe_ledger_entry({
|
4916
|
+
'info': item,
|
4917
|
+
'id': self.safe_string(item, 'tran_id'),
|
4918
|
+
'direction': direction,
|
4919
|
+
'account': None,
|
4920
|
+
'referenceAccount': None,
|
4921
|
+
'referenceId': self.safe_string(item, 'tradeId'),
|
4922
|
+
'type': self.parse_ledger_entry_type(type),
|
4923
|
+
'currency': self.safe_currency_code(currencyId, currency),
|
4924
|
+
'amount': self.parse_number(amount),
|
4925
|
+
'timestamp': timestamp,
|
4926
|
+
'datetime': self.iso8601(timestamp),
|
4927
|
+
'before': None,
|
4928
|
+
'after': None,
|
4929
|
+
'status': None,
|
4930
|
+
'fee': None,
|
4931
|
+
}, currency)
|
4932
|
+
|
4933
|
+
def parse_ledger_entry_type(self, type):
|
4934
|
+
ledgerType: dict = {
|
4935
|
+
'Commission Fee': 'fee',
|
4936
|
+
'Funding Fee': 'fee',
|
4937
|
+
'Realized PNL': 'trade',
|
4938
|
+
'Transfer': 'transfer',
|
4939
|
+
'Liquidation Clearance': 'settlement',
|
4940
|
+
}
|
4941
|
+
return self.safe_string(ledgerType, type, type)
|
4942
|
+
|
4943
|
+
def fetch_transactions_request(self, flowType: Int = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
|
4944
|
+
request: dict = {}
|
4945
|
+
if flowType is not None:
|
4946
|
+
request['flow_type'] = flowType
|
4947
|
+
market = None
|
4948
|
+
if symbol is not None:
|
4949
|
+
market = self.market(symbol)
|
4950
|
+
request['symbol'] = market['id']
|
4951
|
+
if since is not None:
|
4952
|
+
request['start_time'] = since
|
4953
|
+
if limit is not None:
|
4954
|
+
request['page_size'] = limit
|
4955
|
+
request, params = self.handle_until_option('end_time', request, params)
|
4956
|
+
return self.extend(request, params)
|
4957
|
+
|
4958
|
+
def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[FundingHistory]:
|
4959
|
+
"""
|
4960
|
+
fetch the history of funding payments paid and received on self account
|
4961
|
+
|
4962
|
+
https://developer-pro.bitmart.com/en/futuresv2/#get-transaction-history-keyed
|
4963
|
+
|
4964
|
+
:param str [symbol]: unified market symbol
|
4965
|
+
:param int [since]: the starting timestamp in milliseconds
|
4966
|
+
:param int [limit]: the number of entries to return
|
4967
|
+
:param dict [params]: extra parameters specific to the exchange API endpoint
|
4968
|
+
:param int [params.until]: the latest time in ms to fetch funding history for
|
4969
|
+
:returns dict[]: a list of `funding history structures <https://docs.ccxt.com/#/?id=funding-history-structure>`
|
4970
|
+
"""
|
4971
|
+
self.load_markets()
|
4972
|
+
market = None
|
4973
|
+
if symbol is not None:
|
4974
|
+
market = self.market(symbol)
|
4975
|
+
request: dict = {}
|
4976
|
+
request, params = self.handle_until_option('end_time', request, params)
|
4977
|
+
transactionsRequest = self.fetch_transactions_request(3, symbol, since, limit, params)
|
4978
|
+
response = self.privateGetContractPrivateTransactionHistory(transactionsRequest)
|
4979
|
+
#
|
4980
|
+
# {
|
4981
|
+
# "code": 1000,
|
4982
|
+
# "message": "Ok",
|
4983
|
+
# "data": [
|
4984
|
+
# {
|
4985
|
+
# "time": "1734422402121",
|
4986
|
+
# "type": "Funding Fee",
|
4987
|
+
# "amount": "-0.00008253",
|
4988
|
+
# "asset": "USDT",
|
4989
|
+
# "symbol": "LTCUSDT",
|
4990
|
+
# "tran_id": "1734422402121",
|
4991
|
+
# "flow_type": 3
|
4992
|
+
# },
|
4993
|
+
# ],
|
4994
|
+
# "trace": "4cd11f83c71egfhfgh842790f07241e.23.173442343427772866"
|
4995
|
+
# }
|
4996
|
+
#
|
4997
|
+
data = self.safe_list(response, 'data', [])
|
4998
|
+
return self.parse_funding_histories(data, market, since, limit)
|
4999
|
+
|
5000
|
+
def parse_funding_history(self, contract, market: Market = None):
|
5001
|
+
#
|
5002
|
+
# {
|
5003
|
+
# "time": "1734422402121",
|
5004
|
+
# "type": "Funding Fee",
|
5005
|
+
# "amount": "-0.00008253",
|
5006
|
+
# "asset": "USDT",
|
5007
|
+
# "symbol": "LTCUSDT",
|
5008
|
+
# "tran_id": "1734422402121",
|
5009
|
+
# "flow_type": 3
|
5010
|
+
# }
|
5011
|
+
#
|
5012
|
+
marketId = self.safe_string(contract, 'symbol')
|
5013
|
+
currencyId = self.safe_string(contract, 'asset')
|
5014
|
+
timestamp = self.safe_integer(contract, 'time')
|
5015
|
+
return {
|
5016
|
+
'info': contract,
|
5017
|
+
'symbol': self.safe_symbol(marketId, market, None, 'swap'),
|
5018
|
+
'code': self.safe_currency_code(currencyId),
|
5019
|
+
'timestamp': timestamp,
|
5020
|
+
'datetime': self.iso8601(timestamp),
|
5021
|
+
'id': self.safe_string(contract, 'tran_id'),
|
5022
|
+
'amount': self.safe_number(contract, 'amount'),
|
5023
|
+
}
|
5024
|
+
|
5025
|
+
def parse_funding_histories(self, contracts, market=None, since: Int = None, limit: Int = None) -> List[FundingHistory]:
|
5026
|
+
result = []
|
5027
|
+
for i in range(0, len(contracts)):
|
5028
|
+
contract = contracts[i]
|
5029
|
+
result.append(self.parse_funding_history(contract, market))
|
5030
|
+
sorted = self.sort_by(result, 'timestamp')
|
5031
|
+
return self.filter_by_since_limit(sorted, since, limit)
|
5032
|
+
|
4152
5033
|
def nonce(self):
|
4153
|
-
return self.milliseconds()
|
5034
|
+
return self.milliseconds() - self.options['timeDifference']
|
4154
5035
|
|
4155
5036
|
def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
|
4156
|
-
|
5037
|
+
parts = path.split('/')
|
5038
|
+
# to do: refactor api endpoints with spot/swap sections
|
5039
|
+
category = self.safe_string(parts, 0, 'spot')
|
5040
|
+
market = 'spot' if (category == 'spot' or category == 'account') else 'swap'
|
5041
|
+
baseUrl = self.implode_hostname(self.urls['api'][market])
|
4157
5042
|
url = baseUrl + '/' + self.implode_params(path, params)
|
4158
5043
|
query = self.omit(params, self.extract_params(path))
|
4159
5044
|
queryString = ''
|
@@ -4164,7 +5049,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
4164
5049
|
url += '?' + queryString
|
4165
5050
|
if api == 'private':
|
4166
5051
|
self.check_required_credentials()
|
4167
|
-
timestamp = str(self.
|
5052
|
+
timestamp = str(self.nonce())
|
4168
5053
|
brokerId = self.safe_string(self.options, 'brokerId', 'CCXTxBitmart000')
|
4169
5054
|
headers = {
|
4170
5055
|
'X-BM-KEY': self.apiKey,
|
@@ -4180,7 +5065,7 @@ class bitmart(Exchange, ImplicitAPI):
|
|
4180
5065
|
headers['X-BM-SIGN'] = signature
|
4181
5066
|
return {'url': url, 'method': method, 'body': body, 'headers': headers}
|
4182
5067
|
|
4183
|
-
def handle_errors(self, code, reason, url, method, headers, body, response, requestHeaders, requestBody):
|
5068
|
+
def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
|
4184
5069
|
if response is None:
|
4185
5070
|
return None
|
4186
5071
|
#
|