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/test/base/test_position.py
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import sys
|
3
|
-
|
4
|
-
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
|
5
|
-
sys.path.append(root)
|
6
|
-
|
7
|
-
# ----------------------------------------------------------------------------
|
8
|
-
|
9
|
-
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
10
|
-
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
11
|
-
|
12
|
-
# ----------------------------------------------------------------------------
|
13
|
-
# -*- coding: utf-8 -*-
|
14
|
-
|
15
|
-
from ccxt.test.base import test_shared_methods # noqa E402
|
16
|
-
|
17
|
-
def test_position(exchange, skipped_properties, method, entry, symbol, now):
|
18
|
-
format = {
|
19
|
-
'info': {},
|
20
|
-
'symbol': 'XYZ/USDT',
|
21
|
-
'timestamp': 1504224000000,
|
22
|
-
'datetime': '2017-09-01T00:00:00',
|
23
|
-
'initialMargin': exchange.parse_number('1.234'),
|
24
|
-
'initialMarginPercentage': exchange.parse_number('0.123'),
|
25
|
-
'maintenanceMargin': exchange.parse_number('1.234'),
|
26
|
-
'maintenanceMarginPercentage': exchange.parse_number('0.123'),
|
27
|
-
'entryPrice': exchange.parse_number('1.234'),
|
28
|
-
'notional': exchange.parse_number('1.234'),
|
29
|
-
'leverage': exchange.parse_number('1.234'),
|
30
|
-
'unrealizedPnl': exchange.parse_number('1.234'),
|
31
|
-
'contracts': exchange.parse_number('1'),
|
32
|
-
'contractSize': exchange.parse_number('1.234'),
|
33
|
-
'marginRatio': exchange.parse_number('1.234'),
|
34
|
-
'liquidationPrice': exchange.parse_number('1.234'),
|
35
|
-
'markPrice': exchange.parse_number('1.234'),
|
36
|
-
'collateral': exchange.parse_number('1.234'),
|
37
|
-
'marginMode': 'cross',
|
38
|
-
'side': 'long',
|
39
|
-
'percentage': exchange.parse_number('1.234'),
|
40
|
-
}
|
41
|
-
emptyot_allowed_for = ['liquidationPrice', 'initialMargin', 'initialMarginPercentage', 'maintenanceMargin', 'maintenanceMarginPercentage', 'marginRatio']
|
42
|
-
test_shared_methods.assert_structure(exchange, skipped_properties, method, entry, format, emptyot_allowed_for)
|
43
|
-
test_shared_methods.assert_timestamp_and_datetime(exchange, skipped_properties, method, entry, now)
|
44
|
-
test_shared_methods.assert_symbol(exchange, skipped_properties, method, entry, 'symbol', symbol)
|
45
|
-
test_shared_methods.assert_in_array(exchange, skipped_properties, method, entry, 'side', ['long', 'short'])
|
46
|
-
test_shared_methods.assert_in_array(exchange, skipped_properties, method, entry, 'marginMode', ['cross', 'isolated'])
|
47
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'leverage', '0')
|
48
|
-
test_shared_methods.assert_less_or_equal(exchange, skipped_properties, method, entry, 'leverage', '200')
|
49
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'initialMargin', '0')
|
50
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'initialMarginPercentage', '0')
|
51
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'maintenanceMargin', '0')
|
52
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'maintenanceMarginPercentage', '0')
|
53
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'entryPrice', '0')
|
54
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'notional', '0')
|
55
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'contracts', '0')
|
56
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'contractSize', '0')
|
57
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'marginRatio', '0')
|
58
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'liquidationPrice', '0')
|
59
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'markPrice', '0')
|
60
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'collateral', '0')
|
@@ -1,345 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import sys
|
3
|
-
|
4
|
-
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
|
5
|
-
sys.path.append(root)
|
6
|
-
|
7
|
-
# ----------------------------------------------------------------------------
|
8
|
-
|
9
|
-
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
10
|
-
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
11
|
-
|
12
|
-
# ----------------------------------------------------------------------------
|
13
|
-
# -*- coding: utf-8 -*-
|
14
|
-
|
15
|
-
from ccxt.base.decimal_to_precision import TICK_SIZE # noqa E402
|
16
|
-
import numbers # noqa E402
|
17
|
-
from ccxt.base.precise import Precise # noqa E402
|
18
|
-
from ccxt.base.errors import OperationFailed # noqa E402
|
19
|
-
from ccxt.base.errors import OnMaintenance # noqa E402
|
20
|
-
from ccxt.base.errors import ArgumentsRequired # noqa E402
|
21
|
-
|
22
|
-
def log_template(exchange, method, entry):
|
23
|
-
return ' <<< ' + exchange.id + ' ' + method + ' ::: ' + exchange.json(entry) + ' >>> '
|
24
|
-
|
25
|
-
|
26
|
-
def is_temporary_failure(e):
|
27
|
-
return (isinstance(e, OperationFailed)) and (not (isinstance(e, OnMaintenance)))
|
28
|
-
|
29
|
-
|
30
|
-
def string_value(value):
|
31
|
-
string_val = None
|
32
|
-
if isinstance(value, str):
|
33
|
-
string_val = value
|
34
|
-
elif value is None:
|
35
|
-
string_val = 'undefined'
|
36
|
-
else:
|
37
|
-
string_val = str(value)
|
38
|
-
return string_val
|
39
|
-
|
40
|
-
|
41
|
-
def assert_type(exchange, skipped_properties, entry, key, format):
|
42
|
-
if key in skipped_properties:
|
43
|
-
return None
|
44
|
-
# because "typeof" string is not transpilable without === 'name', we list them manually at this moment
|
45
|
-
entry_key_val = exchange.safe_value(entry, key)
|
46
|
-
format_key_val = exchange.safe_value(format, key)
|
47
|
-
same_string = (isinstance(entry_key_val, str)) and (isinstance(format_key_val, str))
|
48
|
-
same_numeric = (isinstance(entry_key_val, numbers.Real)) and (isinstance(format_key_val, numbers.Real))
|
49
|
-
same_boolean = ((entry_key_val) or (entry_key_val is False)) and ((format_key_val) or (format_key_val is False))
|
50
|
-
same_array = isinstance(entry_key_val, list) and isinstance(format_key_val, list)
|
51
|
-
same_object = (isinstance(entry_key_val, dict)) and (isinstance(format_key_val, dict))
|
52
|
-
result = (entry_key_val is None) or same_string or same_numeric or same_boolean or same_array or same_object
|
53
|
-
return result
|
54
|
-
|
55
|
-
|
56
|
-
def assert_structure(exchange, skipped_properties, method, entry, format, empty_allowed_for=[]):
|
57
|
-
log_text = log_template(exchange, method, entry)
|
58
|
-
assert entry, 'item is null/undefined' + log_text
|
59
|
-
# get all expected & predefined keys for this specific item and ensure thos ekeys exist in parsed structure
|
60
|
-
if isinstance(format, list):
|
61
|
-
assert isinstance(entry, list), 'entry is not an array' + log_text
|
62
|
-
real_length = len(entry)
|
63
|
-
expected_length = len(format)
|
64
|
-
assert real_length == expected_length, 'entry length is not equal to expected length of ' + str(expected_length) + log_text
|
65
|
-
for i in range(0, len(format)):
|
66
|
-
empty_allowed_for_this_key = exchange.in_array(i, empty_allowed_for)
|
67
|
-
value = entry[i]
|
68
|
-
if i in skipped_properties:
|
69
|
-
continue
|
70
|
-
# check when:
|
71
|
-
# - it's not inside "allowe empty values" list
|
72
|
-
# - it's not undefined
|
73
|
-
if empty_allowed_for_this_key and (value is None):
|
74
|
-
continue
|
75
|
-
assert value is not None, str(i) + ' index is expected to have a value' + log_text
|
76
|
-
# because of other langs, this is needed for arrays
|
77
|
-
type_assertion = assert_type(exchange, skipped_properties, entry, i, format)
|
78
|
-
assert type_assertion, str(i) + ' index does not have an expected type ' + log_text
|
79
|
-
else:
|
80
|
-
assert isinstance(entry, dict), 'entry is not an object' + log_text
|
81
|
-
keys = list(format.keys())
|
82
|
-
for i in range(0, len(keys)):
|
83
|
-
key = keys[i]
|
84
|
-
if key in skipped_properties:
|
85
|
-
continue
|
86
|
-
assert key in entry, '\"' + string_value(key) + '\" key is missing from structure' + log_text
|
87
|
-
if key in skipped_properties:
|
88
|
-
continue
|
89
|
-
empty_allowed_for_this_key = exchange.in_array(key, empty_allowed_for)
|
90
|
-
value = entry[key]
|
91
|
-
# check when:
|
92
|
-
# - it's not inside "allowe empty values" list
|
93
|
-
# - it's not undefined
|
94
|
-
if empty_allowed_for_this_key and (value is None):
|
95
|
-
continue
|
96
|
-
# if it was in needed keys, then it should have value.
|
97
|
-
assert value is not None, '\"' + string_value(key) + '\" key is expected to have a value' + log_text
|
98
|
-
# add exclusion for info key, as it can be any type
|
99
|
-
if key != 'info':
|
100
|
-
type_assertion = assert_type(exchange, skipped_properties, entry, key, format)
|
101
|
-
assert type_assertion, '\"' + string_value(key) + '\" key is neither undefined, neither of expected type' + log_text
|
102
|
-
|
103
|
-
|
104
|
-
def assert_timestamp(exchange, skipped_properties, method, entry, now_to_check=None, key_name_or_index='timestamp'):
|
105
|
-
log_text = log_template(exchange, method, entry)
|
106
|
-
skip_value = exchange.safe_value(skipped_properties, key_name_or_index)
|
107
|
-
if skip_value is not None:
|
108
|
-
return # skipped
|
109
|
-
is_date_time_object = isinstance(key_name_or_index, str)
|
110
|
-
if is_date_time_object:
|
111
|
-
assert (key_name_or_index in entry), 'timestamp key \"' + key_name_or_index + '\" is missing from structure' + log_text
|
112
|
-
else:
|
113
|
-
# if index was provided (mostly from fetchOHLCV) then we check if it exists, as mandatory
|
114
|
-
assert not (entry[key_name_or_index] is None), 'timestamp index ' + string_value(key_name_or_index) + ' is undefined' + log_text
|
115
|
-
ts = entry[key_name_or_index]
|
116
|
-
if ts is not None:
|
117
|
-
assert isinstance(ts, numbers.Real), 'timestamp is not numeric' + log_text
|
118
|
-
assert isinstance(ts, int), 'timestamp should be an integer' + log_text
|
119
|
-
min_ts = 1230940800000 # 03 Jan 2009 - first block
|
120
|
-
max_ts = 2147483648000 # 19 Jan 2038 - max int
|
121
|
-
assert ts > min_ts, 'timestamp is impossible to be before ' + str(min_ts) + ' (03.01.2009)' + log_text # 03 Jan 2009 - first block
|
122
|
-
assert ts < max_ts, 'timestamp more than ' + str(max_ts) + ' (19.01.2038)' + log_text # 19 Jan 2038 - int32 overflows # 7258118400000 -> Jan 1 2200
|
123
|
-
if now_to_check is not None:
|
124
|
-
max_ms_offset = 60000 # 1 min
|
125
|
-
assert ts < now_to_check + max_ms_offset, 'returned item timestamp (' + exchange.iso8601(ts) + ') is ahead of the current time (' + exchange.iso8601(now_to_check) + ')' + log_text
|
126
|
-
|
127
|
-
|
128
|
-
def assert_timestamp_and_datetime(exchange, skipped_properties, method, entry, now_to_check=None, key_name_or_index='timestamp'):
|
129
|
-
log_text = log_template(exchange, method, entry)
|
130
|
-
skip_value = exchange.safe_value(skipped_properties, key_name_or_index)
|
131
|
-
if skip_value is not None:
|
132
|
-
return
|
133
|
-
assert_timestamp(exchange, skipped_properties, method, entry, now_to_check, key_name_or_index)
|
134
|
-
is_date_time_object = isinstance(key_name_or_index, str)
|
135
|
-
# only in case if the entry is a dictionary, thus it must have 'timestamp' & 'datetime' string keys
|
136
|
-
if is_date_time_object:
|
137
|
-
# we also test 'datetime' here because it's certain sibling of 'timestamp'
|
138
|
-
assert ('datetime' in entry), '\"datetime\" key is missing from structure' + log_text
|
139
|
-
dt = entry['datetime']
|
140
|
-
if dt is not None:
|
141
|
-
assert isinstance(dt, str), '\"datetime\" key does not have a string value' + log_text
|
142
|
-
# there are exceptional cases, like getting microsecond-targeted string '2022-08-08T22:03:19.014680Z', so parsed unified timestamp, which carries only 13 digits (millisecond precision) can not be stringified back to microsecond accuracy, causing the bellow assertion to fail
|
143
|
-
# assert (dt === exchange.iso8601 (entry['timestamp']))
|
144
|
-
# so, we have to compare with millisecond accururacy
|
145
|
-
dt_parsed = exchange.parse8601(dt)
|
146
|
-
assert exchange.iso8601(dt_parsed) == exchange.iso8601(entry['timestamp']), 'datetime is not iso8601 of timestamp' + log_text
|
147
|
-
|
148
|
-
|
149
|
-
def assert_currency_code(exchange, skipped_properties, method, entry, actual_code, expected_code=None):
|
150
|
-
if ('currency' in skipped_properties) or ('currencyIdAndCode' in skipped_properties):
|
151
|
-
return
|
152
|
-
log_text = log_template(exchange, method, entry)
|
153
|
-
if actual_code is not None:
|
154
|
-
assert isinstance(actual_code, str), 'currency code should be either undefined or a string' + log_text
|
155
|
-
assert (actual_code in exchange.currencies), 'currency code (\"' + actual_code + '\") should be present in exchange.currencies' + log_text
|
156
|
-
if expected_code is not None:
|
157
|
-
assert actual_code == expected_code, 'currency code in response (\"' + string_value(actual_code) + '\") should be equal to expected code (\"' + string_value(expected_code) + '\")' + log_text
|
158
|
-
|
159
|
-
|
160
|
-
def assert_valid_currency_id_and_code(exchange, skipped_properties, method, entry, currency_id, currency_code):
|
161
|
-
# this is exclusive exceptional key name to be used in `skip-tests.json`, to skip check for currency id and code
|
162
|
-
if ('currency' in skipped_properties) or ('currencyIdAndCode' in skipped_properties):
|
163
|
-
return
|
164
|
-
log_text = log_template(exchange, method, entry)
|
165
|
-
undefined_values = currency_id is None and currency_code is None
|
166
|
-
defined_values = currency_id is not None and currency_code is not None
|
167
|
-
assert undefined_values or defined_values, 'currencyId and currencyCode should be either both defined or both undefined' + log_text
|
168
|
-
if defined_values:
|
169
|
-
# check by code
|
170
|
-
currency_by_code = exchange.currency(currency_code)
|
171
|
-
assert currency_by_code['id'] == currency_id, 'currencyId \"' + string_value(currency_id) + '\" does not match currency of code: \"' + string_value(currency_code) + '\"' + log_text
|
172
|
-
# check by id
|
173
|
-
currency_by_id = exchange.safe_currency(currency_id)
|
174
|
-
assert currency_by_id['code'] == currency_code, 'currencyCode ' + string_value(currency_code) + ' does not match currency of id: ' + string_value(currency_id) + log_text
|
175
|
-
|
176
|
-
|
177
|
-
def assert_symbol(exchange, skipped_properties, method, entry, key, expected_symbol=None):
|
178
|
-
if key in skipped_properties:
|
179
|
-
return
|
180
|
-
log_text = log_template(exchange, method, entry)
|
181
|
-
actual_symbol = exchange.safe_string(entry, key)
|
182
|
-
if actual_symbol is not None:
|
183
|
-
assert isinstance(actual_symbol, str), 'symbol should be either undefined or a string' + log_text
|
184
|
-
if expected_symbol is not None:
|
185
|
-
assert actual_symbol == expected_symbol, 'symbol in response (\"' + string_value(actual_symbol) + '\") should be equal to expected symbol (\"' + string_value(expected_symbol) + '\")' + log_text
|
186
|
-
|
187
|
-
|
188
|
-
def assert_symbol_in_markets(exchange, skipped_properties, method, symbol):
|
189
|
-
log_text = log_template(exchange, method, {})
|
190
|
-
assert (symbol in exchange.markets), 'symbol should be present in exchange.symbols' + log_text
|
191
|
-
|
192
|
-
|
193
|
-
def assert_greater(exchange, skipped_properties, method, entry, key, compare_to):
|
194
|
-
if key in skipped_properties:
|
195
|
-
return
|
196
|
-
log_text = log_template(exchange, method, entry)
|
197
|
-
value = exchange.safe_string(entry, key)
|
198
|
-
if value is not None:
|
199
|
-
assert Precise.string_gt(value, compare_to), string_value(key) + ' key (with a value of ' + string_value(value) + ') was expected to be > ' + string_value(compare_to) + log_text
|
200
|
-
|
201
|
-
|
202
|
-
def assert_greater_or_equal(exchange, skipped_properties, method, entry, key, compare_to):
|
203
|
-
if key in skipped_properties:
|
204
|
-
return
|
205
|
-
log_text = log_template(exchange, method, entry)
|
206
|
-
value = exchange.safe_string(entry, key)
|
207
|
-
if value is not None and compare_to is not None:
|
208
|
-
assert Precise.string_ge(value, compare_to), string_value(key) + ' key (with a value of ' + string_value(value) + ') was expected to be >= ' + string_value(compare_to) + log_text
|
209
|
-
|
210
|
-
|
211
|
-
def assert_less(exchange, skipped_properties, method, entry, key, compare_to):
|
212
|
-
if key in skipped_properties:
|
213
|
-
return
|
214
|
-
log_text = log_template(exchange, method, entry)
|
215
|
-
value = exchange.safe_string(entry, key)
|
216
|
-
if value is not None and compare_to is not None:
|
217
|
-
assert Precise.string_lt(value, compare_to), string_value(key) + ' key (with a value of ' + string_value(value) + ') was expected to be < ' + string_value(compare_to) + log_text
|
218
|
-
|
219
|
-
|
220
|
-
def assert_less_or_equal(exchange, skipped_properties, method, entry, key, compare_to):
|
221
|
-
if key in skipped_properties:
|
222
|
-
return
|
223
|
-
log_text = log_template(exchange, method, entry)
|
224
|
-
value = exchange.safe_string(entry, key)
|
225
|
-
if value is not None and compare_to is not None:
|
226
|
-
assert Precise.string_le(value, compare_to), string_value(key) + ' key (with a value of ' + string_value(value) + ') was expected to be <= ' + string_value(compare_to) + log_text
|
227
|
-
|
228
|
-
|
229
|
-
def assert_equal(exchange, skipped_properties, method, entry, key, compare_to):
|
230
|
-
if key in skipped_properties:
|
231
|
-
return
|
232
|
-
log_text = log_template(exchange, method, entry)
|
233
|
-
value = exchange.safe_string(entry, key)
|
234
|
-
if value is not None and compare_to is not None:
|
235
|
-
assert Precise.string_eq(value, compare_to), string_value(key) + ' key (with a value of ' + string_value(value) + ') was expected to be equal to ' + string_value(compare_to) + log_text
|
236
|
-
|
237
|
-
|
238
|
-
def assert_non_equal(exchange, skipped_properties, method, entry, key, compare_to):
|
239
|
-
if key in skipped_properties:
|
240
|
-
return
|
241
|
-
log_text = log_template(exchange, method, entry)
|
242
|
-
value = exchange.safe_string(entry, key)
|
243
|
-
if value is not None:
|
244
|
-
assert not Precise.string_eq(value, compare_to), string_value(key) + ' key (with a value of ' + string_value(value) + ') was expected not to be equal to ' + string_value(compare_to) + log_text
|
245
|
-
|
246
|
-
|
247
|
-
def assert_in_array(exchange, skipped_properties, method, entry, key, expected_array):
|
248
|
-
if key in skipped_properties:
|
249
|
-
return
|
250
|
-
log_text = log_template(exchange, method, entry)
|
251
|
-
value = exchange.safe_value(entry, key)
|
252
|
-
# todo: remove undefined check
|
253
|
-
if value is not None:
|
254
|
-
stingified_array_value = exchange.json(expected_array) # don't use expectedArray.join (','), as it bugs in other languages, if values are bool, undefined or etc..
|
255
|
-
assert exchange.in_array(value, expected_array), '\"' + string_value(key) + '\" key (value \"' + string_value(value) + '\") is not from the expected list : [' + stingified_array_value + ']' + log_text
|
256
|
-
|
257
|
-
|
258
|
-
def assert_fee_structure(exchange, skipped_properties, method, entry, key):
|
259
|
-
log_text = log_template(exchange, method, entry)
|
260
|
-
key_string = string_value(key)
|
261
|
-
if isinstance(key, int):
|
262
|
-
assert isinstance(entry, list), 'fee container is expected to be an array' + log_text
|
263
|
-
assert key < len(entry), 'fee key ' + key_string + ' was expected to be present in entry' + log_text
|
264
|
-
else:
|
265
|
-
assert isinstance(entry, dict), 'fee container is expected to be an object' + log_text
|
266
|
-
assert key in entry, 'fee key \"' + key + '\" was expected to be present in entry' + log_text
|
267
|
-
fee_object = exchange.safe_value(entry, key)
|
268
|
-
# todo: remove undefined check to make stricter
|
269
|
-
if fee_object is not None:
|
270
|
-
assert 'cost' in fee_object, key_string + ' fee object should contain \"cost\" key' + log_text
|
271
|
-
# assertGreaterOrEqual (exchange, skippedProperties, method, feeObject, 'cost', '0'); # fee might be negative in the case of a rebate or reward
|
272
|
-
assert 'currency' in fee_object, '\"' + key_string + '\" fee object should contain \"currency\" key' + log_text
|
273
|
-
assert_currency_code(exchange, skipped_properties, method, entry, fee_object['currency'])
|
274
|
-
|
275
|
-
|
276
|
-
def assert_timestamp_order(exchange, method, code_or_symbol, items, ascending=True):
|
277
|
-
for i in range(0, len(items)):
|
278
|
-
if i > 0:
|
279
|
-
current_ts = items[i - 1]['timestamp']
|
280
|
-
next_ts = items[i]['timestamp']
|
281
|
-
if current_ts is not None and next_ts is not None:
|
282
|
-
ascending_or_descending = 'ascending' if ascending else 'descending'
|
283
|
-
comparison = (current_ts <= next_ts) if ascending else (current_ts >= next_ts)
|
284
|
-
assert comparison, exchange.id + ' ' + method + ' ' + string_value(code_or_symbol) + ' must return a ' + ascending_or_descending + ' sorted array of items by timestamp, but ' + str(current_ts) + ' is opposite with its next ' + str(next_ts) + ' ' + exchange.json(items)
|
285
|
-
|
286
|
-
|
287
|
-
def assert_integer(exchange, skipped_properties, method, entry, key):
|
288
|
-
if key in skipped_properties:
|
289
|
-
return
|
290
|
-
log_text = log_template(exchange, method, entry)
|
291
|
-
if entry is not None:
|
292
|
-
value = exchange.safe_value(entry, key)
|
293
|
-
if value is not None:
|
294
|
-
is_integer = isinstance(value, int)
|
295
|
-
assert is_integer, '\"' + string_value(key) + '\" key (value \"' + string_value(value) + '\") is not an integer' + log_text
|
296
|
-
|
297
|
-
|
298
|
-
def check_precision_accuracy(exchange, skipped_properties, method, entry, key):
|
299
|
-
if key in skipped_properties:
|
300
|
-
return
|
301
|
-
if exchange.is_tick_precision():
|
302
|
-
# TICK_SIZE should be above zero
|
303
|
-
assert_greater(exchange, skipped_properties, method, entry, key, '0')
|
304
|
-
# the below array of integers are inexistent tick-sizes (theoretically technically possible, but not in real-world cases), so their existence in our case indicates to incorrectly implemented tick-sizes, which might mistakenly be implemented with DECIMAL_PLACES, so we throw error
|
305
|
-
decimal_numbers = ['2', '3', '4', '6', '7', '8', '9', '11', '12', '13', '14', '15', '16']
|
306
|
-
for i in range(0, len(decimal_numbers)):
|
307
|
-
num = decimal_numbers[i]
|
308
|
-
num_str = num
|
309
|
-
assert_non_equal(exchange, skipped_properties, method, entry, key, num_str)
|
310
|
-
else:
|
311
|
-
assert_integer(exchange, skipped_properties, method, entry, key) # should be integer
|
312
|
-
assert_less_or_equal(exchange, skipped_properties, method, entry, key, '18') # should be under 18 decimals
|
313
|
-
assert_greater_or_equal(exchange, skipped_properties, method, entry, key, '-8') # in real-world cases, there would not be less than that
|
314
|
-
|
315
|
-
|
316
|
-
def remove_proxy_options(exchange, skipped_properties):
|
317
|
-
proxy_url = exchange.check_proxy_url_settings()
|
318
|
-
[http_proxy, https_proxy, socks_proxy] = exchange.check_proxy_settings()
|
319
|
-
# because of bug in transpiled, about `.proxyUrl` being transpiled into `.proxy_url`, we have to use this workaround
|
320
|
-
exchange.set_property(exchange, 'proxyUrl', None)
|
321
|
-
exchange.set_property(exchange, 'proxy_url', None)
|
322
|
-
exchange.set_property(exchange, 'httpProxy', None)
|
323
|
-
exchange.set_property(exchange, 'http_proxy', None)
|
324
|
-
exchange.set_property(exchange, 'httpsProxy', None)
|
325
|
-
exchange.set_property(exchange, 'https_proxy', None)
|
326
|
-
exchange.set_property(exchange, 'socksProxy', None)
|
327
|
-
exchange.set_property(exchange, 'socks_proxy', None)
|
328
|
-
return [proxy_url, http_proxy, https_proxy, socks_proxy]
|
329
|
-
|
330
|
-
|
331
|
-
def set_proxy_options(exchange, skipped_properties, proxy_url, http_proxy, https_proxy, socks_proxy):
|
332
|
-
exchange.proxy_url = proxy_url
|
333
|
-
exchange.http_proxy = http_proxy
|
334
|
-
exchange.https_proxy = https_proxy
|
335
|
-
exchange.socks_proxy = socks_proxy
|
336
|
-
|
337
|
-
|
338
|
-
def assert_non_emtpy_array(exchange, skipped_properties, method, entry, hint=None):
|
339
|
-
log_text = log_template(exchange, method, entry)
|
340
|
-
if hint is not None:
|
341
|
-
log_text = log_text + ' ' + hint
|
342
|
-
assert isinstance(entry, list), 'response is expected to be an array' + log_text
|
343
|
-
if not ('emptyResponse' in skipped_properties):
|
344
|
-
return
|
345
|
-
assert len(entry) > 0, 'response is expected to be a non-empty array' + log_text + ' (add \"emptyResponse\" in skip-tests.json to skip this check)'
|
ccxt/test/base/test_status.py
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import sys
|
3
|
-
|
4
|
-
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
|
5
|
-
sys.path.append(root)
|
6
|
-
|
7
|
-
# ----------------------------------------------------------------------------
|
8
|
-
|
9
|
-
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
10
|
-
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
11
|
-
|
12
|
-
# ----------------------------------------------------------------------------
|
13
|
-
# -*- coding: utf-8 -*-
|
14
|
-
|
15
|
-
from ccxt.test.base import test_shared_methods # noqa E402
|
16
|
-
|
17
|
-
def test_status(exchange, skipped_properties, method, entry, now):
|
18
|
-
format = {
|
19
|
-
'info': {},
|
20
|
-
'status': 'ok',
|
21
|
-
'updated': 1650000000000,
|
22
|
-
'eta': 1660000000000,
|
23
|
-
'url': 'https://example.com',
|
24
|
-
}
|
ccxt/test/base/test_throttle.py
DELETED
@@ -1,126 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import sys
|
3
|
-
|
4
|
-
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
5
|
-
sys.path.append(root)
|
6
|
-
|
7
|
-
# ----------------------------------------------------------------------------
|
8
|
-
|
9
|
-
import asyncio # noqa: E402
|
10
|
-
import time # noqa: E402
|
11
|
-
from ccxt.async_support.base.throttler import Throttler as Throttle # noqa: E402
|
12
|
-
# from ccxt.async_support.base.throttle import throttle as Throttle
|
13
|
-
|
14
|
-
|
15
|
-
delta = 10
|
16
|
-
|
17
|
-
test_cases = [
|
18
|
-
{
|
19
|
-
'tokens': 0,
|
20
|
-
'refillRate': 1 / 50,
|
21
|
-
'cost': 1,
|
22
|
-
'runs': 100,
|
23
|
-
},
|
24
|
-
{
|
25
|
-
'tokens': 20,
|
26
|
-
'refillRate': 1 / 50,
|
27
|
-
'cost': 1,
|
28
|
-
'runs': 100,
|
29
|
-
},
|
30
|
-
{
|
31
|
-
'tokens': 40,
|
32
|
-
'refillRate': 1 / 50,
|
33
|
-
'cost': 1,
|
34
|
-
'runs': 100,
|
35
|
-
},
|
36
|
-
{
|
37
|
-
'tokens': 0,
|
38
|
-
'refillRate': 1 / 20,
|
39
|
-
'cost': 1,
|
40
|
-
'runs': 100,
|
41
|
-
},
|
42
|
-
{
|
43
|
-
'tokens': 100,
|
44
|
-
'refillRate': 1 / 20,
|
45
|
-
'cost': 5,
|
46
|
-
'runs': 50,
|
47
|
-
},
|
48
|
-
{
|
49
|
-
'tokens': 0,
|
50
|
-
'refillRate': 1 / 40,
|
51
|
-
'cost': 2,
|
52
|
-
'runs': 50,
|
53
|
-
},
|
54
|
-
{
|
55
|
-
'tokens': 1,
|
56
|
-
'refillRate': 1 / 100,
|
57
|
-
'cost': 1,
|
58
|
-
'runs': 10,
|
59
|
-
},
|
60
|
-
{
|
61
|
-
'tokens': 5,
|
62
|
-
'refillRate': 1 / 100,
|
63
|
-
'cost': 1,
|
64
|
-
'runs': 10,
|
65
|
-
},
|
66
|
-
{
|
67
|
-
'tokens': 0,
|
68
|
-
'refillRate': 1 / 500,
|
69
|
-
'cost': 1,
|
70
|
-
'runs': 10,
|
71
|
-
},
|
72
|
-
{
|
73
|
-
'tokens': 0,
|
74
|
-
'refillRate': 1 / 10,
|
75
|
-
'cost': 1,
|
76
|
-
'runs': 500,
|
77
|
-
},
|
78
|
-
]
|
79
|
-
|
80
|
-
# add any more tests you want above
|
81
|
-
|
82
|
-
|
83
|
-
for i, case in enumerate(test_cases, 1):
|
84
|
-
case['number'] = i
|
85
|
-
# while the tokenBucket has tokens the throttler should return instantly
|
86
|
-
# so the first tokens / cost runs are deducted
|
87
|
-
instantly_complete = case['tokens'] / case['cost']
|
88
|
-
# after that each run will take cost and the total time will be runs * cost / refillRate
|
89
|
-
remaining = case['runs'] - instantly_complete - 1
|
90
|
-
case['expected'] = remaining * case['cost'] / case['refillRate']
|
91
|
-
|
92
|
-
|
93
|
-
async def schedule(case):
|
94
|
-
throttle = Throttle({
|
95
|
-
'tokens': case['tokens'],
|
96
|
-
'refillRate': case['refillRate'],
|
97
|
-
})
|
98
|
-
start = time.perf_counter_ns()
|
99
|
-
for i in range(case['runs']):
|
100
|
-
await throttle(case['cost'])
|
101
|
-
end = time.perf_counter_ns()
|
102
|
-
elapsed_ms = (end - start) / 1000000
|
103
|
-
result = abs(case['expected'] - elapsed_ms) < delta
|
104
|
-
print(f'case {case["number"]} {"succeeded" if result else "failed"} in {elapsed_ms}ms expected {case["expected"]}ms')
|
105
|
-
assert result
|
106
|
-
|
107
|
-
|
108
|
-
async def main():
|
109
|
-
await asyncio.wait([schedule(case) for case in test_cases], return_when=asyncio.ALL_COMPLETED)
|
110
|
-
|
111
|
-
|
112
|
-
asyncio.run(main())
|
113
|
-
|
114
|
-
# output
|
115
|
-
|
116
|
-
'''
|
117
|
-
case 8 succeeded in 501.224333ms expected 500.0ms
|
118
|
-
case 7 succeeded in 900.647542ms expected 900.0ms
|
119
|
-
case 4 succeeded in 2000.706958ms expected 2000.0ms
|
120
|
-
case 5 succeeded in 3001.669125ms expected 3000.0ms
|
121
|
-
case 3 succeeded in 3001.736666ms expected 3000.0ms
|
122
|
-
case 6 succeeded in 4001.392584ms expected 4000.0ms
|
123
|
-
case 2 succeeded in 4001.503833ms expected 4000.0ms
|
124
|
-
case 9 succeeded in 5001.487ms expected 5000.0ms
|
125
|
-
case 1 succeeded in 5001.635042ms expected 5000.0ms
|
126
|
-
'''
|
ccxt/test/base/test_ticker.py
DELETED
@@ -1,86 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
import sys
|
3
|
-
|
4
|
-
root = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
|
5
|
-
sys.path.append(root)
|
6
|
-
|
7
|
-
# ----------------------------------------------------------------------------
|
8
|
-
|
9
|
-
# PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
|
10
|
-
# https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
|
11
|
-
|
12
|
-
# ----------------------------------------------------------------------------
|
13
|
-
# -*- coding: utf-8 -*-
|
14
|
-
|
15
|
-
from ccxt.base.precise import Precise # noqa E402
|
16
|
-
from ccxt.test.base import test_shared_methods # noqa E402
|
17
|
-
|
18
|
-
def test_ticker(exchange, skipped_properties, method, entry, symbol):
|
19
|
-
format = {
|
20
|
-
'info': {},
|
21
|
-
'symbol': 'ETH/BTC',
|
22
|
-
'timestamp': 1502962946216,
|
23
|
-
'datetime': '2017-09-01T00:00:00',
|
24
|
-
'high': exchange.parse_number('1.234'),
|
25
|
-
'low': exchange.parse_number('1.234'),
|
26
|
-
'bid': exchange.parse_number('1.234'),
|
27
|
-
'bidVolume': exchange.parse_number('1.234'),
|
28
|
-
'ask': exchange.parse_number('1.234'),
|
29
|
-
'askVolume': exchange.parse_number('1.234'),
|
30
|
-
'vwap': exchange.parse_number('1.234'),
|
31
|
-
'open': exchange.parse_number('1.234'),
|
32
|
-
'close': exchange.parse_number('1.234'),
|
33
|
-
'last': exchange.parse_number('1.234'),
|
34
|
-
'previousClose': exchange.parse_number('1.234'),
|
35
|
-
'change': exchange.parse_number('1.234'),
|
36
|
-
'percentage': exchange.parse_number('1.234'),
|
37
|
-
'average': exchange.parse_number('1.234'),
|
38
|
-
'baseVolume': exchange.parse_number('1.234'),
|
39
|
-
'quoteVolume': exchange.parse_number('1.234'),
|
40
|
-
}
|
41
|
-
# todo: atm, many exchanges fail, so temporarily decrease stict mode
|
42
|
-
empty_allowed_for = ['timestamp', 'datetime', 'open', 'high', 'low', 'close', 'last', 'ask', 'bid', 'bidVolume', 'askVolume', 'baseVolume', 'quoteVolume', 'previousClose', 'vwap', 'change', 'percentage', 'average']
|
43
|
-
test_shared_methods.assert_structure(exchange, skipped_properties, method, entry, format, empty_allowed_for)
|
44
|
-
test_shared_methods.assert_timestamp_and_datetime(exchange, skipped_properties, method, entry)
|
45
|
-
log_text = test_shared_methods.log_template(exchange, method, entry)
|
46
|
-
#
|
47
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'open', '0')
|
48
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'high', '0')
|
49
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'low', '0')
|
50
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'close', '0')
|
51
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'ask', '0')
|
52
|
-
test_shared_methods.assert_greater_or_equal(exchange, skipped_properties, method, entry, 'askVolume', '0')
|
53
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'bid', '0')
|
54
|
-
test_shared_methods.assert_greater_or_equal(exchange, skipped_properties, method, entry, 'bidVolume', '0')
|
55
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'vwap', '0')
|
56
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'average', '0')
|
57
|
-
test_shared_methods.assert_greater_or_equal(exchange, skipped_properties, method, entry, 'baseVolume', '0')
|
58
|
-
test_shared_methods.assert_greater_or_equal(exchange, skipped_properties, method, entry, 'quoteVolume', '0')
|
59
|
-
last_string = exchange.safe_string(entry, 'last')
|
60
|
-
close_string = exchange.safe_string(entry, 'close')
|
61
|
-
assert ((close_string is None) and (last_string is None)) or Precise.string_eq(last_string, close_string), '`last` != `close`' + log_text
|
62
|
-
base_volume = exchange.safe_string(entry, 'baseVolume')
|
63
|
-
quote_volume = exchange.safe_string(entry, 'quoteVolume')
|
64
|
-
high = exchange.safe_string(entry, 'high')
|
65
|
-
low = exchange.safe_string(entry, 'low')
|
66
|
-
if not ('quoteVolume' in skipped_properties) and not ('baseVolume' in skipped_properties):
|
67
|
-
if (base_volume is not None) and (quote_volume is not None) and (high is not None) and (low is not None):
|
68
|
-
assert Precise.string_ge(quote_volume, Precise.string_mul(base_volume, low)), 'quoteVolume >= baseVolume * low' + log_text
|
69
|
-
assert Precise.string_le(quote_volume, Precise.string_mul(base_volume, high)), 'quoteVolume <= baseVolume * high' + log_text
|
70
|
-
vwap = exchange.safe_string(entry, 'vwap')
|
71
|
-
if vwap is not None:
|
72
|
-
# todo
|
73
|
-
# assert (high !== undefined, 'vwap is defined, but high is not' + logText);
|
74
|
-
# assert (low !== undefined, 'vwap is defined, but low is not' + logText);
|
75
|
-
# assert (vwap >= low && vwap <= high)
|
76
|
-
assert Precise.string_ge(vwap, '0'), 'vwap is not greater than zero' + log_text
|
77
|
-
if base_volume is not None:
|
78
|
-
assert quote_volume is not None, 'baseVolume & vwap is defined, but quoteVolume is not' + log_text
|
79
|
-
if quote_volume is not None:
|
80
|
-
assert base_volume is not None, 'quoteVolume & vwap is defined, but baseVolume is not' + log_text
|
81
|
-
if not ('spread' in skipped_properties) and not ('ask' in skipped_properties) and not ('bid' in skipped_properties):
|
82
|
-
ask_string = exchange.safe_string(entry, 'ask')
|
83
|
-
bid_string = exchange.safe_string(entry, 'bid')
|
84
|
-
if (ask_string is not None) and (bid_string is not None):
|
85
|
-
test_shared_methods.assert_greater(exchange, skipped_properties, method, entry, 'ask', exchange.safe_string(entry, 'bid'))
|
86
|
-
test_shared_methods.assert_symbol(exchange, skipped_properties, method, entry, 'symbol', symbol)
|