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.
Files changed (546) hide show
  1. ccxt/__init__.py +36 -14
  2. ccxt/abstract/alpaca.py +4 -0
  3. ccxt/abstract/bigone.py +1 -1
  4. ccxt/abstract/binance.py +112 -48
  5. ccxt/abstract/binancecoinm.py +112 -48
  6. ccxt/abstract/binanceus.py +147 -83
  7. ccxt/abstract/binanceusdm.py +112 -48
  8. ccxt/abstract/bingx.py +133 -78
  9. ccxt/abstract/bitbank.py +5 -0
  10. ccxt/abstract/bitfinex.py +136 -65
  11. ccxt/abstract/bitfinex1.py +69 -0
  12. ccxt/abstract/bitflyer.py +1 -0
  13. ccxt/abstract/bitget.py +8 -1
  14. ccxt/abstract/bitmart.py +13 -1
  15. ccxt/abstract/bitopro.py +1 -0
  16. ccxt/abstract/bitpanda.py +0 -12
  17. ccxt/abstract/bitrue.py +3 -3
  18. ccxt/abstract/bitstamp.py +26 -3
  19. ccxt/abstract/blofin.py +24 -0
  20. ccxt/abstract/btcbox.py +1 -0
  21. ccxt/abstract/bybit.py +29 -14
  22. ccxt/abstract/cex.py +28 -29
  23. ccxt/abstract/coinbase.py +6 -0
  24. ccxt/abstract/coinbaseadvanced.py +94 -0
  25. ccxt/abstract/{coinbasepro.py → coinbaseexchange.py} +1 -0
  26. ccxt/abstract/coinbaseinternational.py +1 -1
  27. ccxt/abstract/coincatch.py +94 -0
  28. ccxt/abstract/coinex.py +233 -123
  29. ccxt/abstract/coinmetro.py +1 -0
  30. ccxt/abstract/cryptocom.py +14 -0
  31. ccxt/abstract/defx.py +69 -0
  32. ccxt/abstract/deribit.py +1 -0
  33. ccxt/abstract/digifinex.py +1 -0
  34. ccxt/abstract/ellipx.py +25 -0
  35. ccxt/abstract/gate.py +20 -0
  36. ccxt/abstract/gateio.py +20 -0
  37. ccxt/abstract/gemini.py +1 -0
  38. ccxt/abstract/hashkey.py +67 -0
  39. ccxt/abstract/hyperliquid.py +1 -1
  40. ccxt/abstract/independentreserve.py +6 -0
  41. ccxt/abstract/kraken.py +4 -3
  42. ccxt/abstract/krakenfutures.py +4 -0
  43. ccxt/abstract/kucoin.py +24 -0
  44. ccxt/abstract/kucoinfutures.py +34 -0
  45. ccxt/abstract/luno.py +2 -0
  46. ccxt/abstract/mexc.py +4 -0
  47. ccxt/abstract/myokx.py +340 -0
  48. ccxt/abstract/oceanex.py +5 -0
  49. ccxt/abstract/okx.py +30 -0
  50. ccxt/abstract/onetrading.py +0 -12
  51. ccxt/abstract/oxfun.py +34 -0
  52. ccxt/abstract/paradex.py +40 -0
  53. ccxt/abstract/phemex.py +1 -0
  54. ccxt/abstract/upbit.py +4 -0
  55. ccxt/abstract/vertex.py +19 -0
  56. ccxt/abstract/whitebit.py +31 -1
  57. ccxt/abstract/woo.py +6 -2
  58. ccxt/abstract/woofipro.py +119 -0
  59. ccxt/abstract/xt.py +153 -0
  60. ccxt/abstract/zonda.py +6 -0
  61. ccxt/ace.py +164 -60
  62. ccxt/alpaca.py +727 -63
  63. ccxt/ascendex.py +395 -249
  64. ccxt/async_support/__init__.py +36 -14
  65. ccxt/async_support/ace.py +164 -60
  66. ccxt/async_support/alpaca.py +727 -63
  67. ccxt/async_support/ascendex.py +396 -249
  68. ccxt/async_support/base/exchange.py +531 -155
  69. ccxt/async_support/base/ws/aiohttp_client.py +28 -5
  70. ccxt/async_support/base/ws/cache.py +3 -2
  71. ccxt/async_support/base/ws/client.py +26 -5
  72. ccxt/async_support/base/ws/fast_client.py +4 -3
  73. ccxt/async_support/base/ws/functions.py +1 -1
  74. ccxt/async_support/base/ws/future.py +40 -31
  75. ccxt/async_support/base/ws/order_book_side.py +3 -0
  76. ccxt/async_support/bequant.py +1 -1
  77. ccxt/async_support/bigone.py +329 -202
  78. ccxt/async_support/binance.py +3030 -1087
  79. ccxt/async_support/binancecoinm.py +2 -1
  80. ccxt/async_support/binanceus.py +12 -1
  81. ccxt/async_support/binanceusdm.py +3 -1
  82. ccxt/async_support/bingx.py +3205 -937
  83. ccxt/async_support/bit2c.py +119 -38
  84. ccxt/async_support/bitbank.py +215 -76
  85. ccxt/async_support/bitbns.py +124 -53
  86. ccxt/async_support/bitfinex.py +3236 -1078
  87. ccxt/async_support/bitfinex1.py +1711 -0
  88. ccxt/async_support/bitflyer.py +238 -49
  89. ccxt/async_support/bitget.py +1525 -573
  90. ccxt/async_support/bithumb.py +199 -65
  91. ccxt/async_support/bitmart.py +1320 -435
  92. ccxt/async_support/bitmex.py +308 -111
  93. ccxt/async_support/bitopro.py +256 -96
  94. ccxt/async_support/bitrue.py +365 -233
  95. ccxt/async_support/bitso.py +201 -89
  96. ccxt/async_support/bitstamp.py +438 -269
  97. ccxt/async_support/bitteam.py +179 -73
  98. ccxt/async_support/bitvavo.py +180 -70
  99. ccxt/async_support/bl3p.py +92 -25
  100. ccxt/async_support/blockchaincom.py +193 -79
  101. ccxt/async_support/blofin.py +392 -148
  102. ccxt/async_support/btcalpha.py +161 -55
  103. ccxt/async_support/btcbox.py +250 -34
  104. ccxt/async_support/btcmarkets.py +232 -85
  105. ccxt/async_support/btcturk.py +159 -60
  106. ccxt/async_support/bybit.py +2231 -1193
  107. ccxt/async_support/cex.py +1409 -1329
  108. ccxt/async_support/coinbase.py +1454 -287
  109. ccxt/async_support/coinbaseadvanced.py +17 -0
  110. ccxt/async_support/{coinbasepro.py → coinbaseexchange.py} +233 -99
  111. ccxt/async_support/coinbaseinternational.py +428 -88
  112. ccxt/async_support/coincatch.py +5152 -0
  113. ccxt/async_support/coincheck.py +121 -38
  114. ccxt/async_support/coinex.py +4020 -3339
  115. ccxt/async_support/coinlist.py +273 -116
  116. ccxt/async_support/coinmate.py +204 -97
  117. ccxt/async_support/coinmetro.py +203 -110
  118. ccxt/async_support/coinone.py +142 -68
  119. ccxt/async_support/coinsph.py +223 -97
  120. ccxt/async_support/coinspot.py +137 -62
  121. ccxt/async_support/cryptocom.py +515 -185
  122. ccxt/async_support/currencycom.py +203 -85
  123. ccxt/async_support/defx.py +2066 -0
  124. ccxt/async_support/delta.py +404 -109
  125. ccxt/async_support/deribit.py +639 -323
  126. ccxt/async_support/digifinex.py +465 -233
  127. ccxt/async_support/ellipx.py +1887 -0
  128. ccxt/async_support/exmo.py +317 -128
  129. ccxt/async_support/gate.py +1472 -463
  130. ccxt/async_support/gemini.py +206 -84
  131. ccxt/async_support/hashkey.py +4164 -0
  132. ccxt/async_support/hitbtc.py +433 -178
  133. ccxt/async_support/hollaex.py +207 -83
  134. ccxt/async_support/htx.py +1095 -563
  135. ccxt/async_support/huobijp.py +178 -56
  136. ccxt/async_support/hyperliquid.py +1678 -292
  137. ccxt/async_support/idex.py +219 -95
  138. ccxt/async_support/independentreserve.py +300 -31
  139. ccxt/async_support/indodax.py +226 -62
  140. ccxt/async_support/kraken.py +871 -354
  141. ccxt/async_support/krakenfutures.py +324 -100
  142. ccxt/async_support/kucoin.py +917 -357
  143. ccxt/async_support/kucoinfutures.py +1004 -149
  144. ccxt/async_support/kuna.py +198 -107
  145. ccxt/async_support/latoken.py +199 -79
  146. ccxt/async_support/lbank.py +360 -113
  147. ccxt/async_support/luno.py +185 -62
  148. ccxt/async_support/lykke.py +168 -55
  149. ccxt/async_support/mercado.py +101 -29
  150. ccxt/async_support/mexc.py +995 -429
  151. ccxt/async_support/myokx.py +53 -0
  152. ccxt/async_support/ndax.py +234 -82
  153. ccxt/async_support/novadax.py +195 -75
  154. ccxt/async_support/oceanex.py +244 -59
  155. ccxt/async_support/okcoin.py +301 -165
  156. ccxt/async_support/okx.py +1776 -454
  157. ccxt/async_support/onetrading.py +198 -414
  158. ccxt/async_support/oxfun.py +2898 -0
  159. ccxt/async_support/p2b.py +142 -52
  160. ccxt/async_support/paradex.py +2085 -0
  161. ccxt/async_support/paymium.py +56 -32
  162. ccxt/async_support/phemex.py +572 -196
  163. ccxt/async_support/poloniex.py +218 -95
  164. ccxt/async_support/poloniexfutures.py +260 -92
  165. ccxt/async_support/probit.py +143 -110
  166. ccxt/async_support/timex.py +123 -70
  167. ccxt/async_support/tokocrypto.py +129 -93
  168. ccxt/async_support/tradeogre.py +39 -25
  169. ccxt/async_support/upbit.py +322 -113
  170. ccxt/async_support/vertex.py +2983 -0
  171. ccxt/async_support/wavesexchange.py +227 -173
  172. ccxt/async_support/wazirx.py +145 -65
  173. ccxt/async_support/whitebit.py +533 -138
  174. ccxt/async_support/woo.py +1137 -296
  175. ccxt/async_support/woofipro.py +2716 -0
  176. ccxt/async_support/xt.py +4628 -0
  177. ccxt/async_support/yobit.py +160 -92
  178. ccxt/async_support/zaif.py +80 -33
  179. ccxt/async_support/zonda.py +140 -69
  180. ccxt/base/errors.py +51 -20
  181. ccxt/base/exchange.py +1722 -480
  182. ccxt/base/precise.py +10 -0
  183. ccxt/base/types.py +223 -4
  184. ccxt/bequant.py +1 -1
  185. ccxt/bigone.py +329 -202
  186. ccxt/binance.py +3030 -1087
  187. ccxt/binancecoinm.py +2 -1
  188. ccxt/binanceus.py +12 -1
  189. ccxt/binanceusdm.py +3 -1
  190. ccxt/bingx.py +3205 -937
  191. ccxt/bit2c.py +119 -38
  192. ccxt/bitbank.py +215 -76
  193. ccxt/bitbns.py +124 -53
  194. ccxt/bitfinex.py +3235 -1078
  195. ccxt/bitfinex1.py +1710 -0
  196. ccxt/bitflyer.py +238 -49
  197. ccxt/bitget.py +1525 -573
  198. ccxt/bithumb.py +198 -65
  199. ccxt/bitmart.py +1320 -435
  200. ccxt/bitmex.py +308 -111
  201. ccxt/bitopro.py +256 -96
  202. ccxt/bitrue.py +365 -233
  203. ccxt/bitso.py +201 -89
  204. ccxt/bitstamp.py +438 -269
  205. ccxt/bitteam.py +179 -73
  206. ccxt/bitvavo.py +180 -70
  207. ccxt/bl3p.py +92 -25
  208. ccxt/blockchaincom.py +193 -79
  209. ccxt/blofin.py +392 -148
  210. ccxt/btcalpha.py +161 -55
  211. ccxt/btcbox.py +250 -34
  212. ccxt/btcmarkets.py +232 -85
  213. ccxt/btcturk.py +159 -60
  214. ccxt/bybit.py +2231 -1193
  215. ccxt/cex.py +1408 -1329
  216. ccxt/coinbase.py +1454 -287
  217. ccxt/coinbaseadvanced.py +17 -0
  218. ccxt/{coinbasepro.py → coinbaseexchange.py} +233 -99
  219. ccxt/coinbaseinternational.py +428 -88
  220. ccxt/coincatch.py +5152 -0
  221. ccxt/coincheck.py +121 -38
  222. ccxt/coinex.py +4020 -3339
  223. ccxt/coinlist.py +273 -116
  224. ccxt/coinmate.py +204 -97
  225. ccxt/coinmetro.py +203 -110
  226. ccxt/coinone.py +142 -68
  227. ccxt/coinsph.py +223 -97
  228. ccxt/coinspot.py +137 -62
  229. ccxt/cryptocom.py +515 -185
  230. ccxt/currencycom.py +203 -85
  231. ccxt/defx.py +2065 -0
  232. ccxt/delta.py +404 -109
  233. ccxt/deribit.py +639 -323
  234. ccxt/digifinex.py +465 -233
  235. ccxt/ellipx.py +1887 -0
  236. ccxt/exmo.py +317 -128
  237. ccxt/gate.py +1472 -463
  238. ccxt/gemini.py +206 -84
  239. ccxt/hashkey.py +4164 -0
  240. ccxt/hitbtc.py +433 -178
  241. ccxt/hollaex.py +207 -83
  242. ccxt/htx.py +1095 -563
  243. ccxt/huobijp.py +178 -56
  244. ccxt/hyperliquid.py +1677 -292
  245. ccxt/idex.py +219 -95
  246. ccxt/independentreserve.py +299 -31
  247. ccxt/indodax.py +226 -62
  248. ccxt/kraken.py +871 -354
  249. ccxt/krakenfutures.py +324 -100
  250. ccxt/kucoin.py +917 -357
  251. ccxt/kucoinfutures.py +1004 -149
  252. ccxt/kuna.py +198 -107
  253. ccxt/latoken.py +199 -79
  254. ccxt/lbank.py +360 -113
  255. ccxt/luno.py +185 -62
  256. ccxt/lykke.py +168 -55
  257. ccxt/mercado.py +101 -29
  258. ccxt/mexc.py +994 -429
  259. ccxt/myokx.py +53 -0
  260. ccxt/ndax.py +234 -82
  261. ccxt/novadax.py +195 -75
  262. ccxt/oceanex.py +244 -59
  263. ccxt/okcoin.py +301 -165
  264. ccxt/okx.py +1776 -454
  265. ccxt/onetrading.py +198 -414
  266. ccxt/oxfun.py +2897 -0
  267. ccxt/p2b.py +142 -52
  268. ccxt/paradex.py +2085 -0
  269. ccxt/paymium.py +56 -32
  270. ccxt/phemex.py +572 -196
  271. ccxt/poloniex.py +218 -95
  272. ccxt/poloniexfutures.py +260 -92
  273. ccxt/pro/__init__.py +29 -5
  274. ccxt/pro/alpaca.py +32 -17
  275. ccxt/pro/ascendex.py +62 -14
  276. ccxt/pro/bequant.py +4 -0
  277. ccxt/pro/binance.py +1596 -329
  278. ccxt/pro/binancecoinm.py +1 -0
  279. ccxt/pro/binanceus.py +2 -9
  280. ccxt/pro/binanceusdm.py +2 -0
  281. ccxt/pro/bingx.py +527 -134
  282. ccxt/pro/bitcoincom.py +4 -1
  283. ccxt/pro/bitfinex.py +731 -266
  284. ccxt/pro/bitfinex1.py +635 -0
  285. ccxt/pro/bitget.py +726 -357
  286. ccxt/pro/bithumb.py +380 -0
  287. ccxt/pro/bitmart.py +143 -39
  288. ccxt/pro/bitmex.py +199 -40
  289. ccxt/pro/bitopro.py +25 -13
  290. ccxt/pro/bitrue.py +31 -32
  291. ccxt/pro/bitstamp.py +7 -6
  292. ccxt/pro/bitvavo.py +203 -81
  293. ccxt/pro/blockchaincom.py +30 -17
  294. ccxt/pro/blofin.py +692 -0
  295. ccxt/pro/bybit.py +791 -82
  296. ccxt/pro/cex.py +99 -51
  297. ccxt/pro/coinbase.py +220 -30
  298. ccxt/{async_support/hitbtc3.py → pro/coinbaseadvanced.py} +5 -5
  299. ccxt/pro/{coinbasepro.py → coinbaseexchange.py} +19 -19
  300. ccxt/pro/coinbaseinternational.py +193 -30
  301. ccxt/pro/coincatch.py +1464 -0
  302. ccxt/pro/coincheck.py +11 -6
  303. ccxt/pro/coinex.py +965 -665
  304. ccxt/pro/coinone.py +17 -10
  305. ccxt/pro/cryptocom.py +446 -66
  306. ccxt/pro/currencycom.py +11 -10
  307. ccxt/pro/defx.py +832 -0
  308. ccxt/pro/deribit.py +167 -31
  309. ccxt/pro/exmo.py +252 -20
  310. ccxt/pro/gate.py +729 -64
  311. ccxt/pro/gemini.py +44 -26
  312. ccxt/pro/hashkey.py +802 -0
  313. ccxt/pro/hitbtc.py +208 -103
  314. ccxt/pro/hollaex.py +25 -9
  315. ccxt/pro/htx.py +83 -39
  316. ccxt/pro/huobijp.py +17 -16
  317. ccxt/pro/hyperliquid.py +502 -31
  318. ccxt/pro/idex.py +28 -13
  319. ccxt/pro/independentreserve.py +21 -16
  320. ccxt/pro/kraken.py +298 -51
  321. ccxt/pro/krakenfutures.py +166 -75
  322. ccxt/pro/kucoin.py +395 -77
  323. ccxt/pro/kucoinfutures.py +400 -99
  324. ccxt/pro/lbank.py +52 -31
  325. ccxt/pro/luno.py +12 -10
  326. ccxt/pro/mexc.py +400 -50
  327. ccxt/pro/myokx.py +28 -0
  328. ccxt/pro/ndax.py +25 -12
  329. ccxt/pro/okcoin.py +28 -9
  330. ccxt/pro/okx.py +935 -124
  331. ccxt/pro/onetrading.py +41 -24
  332. ccxt/pro/oxfun.py +1054 -0
  333. ccxt/pro/p2b.py +100 -24
  334. ccxt/pro/paradex.py +352 -0
  335. ccxt/pro/phemex.py +92 -33
  336. ccxt/pro/poloniex.py +128 -49
  337. ccxt/pro/poloniexfutures.py +53 -32
  338. ccxt/pro/probit.py +92 -85
  339. ccxt/pro/upbit.py +401 -8
  340. ccxt/pro/vertex.py +943 -0
  341. ccxt/pro/wazirx.py +46 -28
  342. ccxt/pro/whitebit.py +65 -12
  343. ccxt/pro/woo.py +437 -65
  344. ccxt/pro/woofipro.py +1271 -0
  345. ccxt/pro/xt.py +1067 -0
  346. ccxt/probit.py +143 -110
  347. ccxt/static_dependencies/__init__.py +1 -1
  348. ccxt/static_dependencies/lark/__init__.py +38 -0
  349. ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
  350. ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
  351. ccxt/static_dependencies/lark/ast_utils.py +59 -0
  352. ccxt/static_dependencies/lark/common.py +86 -0
  353. ccxt/static_dependencies/lark/exceptions.py +292 -0
  354. ccxt/static_dependencies/lark/grammar.py +130 -0
  355. ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
  356. ccxt/static_dependencies/lark/indenter.py +143 -0
  357. ccxt/static_dependencies/lark/lark.py +658 -0
  358. ccxt/static_dependencies/lark/lexer.py +678 -0
  359. ccxt/static_dependencies/lark/load_grammar.py +1428 -0
  360. ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
  361. ccxt/static_dependencies/lark/parser_frontends.py +257 -0
  362. ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
  363. ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
  364. ccxt/static_dependencies/lark/parsers/earley.py +314 -0
  365. ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
  366. ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
  367. ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
  368. ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
  369. ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
  370. ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
  371. ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
  372. ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
  373. ccxt/static_dependencies/lark/py.typed +0 -0
  374. ccxt/static_dependencies/lark/reconstruct.py +107 -0
  375. ccxt/static_dependencies/lark/tools/__init__.py +70 -0
  376. ccxt/static_dependencies/lark/tools/nearley.py +202 -0
  377. ccxt/static_dependencies/lark/tools/serialize.py +32 -0
  378. ccxt/static_dependencies/lark/tools/standalone.py +196 -0
  379. ccxt/static_dependencies/lark/tree.py +267 -0
  380. ccxt/static_dependencies/lark/tree_matcher.py +186 -0
  381. ccxt/static_dependencies/lark/tree_templates.py +180 -0
  382. ccxt/static_dependencies/lark/utils.py +343 -0
  383. ccxt/static_dependencies/lark/visitors.py +596 -0
  384. ccxt/static_dependencies/marshmallow/__init__.py +81 -0
  385. ccxt/static_dependencies/marshmallow/base.py +65 -0
  386. ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
  387. ccxt/static_dependencies/marshmallow/decorators.py +231 -0
  388. ccxt/static_dependencies/marshmallow/error_store.py +60 -0
  389. ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
  390. ccxt/static_dependencies/marshmallow/fields.py +2114 -0
  391. ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
  392. ccxt/static_dependencies/marshmallow/py.typed +0 -0
  393. ccxt/static_dependencies/marshmallow/schema.py +1228 -0
  394. ccxt/static_dependencies/marshmallow/types.py +12 -0
  395. ccxt/static_dependencies/marshmallow/utils.py +378 -0
  396. ccxt/static_dependencies/marshmallow/validate.py +678 -0
  397. ccxt/static_dependencies/marshmallow/warnings.py +2 -0
  398. ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
  399. ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
  400. ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
  401. ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
  402. ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  403. ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
  404. ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
  405. ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
  406. ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
  407. ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  408. ccxt/static_dependencies/starknet/__init__.py +0 -0
  409. ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
  410. ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
  411. ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
  412. ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
  413. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
  414. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
  415. ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
  416. ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
  417. ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
  418. ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
  419. ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
  420. ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
  421. ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
  422. ccxt/static_dependencies/starknet/common.py +15 -0
  423. ccxt/static_dependencies/starknet/constants.py +39 -0
  424. ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
  425. ccxt/static_dependencies/starknet/hash/address.py +79 -0
  426. ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
  427. ccxt/static_dependencies/starknet/hash/selector.py +16 -0
  428. ccxt/static_dependencies/starknet/hash/storage.py +12 -0
  429. ccxt/static_dependencies/starknet/hash/utils.py +78 -0
  430. ccxt/static_dependencies/starknet/models/__init__.py +0 -0
  431. ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
  432. ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
  433. ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
  434. ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
  435. ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
  436. ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
  437. ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
  438. ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
  439. ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
  440. ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
  441. ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
  442. ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
  443. ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
  444. ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
  445. ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
  446. ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
  447. ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
  448. ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
  449. ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
  450. ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
  451. ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
  452. ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
  453. ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
  454. ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
  455. ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
  456. ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
  457. ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
  458. ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
  459. ccxt/static_dependencies/starknet/utils/schema.py +13 -0
  460. ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
  461. ccxt/static_dependencies/starkware/__init__.py +0 -0
  462. ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
  463. ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
  464. ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
  465. ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
  466. ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
  467. ccxt/static_dependencies/sympy/__init__.py +0 -0
  468. ccxt/static_dependencies/sympy/core/__init__.py +0 -0
  469. ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
  470. ccxt/static_dependencies/sympy/external/__init__.py +0 -0
  471. ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
  472. ccxt/static_dependencies/sympy/external/importtools.py +187 -0
  473. ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
  474. ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
  475. ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
  476. ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
  477. ccxt/test/{test_async.py → tests_async.py} +456 -391
  478. ccxt/test/tests_helpers.py +285 -0
  479. ccxt/test/tests_init.py +39 -0
  480. ccxt/test/{test_sync.py → tests_sync.py} +456 -393
  481. ccxt/timex.py +123 -70
  482. ccxt/tokocrypto.py +129 -93
  483. ccxt/tradeogre.py +39 -25
  484. ccxt/upbit.py +322 -113
  485. ccxt/vertex.py +2983 -0
  486. ccxt/wavesexchange.py +227 -173
  487. ccxt/wazirx.py +145 -65
  488. ccxt/whitebit.py +533 -138
  489. ccxt/woo.py +1137 -296
  490. ccxt/woofipro.py +2716 -0
  491. ccxt/xt.py +4627 -0
  492. ccxt/yobit.py +159 -92
  493. ccxt/zaif.py +80 -33
  494. ccxt/zonda.py +140 -69
  495. ccxt-4.4.49.dist-info/LICENSE.txt +21 -0
  496. ccxt-4.4.49.dist-info/METADATA +646 -0
  497. ccxt-4.4.49.dist-info/RECORD +669 -0
  498. {ccxt-4.2.77.dist-info → ccxt-4.4.49.dist-info}/WHEEL +1 -1
  499. ccxt/abstract/bitbay.py +0 -47
  500. ccxt/abstract/bitfinex2.py +0 -139
  501. ccxt/abstract/hitbtc3.py +0 -115
  502. ccxt/async_support/bitbay.py +0 -17
  503. ccxt/async_support/bitfinex2.py +0 -3496
  504. ccxt/async_support/flowbtc.py +0 -34
  505. ccxt/bitbay.py +0 -17
  506. ccxt/bitfinex2.py +0 -3496
  507. ccxt/flowbtc.py +0 -34
  508. ccxt/hitbtc3.py +0 -16
  509. ccxt/pro/bitfinex2.py +0 -1081
  510. ccxt/test/base/__init__.py +0 -28
  511. ccxt/test/base/test_account.py +0 -26
  512. ccxt/test/base/test_balance.py +0 -56
  513. ccxt/test/base/test_borrow_interest.py +0 -35
  514. ccxt/test/base/test_borrow_rate.py +0 -32
  515. ccxt/test/base/test_calculate_fee.py +0 -51
  516. ccxt/test/base/test_crypto.py +0 -127
  517. ccxt/test/base/test_currency.py +0 -76
  518. ccxt/test/base/test_datetime.py +0 -103
  519. ccxt/test/base/test_decimal_to_precision.py +0 -392
  520. ccxt/test/base/test_deep_extend.py +0 -68
  521. ccxt/test/base/test_deposit_withdrawal.py +0 -50
  522. ccxt/test/base/test_exchange_datetime_functions.py +0 -76
  523. ccxt/test/base/test_funding_rate_history.py +0 -29
  524. ccxt/test/base/test_last_price.py +0 -32
  525. ccxt/test/base/test_ledger_entry.py +0 -45
  526. ccxt/test/base/test_ledger_item.py +0 -48
  527. ccxt/test/base/test_leverage_tier.py +0 -33
  528. ccxt/test/base/test_margin_mode.py +0 -24
  529. ccxt/test/base/test_margin_modification.py +0 -35
  530. ccxt/test/base/test_market.py +0 -190
  531. ccxt/test/base/test_number.py +0 -411
  532. ccxt/test/base/test_ohlcv.py +0 -32
  533. ccxt/test/base/test_open_interest.py +0 -32
  534. ccxt/test/base/test_order.py +0 -64
  535. ccxt/test/base/test_order_book.py +0 -63
  536. ccxt/test/base/test_position.py +0 -60
  537. ccxt/test/base/test_shared_methods.py +0 -345
  538. ccxt/test/base/test_status.py +0 -24
  539. ccxt/test/base/test_throttle.py +0 -126
  540. ccxt/test/base/test_ticker.py +0 -86
  541. ccxt/test/base/test_trade.py +0 -47
  542. ccxt/test/base/test_trading_fee.py +0 -26
  543. ccxt/test/base/test_transaction.py +0 -39
  544. ccxt-4.2.77.dist-info/METADATA +0 -626
  545. ccxt-4.2.77.dist-info/RECORD +0 -534
  546. {ccxt-4.2.77.dist-info → ccxt-4.4.49.dist-info}/top_level.txt +0 -0
