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/woo.py CHANGED
@@ -6,16 +6,18 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.woo import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Account, Balances, Bool, Currency, Int, Leverage, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Trade, Transaction, TransferEntry
9
+ from ccxt.base.types import Account, Balances, Bool, Conversion, Currencies, Currency, DepositAddress, Int, LedgerEntry, Leverage, MarginModification, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, FundingRate, FundingRates, Trade, TradingFees, Transaction, TransferEntry
10
10
  from typing import List
11
+ from typing import Any
11
12
  from ccxt.base.errors import ExchangeError
13
+ from ccxt.base.errors import AuthenticationError
12
14
  from ccxt.base.errors import ArgumentsRequired
13
15
  from ccxt.base.errors import BadRequest
14
16
  from ccxt.base.errors import InvalidOrder
15
17
  from ccxt.base.errors import NotSupported
18
+ from ccxt.base.errors import OperationFailed
16
19
  from ccxt.base.errors import RateLimitExceeded
17
20
  from ccxt.base.errors import OnMaintenance
18
- from ccxt.base.errors import AuthenticationError
19
21
  from ccxt.base.decimal_to_precision import TICK_SIZE
20
22
  from ccxt.base.precise import Precise
21
23
 
@@ -31,7 +33,7 @@ class woo(Exchange, ImplicitAPI):
31
33
  'version': 'v1',
32
34
  'certified': True,
33
35
  'pro': True,
34
- 'hostname': 'woo.org',
36
+ 'hostname': 'woox.io',
35
37
  'has': {
36
38
  'CORS': None,
37
39
  'spot': True,
@@ -39,17 +41,19 @@ class woo(Exchange, ImplicitAPI):
39
41
  'swap': True,
40
42
  'future': False,
41
43
  'option': False,
42
- 'addMargin': False,
44
+ 'addMargin': True,
43
45
  'cancelAllOrders': True,
46
+ 'cancelAllOrdersAfter': True,
44
47
  'cancelOrder': True,
45
- 'cancelWithdraw': False, # exchange have that endpoint disabled atm, but was once implemented in ccxt per old docs: https://kronosresearch.github.io/wootrade-documents/#cancel-withdraw-request
48
+ 'cancelWithdraw': False, # exchange have that endpoint disabled atm, but was once implemented in ccxt per old docs: https://docx.woo.io/wootrade-documents/#cancel-withdraw-request
46
49
  'closeAllPositions': False,
47
50
  'closePosition': False,
51
+ 'createConvertTrade': True,
48
52
  'createDepositAddress': False,
49
53
  'createMarketBuyOrderWithCost': True,
50
54
  'createMarketOrder': False,
51
55
  'createMarketOrderWithCost': False,
52
- 'createMarketSellOrderWithCost': False,
56
+ 'createMarketSellOrderWithCost': True,
53
57
  'createOrder': True,
54
58
  'createOrderWithTakeProfitAndStopLoss': True,
55
59
  'createReduceOnlyOrder': True,
@@ -65,18 +69,27 @@ class woo(Exchange, ImplicitAPI):
65
69
  'fetchBalance': True,
66
70
  'fetchCanceledOrders': False,
67
71
  'fetchClosedOrder': False,
68
- 'fetchClosedOrders': False,
72
+ 'fetchClosedOrders': True,
73
+ 'fetchConvertCurrencies': True,
74
+ 'fetchConvertQuote': True,
75
+ 'fetchConvertTrade': True,
76
+ 'fetchConvertTradeHistory': True,
69
77
  'fetchCurrencies': True,
70
78
  'fetchDepositAddress': True,
79
+ 'fetchDepositAddresses': False,
80
+ 'fetchDepositAddressesByNetwork': False,
71
81
  'fetchDeposits': True,
72
82
  'fetchDepositsWithdrawals': True,
73
83
  'fetchFundingHistory': True,
84
+ 'fetchFundingInterval': True,
85
+ 'fetchFundingIntervals': False,
74
86
  'fetchFundingRate': True,
75
87
  'fetchFundingRateHistory': True,
76
88
  'fetchFundingRates': True,
77
89
  'fetchIndexOHLCV': False,
78
90
  'fetchLedger': True,
79
91
  'fetchLeverage': True,
92
+ 'fetchMarginAdjustmentHistory': False,
80
93
  'fetchMarginMode': False,
81
94
  'fetchMarkets': True,
82
95
  'fetchMarkOHLCV': False,
@@ -84,14 +97,16 @@ class woo(Exchange, ImplicitAPI):
84
97
  'fetchOHLCV': True,
85
98
  'fetchOpenInterestHistory': False,
86
99
  'fetchOpenOrder': False,
87
- 'fetchOpenOrders': False,
100
+ 'fetchOpenOrders': True,
88
101
  'fetchOrder': True,
89
102
  'fetchOrderBook': True,
90
103
  'fetchOrders': True,
91
104
  'fetchOrderTrades': True,
92
105
  'fetchPosition': True,
106
+ 'fetchPositionHistory': False,
93
107
  'fetchPositionMode': False,
94
108
  'fetchPositions': True,
109
+ 'fetchPositionsHistory': False,
95
110
  'fetchPremiumIndexOHLCV': False,
96
111
  'fetchStatus': True,
97
112
  'fetchTicker': False,
@@ -104,11 +119,12 @@ class woo(Exchange, ImplicitAPI):
104
119
  'fetchTransfers': True,
105
120
  'fetchWithdrawals': True,
106
121
  'reduceMargin': False,
122
+ 'sandbox': True,
107
123
  'setLeverage': True,
108
124
  'setMargin': False,
109
125
  'setPositionMode': True,
110
126
  'transfer': True,
111
- 'withdraw': True, # exchange have that endpoint disabled atm, but was once implemented in ccxt per old docs: https://kronosresearch.github.io/wootrade-documents/#token-withdraw
127
+ 'withdraw': True, # exchange have that endpoint disabled atm, but was once implemented in ccxt per old docs: https://docx.woo.io/wootrade-documents/#token-withdraw
112
128
  },
113
129
  'timeframes': {
114
130
  '1m': '1m',
@@ -126,24 +142,24 @@ class woo(Exchange, ImplicitAPI):
126
142
  'urls': {
127
143
  'logo': 'https://user-images.githubusercontent.com/1294454/150730761-1a00e5e0-d28c-480f-9e65-089ce3e6ef3b.jpg',
128
144
  'api': {
129
- 'pub': 'https://api-pub.woo.org',
145
+ 'pub': 'https://api-pub.woox.io',
130
146
  'public': 'https://api.{hostname}',
131
147
  'private': 'https://api.{hostname}',
132
148
  },
133
149
  'test': {
134
- 'pub': 'https://api-pub.staging.woo.org',
135
- 'public': 'https://api.staging.woo.org',
136
- 'private': 'https://api.staging.woo.org',
150
+ 'pub': 'https://api-pub.staging.woox.io',
151
+ 'public': 'https://api.staging.woox.io',
152
+ 'private': 'https://api.staging.woox.io',
137
153
  },
138
- 'www': 'https://woo.org/',
154
+ 'www': 'https://woox.io/',
139
155
  'doc': [
140
- 'https://docs.woo.org/',
156
+ 'https://docs.woox.io/',
141
157
  ],
142
158
  'fees': [
143
- 'https://support.woo.org/hc/en-001/articles/4404611795353--Trading-Fees',
159
+ 'https://support.woox.io/hc/en-001/articles/4404611795353--Trading-Fees',
144
160
  ],
145
161
  'referral': {
146
- 'url': 'https://x.woo.org/register?ref=YWOWC96B',
162
+ 'url': 'https://woox.io/register?ref=DIJT0CNL',
147
163
  'discount': 0.35,
148
164
  },
149
165
  },
@@ -152,7 +168,7 @@ class woo(Exchange, ImplicitAPI):
152
168
  'pub': {
153
169
  'get': {
154
170
  'hist/kline': 10,
155
- 'hist/trades': 1,
171
+ 'hist/trades': 10,
156
172
  },
157
173
  },
158
174
  'public': {
@@ -199,23 +215,27 @@ class woo(Exchange, ImplicitAPI):
199
215
  'positions': 3.33, # 30 requests per 10 seconds
200
216
  'position/{symbol}': 3.33,
201
217
  'client/transaction_history': 60,
218
+ 'client/futures_leverage': 60,
202
219
  },
203
220
  'post': {
204
- 'order': 5, # 2 requests per 1 second per symbol
221
+ 'order': 1, # 10 requests per 1 second per symbol
222
+ 'order/cancel_all_after': 1,
205
223
  'asset/main_sub_transfer': 30, # 20 requests per 60 seconds
206
224
  'asset/ltv': 30,
207
- 'asset/withdraw': 30, # implemented in ccxt, disabled on the exchange side https://kronosresearch.github.io/wootrade-documents/#token-withdraw
225
+ 'asset/withdraw': 30, # implemented in ccxt, disabled on the exchange side https://docx.woo.io/wootrade-documents/#token-withdraw
208
226
  'asset/internal_withdraw': 30,
209
227
  'interest/repay': 60,
210
228
  'client/account_mode': 120,
211
229
  'client/position_mode': 5,
212
230
  'client/leverage': 120,
231
+ 'client/futures_leverage': 30,
232
+ 'client/isolated_margin': 30,
213
233
  },
214
234
  'delete': {
215
235
  'order': 1,
216
236
  'client/order': 1,
217
237
  'orders': 1,
218
- 'asset/withdraw': 120, # implemented in ccxt, disabled on the exchange side https://kronosresearch.github.io/wootrade-documents/#cancel-withdraw-request
238
+ 'asset/withdraw': 120, # implemented in ccxt, disabled on the exchange side https://docx.woo.io/wootrade-documents/#cancel-withdraw-request
219
239
  },
220
240
  },
221
241
  },
@@ -276,6 +296,8 @@ class woo(Exchange, ImplicitAPI):
276
296
  },
277
297
  },
278
298
  'options': {
299
+ 'timeDifference': 0, # the difference between system clock and exchange clock
300
+ 'adjustForTimeDifference': False, # controls the adjustment logic upon instantiation
279
301
  'sandboxMode': False,
280
302
  'createMarketBuyOrderRequiresPrice': True,
281
303
  # these network aliases require manual mapping here
@@ -301,10 +323,98 @@ class woo(Exchange, ImplicitAPI):
301
323
  },
302
324
  'brokerId': 'bc830de7-50f3-460b-9ee0-f430f83f9dad',
303
325
  },
326
+ 'features': {
327
+ 'default': {
328
+ 'sandbox': True,
329
+ 'createOrder': {
330
+ 'marginMode': True,
331
+ 'triggerPrice': True,
332
+ 'triggerPriceType': {
333
+ 'last': True,
334
+ 'mark': True,
335
+ 'index': False,
336
+ },
337
+ 'triggerDirection': False,
338
+ 'stopLossPrice': False, # todo by triggerPrice
339
+ 'takeProfitPrice': False, # todo by triggerPrice
340
+ 'attachedStopLossTakeProfit': None,
341
+ 'timeInForce': {
342
+ 'IOC': True,
343
+ 'FOK': True,
344
+ 'PO': True,
345
+ 'GTD': True,
346
+ },
347
+ 'hedged': False,
348
+ 'trailing': True,
349
+ 'leverage': False,
350
+ 'marketBuyByCost': True,
351
+ 'marketBuyRequiresPrice': False,
352
+ 'selfTradePrevention': False,
353
+ 'iceberg': True, # todo implement
354
+ },
355
+ 'createOrders': None,
356
+ 'fetchMyTrades': {
357
+ 'marginMode': False,
358
+ 'limit': 500,
359
+ 'daysBack': 90,
360
+ 'untilDays': 10000,
361
+ },
362
+ 'fetchOrder': {
363
+ 'marginMode': False,
364
+ 'trigger': True,
365
+ 'trailing': False,
366
+ },
367
+ 'fetchOpenOrders': {
368
+ 'marginMode': False,
369
+ 'limit': 500,
370
+ 'trigger': True,
371
+ 'trailing': True,
372
+ },
373
+ 'fetchOrders': {
374
+ 'marginMode': False,
375
+ 'limit': 500,
376
+ 'daysBack': None,
377
+ 'untilDays': 100000,
378
+ 'trigger': True,
379
+ 'trailing': True,
380
+ },
381
+ 'fetchClosedOrders': {
382
+ 'marginMode': False,
383
+ 'limit': 500,
384
+ 'daysBack': None,
385
+ 'daysBackCanceled': None,
386
+ 'untilDays': 100000,
387
+ 'trigger': True,
388
+ 'trailing': True,
389
+ },
390
+ 'fetchOHLCV': {
391
+ 'limit': 1000,
392
+ },
393
+ },
394
+ 'spot': {
395
+ 'extends': 'default',
396
+ },
397
+ 'forSwap': {
398
+ 'extends': 'default',
399
+ 'createOrder': {
400
+ 'hedged': True,
401
+ },
402
+ },
403
+ 'swap': {
404
+ 'linear': {
405
+ 'extends': 'forSwap',
406
+ },
407
+ 'inverse': None,
408
+ },
409
+ 'future': {
410
+ 'linear': None,
411
+ 'inverse': None,
412
+ },
413
+ },
304
414
  'commonCurrencies': {},