ccxt/exmo.py CHANGED
@@ -6,9 +6,10 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.exmo 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
9
+ from ccxt.base.types import Balances, Currencies, Currency, DepositAddress, Int, MarginModification, Market, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees, Transaction
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 ArgumentsRequired
14
15
  from ccxt.base.errors import BadRequest
@@ -18,7 +19,6 @@ from ccxt.base.errors import OrderNotFound
18
19
  from ccxt.base.errors import RateLimitExceeded
19
20
  from ccxt.base.errors import OnMaintenance
20
21
  from ccxt.base.errors import InvalidNonce
21
- from ccxt.base.errors import AuthenticationError
22
22
  from ccxt.base.decimal_to_precision import TICK_SIZE
23
23
  from ccxt.base.precise import Precise
24
24
 
@@ -30,7 +30,7 @@ class exmo(Exchange, ImplicitAPI):
30
30
  'id': 'exmo',
31
31
  'name': 'EXMO',
32
32
  'countries': ['LT'], # Lithuania
33
- 'rateLimit': 350, # once every 350 ms ≈ 180 requests per minute ≈ 3 requests per second
33
+ 'rateLimit': 100, # 10 requests per 1 second
34
34
  'version': 'v1.1',
35
35
  'has': {
36
36
  'CORS': None,
@@ -43,6 +43,9 @@ class exmo(Exchange, ImplicitAPI):
43
43
  'cancelOrder': True,
44
44
  'cancelOrders': False,
45
45
  'createDepositAddress': False,
46
+ 'createMarketBuyOrder': True,
47
+ 'createMarketBuyOrderWithCost': True,
48
+ 'createMarketOrderWithCost': True,
46
49
  'createOrder': True,
47
50
  'createStopLimitOrder': True,
48
51
  'createStopMarketOrder': True,
@@ -54,6 +57,8 @@ class exmo(Exchange, ImplicitAPI):
54
57
  'fetchCurrencies': True,
55
58
  'fetchDeposit': True,
56
59
  'fetchDepositAddress': True,
60
+ 'fetchDepositAddresses': False,
61
+ 'fetchDepositAddressesByNetwork': False,
57
62
  'fetchDeposits': True,
58
63
  'fetchDepositsWithdrawals': True,
59
64
  'fetchDepositWithdrawFee': 'emulated',
@@ -74,7 +79,12 @@ class exmo(Exchange, ImplicitAPI):
74
79
  'fetchOrderBook': True,
75
80
  'fetchOrderBooks': True,
76
81
  'fetchOrderTrades': True,
82
+ 'fetchPosition': False,
83
+ 'fetchPositionHistory': False,
77
84
  'fetchPositionMode': False,
85
+ 'fetchPositions': False,
86
+ 'fetchPositionsHistory': False,
87
+ 'fetchPositionsRisk': False,
78
88
  'fetchPremiumIndexOHLCV': False,
79
89
  'fetchTicker': True,
80
90
  'fetchTickers': True,
@@ -210,12 +220,71 @@ class exmo(Exchange, ImplicitAPI):
210
220
  'fillResponseFromRequest': True,
211
221
  },
212
222
  },
223
+ 'features': {
224
+ 'spot': {
225
+ 'sandbox': False,
226
+ 'createOrder': {
227
+ 'marginMode': True, # todo revise
228
+ 'triggerPrice': True, # todo: endpoint lacks other features
229
+ 'triggerPriceType': None,
230
+ 'triggerDirection': False,
231
+ 'stopLossPrice': False,
232
+ 'takeProfitPrice': False,
233
+ 'attachedStopLossTakeProfit': None,
234
+ 'timeInForce': {
235
+ 'IOC': True,
236
+ 'FOK': True,
237
+ 'PO': True,
238
+ 'GTD': True,
239
+ },
240
+ 'hedged': False,
241
+ 'selfTradePrevention': False,
242
+ 'trailing': False,
243
+ 'leverage': True,
244
+ 'marketBuyByCost': True,
245
+ 'marketBuyRequiresPrice': False,
246
+ 'iceberg': False,
247
+ },
248
+ 'createOrders': None,
249
+ 'fetchMyTrades': {
250
+ 'marginMode': True,
251
+ 'limit': 100,
252
+ 'daysBack': None,
253
+ 'untilDays': None,
254
+ },
255
+ 'fetchOrder': {
256
+ 'marginMode': False,
257
+ 'trigger': False,
258
+ 'trailing': False,
259
+ },
260
+ 'fetchOpenOrders': {
261
+ 'marginMode': False,
262
+ 'limit': None,
263
+ 'trigger': False,
264
+ 'trailing': False,
265
+ },
266
+ 'fetchOrders': None,
267
+ 'fetchClosedOrders': None,
268
+ 'fetchOHLCV': {
269
+ 'limit': 1000, # todo, not in request
270
+ },
271
+ },
272
+ 'swap': {
273
+ 'linear': None,
274
+ 'inverse': None,
275
+ },
276
+ 'future': {
277
+ 'linear': None,
278
+ 'inverse': None,
279
+ },
280
+ },
213
281
  'commonCurrencies': {
214
282
  'GMT': 'GMT Token',
215
283
  },