305
415
  'exceptions': {
306
416
  'exact': {
307
- '-1000': ExchangeError, # {"code": -1000, "message": "An unknown error occurred while processing the request"}
417
+ '-1000': OperationFailed, # {"code": -1000, "message": "An unknown error occurred while processing the request"} or {"success":false,"code":"-1000","message":"An internal error has occurred. We are unable to process your request. Please try again later."}
308
418
  '-1001': AuthenticationError, # {"code": -1001, "message": "The api key or secret is in wrong format"}
309
419
  '-1002': AuthenticationError, # {"code": -1002, "message": "API key or secret is invalid, it may because key have insufficient permission or the key is expired/revoked."}
310
420
  '-1003': RateLimitExceeded, # {"code": -1003, "message": "Rate limit exceed."}
@@ -336,7 +446,9 @@ class woo(Exchange, ImplicitAPI):
336
446
  def fetch_status(self, params={}):
337
447
  """
338
448
  the latest known information on the availability of the exchange API
339
- :see: https://docs.woo.org/#get-system-maintenance-status-public
449
+
450
+ https://docs.woox.io/#get-system-maintenance-status-public
451
+
340
452
  :param dict [params]: extra parameters specific to the exchange API endpoint
341
453
  :returns dict: a `status structure <https://docs.ccxt.com/#/?id=exchange-status-structure>`
342
454
  """
@@ -370,7 +482,9 @@ class woo(Exchange, ImplicitAPI):
370
482
  def fetch_time(self, params={}):
371
483
  """
372
484
  fetches the current integer timestamp in milliseconds from the exchange server
373
- :see: https://docs.woo.org/#get-system-maintenance-status-public
485
+
486
+ https://docs.woox.io/#get-system-maintenance-status-public
487
+
374
488
  :param dict [params]: extra parameters specific to the exchange API endpoint
375
489
  :returns int: the current integer timestamp in milliseconds from the exchange server
376
490
  """
@@ -387,12 +501,17 @@ class woo(Exchange, ImplicitAPI):
387
501
  #
388
502
  return self.safe_integer(response, 'timestamp')
389
503
 
390
- def fetch_markets(self, params={}):
504
+ def fetch_markets(self, params={}) -> List[Market]:
391
505
  """
392
506
  retrieves data on all markets for woo
507
+
508
+ https://docs.woox.io/#exchange-information
509
+
393
510
  :param dict [params]: extra parameters specific to the exchange API endpoint
394
511
  :returns dict[]: an array of objects representing market data
395
512
  """
513
+ if self.options['adjustForTimeDifference']:
514
+ self.load_time_difference()
396
515
  response = self.v1PublicGetInfo(params)
397
516
  #
398
517
  # {
@@ -418,7 +537,7 @@ class woo(Exchange, ImplicitAPI):
418
537
  data = self.safe_list(response, 'rows', [])
419
538
  return self.parse_markets(data)
420
539
 
421
- def parse_market(self, market) -> Market:
540
+ def parse_market(self, market: dict) -> Market:
422
541
  marketId = self.safe_string(market, 'symbol')
423
542
  parts = marketId.split('_')
424
543
  first = self.safe_string(parts, 0)
@@ -464,7 +583,7 @@ class woo(Exchange, ImplicitAPI):
464
583
  'swap': swap,
465
584
  'future': False,
466
585
  'option': False,
467
- 'active': None,
586
+ 'active': self.safe_string(market, 'is_trading') == '1',
468
587
  'contract': contract,
469
588
  'linear': linear,
470
589
  'inverse': None,
@@ -502,6 +621,9 @@ class woo(Exchange, ImplicitAPI):
502
621
  def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
503
622
  """
504
623
  get the list of most recent trades for a particular symbol
624
+
625
+ https://docs.woox.io/#market-trades-public
626
+
505
627
  :param str symbol: unified symbol of the market to fetch trades for
506
628
  :param int [since]: timestamp in ms of the earliest trade to fetch
507
629
  :param int [limit]: the maximum amount of trades to fetch
@@ -510,7 +632,7 @@ class woo(Exchange, ImplicitAPI):
510
632
  """
511
633
  self.load_markets()
512
634
  market = self.market(symbol)
513
- request = {
635
+ request: dict = {
514
636
  'symbol': market['id'],
515
637
  }
516
638
  if limit is not None:
@@ -548,7 +670,7 @@ class woo(Exchange, ImplicitAPI):
548
670
  resultResponse = self.safe_list(response, 'rows', [])
549
671
  return self.parse_trades(resultResponse, market, since, limit)
550
672
 
551
- def parse_trade(self, trade, market: Market = None) -> Trade:
673
+ def parse_trade(self, trade: dict, market: Market = None) -> Trade:
552
674
  #
553
675
  # public/market_trades
554
676
  #
@@ -585,6 +707,9 @@ class woo(Exchange, ImplicitAPI):
585
707
  amount = self.safe_string(trade, 'executed_quantity')
586
708
  order_id = self.safe_string(trade, 'order_id')
587
709
  fee = self.parse_token_and_fee_temp(trade, 'fee_asset', 'fee')
710
+ feeCost = self.safe_string(fee, 'cost')
711
+ if feeCost is not None:
712
+ fee['cost'] = feeCost
588
713
  cost = Precise.string_mul(price, amount)
589
714
  side = self.safe_string_lower(trade, 'side')
590
715
  id = self.safe_string(trade, 'id')
@@ -620,10 +745,12 @@ class woo(Exchange, ImplicitAPI):
620
745
  }
621
746
  return fee
622
747
 
623
- def fetch_trading_fees(self, params={}):
748
+ def fetch_trading_fees(self, params={}) -> TradingFees:
624
749
  """
625
750
  fetch the trading fees for multiple markets
626
- :see: https://docs.woo.org/#get-account-information-new
751
+
752
+ https://docs.woox.io/#get-account-information-new
753
+
627
754
  :param dict [params]: extra parameters specific to the exchange API endpoint
628
755
  :returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
629
756
  """
@@ -660,7 +787,7 @@ class woo(Exchange, ImplicitAPI):
660
787
  data = self.safe_dict(response, 'data', {})
661
788
  maker = self.safe_string(data, 'makerFeeRate')
662
789
  taker = self.safe_string(data, 'takerFeeRate')
663
- result = {}
790
+ result: dict = {}
664
791
  for i in range(0, len(self.symbols)):
665
792
  symbol = self.symbols[i]
666
793
  result[symbol] = {
@@ -673,13 +800,16 @@ class woo(Exchange, ImplicitAPI):
673
800
  }
674
801
  return result
675
802
 
676
- def fetch_currencies(self, params={}):
803
+ def fetch_currencies(self, params={}) -> Currencies:
677
804
  """
678
805
  fetches all available currencies on an exchange
806
+
807
+ https://docs.woox.io/#available-token-public
808
+
679
809
  :param dict [params]: extra parameters specific to the exchange API endpoint
680
810
  :returns dict: an associative dictionary of currencies
681
811
  """
682
- result = {}
812
+ result: dict = {}
683
813
  tokenResponse = self.v1PublicGetToken(params)
684
814
  #
685
815
  # {
@@ -750,7 +880,7 @@ class woo(Exchange, ImplicitAPI):
750
880
  code = self.safe_currency_code(currencyId)
751
881
  name: Str = None
752
882
  minPrecision = None
753
- resultingNetworks = {}
883
+ resultingNetworks: dict = {}
754
884
  for j in range(0, len(networks)):
755
885
  network = networks[j]
756
886
  name = self.safe_string(network, 'fullname')
@@ -807,7 +937,9 @@ class woo(Exchange, ImplicitAPI):
807
937
  def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
808
938
  """
809
939
  create a market buy order by providing the symbol and cost
810
- :see: https://docs.woo.org/#send-order
940
+
941
+ https://docs.woox.io/#send-order
942
+
811
943
  :param str symbol: unified symbol of the market to create an order in
812
944
  :param float cost: how much you want to trade in units of the quote currency
813
945
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -817,12 +949,31 @@ class woo(Exchange, ImplicitAPI):
817
949
  market = self.market(symbol)
818
950
  if not market['spot']:
819
951
  raise NotSupported(self.id + ' createMarketBuyOrderWithCost() supports spot orders only')
820
- params['createMarketBuyOrderRequiresPrice'] = False
821
- return self.create_order(symbol, 'market', 'buy', cost, None, params)
952
+ return self.create_order(symbol, 'market', 'buy', cost, 1, params)
953
+
954
+ def create_market_sell_order_with_cost(self, symbol: str, cost: float, params={}):
955
+ """
956
+ create a market sell order by providing the symbol and cost
957
+
958
+ https://docs.woox.io/#send-order
959
+
960
+ :param str symbol: unified symbol of the market to create an order in
961
+ :param float cost: how much you want to trade in units of the quote currency
962
+ :param dict [params]: extra parameters specific to the exchange API endpoint
963
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
964
+ """
965
+ self.load_markets()
966
+ market = self.market(symbol)
967
+ if not market['spot']:
968
+ raise NotSupported(self.id + ' createMarketSellOrderWithCost() supports spot orders only')
969
+ return self.create_order(symbol, 'market', 'sell', cost, 1, params)
822
970
 
823
971
  def create_trailing_amount_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, trailingAmount=None, trailingTriggerPrice=None, params={}) -> Order:
824
972
  """
825
973
  create a trailing order by providing the symbol, type, side, amount, price and trailingAmount
974
+
975
+ https://docs.woox.io/#send-algo-order
976
+
826
977
  :param str symbol: unified symbol of the market to create an order in
827
978
  :param str type: 'market' or 'limit'
828
979
  :param str side: 'buy' or 'sell'
@@ -844,6 +995,9 @@ class woo(Exchange, ImplicitAPI):
844
995
  def create_trailing_percent_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, trailingPercent=None, trailingTriggerPrice=None, params={}) -> Order:
845
996
  """
846
997
  create a trailing order by providing the symbol, type, side, amount, price and trailingPercent
998
+
999
+ https://docs.woox.io/#send-algo-order
1000
+
847
1001
  :param str symbol: unified symbol of the market to create an order in
848
1002
  :param str type: 'market' or 'limit'
849
1003
  :param str side: 'buy' or 'sell'
@@ -865,24 +1019,28 @@ class woo(Exchange, ImplicitAPI):
865
1019
  def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
866
1020
  """
867
1021
  create a trade order
868
- :see: https://docs.woo.org/#send-order
869
- :see: https://docs.woo.org/#send-algo-order
1022
+
1023
+ https://docs.woox.io/#send-order
1024
+ https://docs.woox.io/#send-algo-order
1025
+
870
1026
  :param str symbol: unified symbol of the market to create an order in
871
1027
  :param str type: 'market' or 'limit'
872
1028
  :param str side: 'buy' or 'sell'
873
1029
  :param float amount: how much of currency you want to trade in units of base currency
874
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1030
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
875
1031
  :param dict [params]: extra parameters specific to the exchange API endpoint
1032
+ :param str [params.marginMode]: *for swap markets only* 'cross' or 'isolated', default 'cross'
876
1033
  :param float [params.triggerPrice]: The price a trigger order is triggered at
877
1034
  :param dict [params.takeProfit]: *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered(perpetual swap markets only)
878
1035
  :param float [params.takeProfit.triggerPrice]: take profit trigger price
879
1036
  :param dict [params.stopLoss]: *stopLoss object in params* containing the triggerPrice at which the attached stop loss order will be triggered(perpetual swap markets only)
880
1037
  :param float [params.stopLoss.triggerPrice]: stop loss trigger price
881
- :param float [params.algoType]: 'STOP'or 'TRAILING_STOP' or 'OCO' or 'CLOSE_POSITION'
1038
+ :param float [params.algoType]: 'STOP' or 'TRAILING_STOP' or 'OCO' or 'CLOSE_POSITION'
882
1039
  :param float [params.cost]: *spot market buy only* the quote quantity that can be used alternative for the amount
883
1040
  :param str [params.trailingAmount]: the quote amount to trail away from the current market price
884
1041
  :param str [params.trailingPercent]: the percent to trail away from the current market price
885
1042
  :param str [params.trailingTriggerPrice]: the price to trigger a trailing order, default uses the price argument
1043
+ :param str [params.position_side]: 'SHORT' or 'LONG' - if position mode is HEDGE_MODE and the trading involves futures, then is required, otherwise self parameter is not required
886
1044
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
887
1045
  """
888
1046
  reduceOnly = self.safe_bool_2(params, 'reduceOnly', 'reduce_only')
@@ -891,11 +1049,15 @@ class woo(Exchange, ImplicitAPI):
891
1049
  self.load_markets()
892
1050
  market = self.market(symbol)
893
1051
  orderSide = side.upper()
894
- request = {
1052
+ request: dict = {
895
1053
  'symbol': market['id'],
896
1054
  'side': orderSide,
897
1055
  }
898
- stopPrice = self.safe_number_2(params, 'triggerPrice', 'stopPrice')
1056
+ marginMode: Str = None
1057
+ marginMode, params = self.handle_margin_mode_and_params('createOrder', params)
1058
+ if marginMode is not None:
1059
+ request['margin_mode'] = self.encode_margin_mode(marginMode)
1060
+ triggerPrice = self.safe_string_2(params, 'triggerPrice', 'stopPrice')
899
1061
  stopLoss = self.safe_value(params, 'stopLoss')
900
1062
  takeProfit = self.safe_value(params, 'takeProfit')
901
1063
  algoType = self.safe_string(params, 'algoType')
@@ -905,17 +1067,17 @@ class woo(Exchange, ImplicitAPI):
905
1067
  isTrailingAmountOrder = trailingAmount is not None
906
1068
  isTrailingPercentOrder = trailingPercent is not None
907
1069
  isTrailing = isTrailingAmountOrder or isTrailingPercentOrder
908
- isStop = isTrailing or stopPrice is not None or stopLoss is not None or takeProfit is not None or (self.safe_value(params, 'childOrders') is not None)
1070
+ isConditional = isTrailing or triggerPrice is not None or stopLoss is not None or takeProfit is not None or (self.safe_value(params, 'childOrders') is not None)
909
1071
  isMarket = orderType == 'MARKET'
910
1072
  timeInForce = self.safe_string_lower(params, 'timeInForce')
911
1073
  postOnly = self.is_post_only(isMarket, None, params)
912
- reduceOnlyKey = 'reduceOnly' if isStop else 'reduce_only'
913
- clientOrderIdKey = 'clientOrderId' if isStop else 'client_order_id'
914
- orderQtyKey = 'quantity' if isStop else 'order_quantity'
915
- priceKey = 'price' if isStop else 'order_price'
916
- typeKey = 'type' if isStop else 'order_type'
1074
+ reduceOnlyKey = 'reduceOnly' if isConditional else 'reduce_only'
1075
+ clientOrderIdKey = 'clientOrderId' if isConditional else 'client_order_id'
1076
+ orderQtyKey = 'quantity' if isConditional else 'order_quantity'
1077
+ priceKey = 'price' if isConditional else 'order_price'
1078
+ typeKey = 'type' if isConditional else 'order_type'
917
1079
  request[typeKey] = orderType # LIMIT/MARKET/IOC/FOK/POST_ONLY/ASK/BID
918
- if not isStop:
1080
+ if not isConditional:
919
1081
  if postOnly:
920
1082
  request['order_type'] = 'POST_ONLY'
921
1083
  elif timeInForce == 'fok':
@@ -924,28 +1086,22 @@ class woo(Exchange, ImplicitAPI):
924
1086
  request['order_type'] = 'IOC'
925
1087
  if reduceOnly:
926
1088
  request[reduceOnlyKey] = reduceOnly
927
- if price is not None:
1089
+ if not isMarket and price is not None:
928
1090
  request[priceKey] = self.price_to_precision(symbol, price)
929
- if isMarket and not isStop:
1091
+ if isMarket and not isConditional:
930
1092
  # for market buy it requires the amount of quote currency to spend
931
- if market['spot'] and orderSide == 'BUY':
1093
+ cost = self.safe_string_2(params, 'cost', 'order_amount')
1094
+ params = self.omit(params, ['cost', 'order_amount'])
1095
+ isPriceProvided = price is not None
1096
+ if market['spot'] and (isPriceProvided or (cost is not None)):
932
1097
  quoteAmount = None
933
- createMarketBuyOrderRequiresPrice = True
934
- createMarketBuyOrderRequiresPrice, params = self.handle_option_and_params(params, 'createOrder', 'createMarketBuyOrderRequiresPrice', True)
935
- cost = self.safe_number_2(params, 'cost', 'order_amount')
936
- params = self.omit(params, ['cost', 'order_amount'])
937
1098
  if cost is not None:
938
1099
  quoteAmount = self.cost_to_precision(symbol, cost)
939
- elif createMarketBuyOrderRequiresPrice:
940
- if price is None:
941
- raise InvalidOrder(self.id + ' createOrder() requires the price argument for market buy orders to calculate the total cost to spend(amount * price), alternatively set the createMarketBuyOrderRequiresPrice option or param to False and pass the cost to spend(quote quantity) in the amount argument')
942
- else:
943
- amountString = self.number_to_string(amount)
944
- priceString = self.number_to_string(price)
945
- costRequest = Precise.string_mul(amountString, priceString)
946
- quoteAmount = self.cost_to_precision(symbol, costRequest)
947
1100
  else:
948
- quoteAmount = self.cost_to_precision(symbol, amount)
1101
+ amountString = self.number_to_string(amount)
1102
+ priceString = self.number_to_string(price)
1103
+ costRequest = Precise.string_mul(amountString, priceString)
1104
+ quoteAmount = self.cost_to_precision(symbol, costRequest)
949
1105
  request['order_amount'] = quoteAmount
950
1106
  else:
951
1107
  request['order_quantity'] = self.amount_to_precision(symbol, amount)
@@ -964,13 +1120,13 @@ class woo(Exchange, ImplicitAPI):
964
1120
  elif isTrailingPercentOrder:
965
1121
  convertedTrailingPercent = Precise.string_div(trailingPercent, '100')
966
1122
  request['callbackRate'] = convertedTrailingPercent
967
- elif stopPrice is not None:
1123
+ elif triggerPrice is not None:
968
1124
  if algoType != 'TRAILING_STOP':
969
- request['triggerPrice'] = self.price_to_precision(symbol, stopPrice)
1125
+ request['triggerPrice'] = self.price_to_precision(symbol, triggerPrice)
970
1126
  request['algoType'] = 'STOP'
971
1127
  elif (stopLoss is not None) or (takeProfit is not None):
972
1128
  request['algoType'] = 'BRACKET'
973
- outterOrder = {
1129
+ outterOrder: dict = {
974
1130
  'symbol': market['id'],
975
1131
  'reduceOnly': False,
976
1132
  'algoType': 'POSITIONAL_TP_SL',
@@ -978,8 +1134,8 @@ class woo(Exchange, ImplicitAPI):
978
1134
  }
979
1135
  closeSide = 'SELL' if (orderSide == 'BUY') else 'BUY'
980
1136
  if stopLoss is not None:
981
- stopLossPrice = self.safe_number_2(stopLoss, 'triggerPrice', 'price', stopLoss)
982
- stopLossOrder = {
1137
+ stopLossPrice = self.safe_string(stopLoss, 'triggerPrice', stopLoss)
1138
+ stopLossOrder: dict = {
983
1139
  'side': closeSide,
984
1140
  'algoType': 'STOP_LOSS',
985
1141
  'triggerPrice': self.price_to_precision(symbol, stopLossPrice),
@@ -988,8 +1144,8 @@ class woo(Exchange, ImplicitAPI):
988
1144
  }
989
1145
  outterOrder['childOrders'].append(stopLossOrder)
990
1146
  if takeProfit is not None:
991
- takeProfitPrice = self.safe_number_2(takeProfit, 'triggerPrice', 'price', takeProfit)
992
- takeProfitOrder = {
1147
+ takeProfitPrice = self.safe_string(takeProfit, 'triggerPrice', takeProfit)
1148
+ takeProfitOrder: dict = {
993
1149
  'side': closeSide,
994
1150
  'algoType': 'TAKE_PROFIT',
995
1151
  'triggerPrice': self.price_to_precision(symbol, takeProfitPrice),
@@ -1000,7 +1156,7 @@ class woo(Exchange, ImplicitAPI):
1000
1156
  request['childOrders'] = [outterOrder]
1001
1157
  params = self.omit(params, ['clOrdID', 'clientOrderId', 'client_order_id', 'postOnly', 'timeInForce', 'stopPrice', 'triggerPrice', 'stopLoss', 'takeProfit', 'trailingPercent', 'trailingAmount', 'trailingTriggerPrice'])
1002
1158
  response = None
1003
- if isStop:
1159
+ if isConditional:
1004
1160
  response = self.v3PrivatePostAlgoOrder(self.extend(request, params))
1005
1161
  else:
1006
1162
  response = self.v1PrivatePostOrder(self.extend(request, params))
@@ -1037,19 +1193,28 @@ class woo(Exchange, ImplicitAPI):
1037
1193
  order['type'] = type
1038
1194
  return order
1039
1195
 
1196
+ def encode_margin_mode(self, mode):
1197
+ modes = {
1198
+ 'cross': 'CROSS',
1199
+ 'isolated': 'ISOLATED',
1200
+ }
1201
+ return self.safe_string(modes, mode, mode)
1202
+
1040
1203
  def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
1041
1204
  """
1042
1205
  edit a trade order
1043
- :see: https://docs.woo.org/#edit-order
1044
- :see: https://docs.woo.org/#edit-order-by-client_order_id
1045
- :see: https://docs.woo.org/#edit-algo-order
1046
- :see: https://docs.woo.org/#edit-algo-order-by-client_order_id
1206
+
1207
+ https://docs.woox.io/#edit-order
1208
+ https://docs.woox.io/#edit-order-by-client_order_id
1209
+ https://docs.woox.io/#edit-algo-order
1210
+ https://docs.woox.io/#edit-algo-order-by-client_order_id
1211
+
1047
1212
  :param str id: order id
1048
1213
  :param str symbol: unified symbol of the market to create an order in
1049
1214
  :param str type: 'market' or 'limit'
1050
1215
  :param str side: 'buy' or 'sell'
1051
1216
  :param float amount: how much of currency you want to trade in units of base currency
1052
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1217
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1053
1218
  :param dict [params]: extra parameters specific to the exchange API endpoint
1054
1219
  :param float [params.triggerPrice]: The price a trigger order is triggered at
1055
1220
  :param float [params.stopLossPrice]: price to trigger stop-loss orders
@@ -1061,7 +1226,7 @@ class woo(Exchange, ImplicitAPI):
1061
1226
  """
1062
1227
  self.load_markets()
1063
1228
  market = self.market(symbol)
1064
- request = {
1229
+ request: dict = {
1065
1230
  # 'quantity': self.amount_to_precision(symbol, amount),
1066
1231
  # 'price': self.price_to_precision(symbol, price),
1067
1232
  }
@@ -1072,9 +1237,9 @@ class woo(Exchange, ImplicitAPI):
1072
1237
  clientOrderIdUnified = self.safe_string_2(params, 'clOrdID', 'clientOrderId')
1073
1238
  clientOrderIdExchangeSpecific = self.safe_string(params, 'client_order_id', clientOrderIdUnified)
1074
1239
  isByClientOrder = clientOrderIdExchangeSpecific is not None
1075
- stopPrice = self.safe_number_n(params, ['triggerPrice', 'stopPrice', 'takeProfitPrice', 'stopLossPrice'])
1076
- if stopPrice is not None:
1077
- request['triggerPrice'] = self.price_to_precision(symbol, stopPrice)
1240
+ triggerPrice = self.safe_number_n(params, ['triggerPrice', 'stopPrice', 'takeProfitPrice', 'stopLossPrice'])
1241
+ if triggerPrice is not None:
1242
+ request['triggerPrice'] = self.price_to_precision(symbol, triggerPrice)
1078
1243
  trailingTriggerPrice = self.safe_string_2(params, 'trailingTriggerPrice', 'activatedPrice', self.number_to_string(price))
1079
1244
  trailingAmount = self.safe_string_2(params, 'trailingAmount', 'callbackValue')
1080
1245
  trailingPercent = self.safe_string_2(params, 'trailingPercent', 'callbackRate')
@@ -1090,17 +1255,17 @@ class woo(Exchange, ImplicitAPI):
1090
1255
  convertedTrailingPercent = Precise.string_div(trailingPercent, '100')
1091
1256
  request['callbackRate'] = convertedTrailingPercent
1092
1257
  params = self.omit(params, ['clOrdID', 'clientOrderId', 'client_order_id', 'stopPrice', 'triggerPrice', 'takeProfitPrice', 'stopLossPrice', 'trailingTriggerPrice', 'trailingAmount', 'trailingPercent'])
1093
- isStop = isTrailing or (stopPrice is not None) or (self.safe_value(params, 'childOrders') is not None)
1258
+ isConditional = isTrailing or (triggerPrice is not None) or (self.safe_value(params, 'childOrders') is not None)
1094
1259
  response = None
1095
1260
  if isByClientOrder:
1096
1261
  request['client_order_id'] = clientOrderIdExchangeSpecific
1097
- if isStop:
1262
+ if isConditional:
1098
1263
  response = self.v3PrivatePutAlgoOrderClientClientOrderId(self.extend(request, params))
1099
1264
  else:
1100
1265
  response = self.v3PrivatePutOrderClientClientOrderId(self.extend(request, params))
1101
1266
  else:
1102
1267
  request['oid'] = id
1103
- if isStop:
1268
+ if isConditional:
1104
1269
  response = self.v3PrivatePutAlgoOrderOid(self.extend(request, params))
1105
1270
  else:
1106
1271
  response = self.v3PrivatePutOrderOid(self.extend(request, params))
@@ -1121,30 +1286,32 @@ class woo(Exchange, ImplicitAPI):
1121
1286
 
1122
1287
  def cancel_order(self, id: str, symbol: Str = None, params={}):
1123
1288
  """
1124
- :see: https://docs.woo.org/#cancel-algo-order
1125
- :see: https://docs.woo.org/#cancel-order
1126
- :see: https://docs.woo.org/#cancel-order-by-client_order_id
1289
+
1290
+ https://docs.woox.io/#cancel-algo-order
1291
+ https://docs.woox.io/#cancel-order
1292
+ https://docs.woox.io/#cancel-order-by-client_order_id
1293
+
1127
1294
  cancels an open order
1128
1295
  :param str id: order id
1129
1296
  :param str symbol: unified symbol of the market the order was made in
1130
1297
  :param dict [params]: extra parameters specific to the exchange API endpoint
1131
- :param boolean [params.stop]: whether the order is a stop/algo order
1298
+ :param boolean [params.trigger]: whether the order is a trigger/algo order
1132
1299
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1133
1300
  """
1134
- stop = self.safe_bool(params, 'stop', False)
1135
- params = self.omit(params, 'stop')
1136
- if not stop and (symbol is None):
1301
+ isTrigger = self.safe_bool_2(params, 'trigger', 'stop', False)
1302
+ params = self.omit(params, ['trigger', 'stop'])
1303
+ if not isTrigger and (symbol is None):
1137
1304
  raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol argument')
1138
1305
  self.load_markets()
1139
1306
  market: Market = None
1140
1307
  if symbol is not None:
1141
1308
  market = self.market(symbol)
1142
- request = {}
1309
+ request: dict = {}
1143
1310
  clientOrderIdUnified = self.safe_string_2(params, 'clOrdID', 'clientOrderId')
1144
1311
  clientOrderIdExchangeSpecific = self.safe_string(params, 'client_order_id', clientOrderIdUnified)
1145
1312
  isByClientOrder = clientOrderIdExchangeSpecific is not None
1146
1313
  response = None
1147
- if stop:
1314
+ if isTrigger:
1148
1315
  request['order_id'] = id
1149
1316
  response = self.v3PrivateDeleteAlgoOrderOrderId(self.extend(request, params))
1150
1317
  else:
@@ -1159,7 +1326,7 @@ class woo(Exchange, ImplicitAPI):
1159
1326
  #
1160
1327
  # {success: True, status: "CANCEL_SENT"}
1161
1328
  #
1162
- extendParams = {'symbol': symbol}
1329
+ extendParams: dict = {'symbol': symbol}
1163
1330
  if isByClientOrder:
1164
1331
  extendParams['client_order_id'] = clientOrderIdExchangeSpecific
1165
1332
  else:
@@ -1168,24 +1335,26 @@ class woo(Exchange, ImplicitAPI):
1168
1335
 
1169
1336
  def cancel_all_orders(self, symbol: Str = None, params={}):
1170
1337
  """
1171
- :see: https://docs.woo.org/#cancel-all-pending-orders
1172
- :see: https://docs.woo.org/#cancel-orders
1173
- :see: https://docs.woo.org/#cancel-all-pending-algo-orders
1338
+
1339
+ https://docs.woox.io/#cancel-all-pending-orders
1340
+ https://docs.woox.io/#cancel-orders
1341
+ https://docs.woox.io/#cancel-all-pending-algo-orders
1342
+
1174
1343
  cancel all open orders in a market
1175
1344
  :param str symbol: unified market symbol
1176
1345
  :param dict [params]: extra parameters specific to the exchange API endpoint
1177
- :param boolean [params.stop]: whether the order is a stop/algo order
1346
+ :param boolean [params.trigger]: whether the order is a trigger/algo order
1178
1347
  :returns dict: an list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1179
1348
  """
1180
1349
  self.load_markets()
1181
- stop = self.safe_bool_2(params, 'stop', 'trigger')
1350
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
1182
1351
  params = self.omit(params, ['stop', 'trigger'])
1183
- if stop:
1352
+ if trigger:
1184
1353
  return self.v3PrivateDeleteAlgoOrdersPending(params)
1185
1354
  if symbol is None:
1186
1355
  raise ArgumentsRequired(self.id + ' cancelOrders() requires a symbol argument')
1187
1356
  market = self.market(symbol)
1188
- request = {
1357
+ request: dict = {
1189
1358
  'symbol': market['id'],
1190
1359
  }
1191
1360
  response = self.v1PrivateDeleteOrders(self.extend(request, params))
@@ -1195,26 +1364,59 @@ class woo(Exchange, ImplicitAPI):
1195
1364
  # "status":"CANCEL_ALL_SENT"
1196
1365
  # }
1197
1366
  #
1198
- return response
1367
+ return [
1368
+ self.safe_order(response),
1369
+ ]
1370
+
1371
+ def cancel_all_orders_after(self, timeout: Int, params={}):
1372
+ """
1373
+ dead man's switch, cancel all orders after the given timeout
1374
+
1375
+ https://docs.woox.io/#cancel-all-after
1376
+
1377
+ :param number timeout: time in milliseconds, 0 represents cancel the timer
1378
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1379
+ :returns dict: the api result
1380
+ """
1381
+ self.load_markets()
1382
+ request: dict = {
1383
+ 'trigger_after': timeout if (timeout > 0) else 0,
1384
+ }
1385
+ response = self.v1PrivatePostOrderCancelAllAfter(self.extend(request, params))
1386
+ #
1387
+ # {
1388
+ # "success": True,
1389
+ # "data": {
1390
+ # "expected_trigger_time": 1711534302938
1391
+ # },
1392
+ # "timestamp": 1711534302943
1393
+ # }
1394
+ #
1395
+ return [
1396
+ self.safe_order(response),
1397
+ ]
1199
1398
 
1200
1399
  def fetch_order(self, id: str, symbol: Str = None, params={}):
1201
1400
  """
1202
- :see: https://docs.woo.org/#get-algo-order
1203
- :see: https://docs.woo.org/#get-order
1401
+
1402
+ https://docs.woox.io/#get-algo-order
1403
+ https://docs.woox.io/#get-order
1404
+
1204
1405
  fetches information on an order made by the user
1406
+ :param str id: the order id
1205
1407
  :param str symbol: unified symbol of the market the order was made in
1206
1408
  :param dict [params]: extra parameters specific to the exchange API endpoint
1207
- :param boolean [params.stop]: whether the order is a stop/algo order
1409
+ :param boolean [params.trigger]: whether the order is a trigger/algo order
1208
1410
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1209
1411
  """
1210
1412
  self.load_markets()
1211
1413
  market = self.market(symbol) if (symbol is not None) else None
1212
- stop = self.safe_bool_2(params, 'stop', 'trigger')
1414
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
1213
1415
  params = self.omit(params, ['stop', 'trigger'])
1214
- request = {}
1416
+ request: dict = {}
1215
1417
  clientOrderId = self.safe_string_2(params, 'clOrdID', 'clientOrderId')
1216
1418
  response = None
1217
- if stop:
1419
+ if trigger:
1218
1420
  request['oid'] = id
1219
1421
  response = self.v3PrivateGetAlgoOrderOid(self.extend(request, params))
1220
1422
  elif clientOrderId:
@@ -1258,19 +1460,21 @@ class woo(Exchange, ImplicitAPI):
1258
1460
  # ]
1259
1461
  # }
1260
1462
  #
1261
- orders = self.safe_value(response, 'data', response)
1463
+ orders = self.safe_dict(response, 'data', response)
1262
1464
  return self.parse_order(orders, market)
1263
1465
 
1264
1466
  def fetch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1265
1467
  """
1266
1468
  fetches information on multiple orders made by the user
1267
- :see: https://docs.woo.org/#get-orders
1268
- :see: https://docs.woo.org/#get-algo-orders
1469
+
1470
+ https://docs.woox.io/#get-orders
1471
+ https://docs.woox.io/#get-algo-orders
1472
+
1269
1473
  :param str symbol: unified market symbol of the market orders were made in
1270
1474
  :param int [since]: the earliest time in ms to fetch orders for
1271
1475
  :param int [limit]: the maximum number of order structures to retrieve
1272
1476
  :param dict [params]: extra parameters specific to the exchange API endpoint
1273
- :param boolean [params.stop]: whether the order is a stop/algo order
1477
+ :param boolean [params.trigger]: whether the order is a trigger/algo order
1274
1478
  :param boolean [params.isTriggered]: whether the order has been triggered(False by default)
1275
1479
  :param str [params.side]: 'buy' or 'sell'
1276
1480
  :param boolean [params.trailing]: set to True if you want to fetch trailing orders
@@ -1282,16 +1486,16 @@ class woo(Exchange, ImplicitAPI):
1282
1486
  paginate, params = self.handle_option_and_params(params, 'fetchOrders', 'paginate')
1283
1487
  if paginate:
1284
1488
  return self.fetch_paginated_call_incremental('fetchOrders', symbol, since, limit, params, 'page', 500)
1285
- request = {}
1489
+ request: dict = {}
1286
1490
  market: Market = None
1287
- stop = self.safe_bool_2(params, 'stop', 'trigger')
1491
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
1288
1492
  trailing = self.safe_bool(params, 'trailing', False)
1289
1493
  params = self.omit(params, ['stop', 'trailing', 'trigger'])
1290
1494
  if symbol is not None:
1291
1495
  market = self.market(symbol)
1292
1496
  request['symbol'] = market['id']
1293
1497
  if since is not None:
1294
- if stop or trailing:
1498
+ if trigger or trailing:
1295
1499
  request['createdTimeStart'] = since
1296
1500
  else:
1297
1501
  request['start_t'] = since
@@ -1299,12 +1503,12 @@ class woo(Exchange, ImplicitAPI):
1299
1503
  request['size'] = limit
1300
1504
  else:
1301
1505
  request['size'] = 500
1302
- if stop:
1506
+ if trigger:
1303
1507
  request['algoType'] = 'stop'
1304
1508
  elif trailing:
1305
1509
  request['algoType'] = 'TRAILING_STOP'
1306
1510
  response = None
1307
- if stop or trailing:
1511
+ if trigger or trailing:
1308
1512
  response = self.v3PrivateGetAlgoOrders(self.extend(request, params))
1309
1513
  else:
1310
1514
  response = self.v1PrivateGetOrders(self.extend(request, params))
@@ -1341,17 +1545,61 @@ class woo(Exchange, ImplicitAPI):
1341
1545
  #
1342
1546
  data = self.safe_value(response, 'data', response)
1343
1547
  orders = self.safe_list(data, 'rows')
1344
- return self.parse_orders(orders, market, since, limit, params)
1548
+ return self.parse_orders(orders, market, since, limit)
1549
+
1550
+ def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1551
+ """
1552
+ fetches information on multiple orders made by the user
1553
+
1554
+ https://docs.woox.io/#get-orders
1555
+ https://docs.woox.io/#get-algo-orders
1556
+
1557
+ :param str symbol: unified market symbol of the market orders were made in
1558
+ :param int [since]: the earliest time in ms to fetch orders for
1559
+ :param int [limit]: the maximum number of order structures to retrieve
1560
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1561
+ :param boolean [params.trigger]: whether the order is a trigger/algo order
1562
+ :param boolean [params.isTriggered]: whether the order has been triggered(False by default)
1563
+ :param str [params.side]: 'buy' or 'sell'
1564
+ :param boolean [params.trailing]: set to True if you want to fetch trailing orders
1565
+ :param boolean [params.paginate]: set to True if you want to fetch orders with pagination
1566
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1567
+ """
1568
+ self.load_markets()
1569
+ extendedParams = self.extend(params, {'status': 'INCOMPLETE'})
1570
+ return self.fetch_orders(symbol, since, limit, extendedParams)
1571
+
1572
+ def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1573
+ """
1574
+ fetches information on multiple orders made by the user
1575
+
1576
+ https://docs.woox.io/#get-orders
1577
+ https://docs.woox.io/#get-algo-orders
1578
+
1579
+ :param str symbol: unified market symbol of the market orders were made in
1580
+ :param int [since]: the earliest time in ms to fetch orders for
1581
+ :param int [limit]: the maximum number of order structures to retrieve
1582
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1583
+ :param boolean [params.trigger]: whether the order is a trigger/algo order
1584
+ :param boolean [params.isTriggered]: whether the order has been triggered(False by default)
1585
+ :param str [params.side]: 'buy' or 'sell'
1586
+ :param boolean [params.trailing]: set to True if you want to fetch trailing orders
1587
+ :param boolean [params.paginate]: set to True if you want to fetch orders with pagination
1588
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1589
+ """
1590
+ self.load_markets()
1591
+ extendedParams = self.extend(params, {'status': 'COMPLETED'})
1592
+ return self.fetch_orders(symbol, since, limit, extendedParams)
1345
1593
 
1346
- def parse_time_in_force(self, timeInForce):
1347
- timeInForces = {
1594
+ def parse_time_in_force(self, timeInForce: Str):
1595
+ timeInForces: dict = {
1348
1596
  'ioc': 'IOC',
1349
1597
  'fok': 'FOK',
1350
1598
  'post_only': 'PO',
1351
1599
  }
1352
1600
  return self.safe_string(timeInForces, timeInForce, None)
1353
1601
 
1354
- def parse_order(self, order, market: Market = None) -> Order:
1602
+ def parse_order(self, order: dict, market: Market = None) -> Order:
1355
1603
  #
1356
1604
  # Possible input functions:
1357
1605
  # * createOrder
@@ -1410,11 +1658,11 @@ class woo(Exchange, ImplicitAPI):
1410
1658
  side = self.safe_string_lower(order, 'side')
1411
1659
  filled = self.omit_zero(self.safe_value_2(order, 'executed', 'totalExecutedQuantity'))
1412
1660
  average = self.omit_zero(self.safe_string_2(order, 'average_executed_price', 'averageExecutedPrice'))
1413
- remaining = Precise.string_sub(cost, filled)
1414
- fee = self.safe_value_2(order, 'total_fee', 'totalFee')
1661
+ # remaining = Precise.string_sub(cost, filled)
1662
+ fee = self.safe_number_2(order, 'total_fee', 'totalFee')
1415
1663
  feeCurrency = self.safe_string_2(order, 'fee_asset', 'feeAsset')
1416
1664
  transactions = self.safe_value(order, 'Transactions')
1417
- stopPrice = self.safe_number(order, 'triggerPrice')
1665
+ triggerPrice = self.safe_number(order, 'triggerPrice')
1418
1666
  takeProfitPrice: Num = None
1419
1667
  stopLossPrice: Num = None
1420
1668
  childOrders = self.safe_value(order, 'childOrders')
@@ -1443,14 +1691,13 @@ class woo(Exchange, ImplicitAPI):
1443
1691
  'reduceOnly': self.safe_bool(order, 'reduce_only'),
1444
1692
  'side': side,
1445
1693
  'price': price,
1446
- 'stopPrice': stopPrice,
1447
- 'triggerPrice': stopPrice,
1694
+ 'triggerPrice': triggerPrice,
1448
1695
  'takeProfitPrice': takeProfitPrice,
1449
1696
  'stopLossPrice': stopLossPrice,
1450
1697
  'average': average,
1451
1698
  'amount': amount,
1452
1699
  'filled': filled,
1453
- 'remaining': remaining, # TO_DO
1700
+ 'remaining': None, # TO_DO
1454
1701
  'cost': cost,
1455
1702
  'trades': transactions,
1456
1703
  'fee': {
@@ -1460,9 +1707,9 @@ class woo(Exchange, ImplicitAPI):
1460
1707
  'info': order,
1461
1708
  }, market)
1462
1709
 
1463
- def parse_order_status(self, status):
1710
+ def parse_order_status(self, status: Str):
1464
1711
  if status is not None:
1465
- statuses = {
1712
+ statuses: dict = {
1466
1713
  'NEW': 'open',
1467
1714
  'FILLED': 'closed',
1468
1715
  'CANCEL_SENT': 'canceled',
@@ -1479,6 +1726,9 @@ class woo(Exchange, ImplicitAPI):
1479
1726
  def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
1480
1727
  """
1481
1728
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
1729
+
1730
+ https://docs.woox.io/#orderbook-snapshot-public
1731
+
1482
1732
  :param str symbol: unified symbol of the market to fetch the order book for
1483
1733
  :param int [limit]: the maximum amount of order book entries to return
1484
1734
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -1486,7 +1736,7 @@ class woo(Exchange, ImplicitAPI):
1486
1736
  """
1487
1737
  self.load_markets()
1488
1738
  market = self.market(symbol)
1489
- request = {
1739
+ request: dict = {
1490
1740
  'symbol': market['id'],
1491
1741
  }
1492
1742
  if limit is not None:
@@ -1514,8 +1764,10 @@ class woo(Exchange, ImplicitAPI):
1514
1764
 
1515
1765
  def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
1516
1766
  """
1517
- :see: https://docs.woo.org/#kline-public
1518
- :see: https://docs.woo.org/#kline-historical-data-public
1767
+
1768
+ https://docs.woox.io/#kline-public
1769
+ https://docs.woox.io/#kline-historical-data-public
1770
+
1519
1771
  fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1520
1772
  :param str symbol: unified symbol of the market to fetch OHLCV data for
1521
1773
  :param str timeframe: the length of time each candle represents
@@ -1526,7 +1778,7 @@ class woo(Exchange, ImplicitAPI):
1526
1778
  """
1527
1779
  self.load_markets()
1528
1780
  market = self.market(symbol)
1529
- request = {
1781
+ request: dict = {
1530
1782
  'symbol': market['id'],
1531
1783
  'type': self.safe_string(self.timeframes, timeframe, timeframe),
1532
1784
  }
@@ -1604,6 +1856,9 @@ class woo(Exchange, ImplicitAPI):
1604
1856
  def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1605
1857
  """
1606
1858
  fetch all the trades made from a single order
1859
+
1860
+ https://docs.woox.io/#get-trades
1861
+
1607
1862
  :param str id: order id
1608
1863
  :param str symbol: unified market symbol
1609
1864
  :param int [since]: the earliest time in ms to fetch trades for
@@ -1615,7 +1870,7 @@ class woo(Exchange, ImplicitAPI):
1615
1870
  market: Market = None
1616
1871
  if symbol is not None:
1617
1872
  market = self.market(symbol)
1618
- request = {
1873
+ request: dict = {
1619
1874
  'oid': id,
1620
1875
  }
1621
1876
  response = self.v1PrivateGetOrderOidTrades(self.extend(request, params))
@@ -1642,8 +1897,10 @@ class woo(Exchange, ImplicitAPI):
1642
1897
 
1643
1898
  def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1644
1899
  """
1645
- :see: https://docs.woo.org/#get-trades
1646
1900
  fetch all trades made by the user
1901
+
1902
+ https://docs.woox.io/#get-trade-history
1903
+
1647
1904
  :param str symbol: unified market symbol
1648
1905
  :param int [since]: the earliest time in ms to fetch trades for
1649
1906
  :param int [limit]: the maximum number of trades structures to retrieve
@@ -1656,13 +1913,14 @@ class woo(Exchange, ImplicitAPI):
1656
1913
  paginate, params = self.handle_option_and_params(params, 'fetchMyTrades', 'paginate')
1657
1914
  if paginate:
1658
1915
  return self.fetch_paginated_call_incremental('fetchMyTrades', symbol, since, limit, params, 'page', 500)
1659
- request = {}
1916
+ request: dict = {}
1660
1917
  market: Market = None
1661
1918
  if symbol is not None:
1662
1919
  market = self.market(symbol)
1663
1920
  request['symbol'] = market['id']
1664
1921
  if since is not None:
1665
1922
  request['start_t'] = since
1923
+ request, params = self.handle_until_option('end_t', request, params)
1666
1924
  if limit is not None:
1667
1925
  request['size'] = limit
1668
1926
  else:
@@ -1697,6 +1955,9 @@ class woo(Exchange, ImplicitAPI):
1697
1955
  def fetch_accounts(self, params={}) -> List[Account]:
1698
1956
  """
1699
1957
  fetch all the accounts associated with a profile
1958
+
1959
+ https://docs.woox.io/#get-assets-of-subaccounts
1960
+
1700
1961
  :param dict [params]: extra parameters specific to the exchange API endpoint
1701
1962
  :returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
1702
1963
  """
@@ -1740,7 +2001,9 @@ class woo(Exchange, ImplicitAPI):
1740
2001
  def fetch_balance(self, params={}) -> Balances:
1741
2002
  """
1742
2003
  query for balance and get the amount of funds available for trading or funds locked in orders
1743
- :see: https://docs.woo.org/#get-current-holding-get-balance-new
2004
+
2005
+ https://docs.woox.io/#get-current-holding-get-balance-new
2006
+
1744
2007
  :param dict [params]: extra parameters specific to the exchange API endpoint
1745
2008
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
1746
2009
  """
@@ -1773,7 +2036,7 @@ class woo(Exchange, ImplicitAPI):
1773
2036
  return self.parse_balance(data)
1774
2037
 
1775
2038
  def parse_balance(self, response) -> Balances:
1776
- result = {
2039
+ result: dict = {
1777
2040
  'info': response,
1778
2041
  }
1779
2042
  balances = self.safe_list(response, 'holding', [])
@@ -1786,9 +2049,12 @@ class woo(Exchange, ImplicitAPI):
1786
2049
  result[code] = account
1787
2050
  return self.safe_balance(result)
1788
2051
 
1789
- def fetch_deposit_address(self, code: str, params={}):
2052
+ def fetch_deposit_address(self, code: str, params={}) -> DepositAddress:
1790
2053
  """
1791
2054
  fetch the deposit address for a currency associated with self account
2055
+
2056
+ https://docs.woox.io/#get-token-deposit-address
2057
+
1792
2058
  :param str code: unified currency code
1793
2059
  :param dict [params]: extra parameters specific to the exchange API endpoint
1794
2060
  :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
@@ -1800,7 +2066,7 @@ class woo(Exchange, ImplicitAPI):
1800
2066
  networkCode = self.safe_string(params, 'network', networkCodeDefault)
1801
2067
  params = self.omit(params, 'network')
1802
2068
  codeForExchange = networkCode + '_' + currency['code']
1803
- request = {
2069
+ request: dict = {
1804
2070
  'token': codeForExchange,
1805
2071
  }
1806
2072
  response = self.v1PrivateGetAssetDeposit(self.extend(request, params))
@@ -1813,16 +2079,16 @@ class woo(Exchange, ImplicitAPI):
1813
2079
  address = self.safe_string(response, 'address')
1814
2080
  self.check_address(address)
1815
2081
  return {
2082
+ 'info': response,
1816
2083
  'currency': code,
2084
+ 'network': networkCode,
1817
2085
  'address': address,
1818
2086
  'tag': tag,
1819
- 'network': networkCode,
1820
- 'info': response,
1821
2087
  }
1822
2088
 
1823
- def get_asset_history_rows(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
2089
+ def get_asset_history_rows(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> Any:
1824
2090
  self.load_markets()
1825
- request = {}
2091
+ request: dict = {}
1826
2092
  currency: Currency = None
1827
2093
  if code is not None:
1828
2094
  currency = self.currency(code)
@@ -1870,30 +2136,35 @@ class woo(Exchange, ImplicitAPI):
1870
2136
  # "meta": {total: '1', records_per_page: "25", current_page: "1"},
1871
2137
  # "success": True
1872
2138
  # }
1873
- return [currency, self.safe_value(response, 'rows', {})]
2139
+ return [currency, self.safe_list(response, 'rows', [])]
1874
2140
 
1875
- def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
2141
+ def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
1876
2142
  """
1877
2143
  fetch the history of changes, actions done by the user or operations that altered balance of the user
1878
- :param str code: unified currency code, default is None
2144
+
2145
+ https://docs.woox.io/#get-asset-history
2146
+
2147
+ :param str [code]: unified currency code, default is None
1879
2148
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
1880
- :param int [limit]: max number of ledger entrys to return, default is None
2149
+ :param int [limit]: max number of ledger entries to return, default is None
1881
2150
  :param dict [params]: extra parameters specific to the exchange API endpoint
1882
- :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
2151
+ :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger>`
1883
2152
  """
1884
2153
  currency, rows = self.get_asset_history_rows(code, since, limit, params)
1885
2154
  return self.parse_ledger(rows, currency, since, limit, params)
1886
2155
 
1887
- def parse_ledger_entry(self, item, currency: Currency = None):
2156
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
1888
2157
  networkizedCode = self.safe_string(item, 'token')
1889
2158
  currencyDefined = self.get_currency_from_chaincode(networkizedCode, currency)
1890
2159
  code = currencyDefined['code']
2160
+ currency = self.safe_currency(code, currency)
1891
2161
  amount = self.safe_number(item, 'amount')
1892
2162
  side = self.safe_string(item, 'token_side')
1893
2163
  direction = 'in' if (side == 'DEPOSIT') else 'out'
1894
2164
  timestamp = self.safe_timestamp(item, 'created_time')
1895
2165
  fee = self.parse_token_and_fee_temp(item, 'fee_token', 'fee_amount')
1896
- return {
2166
+ return self.safe_ledger_entry({
2167
+ 'info': item,
1897
2168
  'id': self.safe_string(item, 'id'),
1898
2169
  'currency': code,
1899
2170
  'account': self.safe_string(item, 'account'),
@@ -1903,16 +2174,15 @@ class woo(Exchange, ImplicitAPI):
1903
2174
  'amount': amount,
1904
2175
  'before': None,
1905
2176
  'after': None,
1906
- 'fee': fee,
1907
2177
  'direction': direction,
1908
2178
  'timestamp': timestamp,
1909
2179
  'datetime': self.iso8601(timestamp),
1910
2180
  'type': self.parse_ledger_entry_type(self.safe_string(item, 'type')),
1911
- 'info': item,
1912
- }
2181
+ 'fee': fee,
2182
+ }, currency)
1913
2183
 
1914
2184
  def parse_ledger_entry_type(self, type):
1915
- types = {
2185
+ types: dict = {
1916
2186
  'BALANCE': 'transaction', # Funds moved in/out wallet
1917
2187
  'COLLATERAL': 'transfer', # Funds moved between portfolios
1918
2188
  }
@@ -1934,13 +2204,16 @@ class woo(Exchange, ImplicitAPI):
1934
2204
  def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
1935
2205
  """
1936
2206
  fetch all deposits made to an account
2207
+
2208
+ https://docs.woox.io/#get-asset-history
2209
+
1937
2210
  :param str code: unified currency code
1938
2211
  :param int [since]: the earliest time in ms to fetch deposits for
1939
2212
  :param int [limit]: the maximum number of deposits structures to retrieve
1940
2213
  :param dict [params]: extra parameters specific to the exchange API endpoint
1941
2214
  :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
1942
2215
  """
1943
- request = {
2216
+ request: dict = {
1944
2217
  'token_side': 'DEPOSIT',
1945
2218
  }
1946
2219
  return self.fetch_deposits_withdrawals(code, since, limit, self.extend(request, params))
@@ -1948,13 +2221,16 @@ class woo(Exchange, ImplicitAPI):
1948
2221
  def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
1949
2222
  """
1950
2223
  fetch all withdrawals made from an account
2224
+
2225
+ https://docs.woox.io/#get-asset-history
2226
+
1951
2227
  :param str code: unified currency code
1952
2228
  :param int [since]: the earliest time in ms to fetch withdrawals for
1953
2229
  :param int [limit]: the maximum number of withdrawals structures to retrieve
1954
2230
  :param dict [params]: extra parameters specific to the exchange API endpoint
1955
2231
  :returns dict[]: a list of `transaction structures <https://docs.ccxt.com/#/?id=transaction-structure>`
1956
2232
  """
1957
- request = {
2233
+ request: dict = {
1958
2234
  'token_side': 'WITHDRAW',
1959
2235
  }
1960
2236
  return self.fetch_deposits_withdrawals(code, since, limit, self.extend(request, params))
@@ -1962,13 +2238,16 @@ class woo(Exchange, ImplicitAPI):
1962
2238
  def fetch_deposits_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
1963
2239
  """
1964
2240
  fetch history of deposits and withdrawals
2241
+
2242
+ https://docs.woox.io/#get-asset-history
2243
+
1965
2244
  :param str [code]: unified currency code for the currency of the deposit/withdrawals, default is None
1966
2245
  :param int [since]: timestamp in ms of the earliest deposit/withdrawal, default is None
1967
2246
  :param int [limit]: max number of deposit/withdrawals to return, default is None
1968
2247
  :param dict [params]: extra parameters specific to the exchange API endpoint
1969
2248
  :returns dict: a list of `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
1970
2249
  """
1971
- request = {
2250
+ request: dict = {
1972
2251
  'type': 'BALANCE',
1973
2252
  }
1974
2253
  currency, rows = self.get_asset_history_rows(code, since, limit, self.extend(request, params))
@@ -1985,7 +2264,7 @@ class woo(Exchange, ImplicitAPI):
1985
2264
  #
1986
2265
  return self.parse_transactions(rows, currency, since, limit, params)
1987
2266
 
1988
- def parse_transaction(self, transaction, currency: Currency = None) -> Transaction:
2267
+ def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
1989
2268
  # example in fetchLedger
1990
2269
  networkizedCode = self.safe_string(transaction, 'token')
1991
2270
  currencyDefined = self.get_currency_from_chaincode(networkizedCode, currency)
@@ -2020,8 +2299,8 @@ class woo(Exchange, ImplicitAPI):
2020
2299
  'network': None,
2021
2300
  }
2022
2301
 
2023
- def parse_transaction_status(self, status):
2024
- statuses = {
2302
+ def parse_transaction_status(self, status: Str):
2303
+ statuses: dict = {
2025
2304
  'NEW': 'pending',
2026
2305
  'CONFIRMING': 'pending',
2027
2306
  'PROCESSING': 'pending',
@@ -2032,8 +2311,10 @@ class woo(Exchange, ImplicitAPI):
2032
2311
 
2033
2312
  def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
2034
2313
  """
2035
- :see: https://docs.woo.org/#get-transfer-history
2036
2314
  transfer currency internally between wallets on the same account
2315
+
2316
+ https://docs.woox.io/#get-transfer-history
2317
+
2037
2318
  :param str code: unified currency code
2038
2319
  :param float amount: amount to transfer
2039
2320
  :param str fromAccount: account to transfer from
@@ -2043,7 +2324,7 @@ class woo(Exchange, ImplicitAPI):
2043
2324
  """
2044
2325
  self.load_markets()
2045
2326
  currency = self.currency(code)
2046
- request = {
2327
+ request: dict = {
2047
2328
  'token': currency['id'],
2048
2329
  'amount': self.parse_to_numeric(amount),
2049
2330
  'from_application_id': fromAccount,
@@ -2065,10 +2346,12 @@ class woo(Exchange, ImplicitAPI):
2065
2346
  transfer['toAccount'] = toAccount
2066
2347
  return transfer
2067
2348
 
2068
- def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
2349
+ def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[TransferEntry]:
2069
2350
  """
2070
2351
  fetch a history of internal transfers made on an account
2071
- :see: https://docs.woo.org/#get-transfer-history
2352
+
2353
+ https://docs.woox.io/#get-transfer-history
2354
+
2072
2355
  :param str code: unified currency code of the currency transferred
2073
2356
  :param int [since]: the earliest time in ms to fetch transfers for
2074
2357
  :param int [limit]: the maximum number of transfers structures to retrieve
@@ -2076,13 +2359,13 @@ class woo(Exchange, ImplicitAPI):
2076
2359
  :param int [params.until]: the latest time in ms to fetch entries for
2077
2360
  :returns dict[]: a list of `transfer structures <https://docs.ccxt.com/#/?id=transfer-structure>`
2078
2361
  """
2079
- request = {}
2362
+ request: dict = {}
2080
2363
  if limit is not None:
2081
2364
  request['size'] = limit
2082
2365
  if since is not None:
2083
2366
  request['start_t'] = since
2084
- until = self.safe_integer_2(params, 'until', 'till') # unified in milliseconds
2085
- params = self.omit(params, ['until', 'till'])
2367
+ until = self.safe_integer(params, 'until') # unified in milliseconds
2368
+ params = self.omit(params, ['until'])
2086
2369
  if until is not None:
2087
2370
  request['end_t'] = until
2088
2371
  response = self.v1PrivateGetAssetMainSubTransferHistory(self.extend(request, params))
@@ -2113,7 +2396,7 @@ class woo(Exchange, ImplicitAPI):
2113
2396
  data = self.safe_list(response, 'rows', [])
2114
2397
  return self.parse_transfers(data, None, since, limit, params)
2115
2398
 
2116
- def parse_transfer(self, transfer, currency: Currency = None):
2399
+ def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
2117
2400
  #
2118
2401
  # fetchTransfers
2119
2402
  # {
@@ -2155,8 +2438,8 @@ class woo(Exchange, ImplicitAPI):
2155
2438
  'info': transfer,
2156
2439
  }
2157
2440
 
2158
- def parse_transfer_status(self, status):
2159
- statuses = {
2441
+ def parse_transfer_status(self, status: Str) -> Str:
2442
+ statuses: dict = {
2160
2443
  'NEW': 'pending',
2161
2444
  'CONFIRMING': 'pending',
2162
2445
  'PROCESSING': 'pending',
@@ -2165,9 +2448,12 @@ class woo(Exchange, ImplicitAPI):
2165
2448
  }
2166
2449
  return self.safe_string(statuses, status, status)
2167
2450
 
2168
- def withdraw(self, code: str, amount: float, address, tag=None, params={}):
2451
+ def withdraw(self, code: str, amount: float, address: str, tag=None, params={}) -> Transaction:
2169
2452
  """
2170
2453
  make a withdrawal
2454
+
2455
+ https://docs.woox.io/#token-withdraw
2456
+
2171
2457
  :param str code: unified currency code
2172
2458
  :param float amount: the amount to withdraw
2173
2459
  :param str address: the address to withdraw to
@@ -2179,7 +2465,7 @@ class woo(Exchange, ImplicitAPI):
2179
2465
  self.load_markets()
2180
2466
  self.check_address(address)
2181
2467
  currency = self.currency(code)
2182
- request = {
2468
+ request: dict = {
2183
2469
  'amount': amount,
2184
2470
  'address': address,
2185
2471
  }
@@ -2203,10 +2489,12 @@ class woo(Exchange, ImplicitAPI):
2203
2489
  #
2204
2490
  return self.parse_transaction(response, currency)
2205
2491
 
2206
- def repay_margin(self, code: str, amount, symbol: Str = None, params={}):
2492
+ def repay_margin(self, code: str, amount: float, symbol: Str = None, params={}):
2207
2493
  """
2208
2494
  repay borrowed margin and interest
2209
- :see: https://docs.woo.org/#repay-interest
2495
+
2496
+ https://docs.woox.io/#repay-interest
2497
+
2210
2498
  :param str code: unified currency code of the currency to repay
2211
2499
  :param float amount: the amount to repay
2212
2500
  :param str symbol: not used by woo.repayMargin()
@@ -2219,7 +2507,7 @@ class woo(Exchange, ImplicitAPI):
2219
2507
  market = self.market(symbol)
2220
2508
  symbol = market['symbol']
2221
2509
  currency = self.currency(code)
2222
- request = {
2510
+ request: dict = {
2223
2511
  'token': currency['id'], # interest token that you want to repay
2224
2512
  'amount': self.currency_to_precision(code, amount),
2225
2513
  }
@@ -2252,7 +2540,7 @@ class woo(Exchange, ImplicitAPI):
2252
2540
  }
2253
2541
 
2254
2542
  def nonce(self):
2255
- return self.milliseconds()
2543
+ return self.milliseconds() - self.options['timeDifference']
2256
2544
 
2257
2545
  def sign(self, path, section='public', method='GET', params={}, headers=None, body=None):
2258
2546
  version = section[0]
@@ -2266,6 +2554,10 @@ class woo(Exchange, ImplicitAPI):
2266
2554
  url += access + '/' + pathWithParams
2267
2555
  if params:
2268
2556
  url += '?' + self.urlencode(params)
2557
+ elif access == 'pub':
2558
+ url += pathWithParams
2559
+ if params:
2560
+ url += '?' + self.urlencode(params)
2269
2561
  else:
2270
2562
  self.check_required_credentials()
2271
2563
  if method == 'POST' and (path == 'algo/order' or path == 'order'):
@@ -2273,8 +2565,8 @@ class woo(Exchange, ImplicitAPI):
2273
2565
  if not isSandboxMode:
2274
2566
  applicationId = 'bc830de7-50f3-460b-9ee0-f430f83f9dad'
2275
2567
  brokerId = self.safe_string(self.options, 'brokerId', applicationId)
2276
- isStop = path.find('algo') > -1
2277
- if isStop:
2568
+ isTrigger = path.find('algo') > -1
2569
+ if isTrigger:
2278
2570
  params['brokerId'] = brokerId
2279
2571
  else:
2280
2572
  params['broker_id'] = brokerId
@@ -2309,7 +2601,7 @@ class woo(Exchange, ImplicitAPI):
2309
2601
  headers['x-api-signature'] = self.hmac(self.encode(auth), self.encode(self.secret), hashlib.sha256)
2310
2602
  return {'url': url, 'method': method, 'body': body, 'headers': headers}
2311
2603
 
2312
- def handle_errors(self, httpCode, reason, url, method, headers, body, response, requestHeaders, requestBody):
2604
+ def handle_errors(self, httpCode: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
2313
2605
  if not response:
2314
2606
  return None # fallback to default error handler
2315
2607
  #
@@ -2340,11 +2632,13 @@ class woo(Exchange, ImplicitAPI):
2340
2632
  #
2341
2633
  marketId = self.safe_string(income, 'symbol')
2342
2634
  symbol = self.safe_symbol(marketId, market)
2343
- amount = self.safe_number(income, 'funding_fee')
2635
+ amount = self.safe_string(income, 'funding_fee')
2344
2636
  code = self.safe_currency_code('USD')
2345
2637
  id = self.safe_string(income, 'id')
2346
2638
  timestamp = self.safe_timestamp(income, 'updated_time')
2347
2639
  rate = self.safe_number(income, 'funding_rate')
2640
+ paymentType = self.safe_string(income, 'payment_type')
2641
+ amount = Precise.string_neg(amount) if (paymentType == 'Pay') else amount
2348
2642
  return {
2349
2643
  'info': income,
2350
2644
  'symbol': symbol,
@@ -2352,19 +2646,39 @@ class woo(Exchange, ImplicitAPI):
2352
2646
  'timestamp': timestamp,
2353
2647
  'datetime': self.iso8601(timestamp),
2354
2648
  'id': id,
2355
- 'amount': amount,
2649
+ 'amount': self.parse_number(amount),
2356
2650
  'rate': rate,
2357
2651
  }
2358
2652
 
2359
2653
  def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2654
+ """
2655
+ fetch the history of funding payments paid and received on self account
2656
+
2657
+ https://docs.woox.io/#get-funding-fee-history
2658
+
2659
+ :param str [symbol]: unified market symbol
2660
+ :param int [since]: the earliest time in ms to fetch funding history for
2661
+ :param int [limit]: the maximum number of funding history structures to retrieve
2662
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2663
+ :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
2664
+ :returns dict: a `funding history structure <https://docs.ccxt.com/#/?id=funding-history-structure>`
2665
+ """
2360
2666
  self.load_markets()
2361
- request = {}
2667
+ paginate = False
2668
+ paginate, params = self.handle_option_and_params(params, 'fetchFundingHistory', 'paginate')
2669
+ if paginate:
2670
+ return self.fetch_paginated_call_cursor('fetchFundingHistory', symbol, since, limit, params, 'page', 'page', 1, 500)
2671
+ request: dict = {}
2362
2672
  market: Market = None
2363
2673
  if symbol is not None:
2364
2674
  market = self.market(symbol)
2365
2675
  request['symbol'] = market['id']
2366
2676
  if since is not None:
2367
2677
  request['start_t'] = since
2678
+ if limit is not None:
2679
+ request['size'] = limit
2680
+ else:
2681
+ request['size'] = 5000
2368
2682
  response = self.v1PrivateGetFundingFeeHistory(self.extend(request, params))
2369
2683
  #
2370
2684
  # {
@@ -2389,26 +2703,37 @@ class woo(Exchange, ImplicitAPI):
2389
2703
  # "success":true
2390
2704
  # }
2391
2705
  #
2706
+ meta = self.safe_dict(response, 'meta', {})
2707
+ cursor = self.safe_integer(meta, 'current_page')
2392
2708
  result = self.safe_list(response, 'rows', [])
2709
+ resultLength = len(result)
2710
+ if resultLength > 0:
2711
+ lastItem = result[resultLength - 1]
2712
+ lastItem['page'] = cursor
2713
+ result[resultLength - 1] = lastItem
2393
2714
  return self.parse_incomes(result, market, since, limit)
2394
2715
 
2395
- def parse_funding_rate(self, fundingRate, market: Market = None):
2396
- #
2397
- # {
2398
- # "symbol":"PERP_AAVE_USDT",
2399
- # "est_funding_rate":-0.00003447,
2400
- # "est_funding_rate_timestamp":1653633959001,
2401
- # "last_funding_rate":-0.00002094,
2402
- # "last_funding_rate_timestamp":1653631200000,
2403
- # "next_funding_time":1653634800000
2404
- # }
2716
+ def parse_funding_rate(self, fundingRate, market: Market = None) -> FundingRate:
2405
2717
  #
2718
+ # {
2719
+ # "success": True,
2720
+ # "timestamp": 1727427915529,
2721
+ # "symbol": "PERP_BTC_USDT",
2722
+ # "est_funding_rate": -0.00092719,
2723
+ # "est_funding_rate_timestamp": 1727427899060,
2724
+ # "last_funding_rate": -0.00092610,
2725
+ # "last_funding_rate_timestamp": 1727424000000,
2726
+ # "next_funding_time": 1727452800000,
2727
+ # "last_funding_rate_interval": 8,
2728
+ # "est_funding_rate_interval": 8
2729
+ # }
2406
2730
  #
2407
2731
  symbol = self.safe_string(fundingRate, 'symbol')
2408
2732
  market = self.market(symbol)
2409
2733
  nextFundingTimestamp = self.safe_integer(fundingRate, 'next_funding_time')
2410
2734
  estFundingRateTimestamp = self.safe_integer(fundingRate, 'est_funding_rate_timestamp')
2411
2735
  lastFundingRateTimestamp = self.safe_integer(fundingRate, 'last_funding_rate_timestamp')
2736
+ intervalString = self.safe_string(fundingRate, 'est_funding_rate_interval')
2412
2737
  return {
2413
2738
  'info': fundingRate,
2414
2739
  'symbol': market['symbol'],
@@ -2427,30 +2752,63 @@ class woo(Exchange, ImplicitAPI):
2427
2752
  'previousFundingRate': self.safe_number(fundingRate, 'last_funding_rate'),
2428
2753
  'previousFundingTimestamp': lastFundingRateTimestamp,
2429
2754
  'previousFundingDatetime': self.iso8601(lastFundingRateTimestamp),
2755
+ 'interval': intervalString + 'h',
2430
2756
  }
2431
2757
 
2432
- def fetch_funding_rate(self, symbol: str, params={}):
2758
+ def fetch_funding_interval(self, symbol: str, params={}) -> FundingRate:
2759
+ """
2760
+ fetch the current funding rate interval
2761
+
2762
+ https://docs.woox.io/#get-predicted-funding-rate-for-one-market-public
2763
+
2764
+ :param str symbol: unified market symbol
2765
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2766
+ :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
2767
+ """
2768
+ return self.fetch_funding_rate(symbol, params)
2769
+
2770
+ def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
2771
+ """
2772
+ fetch the current funding rate
2773
+
2774
+ https://docs.woox.io/#get-predicted-funding-rate-for-one-market-public
2775
+
2776
+ :param str symbol: unified market symbol
2777
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2778
+ :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
2779
+ """
2433
2780
  self.load_markets()
2434
2781
  market = self.market(symbol)
2435
- request = {
2782
+ request: dict = {
2436
2783
  'symbol': market['id'],
2437
2784
  }
2438
2785
  response = self.v1PublicGetFundingRateSymbol(self.extend(request, params))
2439
2786
  #
2440
2787
  # {
2441
- # "success":true,
2442
- # "timestamp":1653640572711,
2443
- # "symbol":"PERP_BTC_USDT",
2444
- # "est_funding_rate":0.00000738,
2445
- # "est_funding_rate_timestamp":1653640559003,
2446
- # "last_funding_rate":0.00000629,
2447
- # "last_funding_rate_timestamp":1653638400000,
2448
- # "next_funding_time":1653642000000
2788
+ # "success": True,
2789
+ # "timestamp": 1727428037877,
2790
+ # "symbol": "PERP_BTC_USDT",
2791
+ # "est_funding_rate": -0.00092674,
2792
+ # "est_funding_rate_timestamp": 1727428019064,
2793
+ # "last_funding_rate": -0.00092610,
2794
+ # "last_funding_rate_timestamp": 1727424000000,
2795
+ # "next_funding_time": 1727452800000,
2796
+ # "last_funding_rate_interval": 8,
2797
+ # "est_funding_rate_interval": 8
2449
2798
  # }
2450
2799
  #
2451
2800
  return self.parse_funding_rate(response, market)
2452
2801
 
2453
- def fetch_funding_rates(self, symbols: Strings = None, params={}):
2802
+ def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
2803
+ """
2804
+ fetch the funding rate for multiple markets
2805
+
2806
+ https://docs.woox.io/#get-predicted-funding-rate-for-all-markets-public
2807
+
2808
+ :param str[]|None symbols: list of unified market symbols
2809
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2810
+ :returns dict[]: a list of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rates-structure>`, indexed by market symbols
2811
+ """
2454
2812
  self.load_markets()
2455
2813
  symbols = self.market_symbols(symbols)
2456
2814
  response = self.v1PublicGetFundingRates(params)
@@ -2471,13 +2829,14 @@ class woo(Exchange, ImplicitAPI):
2471
2829
  # }
2472
2830
  #
2473
2831
  rows = self.safe_list(response, 'rows', [])
2474
- result = self.parse_funding_rates(rows)
2475
- return self.filter_by_array(result, 'symbol', symbols)
2832
+ return self.parse_funding_rates(rows, symbols)
2476
2833
 
2477
2834
  def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2478
2835
  """
2479
2836
  fetches historical funding rate prices
2480
- :see: https://docs.woo.org/#get-funding-rate-history-for-one-market-public
2837
+
2838
+ https://docs.woox.io/#get-funding-rate-history-for-one-market-public
2839
+
2481
2840
  :param str symbol: unified symbol of the market to fetch the funding rate history for
2482
2841
  :param int [since]: timestamp in ms of the earliest funding rate to fetch
2483
2842
  :param int [limit]: the maximum amount of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>` to fetch
@@ -2491,7 +2850,7 @@ class woo(Exchange, ImplicitAPI):
2491
2850
  paginate, params = self.handle_option_and_params(params, 'fetchFundingRateHistory', 'paginate')
2492
2851
  if paginate:
2493
2852
  return self.fetch_paginated_call_incremental('fetchFundingRateHistory', symbol, since, limit, params, 'page', 25)
2494
- request = {}
2853
+ request: dict = {}
2495
2854
  if symbol is not None:
2496
2855
  market = self.market(symbol)
2497
2856
  symbol = market['symbol']
@@ -2538,7 +2897,9 @@ class woo(Exchange, ImplicitAPI):
2538
2897
  def set_position_mode(self, hedged: bool, symbol: Str = None, params={}):
2539
2898
  """
2540
2899
  set hedged to True or False for a market
2541
- :see: https://docs.woo.org/#update-position-mode
2900
+
2901
+ https://docs.woox.io/#update-position-mode
2902
+
2542
2903
  :param bool hedged: set to True to use HEDGE_MODE, False for ONE_WAY
2543
2904
  :param str symbol: not used by woo setPositionMode
2544
2905
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2549,7 +2910,7 @@ class woo(Exchange, ImplicitAPI):
2549
2910
  hedgeMode = 'HEDGE_MODE'
2550
2911
  else:
2551
2912
  hedgeMode = 'ONE_WAY'
2552
- request = {
2913
+ request: dict = {
2553
2914
  'position_mode': hedgeMode,
2554
2915
  }
2555
2916
  response = self.v1PrivatePostClientPositionMode(self.extend(request, params))
@@ -2565,84 +2926,228 @@ class woo(Exchange, ImplicitAPI):
2565
2926
  def fetch_leverage(self, symbol: str, params={}) -> Leverage:
2566
2927
  """
2567
2928
  fetch the set leverage for a market
2568
- :see: https://docs.woo.org/#get-account-information-new
2929
+
2930
+ https://docs.woox.io/#get-account-information-new
2931
+
2569
2932
  :param str symbol: unified market symbol
2570
2933
  :param dict [params]: extra parameters specific to the exchange API endpoint
2934
+ :param str [params.marginMode]: *for swap markets only* 'cross' or 'isolated'
2935
+ :param str [params.position_mode]: *for swap markets only* 'ONE_WAY' or 'HEDGE_MODE'
2571
2936
  :returns dict: a `leverage structure <https://docs.ccxt.com/#/?id=leverage-structure>`
2572
2937
  """
2573
2938
  self.load_markets()
2574
2939
  market = self.market(symbol)
2575
- response = self.v3PrivateGetAccountinfo(params)
2576
- #
2577
- # {
2578
- # "success": True,
2579
- # "data": {
2580
- # "applicationId": "dsa",
2581
- # "account": "dsa",
2582
- # "alias": "haha",
2583
- # "accountMode": "MARGIN",
2584
- # "leverage": 1,
2585
- # "takerFeeRate": 1,
2586
- # "makerFeeRate": 1,
2587
- # "interestRate": 1,
2588
- # "futuresTakerFeeRate": 1,
2589
- # "futuresMakerFeeRate": 1,
2590
- # "otpauth": True,
2591
- # "marginRatio": 1,
2592
- # "openMarginRatio": 1,
2593
- # "initialMarginRatio": 1,
2594
- # "maintenanceMarginRatio": 1,
2595
- # "totalCollateral": 1,
2596
- # "freeCollateral": 1,
2597
- # "totalAccountValue": 1,
2598
- # "totalVaultValue": 1,
2599
- # "totalStakingValue": 1
2600
- # },
2601
- # "timestamp": 1673323685109
2602
- # }
2603
- #
2940
+ response: dict = None
2941
+ if market['spot']:
2942
+ response = self.v3PrivateGetAccountinfo(params)
2943
+ #
2944
+ # {
2945
+ # "success": True,
2946
+ # "data": {
2947
+ # "applicationId": "dsa",
2948
+ # "account": "dsa",
2949
+ # "alias": "haha",
2950
+ # "accountMode": "MARGIN",
2951
+ # "leverage": 1,
2952
+ # "takerFeeRate": 1,
2953
+ # "makerFeeRate": 1,
2954
+ # "interestRate": 1,
2955
+ # "futuresTakerFeeRate": 1,
2956
+ # "futuresMakerFeeRate": 1,
2957
+ # "otpauth": True,
2958
+ # "marginRatio": 1,
2959
+ # "openMarginRatio": 1,
2960
+ # "initialMarginRatio": 1,
2961
+ # "maintenanceMarginRatio": 1,
2962
+ # "totalCollateral": 1,
2963
+ # "freeCollateral": 1,
2964
+ # "totalAccountValue": 1,
2965
+ # "totalVaultValue": 1,
2966
+ # "totalStakingValue": 1
2967
+ # },
2968
+ # "timestamp": 1673323685109
2969
+ # }
2970
+ #
2971
+ elif market['swap']:
2972
+ request: dict = {
2973
+ 'symbol': market['id'],
2974
+ }
2975
+ marginMode: Str = None
2976
+ marginMode, params = self.handle_margin_mode_and_params('fetchLeverage', params, 'cross')
2977
+ request['margin_mode'] = self.encode_margin_mode(marginMode)
2978
+ response = self.v1PrivateGetClientFuturesLeverage(self.extend(request, params))
2979
+ #
2980
+ # HEDGE_MODE
2981
+ # {
2982
+ # "success": True,
2983
+ # "data":
2984
+ # {
2985
+ # "symbol": "PERP_ETH_USDT",
2986
+ # "default_margin_mode": "CROSS",
2987
+ # "position_mode": "HEDGE_MODE",
2988
+ # "details": [
2989
+ # {
2990
+ # "position_side": "LONG",
2991
+ # "leverage": 10
2992
+ # },
2993
+ # {
2994
+ # "position_side": "SHORT",
2995
+ # "leverage": 10
2996
+ # }
2997
+ # ]
2998
+ # },
2999
+ # "timestamp": 1720886470482
3000
+ # }
3001
+ #
3002
+ # ONE_WAY
3003
+ # {
3004
+ # "success": True,
3005
+ # "data": {
3006
+ # "symbol": "PERP_ETH_USDT",
3007
+ # "default_margin_mode": "ISOLATED",
3008
+ # "position_mode": "ONE_WAY",
3009
+ # "details": [
3010
+ # {
3011
+ # "position_side": "BOTH",
3012
+ # "leverage": 10
3013
+ # }
3014
+ # ]
3015
+ # },
3016
+ # "timestamp": 1720886810317
3017
+ # }
3018
+ #
3019
+ else:
3020
+ raise NotSupported(self.id + ' fetchLeverage() is not supported for ' + market['type'] + ' markets')
2604
3021
  data = self.safe_dict(response, 'data', {})
2605
3022
  return self.parse_leverage(data, market)
2606
3023
 
2607
- def parse_leverage(self, leverage, market=None) -> Leverage:
2608
- leverageValue = self.safe_integer(leverage, 'leverage')
3024
+ def parse_leverage(self, leverage: dict, market: Market = None) -> Leverage:
3025
+ marketId = self.safe_string(leverage, 'symbol')
3026
+ market = self.safe_market(marketId, market)
3027
+ marginMode = self.safe_string_lower(leverage, 'default_margin_mode')
3028
+ spotLeverage = self.safe_integer(leverage, 'leverage')
3029
+ longLeverage = spotLeverage
3030
+ shortLeverage = spotLeverage
3031
+ details = self.safe_list(leverage, 'details', [])
3032
+ for i in range(0, len(details)):
3033
+ position = self.safe_dict(details, i, {})
3034
+ positionLeverage = self.safe_integer(position, 'leverage')
3035
+ side = self.safe_string(position, 'position_side')
3036
+ if side == 'BOTH':
3037
+ longLeverage = positionLeverage
3038
+ shortLeverage = positionLeverage
3039
+ elif side == 'LONG':
3040
+ longLeverage = positionLeverage
3041
+ elif side == 'SHORT':
3042
+ shortLeverage = positionLeverage
2609
3043
  return {
2610
3044
  'info': leverage,
2611
3045
  'symbol': market['symbol'],
2612
- 'marginMode': None,
2613
- 'longLeverage': leverageValue,
2614
- 'shortLeverage': leverageValue,
3046
+ 'marginMode': marginMode,
3047
+ 'longLeverage': longLeverage,
3048
+ 'shortLeverage': shortLeverage,
2615
3049
  }
2616
3050
 
2617
3051
  def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
3052
+ """
3053
+ set the level of leverage for a market
3054
+
3055
+ https://docs.woox.io/#update-leverage-setting
3056
+ https://docs.woox.io/#update-futures-leverage-setting
3057
+
3058
+ :param float leverage: the rate of leverage(1, 2, 3, 4 or 5 for spot markets, 1, 2, 3, 4, 5, 10, 15, 20 for swap markets)
3059
+ :param str [symbol]: unified market symbol(is mandatory for swap markets)
3060
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3061
+ :param str [params.marginMode]: *for swap markets only* 'cross' or 'isolated'
3062
+ :param str [params.position_side]: *for swap markets only* 'LONG' or 'SHORT' in hedge mode, 'BOTH' in one way mode.
3063
+ :returns dict: response from the exchange
3064
+ """
2618
3065
  self.load_markets()
2619
- if (leverage < 1) or (leverage > 20):
2620
- raise BadRequest(self.id + ' leverage should be between 1 and 20')
2621
- request = {
3066
+ request: dict = {
2622
3067
  'leverage': leverage,
2623
3068
  }
2624
- return self.v1PrivatePostClientLeverage(self.extend(request, params))
3069
+ market: Market = None
3070
+ if symbol is not None:
3071
+ market = self.market(symbol)
3072
+ if (symbol is None) or market['spot']:
3073
+ return self.v1PrivatePostClientLeverage(self.extend(request, params))
3074
+ elif market['swap']:
3075
+ request['symbol'] = market['id']
3076
+ marginMode: Str = None
3077
+ marginMode, params = self.handle_margin_mode_and_params('fetchLeverage', params, 'cross')
3078
+ request['margin_mode'] = self.encode_margin_mode(marginMode)
3079
+ return self.v1PrivatePostClientFuturesLeverage(self.extend(request, params))
3080
+ else:
3081
+ raise NotSupported(self.id + ' fetchLeverage() is not supported for ' + market['type'] + ' markets')
3082
+
3083
+ def add_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
3084
+ """
3085
+ add margin
3086
+
3087
+ https://docs.woox.io/#update-isolated-margin-setting
3088
+
3089
+ :param str symbol: unified market symbol
3090
+ :param float amount: amount of margin to add
3091
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3092
+ :param str [params.position_side]: 'LONG' or 'SHORT' in hedge mode, 'BOTH' in one way mode
3093
+ :returns dict: a `margin structure <https://docs.ccxt.com/#/?id=add-margin-structure>`
3094
+ """
3095
+ return self.modify_margin_helper(symbol, amount, 'ADD', params)
3096
+
3097
+ def reduce_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
3098
+ """
3099
+ remove margin from a position
3100
+
3101
+ https://docs.woox.io/#update-isolated-margin-setting
3102
+
3103
+ :param str symbol: unified market symbol
3104
+ :param float amount: amount of margin to remove
3105
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3106
+ :param str [params.position_side]: 'LONG' or 'SHORT' in hedge mode, 'BOTH' in one way mode
3107
+ :returns dict: a `margin structure <https://docs.ccxt.com/#/?id=reduce-margin-structure>`
3108
+ """
3109
+ return self.modify_margin_helper(symbol, amount, 'REDUCE', params)
3110
+
3111
+ def modify_margin_helper(self, symbol: str, amount, type, params={}) -> MarginModification:
3112
+ self.load_markets()
3113
+ market = self.market(symbol)
3114
+ request: dict = {
3115
+ 'symbol': market['id'],
3116
+ 'adjust_token': 'USDT', # todo check
3117
+ 'adjust_amount': amount,
3118
+ 'action': type,
3119
+ }
3120
+ return self.v1PrivatePostClientIsolatedMargin(self.extend(request, params))
2625
3121
 
2626
3122
  def fetch_position(self, symbol: Str = None, params={}):
2627
3123
  self.load_markets()
2628
3124
  market = self.market(symbol)
2629
- request = {
3125
+ request: dict = {
2630
3126
  'symbol': market['id'],
2631
3127
  }
2632
3128
  response = self.v1PrivateGetPositionSymbol(self.extend(request, params))
2633
3129
  #
2634
3130
  # {
2635
- # "symbol":"PERP_ETC_USDT",
2636
- # "holding":0.0,
2637
- # "pnl_24_h":0,
2638
- # "settle_price":0.0,
2639
- # "average_open_price":0,
2640
- # "success":true,
2641
- # "mark_price":22.6955,
2642
- # "pending_short_qty":0.0,
2643
- # "pending_long_qty":0.0,
2644
- # "fee_24_h":0,
2645
- # "timestamp":"1652231044.920"
3131
+ # "symbol": "PERP_ETH_USDT",
3132
+ # "position_side": "BOTH",
3133
+ # "leverage": 10,
3134
+ # "margin_mode": "CROSS",
3135
+ # "average_open_price": 3139.9,
3136
+ # "isolated_margin_amount": 0.0,
3137
+ # "isolated_margin_token": "",
3138
+ # "opening_time": "1720627963.094",
3139
+ # "mark_price": 3155.19169891,
3140
+ # "pending_short_qty": 0.0,
3141
+ # "pending_long_qty": 0.0,
3142
+ # "holding": -0.7,
3143
+ # "pnl_24_h": 0.0,
3144
+ # "est_liq_price": 9107.40055552,
3145
+ # "settle_price": 3151.0319904,
3146
+ # "success": True,
3147
+ # "fee_24_h": 0.0,
3148
+ # "isolated_frozen_long": 0.0,
3149
+ # "isolated_frozen_short": 0.0,
3150
+ # "timestamp": "1720867502.544"
2646
3151
  # }
2647
3152
  #
2648
3153
  return self.parse_position(response, market)
@@ -2653,44 +3158,107 @@ class woo(Exchange, ImplicitAPI):
2653
3158
  #
2654
3159
  # {
2655
3160
  # "success": True,
2656
- # "data": {
3161
+ # "data":
3162
+ # {
2657
3163
  # "positions": [
2658
3164
  # {
2659
- # "symbol": "0_symbol",
2660
- # "holding": 1,
2661
- # "pendingLongQty": 0,
2662
- # "pendingShortQty": 1,
2663
- # "settlePrice": 1,
2664
- # "averageOpenPrice": 1,
2665
- # "pnl24H": 1,
2666
- # "fee24H": 1,
2667
- # "markPrice": 1,
2668
- # "estLiqPrice": 1,
2669
- # "timestamp": 12321321
3165
+ # "symbol": "PERP_ETH_USDT",
3166
+ # "holding": -1.0,
3167
+ # "pendingLongQty": 0.0,
3168
+ # "pendingShortQty": 0.0,
3169
+ # "settlePrice": 3143.2,
3170
+ # "averageOpenPrice": 3143.2,
3171
+ # "pnl24H": 0.0,
3172
+ # "fee24H": 1.5716,
3173
+ # "markPrice": 3134.97984158,
3174
+ # "estLiqPrice": 3436.176349,
3175
+ # "timestamp": 1720628031.463,
3176
+ # "adlQuantile": 5,
3177
+ # "positionSide": "BOTH",
3178
+ # "marginMode": "ISOLATED",
3179
+ # "isolatedMarginToken": "USDT",
3180
+ # "isolatedMarginAmount": 314.62426,
3181
+ # "isolatedFrozenLong": 0.0,
3182
+ # "isolatedFrozenShort": 0.0,
3183
+ # "leverage": 10
3184
+ # },
3185
+ # {
3186
+ # "symbol": "PERP_SOL_USDT",
3187
+ # "holding": -1.0,
3188
+ # "pendingLongQty": 0.0,
3189
+ # "pendingShortQty": 0.0,
3190
+ # "settlePrice": 141.89933923,
3191
+ # "averageOpenPrice": 171.38,
3192
+ # "pnl24H": 0.0,
3193
+ # "fee24H": 0.0,
3194
+ # "markPrice": 141.65155427,
3195
+ # "estLiqPrice": 4242.73548551,
3196
+ # "timestamp": 1720616702.68,
3197
+ # "adlQuantile": 5,
3198
+ # "positionSide": "BOTH",
3199
+ # "marginMode": "CROSS",
3200
+ # "isolatedMarginToken": "",
3201
+ # "isolatedMarginAmount": 0.0,
3202
+ # "isolatedFrozenLong": 0.0,
3203
+ # "isolatedFrozenShort": 0.0,
3204
+ # "leverage": 10
2670
3205
  # }
2671
3206
  # ]
2672
3207
  # },
2673
- # "timestamp": 1673323880342
3208
+ # "timestamp": 1720628675078
2674
3209
  # }
2675
3210
  #
2676
3211
  result = self.safe_dict(response, 'data', {})
2677
3212
  positions = self.safe_list(result, 'positions', [])
2678
3213
  return self.parse_positions(positions, symbols)
2679
3214
 
2680
- def parse_position(self, position, market: Market = None):
3215
+ def parse_position(self, position: dict, market: Market = None):
2681
3216
  #
3217
+ # v1PrivateGetPositionSymbol
2682
3218
  # {
2683
- # "symbol": "0_symbol",
2684
- # "holding": 1,
2685
- # "pendingLongQty": 0,
2686
- # "pendingShortQty": 1,
2687
- # "settlePrice": 1,
2688
- # "averageOpenPrice": 1,
2689
- # "pnl24H": 1,
2690
- # "fee24H": 1,
2691
- # "markPrice": 1,
2692
- # "estLiqPrice": 1,
2693
- # "timestamp": 12321321
3219
+ # "symbol": "PERP_ETH_USDT",
3220
+ # "position_side": "BOTH",
3221
+ # "leverage": 10,
3222
+ # "margin_mode": "CROSS",
3223
+ # "average_open_price": 3139.9,
3224
+ # "isolated_margin_amount": 0.0,
3225
+ # "isolated_margin_token": "",
3226
+ # "opening_time": "1720627963.094",
3227
+ # "mark_price": 3155.19169891,
3228
+ # "pending_short_qty": 0.0,
3229
+ # "pending_long_qty": 0.0,
3230
+ # "holding": -0.7,
3231
+ # "pnl_24_h": 0.0,
3232
+ # "est_liq_price": 9107.40055552,
3233
+ # "settle_price": 3151.0319904,
3234
+ # "success": True,
3235
+ # "fee_24_h": 0.0,
3236
+ # "isolated_frozen_long": 0.0,
3237
+ # "isolated_frozen_short": 0.0,
3238
+ # "timestamp": "1720867502.544"
3239
+ # }
3240
+ #
3241
+ # v3PrivateGetPositions
3242
+ # {
3243
+ # "symbol": "PERP_ETH_USDT",
3244
+ # "holding": -1.0,
3245
+ # "pendingLongQty": 0.0, # todo: check
3246
+ # "pendingShortQty": 0.0, # todo: check
3247
+ # "settlePrice": 3143.2,
3248
+ # "averageOpenPrice": 3143.2,
3249
+ # "pnl24H": 0.0, # todo: check
3250
+ # "fee24H": 1.5716, # todo: check
3251
+ # "markPrice": 3134.97984158,
3252
+ # "estLiqPrice": 3436.176349,
3253
+ # "timestamp": 1720628031.463,
3254
+ # "adlQuantile": 5,
3255
+ # "positionSide": "BOTH",
3256
+ # "marginMode": "ISOLATED",
3257
+ # "isolatedMarginToken": "USDT", # todo: check
3258
+ # "isolatedMarginAmount": 314.62426, # todo: check
3259
+ # "isolatedFrozenLong": 0.0, # todo: check
3260
+ # "isolatedFrozenShort": 0.0, # todo: check
3261
+ # "leverage": 10
2694
3262
  # }
2695
3263
  #
2696
3264
  contract = self.safe_string(position, 'symbol')
@@ -2702,13 +3270,14 @@ class woo(Exchange, ImplicitAPI):
2702
3270
  else:
2703
3271
  side = 'short'
2704
3272
  contractSize = self.safe_string(market, 'contractSize')
2705
- markPrice = self.safe_string(position, 'markPrice')
3273
+ markPrice = self.safe_string_2(position, 'markPrice', 'mark_price')
2706
3274
  timestamp = self.safe_timestamp(position, 'timestamp')
2707
- entryPrice = self.safe_string(position, 'averageOpenPrice')
3275
+ entryPrice = self.safe_string_2(position, 'averageOpenPrice', 'average_open_price')
2708
3276
  priceDifference = Precise.string_sub(markPrice, entryPrice)
2709
3277
  unrealisedPnl = Precise.string_mul(priceDifference, size)
2710
3278
  size = Precise.string_abs(size)
2711
3279
  notional = Precise.string_mul(size, markPrice)
3280
+ positionSide = self.safe_string(position, 'positionSide') # 'SHORT' or 'LONG' for hedged, 'BOTH' for non-hedged
2712
3281
  return self.safe_position({
2713
3282
  'info': position,
2714
3283
  'id': None,
@@ -2722,24 +3291,296 @@ class woo(Exchange, ImplicitAPI):
2722
3291
  'maintenanceMarginPercentage': None,
2723
3292
  'entryPrice': self.parse_number(entryPrice),
2724
3293
  'notional': self.parse_number(notional),
2725
- 'leverage': None,
3294
+ 'leverage': self.safe_number(position, 'leverage'),
2726
3295
  'unrealizedPnl': self.parse_number(unrealisedPnl),
2727
3296
  'contracts': self.parse_number(size),
2728
3297
  'contractSize': self.parse_number(contractSize),
2729
3298
  'marginRatio': None,
2730
- 'liquidationPrice': self.safe_number(position, 'estLiqPrice'),
3299
+ 'liquidationPrice': self.safe_number_2(position, 'estLiqPrice', 'est_liq_price'),
2731
3300
  'markPrice': self.parse_number(markPrice),
2732
3301
  'lastPrice': None,
2733
3302
  'collateral': None,
2734
- 'marginMode': 'cross',
2735
- 'marginType': None,
3303
+ 'marginMode': self.safe_string_lower_2(position, 'marginMode', 'margin_mode'),
2736
3304
  'side': side,
2737
3305
  'percentage': None,
2738
- 'hedged': None,
3306
+ 'hedged': positionSide != 'BOTH',
2739
3307
  'stopLossPrice': None,
2740
3308
  'takeProfitPrice': None,
2741
3309
  })
2742
3310
 
3311
+ def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
3312
+ """
3313
+ fetch a quote for converting from one currency to another
3314
+
3315
+ https://docs.woox.io/#get-quote-rfq
3316
+
3317
+ :param str fromCode: the currency that you want to sell and convert from
3318
+ :param str toCode: the currency that you want to buy and convert into
3319
+ :param float [amount]: how much you want to trade in units of the from currency
3320
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3321
+ :returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
3322
+ """
3323
+ self.load_markets()
3324
+ request: dict = {
3325
+ 'sellToken': fromCode.upper(),
3326
+ 'buyToken': toCode.upper(),
3327
+ 'sellQuantity': self.number_to_string(amount),
3328
+ }
3329
+ response = self.v3PrivateGetConvertRfq(self.extend(request, params))
3330
+ #
3331
+ # {
3332
+ # "success": True,
3333
+ # "data": {
3334
+ # "quoteId": 123123123,
3335
+ # "counterPartyId": "",
3336
+ # "sellToken": "ETH",
3337
+ # "sellQuantity": "0.0445",
3338
+ # "buyToken": "USDT",
3339
+ # "buyQuantity": "33.45",
3340
+ # "buyPrice": "6.77",
3341
+ # "expireTimestamp": 1659084466000,
3342
+ # "message": 1659084466000
3343
+ # }
3344
+ # }
3345
+ #
3346
+ data = self.safe_dict(response, 'data', {})
3347
+ fromCurrencyId = self.safe_string(data, 'sellToken', fromCode)
3348
+ fromCurrency = self.currency(fromCurrencyId)
3349
+ toCurrencyId = self.safe_string(data, 'buyToken', toCode)
3350
+ toCurrency = self.currency(toCurrencyId)
3351
+ return self.parse_conversion(data, fromCurrency, toCurrency)
3352
+
3353
+ def create_convert_trade(self, id: str, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
3354
+ """
3355
+ convert from one currency to another
3356
+
3357
+ https://docs.woox.io/#send-quote-rft
3358
+
3359
+ :param str id: the id of the trade that you want to make
3360
+ :param str fromCode: the currency that you want to sell and convert from
3361
+ :param str toCode: the currency that you want to buy and convert into
3362
+ :param float [amount]: how much you want to trade in units of the from currency
3363
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3364
+ :returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
3365
+ """
3366
+ self.load_markets()
3367
+ request: dict = {
3368
+ 'quoteId': id,
3369
+ }
3370
+ response = self.v3PrivatePostConvertRft(self.extend(request, params))
3371
+ #
3372
+ # {
3373
+ # "success": True,
3374
+ # "data": {
3375
+ # "quoteId": 123123123,
3376
+ # "counterPartyId": "",
3377
+ # "rftAccepted": 1 # 1 -> success; 2 -> processing; 3 -> fail
3378
+ # }
3379
+ # }
3380
+ #
3381
+ data = self.safe_dict(response, 'data', {})
3382
+ return self.parse_conversion(data)
3383
+
3384
+ def fetch_convert_trade(self, id: str, code: Str = None, params={}) -> Conversion:
3385
+ """
3386
+ fetch the data for a conversion trade
3387
+
3388
+ https://docs.woox.io/#get-quote-trade
3389
+
3390
+ :param str id: the id of the trade that you want to fetch
3391
+ :param str [code]: the unified currency code of the conversion trade
3392
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3393
+ :returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
3394
+ """
3395
+ self.load_markets()
3396
+ request: dict = {
3397
+ 'quoteId': id,
3398
+ }
3399
+ response = self.v3PrivateGetConvertTrade(self.extend(request, params))
3400
+ #
3401
+ # {
3402
+ # "success": True,
3403
+ # "data": {
3404
+ # "quoteId": 12,
3405
+ # "buyAsset": "",
3406
+ # "sellAsset": "",
3407
+ # "buyAmount": 12.11,
3408
+ # "sellAmount": 12.11,
3409
+ # "tradeStatus": 12,
3410
+ # "createdTime": ""
3411
+ # }
3412
+ # }
3413
+ #
3414
+ data = self.safe_dict(response, 'data', {})
3415
+ fromCurrencyId = self.safe_string(data, 'sellAsset')
3416
+ toCurrencyId = self.safe_string(data, 'buyAsset')
3417
+ fromCurrency = None
3418
+ toCurrency = None
3419
+ if fromCurrencyId is not None:
3420
+ fromCurrency = self.currency(fromCurrencyId)
3421
+ if toCurrencyId is not None:
3422
+ toCurrency = self.currency(toCurrencyId)
3423
+ return self.parse_conversion(data, fromCurrency, toCurrency)
3424
+
3425
+ def fetch_convert_trade_history(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Conversion]:
3426
+ """
3427
+ fetch the users history of conversion trades
3428
+
3429
+ https://docs.woox.io/#get-quote-trades
3430
+
3431
+ :param str [code]: the unified currency code
3432
+ :param int [since]: the earliest time in ms to fetch conversions for
3433
+ :param int [limit]: the maximum number of conversion structures to retrieve
3434
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3435
+ :param int [params.until]: timestamp in ms of the latest conversion to fetch
3436
+ :returns dict[]: a list of `conversion structures <https://docs.ccxt.com/#/?id=conversion-structure>`
3437
+ """
3438
+ self.load_markets()
3439
+ request: dict = {}
3440
+ request, params = self.handle_until_option('endTime', request, params)
3441
+ if since is not None:
3442
+ request['startTime'] = since
3443
+ if limit is not None:
3444
+ request['size'] = limit
3445
+ response = self.v3PrivateGetConvertTrades(self.extend(request, params))
3446
+ #
3447
+ # {
3448
+ # "success": True,
3449
+ # "data": {
3450
+ # "count": 12,
3451
+ # "tradeVos":[
3452
+ # {
3453
+ # "quoteId": 12,
3454
+ # "buyAsset": "",
3455
+ # "sellAsset": "",
3456
+ # "buyAmount": 12.11,
3457
+ # "sellAmount": 12.11,
3458
+ # "tradeStatus": 12,
3459
+ # "createdTime": ""
3460
+ # }
3461
+ # ...
3462
+ # ]
3463
+ # }
3464
+ # }
3465
+ #
3466
+ data = self.safe_dict(response, 'data', {})
3467
+ rows = self.safe_list(data, 'tradeVos', [])
3468
+ return self.parse_conversions(rows, code, 'sellAsset', 'buyAsset', since, limit)
3469
+
3470
+ def parse_conversion(self, conversion: dict, fromCurrency: Currency = None, toCurrency: Currency = None) -> Conversion:
3471
+ #
3472
+ # fetchConvertQuote
3473
+ #
3474
+ # {
3475
+ # "quoteId": 123123123,
3476
+ # "counterPartyId": "",
3477
+ # "sellToken": "ETH",
3478
+ # "sellQuantity": "0.0445",
3479
+ # "buyToken": "USDT",
3480
+ # "buyQuantity": "33.45",
3481
+ # "buyPrice": "6.77",
3482
+ # "expireTimestamp": 1659084466000,
3483
+ # "message": 1659084466000
3484
+ # }
3485
+ #
3486
+ # createConvertTrade
3487
+ #
3488
+ # {
3489
+ # "quoteId": 123123123,
3490
+ # "counterPartyId": "",
3491
+ # "rftAccepted": 1 # 1 -> success; 2 -> processing; 3 -> fail
3492
+ # }
3493
+ #
3494
+ # fetchConvertTrade, fetchConvertTradeHistory
3495
+ #
3496
+ # {
3497
+ # "quoteId": 12,
3498
+ # "buyAsset": "",
3499
+ # "sellAsset": "",
3500
+ # "buyAmount": 12.11,
3501
+ # "sellAmount": 12.11,
3502
+ # "tradeStatus": 12,
3503
+ # "createdTime": ""
3504
+ # }
3505
+ #
3506
+ timestamp = self.safe_integer_2(conversion, 'expireTimestamp', 'createdTime')
3507
+ fromCurr = self.safe_string_2(conversion, 'sellToken', 'buyAsset')
3508
+ fromCode = self.safe_currency_code(fromCurr, fromCurrency)
3509
+ to = self.safe_string_2(conversion, 'buyToken', 'sellAsset')
3510
+ toCode = self.safe_currency_code(to, toCurrency)
3511
+ return {
3512
+ 'info': conversion,
3513
+ 'timestamp': timestamp,
3514
+ 'datetime': self.iso8601(timestamp),
3515
+ 'id': self.safe_string(conversion, 'quoteId'),
3516
+ 'fromCurrency': fromCode,
3517
+ 'fromAmount': self.safe_number_2(conversion, 'sellQuantity', 'sellAmount'),
3518
+ 'toCurrency': toCode,
3519
+ 'toAmount': self.safe_number_2(conversion, 'buyQuantity', 'buyAmount'),
3520
+ 'price': self.safe_number(conversion, 'buyPrice'),
3521
+ 'fee': None,
3522
+ }
3523
+
3524
+ def fetch_convert_currencies(self, params={}) -> Currencies:
3525
+ """
3526
+ fetches all available currencies that can be converted
3527
+
3528
+ https://docs.woox.io/#get-quote-asset-info
3529
+
3530
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3531
+ :returns dict: an associative dictionary of currencies
3532
+ """
3533
+ self.load_markets()
3534
+ response = self.v3PrivateGetConvertAssetInfo(params)
3535
+ #
3536
+ # {
3537
+ # "success": True,
3538
+ # "rows": [
3539
+ # {
3540
+ # "token": "BTC",
3541
+ # "tick": 0.0001,
3542
+ # "createdTime": "1575014248.99", # Unix epoch time in seconds
3543
+ # "updatedTime": "1575014248.99" # Unix epoch time in seconds
3544
+ # },
3545
+ # ]
3546
+ # }
3547
+ #
3548
+ result: dict = {}
3549
+ data = self.safe_list(response, 'rows', [])
3550
+ for i in range(0, len(data)):
3551
+ entry = data[i]
3552
+ id = self.safe_string(entry, 'token')
3553
+ code = self.safe_currency_code(id)
3554
+ result[code] = {
3555
+ 'info': entry,
3556
+ 'id': id,
3557
+ 'code': code,
3558
+ 'networks': None,
3559
+ 'type': None,
3560
+ 'name': None,
3561
+ 'active': None,
3562
+ 'deposit': None,
3563
+ 'withdraw': None,
3564
+ 'fee': None,
3565
+ 'precision': self.safe_number(entry, 'tick'),
3566
+ 'limits': {
3567
+ 'amount': {
3568
+ 'min': None,
3569
+ 'max': None,
3570
+ },
3571
+ 'withdraw': {
3572
+ 'min': None,
3573
+ 'max': None,
3574
+ },
3575
+ 'deposit': {
3576
+ 'min': None,
3577
+ 'max': None,
3578
+ },
3579
+ },
3580
+ 'created': self.safe_timestamp(entry, 'createdTime'),
3581
+ }
3582
+ return result
3583
+
2743
3584
  def default_network_code_for_currency(self, code):
2744
3585
  currencyItem = self.currency(code)
2745
3586
  networks = currencyItem['networks']