216
284
  'precisionMode': TICK_SIZE,
217
285
  'exceptions': {
218
286
  'exact': {
287
+ '140333': InvalidOrder, # {"error":{"code":140333,"msg":"The number of characters after the point in the price exceeds the maximum number '8\u003e6'"}}
219
288
  '140434': BadRequest,
220
289
  '40005': AuthenticationError, # Authorization error, incorrect signature
221
290
  '40009': InvalidNonce, #
@@ -245,7 +314,7 @@ class exmo(Exchange, ImplicitAPI):
245
314
  def modify_margin_helper(self, symbol: str, amount, type, params={}):
246
315
  self.load_markets()
247
316
  market = self.market(symbol)
248
- request = {
317
+ request: dict = {
249
318
  'position_id': market['id'],
250
319
  'quantity': amount,
251
320
  }
@@ -265,24 +334,29 @@ class exmo(Exchange, ImplicitAPI):
265
334
  margin['amount'] = amount
266
335
  return margin
267
336
 
268
- def parse_margin_modification(self, data, market: Market = None):
337
+ def parse_margin_modification(self, data: dict, market: Market = None) -> MarginModification:
269
338
  #
270
339
  # {}
271
340
  #
272
341
  return {
273
342
  'info': data,
343
+ 'symbol': self.safe_symbol(None, market),
274
344
  'type': None,
345
+ 'marginMode': 'isolated',
275
346
  'amount': None,
276
- 'code': self.safe_value(market, 'quote'),
277
- 'symbol': self.safe_symbol(None, market),
278
347
  'total': None,
348
+ 'code': self.safe_value(market, 'quote'),
279
349
  'status': 'ok',
350
+ 'timestamp': None,
351
+ 'datetime': None,
280
352
  }
281
353
 
282
- def reduce_margin(self, symbol: str, amount, params={}):
354
+ def reduce_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
283
355
  """
284
356
  remove margin from a position
285
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#eebf9f25-0289-4946-9482-89872c738449
357
+
358
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#eebf9f25-0289-4946-9482-89872c738449
359
+
286
360
  :param str symbol: unified market symbol
287
361
  :param float amount: the amount of margin to remove
288
362
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -290,10 +364,12 @@ class exmo(Exchange, ImplicitAPI):
290
364
  """
291
365
  return self.modify_margin_helper(symbol, amount, 'reduce', params)
292
366
 
293
- def add_margin(self, symbol: str, amount, params={}):
367
+ def add_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
294
368
  """
295
369
  add margin
296
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#143ef808-79ca-4e49-9e79-a60ea4d8c0e3
370
+
371
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#143ef808-79ca-4e49-9e79-a60ea4d8c0e3
372
+
297
373
  :param str symbol: unified market symbol
298
374
  :param float amount: amount of margin to add
299
375
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -301,11 +377,13 @@ class exmo(Exchange, ImplicitAPI):
301
377
  """
302
378
  return self.modify_margin_helper(symbol, amount, 'add', params)
303
379
 
304
- def fetch_trading_fees(self, params={}):
380
+ def fetch_trading_fees(self, params={}) -> TradingFees:
305
381
  """
306
382
  fetch the trading fees for multiple markets
307
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#90927062-256c-4b03-900f-2b99131f9a54
308
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#7de7e75c-5833-45a8-b937-c2276d235aaa
383
+
384
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#90927062-256c-4b03-900f-2b99131f9a54
385
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#7de7e75c-5833-45a8-b937-c2276d235aaa
386
+
309
387
  :param dict [params]: extra parameters specific to the exchange API endpoint
310
388
  :returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
311
389
  """
@@ -351,7 +429,7 @@ class exmo(Exchange, ImplicitAPI):
351
429
  # }
352
430
  #
353
431
  pairs = self.safe_value(response, 'pairs', [])
354
- result = {}
432
+ result: dict = {}
355
433
  for i in range(0, len(pairs)):
356
434
  pair = pairs[i]
357
435
  marketId = self.safe_string(pair, 'name')
@@ -388,7 +466,7 @@ class exmo(Exchange, ImplicitAPI):
388
466
  # },
389
467
  # }
390
468
  #
391
- result = {}
469
+ result: dict = {}
392
470
  for i in range(0, len(self.symbols)):
393
471
  symbol = self.symbols[i]
394
472
  market = self.market(symbol)
@@ -420,11 +498,13 @@ class exmo(Exchange, ImplicitAPI):
420
498
  raise ExchangeError(self.id + ' parseFixedFloatValue() detected an unsupported non-zero percentage-based fee ' + input)
421
499
  return result
422
500
 
423
- def fetch_transaction_fees(self, codes: List[str] = None, params={}):
501
+ def fetch_transaction_fees(self, codes: Strings = None, params={}):
424
502
  """
425
- * @deprecated
503
+ @deprecated
426
504
  please use fetchDepositWithdrawFees instead
427
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#4190035d-24b1-453d-833b-37e0a52f88e2
505
+
506
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#4190035d-24b1-453d-833b-37e0a52f88e2
507
+
428
508
  :param str[]|None codes: list of unified currency codes
429
509
  :param dict [params]: extra parameters specific to the exchange API endpoint
430
510
  :returns dict: a list of `transaction fees structures <https://docs.ccxt.com/#/?id=fees-structure>`
@@ -465,7 +545,7 @@ class exmo(Exchange, ImplicitAPI):
465
545
  # ],
466
546
  # }
467
547
  #
468
- result = {}
548
+ result: dict = {}
469
549
  cryptoListKeys = list(cryptoList.keys())
470
550
  for i in range(0, len(cryptoListKeys)):
471
551
  code = cryptoListKeys[i]
@@ -492,7 +572,9 @@ class exmo(Exchange, ImplicitAPI):
492
572
  def fetch_deposit_withdraw_fees(self, codes: Strings = None, params={}):
493
573
  """
494
574
  fetch deposit and withdraw fees
495
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#4190035d-24b1-453d-833b-37e0a52f88e2
575
+
576
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#4190035d-24b1-453d-833b-37e0a52f88e2
577
+
496
578
  :param str[]|None codes: list of unified currency codes
497
579
  :param dict [params]: extra parameters specific to the exchange API endpoint
498
580
  :returns dict: a list of `transaction fees structures <https://docs.ccxt.com/#/?id=fees-structure>`
@@ -571,11 +653,13 @@ class exmo(Exchange, ImplicitAPI):
571
653
  }
572
654
  return self.assign_default_deposit_withdraw_fees(result)
573
655
 
574
- def fetch_currencies(self, params={}):
656
+ def fetch_currencies(self, params={}) -> Currencies:
575
657
  """
576
658
  fetches all available currencies on an exchange
577
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#7cdf0ca8-9ff6-4cf3-aa33-bcec83155c49
578
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#4190035d-24b1-453d-833b-37e0a52f88e2
659
+
660
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#7cdf0ca8-9ff6-4cf3-aa33-bcec83155c49
661
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#4190035d-24b1-453d-833b-37e0a52f88e2
662
+
579
663
  :param dict [params]: extra parameters specific to the exchange API endpoint
580
664
  :returns dict: an associative dictionary of currencies
581
665
  """
@@ -614,7 +698,7 @@ class exmo(Exchange, ImplicitAPI):
614
698
  # ],
615
699
  # }
616
700
  #
617
- result = {}
701
+ result: dict = {}
618
702
  for i in range(0, len(currencyList)):
619
703
  currency = currencyList[i]
620
704
  currencyId = self.safe_string(currency, 'name')
@@ -622,7 +706,7 @@ class exmo(Exchange, ImplicitAPI):
622
706
  providers = self.safe_value(cryptoList, currencyId)
623
707
  active = False
624
708
  type = 'crypto'
625
- limits = {
709
+ limits: dict = {
626
710
  'deposit': {
627
711
  'min': None,
628
712
  'max': None,
@@ -683,10 +767,12 @@ class exmo(Exchange, ImplicitAPI):
683
767
  }
684
768
  return result
685
769
 
686
- def fetch_markets(self, params={}):
770
+ def fetch_markets(self, params={}) -> List[Market]:
687
771
  """
688
772
  retrieves data on all markets for exmo
689
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#7de7e75c-5833-45a8-b937-c2276d235aaa
773
+
774
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#7de7e75c-5833-45a8-b937-c2276d235aaa
775
+
690
776
  :param dict [params]: extra parameters specific to the exchange API endpoint
691
777
  :returns dict[]: an array of objects representing market data
692
778
  """
@@ -706,7 +792,7 @@ class exmo(Exchange, ImplicitAPI):
706
792
  # },
707
793
  # }
708
794
  #
709
- marginPairsDict = {}
795
+ marginPairsDict: dict = {}
710
796
  if self.check_required_credentials(False):
711
797
  marginPairs = self.privatePostMarginPairList(params)
712
798
  #
@@ -810,40 +896,48 @@ class exmo(Exchange, ImplicitAPI):
810
896
  def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
811
897
  """
812
898
  fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
813
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#65eeb949-74e5-4631-9184-c38387fe53e8
899
+
900
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#65eeb949-74e5-4631-9184-c38387fe53e8
901
+
814
902
  :param str symbol: unified symbol of the market to fetch OHLCV data for
815
903
  :param str timeframe: the length of time each candle represents
816
904
  :param int [since]: timestamp in ms of the earliest candle to fetch
817
905
  :param int [limit]: the maximum amount of candles to fetch
818
906
  :param dict [params]: extra parameters specific to the exchange API endpoint
907
+ :param int [params.until]: timestamp in ms of the latest candle to fetch
819
908
  :returns int[][]: A list of candles ordered, open, high, low, close, volume
820
909
  """
821
910
  self.load_markets()
822
911
  market = self.market(symbol)
823
- request = {
912
+ until = self.safe_integer_product(params, 'until', 0.001)
913
+ untilIsDefined = (until is not None)
914
+ request: dict = {
824
915
  'symbol': market['id'],
825
916
  'resolution': self.safe_string(self.timeframes, timeframe, timeframe),
826
917
  }
827
- options = self.safe_value(self.options, 'fetchOHLCV')
828
- maxLimit = self.safe_integer(options, 'maxLimit', 3000)
918
+ maxLimit = 3000
829
919
  duration = self.parse_timeframe(timeframe)
830
- now = self.milliseconds()
920
+ now = self.parse_to_int(self.milliseconds() / 1000)
831
921
  if since is None:
922
+ to = min(until, now) if untilIsDefined else now
832
923
  if limit is None:
833
924
  limit = 1000 # cap default at generous amount
834
- if limit > maxLimit:
835
- limit = maxLimit # avoid exception
836
- request['from'] = self.parse_to_int(now / 1000) - limit * duration - 1
837
- request['to'] = self.parse_to_int(now / 1000)
925
+ else:
926
+ limit = min(limit, maxLimit)
927
+ request['from'] = to - (limit * duration) - 1
928
+ request['to'] = to
838
929
  else:
839
930
  request['from'] = self.parse_to_int(since / 1000) - 1
840
- if limit is None:
841
- request['to'] = self.parse_to_int(now / 1000)
931
+ if untilIsDefined:
932
+ request['to'] = min(until, now)
842
933
  else:
843
- if limit > maxLimit:
844
- raise BadRequest(self.id + ' fetchOHLCV() will serve ' + str(maxLimit) + ' candles at most')
845
- to = self.sum(since, limit * duration * 1000)
846
- request['to'] = self.parse_to_int(to / 1000)
934
+ if limit is None:
935
+ limit = maxLimit
936
+ else:
937
+ limit = min(limit, maxLimit)
938
+ to = self.sum(since, limit * duration)
939
+ request['to'] = min(to, now)
940
+ params = self.omit(params, 'until')
847
941
  response = self.publicGetCandlesHistory(self.extend(request, params))
848
942
  #
849
943
  # {
@@ -854,7 +948,7 @@ class exmo(Exchange, ImplicitAPI):
854
948
  # ]
855
949
  # }
856
950
  #
857
- candles = self.safe_value(response, 'candles', [])
951
+ candles = self.safe_list(response, 'candles', [])
858
952
  return self.parse_ohlcvs(candles, market, timeframe, since, limit)
859
953
 
860
954
  def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
@@ -878,7 +972,7 @@ class exmo(Exchange, ImplicitAPI):
878
972
  ]
879
973
 
880
974
  def parse_balance(self, response) -> Balances:
881
- result = {'info': response}
975
+ result: dict = {'info': response}
882
976
  wallets = self.safe_value(response, 'wallets')
883
977
  if wallets is not None:
884
978
  currencyIds = list(wallets.keys())
@@ -909,8 +1003,10 @@ class exmo(Exchange, ImplicitAPI):
909
1003
  def fetch_balance(self, params={}) -> Balances:
910
1004
  """
911
1005
  query for balance and get the amount of funds available for trading or funds locked in orders
912
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#59c5160f-27a1-4d9a-8cfb-7979c7ffaac6
913
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#c8388df7-1f9f-4d41-81c4-5a387d171dc6
1006
+
1007
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#59c5160f-27a1-4d9a-8cfb-7979c7ffaac6
1008
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#c8388df7-1f9f-4d41-81c4-5a387d171dc6
1009
+
914
1010
  :param dict [params]: extra parameters specific to the exchange API endpoint
915
1011
  :param str [params.marginMode]: *isolated* fetches the isolated margin balance
916
1012
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
@@ -953,7 +1049,9 @@ class exmo(Exchange, ImplicitAPI):
953
1049
  def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
954
1050
  """
955
1051
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
956
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#c60c51a8-e683-4f45-a000-820723d37871
1052
+
1053
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#c60c51a8-e683-4f45-a000-820723d37871
1054
+
957
1055
  :param str symbol: unified symbol of the market to fetch the order book for
958
1056
  :param int [limit]: the maximum amount of order book entries to return
959
1057
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -961,19 +1059,21 @@ class exmo(Exchange, ImplicitAPI):
961
1059
  """
962
1060
  self.load_markets()
963
1061
  market = self.market(symbol)
964
- request = {
1062
+ request: dict = {
965
1063
  'pair': market['id'],
966
1064
  }
967
1065
  if limit is not None:
968
1066
  request['limit'] = limit
969
1067
  response = self.publicGetOrderBook(self.extend(request, params))
970
- result = self.safe_value(response, market['id'])
1068
+ result = self.safe_dict(response, market['id'])
971
1069
  return self.parse_order_book(result, market['symbol'], None, 'bid', 'ask')
972
1070
 
973
1071
  def fetch_order_books(self, symbols: Strings = None, limit: Int = None, params={}):
974
1072
  """
975
1073
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data for multiple markets
976
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#c60c51a8-e683-4f45-a000-820723d37871
1074
+
1075
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#c60c51a8-e683-4f45-a000-820723d37871
1076
+
977
1077
  :param str[]|None symbols: list of unified market symbols, all symbols fetched if None, default is None
978
1078
  :param int [limit]: max number of entries per orderbook to return, default is None
979
1079
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -990,13 +1090,13 @@ class exmo(Exchange, ImplicitAPI):
990
1090
  else:
991
1091
  ids = self.market_ids(symbols)
992
1092
  ids = ','.join(ids)
993
- request = {
1093
+ request: dict = {
994
1094
  'pair': ids,
995
1095
  }
996
1096
  if limit is not None:
997
1097
  request['limit'] = limit
998
1098
  response = self.publicGetOrderBook(self.extend(request, params))
999
- result = {}
1099
+ result: dict = {}
1000
1100
  marketIds = list(response.keys())
1001
1101
  for i in range(0, len(marketIds)):
1002
1102
  marketId = marketIds[i]
@@ -1004,7 +1104,7 @@ class exmo(Exchange, ImplicitAPI):
1004
1104
  result[symbol] = self.parse_order_book(response[marketId], symbol, None, 'bid', 'ask')
1005
1105
  return result
1006
1106
 
1007
- def parse_ticker(self, ticker, market: Market = None) -> Ticker:
1107
+ def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
1008
1108
  #
1009
1109
  # {
1010
1110
  # "buy_price":"0.00002996",
@@ -1047,7 +1147,9 @@ class exmo(Exchange, ImplicitAPI):
1047
1147
  def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
1048
1148
  """
1049
1149
  fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
1050
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#4c8e6459-3503-4361-b012-c34bb9f7e385
1150
+
1151
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#4c8e6459-3503-4361-b012-c34bb9f7e385
1152
+
1051
1153
  :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1052
1154
  :param dict [params]: extra parameters specific to the exchange API endpoint
1053
1155
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -1070,7 +1172,7 @@ class exmo(Exchange, ImplicitAPI):
1070
1172
  # }
1071
1173
  # }
1072
1174
  #
1073
- result = {}
1175
+ result: dict = {}
1074
1176
  marketIds = list(response.keys())
1075
1177
  for i in range(0, len(marketIds)):
1076
1178
  marketId = marketIds[i]
@@ -1083,7 +1185,9 @@ class exmo(Exchange, ImplicitAPI):
1083
1185
  def fetch_ticker(self, symbol: str, params={}) -> Ticker:
1084
1186
  """
1085
1187
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
1086
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#4c8e6459-3503-4361-b012-c34bb9f7e385
1188
+
1189
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#4c8e6459-3503-4361-b012-c34bb9f7e385
1190
+
1087
1191
  :param str symbol: unified symbol of the market to fetch the ticker for
1088
1192
  :param dict [params]: extra parameters specific to the exchange API endpoint
1089
1193
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -1093,7 +1197,7 @@ class exmo(Exchange, ImplicitAPI):
1093
1197
  market = self.market(symbol)
1094
1198
  return self.parse_ticker(response[market['id']], market)
1095
1199
 
1096
- def parse_trade(self, trade, market: Market = None) -> Trade:
1200
+ def parse_trade(self, trade: dict, market: Market = None) -> Trade:
1097
1201
  #
1098
1202
  # fetchTrades(public)
1099
1203
  #
@@ -1183,7 +1287,9 @@ class exmo(Exchange, ImplicitAPI):
1183
1287
  def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
1184
1288
  """
1185
1289
  get the list of most recent trades for a particular symbol
1186
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#5a5a9c0d-cf17-47f6-9d62-6d4404ebd5ac
1290
+
1291
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#5a5a9c0d-cf17-47f6-9d62-6d4404ebd5ac
1292
+
1187
1293
  :param str symbol: unified symbol of the market to fetch trades for
1188
1294
  :param int [since]: timestamp in ms of the earliest trade to fetch
1189
1295
  :param int [limit]: the maximum amount of trades to fetch
@@ -1192,7 +1298,7 @@ class exmo(Exchange, ImplicitAPI):
1192
1298
  """
1193
1299
  self.load_markets()
1194
1300
  market = self.market(symbol)
1195
- request = {
1301
+ request: dict = {
1196
1302
  'pair': market['id'],
1197
1303
  }
1198
1304
  response = self.publicGetTrades(self.extend(request, params))
@@ -1218,20 +1324,22 @@ class exmo(Exchange, ImplicitAPI):
1218
1324
  # ]
1219
1325
  # }
1220
1326
  #
1221
- data = self.safe_value(response, market['id'], [])
1327
+ data = self.safe_list(response, market['id'], [])
1222
1328
  return self.parse_trades(data, market, since, limit)
1223
1329
 
1224
1330
  def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1225
1331
  """
1226
1332
  fetch all trades made by the user
1227
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#b8d8d9af-4f46-46a1-939b-ad261d79f452 # spot
1228
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#f4b1aaf8-399f-403b-ab5e-4926d967a106 # margin
1333
+
1334
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#b8d8d9af-4f46-46a1-939b-ad261d79f452 # spot
1335
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#f4b1aaf8-399f-403b-ab5e-4926d967a106 # margin
1336
+
1229
1337
  :param str symbol: a symbol is required but it can be a single string, or a non-empty array
1230
1338
  :param int [since]: the earliest time in ms to fetch trades for
1231
1339
  :param int [limit]: *required for margin orders* the maximum number of trades structures to retrieve
1232
1340
  :param dict [params]: extra parameters specific to the exchange API endpoint
1233
- *
1234
- * EXCHANGE SPECIFIC PARAMETERS
1341
+
1342
+ EXCHANGE SPECIFIC PARAMETERS
1235
1343
  :param int [params.offset]: last deal offset, default = 0
1236
1344
  :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
1237
1345
  """
@@ -1247,7 +1355,7 @@ class exmo(Exchange, ImplicitAPI):
1247
1355
  isSpot = marginMode != 'isolated'
1248
1356
  if limit is None:
1249
1357
  limit = 100
1250
- request = {}
1358
+ request: dict = {}
1251
1359
  if isSpot:
1252
1360
  request['pair'] = pair
1253
1361
  else:
@@ -1313,21 +1421,70 @@ class exmo(Exchange, ImplicitAPI):
1313
1421
  result = self.array_concat(result, trades)
1314
1422
  return self.filter_by_since_limit(result, since, limit)
1315
1423
 
1424
+ def create_market_order_with_cost(self, symbol: str, side: OrderSide, cost: float, params={}):
1425
+ """
1426
+ create a market order by providing the symbol, side and cost
1427
+
1428
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#80daa469-ec59-4d0a-b229-6a311d8dd1cd
1429
+
1430
+ :param str symbol: unified symbol of the market to create an order in
1431
+ :param str side: 'buy' or 'sell'
1432
+ :param float cost: how much you want to trade in units of the quote currency
1433
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1434
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1435
+ """
1436
+ self.load_markets()
1437
+ params = self.extend(params, {'cost': cost})
1438
+ return self.create_order(symbol, 'market', side, cost, None, params)
1439
+
1440
+ def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
1441
+ """
1442
+ create a market buy order by providing the symbol and cost
1443
+
1444
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#80daa469-ec59-4d0a-b229-6a311d8dd1cd
1445
+
1446
+ :param str symbol: unified symbol of the market to create an order in
1447
+ :param float cost: how much you want to trade in units of the quote currency
1448
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1449
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1450
+ """
1451
+ self.load_markets()
1452
+ params = self.extend(params, {'cost': cost})
1453
+ return self.create_order(symbol, 'market', 'buy', cost, None, params)
1454
+
1455
+ def create_market_sell_order_with_cost(self, symbol: str, cost: float, params={}):
1456
+ """
1457
+ create a market sell order by providing the symbol and cost
1458
+
1459
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#80daa469-ec59-4d0a-b229-6a311d8dd1cd
1460
+
1461
+ :param str symbol: unified symbol of the market to create an order in
1462
+ :param float cost: how much you want to trade in units of the quote currency
1463
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1464
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1465
+ """
1466
+ self.load_markets()
1467
+ params = self.extend(params, {'cost': cost})
1468
+ return self.create_order(symbol, 'market', 'sell', cost, None, params)
1469
+
1316
1470
  def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1317
1471
  """
1318
1472
  create a trade order
1319
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#80daa469-ec59-4d0a-b229-6a311d8dd1cd
1320
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#de6f4321-eeac-468c-87f7-c4ad7062e265 # stop market
1321
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#3561b86c-9ff1-436e-8e68-ac926b7eb523 # margin
1473
+
1474
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#80daa469-ec59-4d0a-b229-6a311d8dd1cd
1475
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#de6f4321-eeac-468c-87f7-c4ad7062e265 # stop market
1476
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#3561b86c-9ff1-436e-8e68-ac926b7eb523 # margin
1477
+
1322
1478
  :param str symbol: unified symbol of the market to create an order in
1323
1479
  :param str type: 'market' or 'limit'
1324
1480
  :param str side: 'buy' or 'sell'
1325
1481
  :param float amount: how much of currency you want to trade in units of base currency
1326
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1482
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1327
1483
  :param dict [params]: extra parameters specific to the exchange API endpoint
1328
- :param float [params.stopPrice]: the price at which a trigger order is triggered at
1484
+ :param float [params.triggerPrice]: the price at which a trigger order is triggered at
1329
1485
  :param str [params.timeInForce]: *spot only* 'fok', 'ioc' or 'post_only'
1330
1486
  :param boolean [params.postOnly]: *spot only* True for post only orders
1487
+ :param float [params.cost]: *spot only* *market orders only* the cost of the order in the quote currency for market orders
1331
1488
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1332
1489
  """
1333
1490
  self.load_markets()
@@ -1338,11 +1495,12 @@ class exmo(Exchange, ImplicitAPI):
1338
1495
  if marginMode == 'cross':
1339
1496
  raise BadRequest(self.id + ' only supports isolated margin')
1340
1497
  isSpot = (marginMode != 'isolated')
1341
- triggerPrice = self.safe_number_n(params, ['triggerPrice', 'stopPrice', 'stop_price'])
1342
- request = {
1498
+ triggerPrice = self.safe_string_n(params, ['triggerPrice', 'stopPrice', 'stop_price'])
1499
+ cost = self.safe_string(params, 'cost')
1500
+ request: dict = {
1343
1501
  'pair': market['id'],
1344
1502
  # 'leverage': 2,
1345
- 'quantity': self.amount_to_precision(market['symbol'], amount),
1503
+ # 'quantity': self.amount_to_precision(market['symbol'], amount),
1346
1504
  # spot - buy, sell, market_buy, market_sell, market_buy_total, market_sell_total
1347
1505
  # margin - limit_buy, limit_sell, market_buy, market_sell, stop_buy, stop_sell, stop_limit_buy, stop_limit_sell, trailing_stop_buy, trailing_stop_sell
1348
1506
  # 'stop_price': self.price_to_precision(symbol, stopPrice),
@@ -1351,6 +1509,10 @@ class exmo(Exchange, ImplicitAPI):
1351
1509
  # 'client_id': 123, # optional, must be a positive integer
1352
1510
  # 'comment': '', # up to 50 latin symbols, whitespaces, underscores
1353
1511
  }
1512
+ if cost is None:
1513
+ request['quantity'] = self.amount_to_precision(market['symbol'], amount)
1514
+ else:
1515
+ request['quantity'] = self.cost_to_precision(market['symbol'], cost)
1354
1516
  clientOrderId = self.safe_value_2(params, 'client_id', 'clientOrderId')
1355
1517
  if clientOrderId is not None:
1356
1518
  clientOrderId = self.safe_integer_2(params, 'client_id', 'clientOrderId')
@@ -1361,7 +1523,7 @@ class exmo(Exchange, ImplicitAPI):
1361
1523
  leverage = self.safe_number(params, 'leverage')
1362
1524
  if not isSpot and (leverage is None):
1363
1525
  raise ArgumentsRequired(self.id + ' createOrder requires an extra param params["leverage"] for margin orders')
1364
- params = self.omit(params, ['stopPrice', 'stop_price', 'triggerPrice', 'timeInForce', 'client_id', 'clientOrderId'])
1526
+ params = self.omit(params, ['stopPrice', 'stop_price', 'triggerPrice', 'timeInForce', 'client_id', 'clientOrderId', 'cost'])
1365
1527
  if price is not None:
1366
1528
  request['price'] = self.price_to_precision(market['symbol'], price)
1367
1529
  response = None
@@ -1382,7 +1544,8 @@ class exmo(Exchange, ImplicitAPI):
1382
1544
  if type == 'limit':
1383
1545
  request['type'] = side
1384
1546
  elif type == 'market':
1385
- request['type'] = 'market_' + side
1547
+ marketSuffix = '_total' if (cost is not None) else ''
1548
+ request['type'] = 'market_' + side + marketSuffix
1386
1549
  if isPostOnly:
1387
1550
  request['exec_type'] = 'post_only'
1388
1551
  elif timeInForce is not None:
@@ -1408,9 +1571,11 @@ class exmo(Exchange, ImplicitAPI):
1408
1571
  def cancel_order(self, id: str, symbol: Str = None, params={}):
1409
1572
  """
1410
1573
  cancels an open order
1411
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#1f710d4b-75bc-4b65-ad68-006f863a3f26
1412
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#a4d0aae8-28f7-41ac-94fd-c4030130453d # stop market
1413
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#705dfec5-2b35-4667-862b-faf54eca6209 # margin
1574
+
1575
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#1f710d4b-75bc-4b65-ad68-006f863a3f26
1576
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#a4d0aae8-28f7-41ac-94fd-c4030130453d # stop market
1577
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#705dfec5-2b35-4667-862b-faf54eca6209 # margin
1578
+
1414
1579
  :param str id: order id
1415
1580
  :param str symbol: not used by exmo cancelOrder()
1416
1581
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -1419,8 +1584,8 @@ class exmo(Exchange, ImplicitAPI):
1419
1584
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1420
1585
  """
1421
1586
  self.load_markets()
1422
- request = {}
1423
- stop = self.safe_value_2(params, 'trigger', 'stop')
1587
+ request: dict = {}
1588
+ trigger = self.safe_value_2(params, 'trigger', 'stop')
1424
1589
  params = self.omit(params, ['trigger', 'stop'])
1425
1590
  marginMode = None
1426
1591
  marginMode, params = self.handle_margin_mode_and_params('cancelOrder', params)
@@ -1434,7 +1599,7 @@ class exmo(Exchange, ImplicitAPI):
1434
1599
  # {}
1435
1600
  #
1436
1601
  else:
1437
- if stop:
1602
+ if trigger:
1438
1603
  request['parent_order_id'] = id
1439
1604
  response = self.privatePostStopMarketOrderCancel(self.extend(request, params))
1440
1605
  #
@@ -1454,13 +1619,16 @@ class exmo(Exchange, ImplicitAPI):
1454
1619
  def fetch_order(self, id: str, symbol: Str = None, params={}):
1455
1620
  """
1456
1621
  *spot only* fetches information on an order made by the user
1457
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#cf27781e-28e5-4b39-a52d-3110f5d22459 # spot
1622
+
1623
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#cf27781e-28e5-4b39-a52d-3110f5d22459 # spot
1624
+
1625
+ :param str id: order id
1458
1626
  :param str symbol: not used by exmo fetchOrder
1459
1627
  :param dict [params]: extra parameters specific to the exchange API endpoint
1460
1628
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1461
1629
  """
1462
1630
  self.load_markets()
1463
- request = {
1631
+ request: dict = {
1464
1632
  'order_id': str(id),
1465
1633
  }
1466
1634
  response = self.privatePostOrderTrades(self.extend(request, params))
@@ -1492,8 +1660,10 @@ class exmo(Exchange, ImplicitAPI):
1492
1660
  def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1493
1661
  """
1494
1662
  fetch all the trades made from a single order
1495
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#cf27781e-28e5-4b39-a52d-3110f5d22459 # spot
1496
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#00810661-9119-46c5-aec5-55abe9cb42c7 # margin
1663
+
1664
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#cf27781e-28e5-4b39-a52d-3110f5d22459 # spot
1665
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#00810661-9119-46c5-aec5-55abe9cb42c7 # margin
1666
+
1497
1667
  :param str id: order id
1498
1668
  :param str symbol: unified market symbol
1499
1669
  :param int [since]: the earliest time in ms to fetch trades for
@@ -1509,7 +1679,7 @@ class exmo(Exchange, ImplicitAPI):
1509
1679
  market = None
1510
1680
  if symbol is not None:
1511
1681
  market = self.market(symbol)
1512
- request = {
1682
+ request: dict = {
1513
1683
  'order_id': str(id),
1514
1684
  }
1515
1685
  response = None
@@ -1558,14 +1728,16 @@ class exmo(Exchange, ImplicitAPI):
1558
1728
  # ]
1559
1729
  # }
1560
1730
  #
1561
- trades = self.safe_value(response, 'trades')
1731
+ trades = self.safe_list(response, 'trades')
1562
1732
  return self.parse_trades(trades, market, since, limit)
1563
1733
 
1564
1734
  def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1565
1735
  """
1566
1736
  fetch all unfilled currently open orders
1567
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#0e135370-daa4-4689-8acd-b6876dee9ba1 # spot open orders
1568
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#a7cfd4f0-476e-4675-b33f-22a46902f245 # margin
1737
+
1738
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#0e135370-daa4-4689-8acd-b6876dee9ba1 # spot open orders
1739
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#a7cfd4f0-476e-4675-b33f-22a46902f245 # margin
1740
+
1569
1741
  :param str symbol: unified market symbol
1570
1742
  :param int [since]: the earliest time in ms to fetch open orders for
1571
1743
  :param int [limit]: the maximum number of open orders structures to retrieve
@@ -1650,7 +1822,7 @@ class exmo(Exchange, ImplicitAPI):
1650
1822
  def parse_status(self, status):
1651
1823
  if status is None:
1652
1824
  return None
1653
- statuses = {
1825
+ statuses: dict = {
1654
1826
  'cancel_started': 'canceled',
1655
1827
  }
1656
1828
  if status.find('cancel') >= 0:
@@ -1658,7 +1830,7 @@ class exmo(Exchange, ImplicitAPI):
1658
1830
  return self.safe_string(statuses, status, status)
1659
1831
 
1660
1832
  def parse_side(self, orderType):
1661
- side = {
1833
+ side: dict = {
1662
1834
  'limit_buy': 'buy',
1663
1835
  'limit_sell': 'sell',
1664
1836
  'market_buy': 'buy',
@@ -1676,7 +1848,7 @@ class exmo(Exchange, ImplicitAPI):
1676
1848
  }
1677
1849
  return self.safe_string(side, orderType, orderType)
1678
1850
 
1679
- def parse_order(self, order, market: Market = None) -> Order:
1851
+ def parse_order(self, order: dict, market: Market = None) -> Order:
1680
1852
  #
1681
1853
  # fetchOrders, fetchOpenOrders, fetchClosedOrders, fetchCanceledOrders
1682
1854
  #
@@ -1798,7 +1970,6 @@ class exmo(Exchange, ImplicitAPI):
1798
1970
  'postOnly': None,
1799
1971
  'side': side,
1800
1972
  'price': price,
1801
- 'stopPrice': triggerPrice,
1802
1973
  'triggerPrice': triggerPrice,
1803
1974
  'cost': cost,
1804
1975
  'amount': amount,
@@ -1813,8 +1984,10 @@ class exmo(Exchange, ImplicitAPI):
1813
1984
  def fetch_canceled_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1814
1985
  """
1815
1986
  fetches information on multiple canceled orders made by the user
1816
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#1d2524dd-ae6d-403a-a067-77b50d13fbe5 # margin
1817
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#a51be1d0-af5f-44e4-99d7-f7b04c6067d0 # spot canceled orders
1987
+
1988
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#1d2524dd-ae6d-403a-a067-77b50d13fbe5 # margin
1989
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#a51be1d0-af5f-44e4-99d7-f7b04c6067d0 # spot canceled orders
1990
+
1818
1991
  :param str symbol: unified market symbol of the market orders were made in
1819
1992
  :param int [since]: timestamp in ms of the earliest order, default is None
1820
1993
  :param int [limit]: max number of orders to return, default is None
@@ -1833,7 +2006,7 @@ class exmo(Exchange, ImplicitAPI):
1833
2006
  if symbol is not None:
1834
2007
  marketInner = self.market(symbol)
1835
2008
  symbol = marketInner['symbol']
1836
- request = {
2009
+ request: dict = {
1837
2010
  'limit': limit,
1838
2011
  }
1839
2012
  request['offset'] = limit if (since is not None) else 0
@@ -1900,18 +2073,20 @@ class exmo(Exchange, ImplicitAPI):
1900
2073
  def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
1901
2074
  """
1902
2075
  *margin only* edit a trade order
1903
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#f27ee040-c75f-4b59-b608-d05bd45b7899 # margin
2076
+
2077
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#f27ee040-c75f-4b59-b608-d05bd45b7899 # margin
2078
+
1904
2079
  :param str id: order id
1905
2080
  :param str symbol: unified CCXT market symbol
1906
2081
  :param str type: not used by exmo editOrder
1907
2082
  :param str side: not used by exmo editOrder
1908
2083
  :param float [amount]: how much of the currency you want to trade in units of the base currency
1909
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
2084
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1910
2085
  :param dict [params]: extra parameters specific to the exchange API endpoint
1911
2086
  :param float [params.triggerPrice]: stop price for stop-market and stop-limit orders
1912
2087
  :param str params['marginMode']: must be set to isolated
1913
- *
1914
- * EXCHANGE SPECIFIC PARAMETERS
2088
+
2089
+ EXCHANGE SPECIFIC PARAMETERS
1915
2090
  :param int [params.distance]: distance for trailing stop orders
1916
2091
  :param int [params.expire]: expiration timestamp in UTC timezone for the order. order will not be expired if expire is 0
1917
2092
  :param str [params.comment]: optional comment for order. up to 50 latin symbols, whitespaces, underscores
@@ -1925,7 +2100,7 @@ class exmo(Exchange, ImplicitAPI):
1925
2100
  raise BadRequest(self.id + ' editOrder() can only be used for isolated margin orders')
1926
2101
  triggerPrice = self.safe_number_n(params, ['triggerPrice', 'stopPrice', 'stop_price'])
1927
2102
  params = self.omit(params, ['triggerPrice', 'stopPrice'])
1928
- request = {
2103
+ request: dict = {
1929
2104
  'order_id': id, # id of the open order
1930
2105
  }
1931
2106
  if amount is not None:
@@ -1937,10 +2112,12 @@ class exmo(Exchange, ImplicitAPI):
1937
2112
  response = self.privatePostMarginUserOrderUpdate(self.extend(request, params))
1938
2113
  return self.parse_order(response)
1939
2114
 
1940
- def fetch_deposit_address(self, code: str, params={}):
2115
+ def fetch_deposit_address(self, code: str, params={}) -> DepositAddress:
1941
2116
  """
1942
2117
  fetch the deposit address for a currency associated with self account
1943
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#c8f9ced9-7ab6-4383-a6a4-bc54469ba60e
2118
+
2119
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#c8f9ced9-7ab6-4383-a6a4-bc54469ba60e
2120
+
1944
2121
  :param str code: unified currency code
1945
2122
  :param dict [params]: extra parameters specific to the exchange API endpoint
1946
2123
  :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
@@ -1964,11 +2141,11 @@ class exmo(Exchange, ImplicitAPI):
1964
2141
  tag = addressAndTag[1]
1965
2142
  self.check_address(address)
1966
2143
  return {
2144
+ 'info': response,
1967
2145
  'currency': code,
2146
+ 'network': None,
1968
2147
  'address': address,
1969
2148
  'tag': tag,
1970
- 'network': None,
1971
- 'info': response,
1972
2149
  }
1973
2150
 
1974
2151
  def get_market_from_trades(self, trades):
@@ -1979,10 +2156,12 @@ class exmo(Exchange, ImplicitAPI):
1979
2156
  return self.markets[symbols[0]]
1980
2157
  return None
1981
2158
 
1982
- def withdraw(self, code: str, amount: float, address, tag=None, params={}):
2159
+ def withdraw(self, code: str, amount: float, address: str, tag=None, params={}) -> Transaction:
1983
2160
  """
1984
2161
  make a withdrawal
1985
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#3ab9c34d-ad58-4f87-9c57-2e2ea88a8325
2162
+
2163
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#3ab9c34d-ad58-4f87-9c57-2e2ea88a8325
2164
+
1986
2165
  :param str code: unified currency code
1987
2166
  :param float amount: the amount to withdraw
1988
2167
  :param str address: the address to withdraw to
@@ -1993,7 +2172,7 @@ class exmo(Exchange, ImplicitAPI):
1993
2172
  tag, params = self.handle_withdraw_tag_and_params(tag, params)
1994
2173
  self.load_markets()
1995
2174
  currency = self.currency(code)
1996
- request = {
2175
+ request: dict = {
1997
2176
  'amount': amount,
1998
2177
  'currency': currency['id'],
1999
2178
  'address': address,
@@ -2009,8 +2188,8 @@ class exmo(Exchange, ImplicitAPI):
2009
2188
  response = self.privatePostWithdrawCrypt(self.extend(request, params))
2010
2189
  return self.parse_transaction(response, currency)
2011
2190
 
2012
- def parse_transaction_status(self, status):
2013
- statuses = {
2191
+ def parse_transaction_status(self, status: Str):
2192
+ statuses: dict = {
2014
2193
  'transferred': 'ok',
2015
2194
  'paid': 'ok',
2016
2195
  'pending': 'pending',
@@ -2019,7 +2198,7 @@ class exmo(Exchange, ImplicitAPI):
2019
2198
  }
2020
2199
  return self.safe_string(statuses, status, status)
2021
2200
 
2022
- def parse_transaction(self, transaction, currency: Currency = None) -> Transaction:
2201
+ def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
2023
2202
  #
2024
2203
  # fetchDepositsWithdrawals
2025
2204
  #
@@ -2146,7 +2325,9 @@ class exmo(Exchange, ImplicitAPI):
2146
2325
  def fetch_deposits_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
2147
2326
  """
2148
2327
  fetch history of deposits and withdrawals
2149
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#31e69a33-4849-4e6a-b4b4-6d574238f6a7
2328
+
2329
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#31e69a33-4849-4e6a-b4b4-6d574238f6a7
2330
+
2150
2331
  :param str [code]: unified currency code for the currency of the deposit/withdrawals, default is None
2151
2332
  :param int [since]: timestamp in ms of the earliest deposit/withdrawal, default is None
2152
2333
  :param int [limit]: max number of deposit/withdrawals to return, default is None
@@ -2154,7 +2335,7 @@ class exmo(Exchange, ImplicitAPI):
2154
2335
  :returns dict: a list of `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
2155
2336
  """
2156
2337
  self.load_markets()
2157
- request = {}
2338
+ request: dict = {}
2158
2339
  if since is not None:
2159
2340
  request['date'] = self.parse_to_int(since / 1000)
2160
2341
  currency = None
@@ -2196,7 +2377,9 @@ class exmo(Exchange, ImplicitAPI):
2196
2377
  def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
2197
2378
  """
2198
2379
  fetch all withdrawals made from an account
2199
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#97f1becd-7aad-4e0e-babe-7bbe09e33706
2380
+
2381
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#97f1becd-7aad-4e0e-babe-7bbe09e33706
2382
+
2200
2383
  :param str code: unified currency code
2201
2384
  :param int [since]: the earliest time in ms to fetch withdrawals for
2202
2385
  :param int [limit]: the maximum number of withdrawals structures to retrieve
@@ -2205,7 +2388,7 @@ class exmo(Exchange, ImplicitAPI):
2205
2388
  """
2206
2389
  self.load_markets()
2207
2390
  currency = None
2208
- request = {
2391
+ request: dict = {
2209
2392
  'type': 'withdraw',
2210
2393
  }
2211
2394
  if limit is not None:
@@ -2240,13 +2423,15 @@ class exmo(Exchange, ImplicitAPI):
2240
2423
  # "count": 23
2241
2424
  # }
2242
2425
  #
2243
- items = self.safe_value(response, 'items', [])
2426
+ items = self.safe_list(response, 'items', [])
2244
2427
  return self.parse_transactions(items, currency, since, limit)
2245
2428
 
2246
2429
  def fetch_withdrawal(self, id: str, code: Str = None, params={}):
2247
2430
  """
2248
2431
  fetch data on a currency withdrawal via the withdrawal id
2249
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#97f1becd-7aad-4e0e-babe-7bbe09e33706
2432
+
2433
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#97f1becd-7aad-4e0e-babe-7bbe09e33706
2434
+
2250
2435
  :param str id: withdrawal id
2251
2436
  :param str code: unified currency code of the currency withdrawn, default is None
2252
2437
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2254,7 +2439,7 @@ class exmo(Exchange, ImplicitAPI):
2254
2439
  """
2255
2440
  self.load_markets()
2256
2441
  currency = None
2257
- request = {
2442
+ request: dict = {
2258
2443
  'order_id': id,
2259
2444
  'type': 'withdraw',
2260
2445
  }
@@ -2289,13 +2474,15 @@ class exmo(Exchange, ImplicitAPI):
2289
2474
  # }
2290
2475
  #
2291
2476
  items = self.safe_value(response, 'items', [])
2292
- first = self.safe_value(items, 0, {})
2477
+ first = self.safe_dict(items, 0, {})
2293
2478
  return self.parse_transaction(first, currency)
2294
2479
 
2295
2480
  def fetch_deposit(self, id=None, code: Str = None, params={}):
2296
2481
  """
2297
2482
  fetch information on a deposit
2298
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#97f1becd-7aad-4e0e-babe-7bbe09e33706
2483
+
2484
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#97f1becd-7aad-4e0e-babe-7bbe09e33706
2485
+
2299
2486
  :param str id: deposit id
2300
2487
  :param str code: unified currency code, default is None
2301
2488
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2303,7 +2490,7 @@ class exmo(Exchange, ImplicitAPI):
2303
2490
  """
2304
2491
  self.load_markets()
2305
2492
  currency = None
2306
- request = {
2493
+ request: dict = {
2307
2494
  'order_id': id,
2308
2495
  'type': 'deposit',
2309
2496
  }
@@ -2338,13 +2525,15 @@ class exmo(Exchange, ImplicitAPI):
2338
2525
  # }
2339
2526
  #
2340
2527
  items = self.safe_value(response, 'items', [])
2341
- first = self.safe_value(items, 0, {})
2528
+ first = self.safe_dict(items, 0, {})
2342
2529
  return self.parse_transaction(first, currency)
2343
2530
 
2344
2531
  def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
2345
2532
  """
2346
2533
  fetch all deposits made to an account
2347
- :see: https://documenter.getpostman.com/view/10287440/SzYXWKPi#97f1becd-7aad-4e0e-babe-7bbe09e33706
2534
+
2535
+ https://documenter.getpostman.com/view/10287440/SzYXWKPi#97f1becd-7aad-4e0e-babe-7bbe09e33706
2536
+
2348
2537
  :param str code: unified currency code
2349
2538
  :param int [since]: the earliest time in ms to fetch deposits for
2350
2539
  :param int [limit]: the maximum number of deposits structures to retrieve
@@ -2353,7 +2542,7 @@ class exmo(Exchange, ImplicitAPI):
2353
2542
  """
2354
2543
  self.load_markets()
2355
2544
  currency = None
2356
- request = {
2545
+ request: dict = {
2357
2546
  'type': 'deposit',
2358
2547
  }
2359
2548
  if limit is not None:
@@ -2388,7 +2577,7 @@ class exmo(Exchange, ImplicitAPI):
2388
2577
  # "count": 23
2389
2578
  # }
2390
2579
  #
2391
- items = self.safe_value(response, 'items', [])
2580
+ items = self.safe_list(response, 'items', [])
2392
2581
  return self.parse_transactions(items, currency, since, limit)
2393
2582
 
2394
2583
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
@@ -2413,7 +2602,7 @@ class exmo(Exchange, ImplicitAPI):
2413
2602
  def nonce(self):
2414
2603
  return self.milliseconds()
2415
2604
 
2416
- def handle_errors(self, httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody):
2605
+ def handle_errors(self, httpCode: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
2417
2606
  if response is None:
2418
2607
  return None # fallback to default error handler
2419
2608
  if ('error' in response) and not ('result' in response):