ccxt-ir 4.3.46.0.2__py2.py3-none-any.whl → 4.5.0__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 (528) hide show
  1. ccxt/__init__.py +39 -35
  2. ccxt/abantether.py +9 -9
  3. ccxt/abstract/alpaca.py +4 -0
  4. ccxt/abstract/apex.py +31 -0
  5. ccxt/abstract/bigone.py +1 -1
  6. ccxt/abstract/binance.py +106 -48
  7. ccxt/abstract/binancecoinm.py +106 -48
  8. ccxt/abstract/binanceus.py +141 -83
  9. ccxt/abstract/binanceusdm.py +106 -48
  10. ccxt/abstract/bingx.py +50 -1
  11. ccxt/abstract/bitbank.py +5 -0
  12. ccxt/abstract/bitfinex.py +136 -65
  13. ccxt/abstract/bitflyer.py +1 -0
  14. ccxt/abstract/bitget.py +67 -0
  15. ccxt/abstract/bitmart.py +19 -1
  16. ccxt/abstract/bitopro.py +1 -0
  17. ccxt/abstract/bitrue.py +68 -68
  18. ccxt/abstract/bitstamp.py +1 -0
  19. ccxt/abstract/blofin.py +30 -0
  20. ccxt/abstract/btcbox.py +2 -0
  21. ccxt/abstract/bybit.py +28 -13
  22. ccxt/abstract/cex.py +28 -29
  23. ccxt/abstract/coinbaseexchange.py +1 -0
  24. ccxt/abstract/coinbaseinternational.py +1 -1
  25. ccxt/abstract/cryptocom.py +16 -0
  26. ccxt/abstract/cryptomus.py +20 -0
  27. ccxt/abstract/defx.py +69 -0
  28. ccxt/abstract/deribit.py +1 -0
  29. ccxt/abstract/derive.py +117 -0
  30. ccxt/abstract/digifinex.py +1 -0
  31. ccxt/abstract/ellipx.py +25 -0
  32. ccxt/abstract/foxbit.py +26 -0
  33. ccxt/abstract/gate.py +19 -0
  34. ccxt/abstract/gateio.py +19 -0
  35. ccxt/abstract/gemini.py +1 -0
  36. ccxt/abstract/hibachi.py +26 -0
  37. ccxt/abstract/hyperliquid.py +1 -1
  38. ccxt/abstract/independentreserve.py +6 -0
  39. ccxt/abstract/kraken.py +1 -0
  40. ccxt/abstract/krakenfutures.py +4 -0
  41. ccxt/abstract/kucoin.py +10 -0
  42. ccxt/abstract/kucoinfutures.py +18 -0
  43. ccxt/abstract/lbank.py +2 -1
  44. ccxt/abstract/luno.py +1 -0
  45. ccxt/abstract/mexc.py +2 -0
  46. ccxt/abstract/modetrade.py +119 -0
  47. ccxt/abstract/myokx.py +349 -0
  48. ccxt/abstract/oceanex.py +5 -0
  49. ccxt/abstract/okx.py +25 -0
  50. ccxt/abstract/okxus.py +349 -0
  51. ccxt/abstract/onetrading.py +0 -12
  52. ccxt/abstract/paradex.py +23 -0
  53. ccxt/abstract/phemex.py +2 -0
  54. ccxt/abstract/poloniex.py +36 -0
  55. ccxt/abstract/tradeogre.py +3 -1
  56. ccxt/abstract/upbit.py +51 -34
  57. ccxt/abstract/whitebit.py +16 -0
  58. ccxt/abstract/woo.py +64 -6
  59. ccxt/abstract/xt.py +10 -5
  60. ccxt/afratether.py +7 -7
  61. ccxt/alpaca.py +828 -51
  62. ccxt/apex.py +1875 -0
  63. ccxt/arzinja.py +7 -7
  64. ccxt/arzplus.py +9 -9
  65. ccxt/ascendex.py +501 -306
  66. ccxt/async_support/__init__.py +39 -35
  67. ccxt/async_support/abantether.py +10 -10
  68. ccxt/async_support/afratether.py +9 -9
  69. ccxt/async_support/alpaca.py +828 -51
  70. ccxt/async_support/apex.py +1875 -0
  71. ccxt/async_support/arzinja.py +10 -10
  72. ccxt/async_support/arzplus.py +12 -12
  73. ccxt/async_support/ascendex.py +502 -306
  74. ccxt/async_support/base/exchange.py +303 -89
  75. ccxt/async_support/base/ws/cache.py +9 -3
  76. ccxt/async_support/base/ws/client.py +173 -38
  77. ccxt/async_support/base/ws/future.py +25 -37
  78. ccxt/async_support/bequant.py +5 -3
  79. ccxt/async_support/bigone.py +279 -144
  80. ccxt/async_support/binance.py +2347 -1158
  81. ccxt/async_support/binancecoinm.py +9 -3
  82. ccxt/async_support/binanceus.py +17 -3
  83. ccxt/async_support/binanceusdm.py +9 -4
  84. ccxt/async_support/bingx.py +2962 -920
  85. ccxt/async_support/bit2c.py +147 -27
  86. ccxt/async_support/bitbank.py +151 -23
  87. ccxt/async_support/bitbns.py +104 -30
  88. ccxt/async_support/bitfinex.py +3291 -1113
  89. ccxt/async_support/bitflyer.py +202 -27
  90. ccxt/async_support/bitget.py +3683 -1538
  91. ccxt/async_support/bithumb.py +195 -38
  92. ccxt/async_support/bitimen.py +12 -12
  93. ccxt/async_support/bitir.py +38 -38
  94. ccxt/async_support/bitmart.py +1288 -350
  95. ccxt/async_support/bitmex.py +260 -75
  96. ccxt/async_support/bitopro.py +262 -62
  97. ccxt/async_support/bitpin.py +17 -16
  98. ccxt/async_support/bitrue.py +459 -290
  99. ccxt/async_support/bitso.py +199 -54
  100. ccxt/async_support/bitstamp.py +230 -96
  101. ccxt/async_support/bitteam.py +167 -25
  102. ccxt/async_support/{huobijp.py → bittrade.py} +158 -30
  103. ccxt/async_support/bitvavo.py +213 -49
  104. ccxt/async_support/blockchaincom.py +160 -46
  105. ccxt/async_support/blofin.py +502 -120
  106. ccxt/async_support/btcalpha.py +169 -31
  107. ccxt/async_support/btcbox.py +292 -23
  108. ccxt/async_support/btcmarkets.py +211 -58
  109. ccxt/async_support/btcturk.py +161 -38
  110. ccxt/async_support/bybit.py +1775 -1030
  111. ccxt/async_support/cex.py +1440 -1303
  112. ccxt/async_support/coinbase.py +724 -212
  113. ccxt/async_support/coinbaseadvanced.py +2 -1
  114. ccxt/async_support/coinbaseexchange.py +388 -89
  115. ccxt/async_support/coinbaseinternational.py +412 -57
  116. ccxt/async_support/coincatch.py +177 -78
  117. ccxt/async_support/coincheck.py +135 -19
  118. ccxt/async_support/coinex.py +606 -232
  119. ccxt/async_support/coinmate.py +189 -63
  120. ccxt/async_support/coinmetro.py +195 -54
  121. ccxt/async_support/coinone.py +158 -51
  122. ccxt/async_support/coinsph.py +336 -61
  123. ccxt/async_support/coinspot.py +151 -52
  124. ccxt/async_support/cryptocom.py +661 -111
  125. ccxt/async_support/cryptomus.py +1137 -0
  126. ccxt/async_support/defx.py +2071 -0
  127. ccxt/async_support/delta.py +299 -99
  128. ccxt/async_support/deribit.py +348 -126
  129. ccxt/async_support/derive.py +2572 -0
  130. ccxt/async_support/digifinex.py +430 -214
  131. ccxt/async_support/ellipx.py +2029 -0
  132. ccxt/async_support/eterex.py +10 -10
  133. ccxt/async_support/excoino.py +31 -31
  134. ccxt/async_support/exir.py +14 -14
  135. ccxt/async_support/exmo.py +344 -131
  136. ccxt/async_support/exnovin.py +10 -10
  137. ccxt/async_support/farhadexchange.py +12 -12
  138. ccxt/async_support/fmfwio.py +2 -1
  139. ccxt/async_support/foxbit.py +1935 -0
  140. ccxt/async_support/gate.py +1351 -529
  141. ccxt/async_support/gateio.py +2 -1
  142. ccxt/async_support/gemini.py +144 -39
  143. ccxt/async_support/hashkey.py +152 -109
  144. ccxt/async_support/hibachi.py +2080 -0
  145. ccxt/async_support/hitbtc.py +395 -167
  146. ccxt/async_support/hitobit.py +12 -12
  147. ccxt/async_support/hollaex.py +307 -119
  148. ccxt/async_support/htx.py +851 -383
  149. ccxt/async_support/huobi.py +2 -1
  150. ccxt/async_support/hyperliquid.py +1848 -536
  151. ccxt/async_support/independentreserve.py +288 -15
  152. ccxt/async_support/indodax.py +190 -33
  153. ccxt/async_support/jibitex.py +12 -12
  154. ccxt/async_support/kraken.py +795 -351
  155. ccxt/async_support/krakenfutures.py +214 -62
  156. ccxt/async_support/kucoin.py +715 -396
  157. ccxt/async_support/kucoinfutures.py +652 -89
  158. ccxt/async_support/latoken.py +217 -113
  159. ccxt/async_support/lbank.py +425 -97
  160. ccxt/async_support/luno.py +382 -35
  161. ccxt/async_support/mercado.py +113 -6
  162. ccxt/async_support/mexc.py +874 -437
  163. ccxt/async_support/modetrade.py +2818 -0
  164. ccxt/async_support/myokx.py +54 -0
  165. ccxt/async_support/ndax.py +221 -64
  166. ccxt/async_support/nobitex.py +31 -37
  167. ccxt/async_support/novadax.py +190 -34
  168. ccxt/async_support/oceanex.py +217 -28
  169. ccxt/async_support/okcoin.py +253 -145
  170. ccxt/async_support/okexchange.py +11 -11
  171. ccxt/async_support/okx.py +1088 -351
  172. ccxt/async_support/okxus.py +54 -0
  173. ccxt/async_support/ompfinex.py +25 -24
  174. ccxt/async_support/onetrading.py +213 -392
  175. ccxt/async_support/oxfun.py +245 -166
  176. ccxt/async_support/p2b.py +151 -29
  177. ccxt/async_support/paradex.py +562 -49
  178. ccxt/async_support/paymium.py +82 -19
  179. ccxt/async_support/phemex.py +713 -172
  180. ccxt/async_support/poloniex.py +1602 -283
  181. ccxt/async_support/probit.py +224 -95
  182. ccxt/async_support/ramzinex.py +30 -27
  183. ccxt/async_support/sarmayex.py +9 -9
  184. ccxt/async_support/sarrafex.py +13 -13
  185. ccxt/async_support/tabdeal.py +14 -13
  186. ccxt/async_support/tetherland.py +9 -9
  187. ccxt/async_support/timex.py +210 -51
  188. ccxt/async_support/tokocrypto.py +167 -47
  189. ccxt/async_support/tradeogre.py +266 -31
  190. ccxt/async_support/twox.py +9 -9
  191. ccxt/async_support/ubitex.py +12 -12
  192. ccxt/async_support/upbit.py +568 -165
  193. ccxt/async_support/vertex.py +160 -32
  194. ccxt/async_support/wallex.py +12 -12
  195. ccxt/async_support/wavesexchange.py +165 -30
  196. ccxt/async_support/whitebit.py +975 -127
  197. ccxt/async_support/woo.py +1918 -1016
  198. ccxt/async_support/woofipro.py +433 -141
  199. ccxt/async_support/xt.py +649 -193
  200. ccxt/async_support/yobit.py +195 -70
  201. ccxt/async_support/zaif.py +91 -15
  202. ccxt/async_support/zonda.py +151 -36
  203. ccxt/base/decimal_to_precision.py +14 -10
  204. ccxt/base/errors.py +49 -18
  205. ccxt/base/exchange.py +1556 -450
  206. ccxt/base/precise.py +10 -0
  207. ccxt/base/types.py +114 -6
  208. ccxt/bequant.py +5 -3
  209. ccxt/bigone.py +279 -144
  210. ccxt/binance.py +2347 -1158
  211. ccxt/binancecoinm.py +9 -3
  212. ccxt/binanceus.py +17 -3
  213. ccxt/binanceusdm.py +9 -4
  214. ccxt/bingx.py +2962 -920
  215. ccxt/bit2c.py +147 -27
  216. ccxt/bitbank.py +151 -23
  217. ccxt/bitbns.py +104 -30
  218. ccxt/bitfinex.py +3290 -1113
  219. ccxt/bitflyer.py +202 -27
  220. ccxt/bitget.py +3683 -1538
  221. ccxt/bithumb.py +194 -38
  222. ccxt/bitimen.py +9 -9
  223. ccxt/bitir.py +35 -35
  224. ccxt/bitmart.py +1288 -350
  225. ccxt/bitmex.py +260 -75
  226. ccxt/bitopro.py +262 -62
  227. ccxt/bitpin.py +15 -14
  228. ccxt/bitrue.py +459 -290
  229. ccxt/bitso.py +199 -54
  230. ccxt/bitstamp.py +230 -96
  231. ccxt/bitteam.py +167 -25
  232. ccxt/{huobijp.py → bittrade.py} +158 -30
  233. ccxt/bitvavo.py +213 -49
  234. ccxt/blockchaincom.py +160 -46
  235. ccxt/blofin.py +502 -120
  236. ccxt/btcalpha.py +169 -31
  237. ccxt/btcbox.py +291 -23
  238. ccxt/btcmarkets.py +211 -58
  239. ccxt/btcturk.py +161 -38
  240. ccxt/bybit.py +1775 -1030
  241. ccxt/cex.py +1439 -1303
  242. ccxt/coinbase.py +724 -212
  243. ccxt/coinbaseadvanced.py +2 -1
  244. ccxt/coinbaseexchange.py +388 -89
  245. ccxt/coinbaseinternational.py +412 -57
  246. ccxt/coincatch.py +177 -78
  247. ccxt/coincheck.py +135 -19
  248. ccxt/coinex.py +606 -232
  249. ccxt/coinmate.py +189 -63
  250. ccxt/coinmetro.py +194 -54
  251. ccxt/coinone.py +158 -51
  252. ccxt/coinsph.py +336 -61
  253. ccxt/coinspot.py +151 -52
  254. ccxt/cryptocom.py +661 -111
  255. ccxt/cryptomus.py +1137 -0
  256. ccxt/defx.py +2070 -0
  257. ccxt/delta.py +299 -99
  258. ccxt/deribit.py +348 -126
  259. ccxt/derive.py +2571 -0
  260. ccxt/digifinex.py +430 -214
  261. ccxt/ellipx.py +2029 -0
  262. ccxt/eterex.py +7 -7
  263. ccxt/excoino.py +29 -29
  264. ccxt/exir.py +11 -11
  265. ccxt/exmo.py +343 -131
  266. ccxt/exnovin.py +8 -8
  267. ccxt/farhadexchange.py +10 -10
  268. ccxt/fmfwio.py +2 -1
  269. ccxt/foxbit.py +1935 -0
  270. ccxt/gate.py +1351 -529
  271. ccxt/gateio.py +2 -1
  272. ccxt/gemini.py +144 -39
  273. ccxt/hashkey.py +152 -109
  274. ccxt/hibachi.py +2079 -0
  275. ccxt/hitbtc.py +395 -167
  276. ccxt/hitobit.py +9 -9
  277. ccxt/hollaex.py +307 -119
  278. ccxt/htx.py +851 -383
  279. ccxt/huobi.py +2 -1
  280. ccxt/hyperliquid.py +1848 -536
  281. ccxt/independentreserve.py +287 -15
  282. ccxt/indodax.py +190 -33
  283. ccxt/jibitex.py +9 -9
  284. ccxt/kraken.py +794 -351
  285. ccxt/krakenfutures.py +214 -62
  286. ccxt/kucoin.py +715 -396
  287. ccxt/kucoinfutures.py +652 -89
  288. ccxt/latoken.py +217 -113
  289. ccxt/lbank.py +425 -97
  290. ccxt/luno.py +382 -35
  291. ccxt/mercado.py +113 -6
  292. ccxt/mexc.py +873 -437
  293. ccxt/modetrade.py +2818 -0
  294. ccxt/myokx.py +54 -0
  295. ccxt/ndax.py +221 -64
  296. ccxt/nobitex.py +29 -35
  297. ccxt/novadax.py +190 -34
  298. ccxt/oceanex.py +217 -28
  299. ccxt/okcoin.py +253 -145
  300. ccxt/okexchange.py +9 -9
  301. ccxt/okx.py +1088 -351
  302. ccxt/okxus.py +54 -0
  303. ccxt/ompfinex.py +22 -21
  304. ccxt/onetrading.py +213 -392
  305. ccxt/oxfun.py +245 -166
  306. ccxt/p2b.py +151 -29
  307. ccxt/paradex.py +562 -49
  308. ccxt/paymium.py +82 -19
  309. ccxt/phemex.py +712 -172
  310. ccxt/poloniex.py +1601 -283
  311. ccxt/pro/__init__.py +76 -17
  312. ccxt/pro/alpaca.py +21 -6
  313. ccxt/pro/apex.py +984 -0
  314. ccxt/pro/ascendex.py +58 -10
  315. ccxt/pro/bequant.py +6 -1
  316. ccxt/pro/binance.py +728 -156
  317. ccxt/pro/binancecoinm.py +6 -2
  318. ccxt/pro/binanceus.py +8 -4
  319. ccxt/pro/binanceusdm.py +7 -2
  320. ccxt/pro/bingx.py +333 -142
  321. ccxt/pro/bitfinex.py +727 -262
  322. ccxt/pro/bitget.py +570 -79
  323. ccxt/pro/bithumb.py +20 -6
  324. ccxt/pro/bitmart.py +216 -87
  325. ccxt/pro/bitmex.py +47 -9
  326. ccxt/pro/bitopro.py +26 -14
  327. ccxt/pro/bitrue.py +22 -22
  328. ccxt/pro/bitstamp.py +54 -21
  329. ccxt/pro/{huobijp.py → bittrade.py} +7 -6
  330. ccxt/pro/bitvavo.py +191 -67
  331. ccxt/pro/blockchaincom.py +21 -8
  332. ccxt/pro/blofin.py +9 -1
  333. ccxt/pro/bybit.py +632 -245
  334. ccxt/pro/cex.py +59 -24
  335. ccxt/pro/coinbase.py +102 -73
  336. ccxt/pro/coinbaseadvanced.py +2 -1
  337. ccxt/pro/coinbaseexchange.py +8 -8
  338. ccxt/pro/coinbaseinternational.py +181 -25
  339. ccxt/pro/coincatch.py +6 -7
  340. ccxt/pro/coincheck.py +11 -6
  341. ccxt/pro/coinex.py +967 -665
  342. ccxt/pro/coinone.py +16 -9
  343. ccxt/pro/cryptocom.py +448 -45
  344. ccxt/pro/defx.py +831 -0
  345. ccxt/pro/deribit.py +150 -14
  346. ccxt/pro/derive.py +704 -0
  347. ccxt/pro/exmo.py +239 -6
  348. ccxt/pro/gate.py +623 -65
  349. ccxt/pro/gateio.py +2 -1
  350. ccxt/pro/gemini.py +27 -11
  351. ccxt/pro/hashkey.py +2 -2
  352. ccxt/pro/hitbtc.py +196 -91
  353. ccxt/pro/hollaex.py +23 -7
  354. ccxt/pro/htx.py +51 -14
  355. ccxt/pro/huobi.py +2 -1
  356. ccxt/pro/hyperliquid.py +591 -27
  357. ccxt/pro/independentreserve.py +9 -6
  358. ccxt/pro/kraken.py +640 -320
  359. ccxt/pro/krakenfutures.py +62 -35
  360. ccxt/pro/kucoin.py +267 -46
  361. ccxt/pro/kucoinfutures.py +165 -21
  362. ccxt/pro/lbank.py +102 -21
  363. ccxt/pro/luno.py +12 -8
  364. ccxt/pro/mexc.py +877 -111
  365. ccxt/pro/modetrade.py +1271 -0
  366. ccxt/pro/myokx.py +38 -0
  367. ccxt/pro/ndax.py +15 -2
  368. ccxt/pro/okcoin.py +23 -4
  369. ccxt/pro/okx.py +573 -98
  370. ccxt/pro/okxus.py +38 -0
  371. ccxt/pro/onetrading.py +30 -13
  372. ccxt/pro/oxfun.py +131 -27
  373. ccxt/pro/p2b.py +88 -22
  374. ccxt/pro/paradex.py +3 -3
  375. ccxt/pro/phemex.py +75 -21
  376. ccxt/pro/poloniex.py +124 -41
  377. ccxt/pro/probit.py +87 -80
  378. ccxt/pro/tradeogre.py +272 -0
  379. ccxt/pro/upbit.py +152 -12
  380. ccxt/pro/vertex.py +8 -3
  381. ccxt/pro/whitebit.py +58 -5
  382. ccxt/pro/woo.py +228 -37
  383. ccxt/pro/woofipro.py +106 -18
  384. ccxt/pro/xt.py +111 -5
  385. ccxt/probit.py +224 -95
  386. ccxt/protobuf/__init__.py +0 -0
  387. ccxt/protobuf/mexc/PrivateAccountV3Api_pb2.py +37 -0
  388. ccxt/protobuf/mexc/PrivateDealsV3Api_pb2.py +37 -0
  389. ccxt/protobuf/mexc/PrivateOrdersV3Api_pb2.py +37 -0
  390. ccxt/protobuf/mexc/PublicAggreBookTickerV3Api_pb2.py +37 -0
  391. ccxt/protobuf/mexc/PublicAggreDealsV3Api_pb2.py +39 -0
  392. ccxt/protobuf/mexc/PublicAggreDepthsV3Api_pb2.py +39 -0
  393. ccxt/protobuf/mexc/PublicBookTickerBatchV3Api_pb2.py +38 -0
  394. ccxt/protobuf/mexc/PublicBookTickerV3Api_pb2.py +37 -0
  395. ccxt/protobuf/mexc/PublicDealsV3Api_pb2.py +39 -0
  396. ccxt/protobuf/mexc/PublicIncreaseDepthsBatchV3Api_pb2.py +38 -0
  397. ccxt/protobuf/mexc/PublicIncreaseDepthsV3Api_pb2.py +39 -0
  398. ccxt/protobuf/mexc/PublicLimitDepthsV3Api_pb2.py +39 -0
  399. ccxt/protobuf/mexc/PublicMiniTickerV3Api_pb2.py +37 -0
  400. ccxt/protobuf/mexc/PublicMiniTickersV3Api_pb2.py +38 -0
  401. ccxt/protobuf/mexc/PublicSpotKlineV3Api_pb2.py +37 -0
  402. ccxt/protobuf/mexc/PushDataV3ApiWrapper_pb2.py +52 -0
  403. ccxt/protobuf/mexc/__init__.py +0 -0
  404. ccxt/ramzinex.py +28 -25
  405. ccxt/sarmayex.py +7 -7
  406. ccxt/sarrafex.py +10 -10
  407. ccxt/static_dependencies/__init__.py +1 -1
  408. ccxt/static_dependencies/lark/py.typed +0 -0
  409. ccxt/static_dependencies/marshmallow/py.typed +0 -0
  410. ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  411. ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  412. ccxt/tabdeal.py +12 -11
  413. ccxt/test/tests_async.py +261 -57
  414. ccxt/test/tests_helpers.py +1 -3
  415. ccxt/test/tests_init.py +4 -3
  416. ccxt/test/tests_sync.py +261 -57
  417. ccxt/tetherland.py +7 -7
  418. ccxt/timex.py +210 -51
  419. ccxt/tokocrypto.py +167 -47
  420. ccxt/tradeogre.py +266 -31
  421. ccxt/twox.py +7 -7
  422. ccxt/ubitex.py +9 -9
  423. ccxt/upbit.py +568 -165
  424. ccxt/vertex.py +160 -32
  425. ccxt/wallex.py +9 -9
  426. ccxt/wavesexchange.py +165 -30
  427. ccxt/whitebit.py +975 -127
  428. ccxt/woo.py +1917 -1016
  429. ccxt/woofipro.py +432 -141
  430. ccxt/xt.py +649 -193
  431. ccxt/yobit.py +194 -70
  432. ccxt/zaif.py +91 -15
  433. ccxt/zonda.py +151 -36
  434. {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/METADATA +225 -73
  435. ccxt_ir-4.5.0.dist-info/RECORD +743 -0
  436. {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/WHEEL +1 -1
  437. ccxt/abstract/ace.py +0 -15
  438. ccxt/abstract/bitbay.py +0 -53
  439. ccxt/abstract/bitcoincom.py +0 -115
  440. ccxt/abstract/bitfinex2.py +0 -139
  441. ccxt/abstract/bitpanda.py +0 -35
  442. ccxt/abstract/bl3p.py +0 -19
  443. ccxt/abstract/coinlist.py +0 -54
  444. ccxt/abstract/currencycom.py +0 -68
  445. ccxt/abstract/hitbtc3.py +0 -115
  446. ccxt/abstract/idex.py +0 -26
  447. ccxt/abstract/kuna.py +0 -182
  448. ccxt/abstract/lykke.py +0 -29
  449. ccxt/abstract/poloniexfutures.py +0 -48
  450. ccxt/abstract/wazirx.py +0 -30
  451. ccxt/ace.py +0 -1012
  452. ccxt/async_support/ace.py +0 -1012
  453. ccxt/async_support/base/ws/aiohttp_client.py +0 -125
  454. ccxt/async_support/base/ws/fast_client.py +0 -96
  455. ccxt/async_support/bitbay.py +0 -17
  456. ccxt/async_support/bitcoincom.py +0 -17
  457. ccxt/async_support/bitfinex2.py +0 -3552
  458. ccxt/async_support/bitpanda.py +0 -16
  459. ccxt/async_support/bl3p.py +0 -485
  460. ccxt/async_support/coinlist.py +0 -2243
  461. ccxt/async_support/currencycom.py +0 -1950
  462. ccxt/async_support/hitbtc3.py +0 -16
  463. ccxt/async_support/idex.py +0 -1766
  464. ccxt/async_support/kuna.py +0 -1841
  465. ccxt/async_support/lykke.py +0 -1270
  466. ccxt/async_support/poloniexfutures.py +0 -1717
  467. ccxt/async_support/wazirx.py +0 -1224
  468. ccxt/bitbay.py +0 -17
  469. ccxt/bitcoincom.py +0 -17
  470. ccxt/bitfinex2.py +0 -3552
  471. ccxt/bitpanda.py +0 -16
  472. ccxt/bl3p.py +0 -485
  473. ccxt/coinlist.py +0 -2243
  474. ccxt/currencycom.py +0 -1950
  475. ccxt/hitbtc3.py +0 -16
  476. ccxt/idex.py +0 -1766
  477. ccxt/kuna.py +0 -1841
  478. ccxt/lykke.py +0 -1270
  479. ccxt/poloniexfutures.py +0 -1717
  480. ccxt/pro/bitcoincom.py +0 -34
  481. ccxt/pro/bitfinex2.py +0 -1083
  482. ccxt/pro/bitpanda.py +0 -15
  483. ccxt/pro/currencycom.py +0 -536
  484. ccxt/pro/idex.py +0 -672
  485. ccxt/pro/poloniexfutures.py +0 -990
  486. ccxt/pro/wazirx.py +0 -749
  487. ccxt/test/base/__init__.py +0 -29
  488. ccxt/test/base/test_account.py +0 -26
  489. ccxt/test/base/test_balance.py +0 -56
  490. ccxt/test/base/test_borrow_interest.py +0 -35
  491. ccxt/test/base/test_borrow_rate.py +0 -32
  492. ccxt/test/base/test_calculate_fee.py +0 -51
  493. ccxt/test/base/test_crypto.py +0 -127
  494. ccxt/test/base/test_currency.py +0 -76
  495. ccxt/test/base/test_datetime.py +0 -109
  496. ccxt/test/base/test_decimal_to_precision.py +0 -392
  497. ccxt/test/base/test_deep_extend.py +0 -68
  498. ccxt/test/base/test_deposit_withdrawal.py +0 -50
  499. ccxt/test/base/test_exchange_datetime_functions.py +0 -76
  500. ccxt/test/base/test_funding_rate_history.py +0 -29
  501. ccxt/test/base/test_last_price.py +0 -31
  502. ccxt/test/base/test_ledger_entry.py +0 -45
  503. ccxt/test/base/test_ledger_item.py +0 -48
  504. ccxt/test/base/test_leverage_tier.py +0 -33
  505. ccxt/test/base/test_liquidation.py +0 -50
  506. ccxt/test/base/test_margin_mode.py +0 -24
  507. ccxt/test/base/test_margin_modification.py +0 -35
  508. ccxt/test/base/test_market.py +0 -193
  509. ccxt/test/base/test_number.py +0 -411
  510. ccxt/test/base/test_ohlcv.py +0 -33
  511. ccxt/test/base/test_open_interest.py +0 -32
  512. ccxt/test/base/test_order.py +0 -64
  513. ccxt/test/base/test_order_book.py +0 -69
  514. ccxt/test/base/test_position.py +0 -60
  515. ccxt/test/base/test_shared_methods.py +0 -353
  516. ccxt/test/base/test_status.py +0 -24
  517. ccxt/test/base/test_throttle.py +0 -126
  518. ccxt/test/base/test_ticker.py +0 -92
  519. ccxt/test/base/test_trade.py +0 -47
  520. ccxt/test/base/test_trading_fee.py +0 -26
  521. ccxt/test/base/test_transaction.py +0 -39
  522. ccxt/test/test_async.py +0 -1649
  523. ccxt/test/test_sync.py +0 -1648
  524. ccxt/wazirx.py +0 -1224
  525. ccxt_ir-4.3.46.0.2.dist-info/RECORD +0 -772
  526. /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
  527. {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info/licenses}/LICENSE.txt +0 -0
  528. {ccxt_ir-4.3.46.0.2.dist-info → ccxt_ir-4.5.0.dist-info}/top_level.txt +0 -0
@@ -6,7 +6,7 @@
6
6
  from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.whitebit import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Bool, Currencies, Currency, Int, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Str, Strings, Ticker, Tickers, Trade, TradingFees, Transaction, TransferEntry
9
+ from ccxt.base.types import Any, Balances, BorrowInterest, Bool, Conversion, CrossBorrowRate, Currencies, Currency, DepositAddress, FundingHistory, Int, Market, MarketType, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, Trade, TradingFees, Transaction, TransferEntry
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -26,7 +26,7 @@ from ccxt.base.precise import Precise
26
26
 
27
27
  class whitebit(Exchange, ImplicitAPI):
28
28
 
29
- def describe(self):
29
+ def describe(self) -> Any:
30
30
  return self.deep_extend(super(whitebit, self).describe(), {
31
31
  'id': 'whitebit',
32
32
  'name': 'WhiteBit',
@@ -38,35 +38,44 @@ class whitebit(Exchange, ImplicitAPI):
38
38
  'CORS': None,
39
39
  'spot': True,
40
40
  'margin': True,
41
- 'swap': False,
41
+ 'swap': True,
42
42
  'future': False,
43
43
  'option': False,
44
44
  'cancelAllOrders': True,
45
45
  'cancelAllOrdersAfter': True,
46
46
  'cancelOrder': True,
47
47
  'cancelOrders': False,
48
+ 'createConvertTrade': True,
49
+ 'createDepositAddress': True,
48
50
  'createMarketBuyOrderWithCost': True,
49
51
  'createMarketOrderWithCost': False,
50
52
  'createMarketSellOrderWithCost': False,
51
53
  'createOrder': True,
54
+ 'createPostOnlyOrder': True,
52
55
  'createStopLimitOrder': True,
53
56
  'createStopMarketOrder': True,
54
57
  'createStopOrder': True,
58
+ 'createTriggerOrder': True,
55
59
  'editOrder': False,
56
60
  'fetchBalance': True,
57
61
  'fetchBorrowRateHistories': False,
58
62
  'fetchBorrowRateHistory': False,
59
63
  'fetchClosedOrders': True,
60
- 'fetchCrossBorrowRate': False,
64
+ 'fetchConvertQuote': True,
65
+ 'fetchConvertTrade': False,
66
+ 'fetchConvertTradeHistory': True,
67
+ 'fetchCrossBorrowRate': True,
61
68
  'fetchCrossBorrowRates': False,
62
69
  'fetchCurrencies': True,
63
70
  'fetchDeposit': True,
64
71
  'fetchDepositAddress': True,
72
+ 'fetchDepositAddresses': False,
73
+ 'fetchDepositAddressesByNetwork': False,
65
74
  'fetchDeposits': True,
66
75
  'fetchDepositsWithdrawals': True,
67
76
  'fetchDepositWithdrawFee': 'emulated',
68
77
  'fetchDepositWithdrawFees': True,
69
- 'fetchFundingHistory': False,
78
+ 'fetchFundingHistory': True,
70
79
  'fetchFundingRate': True,
71
80
  'fetchFundingRateHistory': False,
72
81
  'fetchFundingRates': True,
@@ -82,7 +91,10 @@ class whitebit(Exchange, ImplicitAPI):
82
91
  'fetchOpenOrders': True,
83
92
  'fetchOrderBook': True,
84
93
  'fetchOrderTrades': True,
94
+ 'fetchPosition': True,
95
+ 'fetchPositionHistory': True,
85
96
  'fetchPositionMode': False,
97
+ 'fetchPositions': True,
86
98
  'fetchPremiumIndexOHLCV': False,
87
99
  'fetchStatus': True,
88
100
  'fetchTicker': True,
@@ -184,6 +196,7 @@ class whitebit(Exchange, ImplicitAPI):
184
196
  'assets',
185
197
  'collateral/markets',
186
198
  'fee',
199
+ 'orderbook/depth/{market}',
187
200
  'orderbook/{market}',
188
201
  'ticker',
189
202
  'trades/{market}',
@@ -192,6 +205,7 @@ class whitebit(Exchange, ImplicitAPI):
192
205
  'markets',
193
206
  'futures',
194
207
  'platform/status',
208
+ 'mining-pool',
195
209
  ],
196
210
  },
197
211
  'private': {
@@ -202,6 +216,7 @@ class whitebit(Exchange, ImplicitAPI):
202
216
  'collateral-account/leverage',
203
217
  'collateral-account/positions/open',
204
218
  'collateral-account/summary',
219
+ 'collateral-account/funding-history',
205
220
  'main-account/address',
206
221
  'main-account/balance',
207
222
  'main-account/create-new-address',
@@ -228,6 +243,7 @@ class whitebit(Exchange, ImplicitAPI):
228
243
  'order/collateral/market',
229
244
  'order/collateral/stop-limit',
230
245
  'order/collateral/trigger-market',
246
+ 'order/collateral/bulk',
231
247
  'order/new',
232
248
  'order/market',
233
249
  'order/stock_market',
@@ -239,6 +255,7 @@ class whitebit(Exchange, ImplicitAPI):
239
255
  'order/kill-switch/status',
240
256
  'order/bulk',
241
257
  'order/modify',
258
+ 'order/conditional-cancel',
242
259
  'orders',
243
260
  'oco-orders',
244
261
  'order/collateral/oco',
@@ -257,6 +274,17 @@ class whitebit(Exchange, ImplicitAPI):
257
274
  'sub-account/unblock',
258
275
  'sub-account/balances',
259
276
  'sub-account/transfer/history',
277
+ 'sub-account/api-key/create',
278
+ 'sub-account/api-key/edit',
279
+ 'sub-account/api-key/delete',
280
+ 'sub-account/api-key/list',
281
+ 'sub-account/api-key/reset',
282
+ 'sub-account/api-key/ip-address/list',
283
+ 'sub-account/api-key/ip-address/create',
284
+ 'sub-account/api-key/ip-address/delete',
285
+ 'mining/rewards',
286
+ 'market/fee',
287
+ 'conditional-orders',
260
288
  ],
261
289
  },
262
290
  },
@@ -270,6 +298,8 @@ class whitebit(Exchange, ImplicitAPI):
270
298
  },
271
299
  },
272
300
  'options': {
301
+ 'timeDifference': 0, # the difference between system clock and exchange clock
302
+ 'adjustForTimeDifference': False, # controls the adjustment logic upon instantiation
273
303
  'fiatCurrencies': ['EUR', 'USD', 'RUB', 'UAH'],
274
304
  'fetchBalance': {
275
305
  'account': 'spot',
@@ -287,6 +317,78 @@ class whitebit(Exchange, ImplicitAPI):
287
317
  'defaultType': 'spot',
288
318
  'brokerId': 'ccxt',
289
319
  },
320
+ 'features': {
321
+ 'default': {
322
+ 'sandbox': False,
323
+ 'createOrder': {
324
+ 'marginMode': True,
325
+ 'triggerPrice': True,
326
+ 'triggerDirection': False,
327
+ 'triggerPriceType': None,
328
+ 'stopLossPrice': False, # todo
329
+ 'takeProfitPrice': False, # todo
330
+ 'attachedStopLossTakeProfit': None,
331
+ 'timeInForce': {
332
+ 'IOC': True, # todo
333
+ 'FOK': False,
334
+ 'PO': True, # todo
335
+ 'GTD': False,
336
+ },
337
+ 'hedged': False,
338
+ 'trailing': False,
339
+ 'leverage': False,
340
+ 'marketBuyByCost': True,
341
+ 'marketBuyRequiresPrice': False,
342
+ 'selfTradePrevention': False,
343
+ 'iceberg': False,
344
+ },
345
+ 'createOrders': None,
346
+ 'fetchMyTrades': {
347
+ 'marginMode': False,
348
+ 'limit': 100,
349
+ 'daysBack': None,
350
+ 'untilDays': None,
351
+ 'symbolRequired': False,
352
+ },
353
+ 'fetchOrder': None,
354
+ 'fetchOpenOrders': {
355
+ 'marginMode': False,
356
+ 'limit': 100,
357
+ 'trigger': False,
358
+ 'trailing': False,
359
+ 'symbolRequired': False,
360
+ },
361
+ 'fetchOrders': None, # todo
362
+ 'fetchClosedOrders': {
363
+ 'marginMode': False,
364
+ 'limit': 100,
365
+ 'daysBack': None,
366
+ 'daysBackCanceled': None,
367
+ 'untilDays': None,
368
+ 'trigger': False,
369
+ 'trailing': False,
370
+ 'symbolRequired': False,
371
+ },
372
+ 'fetchOHLCV': {
373
+ 'limit': 1440,
374
+ },
375
+ },
376
+ 'spot': {
377
+ 'extends': 'default',
378
+ },
379
+ 'swap': {
380
+ 'linear': {
381
+ 'extends': 'default',
382
+ },
383
+ 'inverse': {
384
+ 'extends': 'default',
385
+ },
386
+ },
387
+ 'future': {
388
+ 'linear': None,
389
+ 'inverse': None,
390
+ },
391
+ },
290
392
  'precisionMode': TICK_SIZE,
291
393
  'exceptions': {
292
394
  'exact': {
@@ -308,6 +410,7 @@ class whitebit(Exchange, ImplicitAPI):
308
410
  'broad': {
309
411
  'This action is unauthorized': PermissionDenied, # {"code":2,"message":"This action is unauthorized. Enable your key in API settings"}
310
412
  'Given amount is less than min amount': InvalidOrder, # {"code":0,"message":"Validation failed","errors":{"amount":["Given amount is less than min amount 200000"],"total":["Total is less than 5.05"]}}
413
+ 'Min amount step': InvalidOrder, # {"code":32,"errors":{"amount":["Min amount step = 0.01"]},"message":"Validation failed"}
311
414
  'Total is less than': InvalidOrder, # {"code":0,"message":"Validation failed","errors":{"amount":["Given amount is less than min amount 200000"],"total":["Total is less than 5.05"]}}
312
415
  'fee must be no less than': InvalidOrder, # {"code":0,"message":"Validation failed","errors":{"amount":["Total amount + fee must be no less than 5.05505"]}}
313
416
  'Enable your key in API settings': PermissionDenied, # {"code":2,"message":"This action is unauthorized. Enable your key in API settings"}
@@ -319,10 +422,14 @@ class whitebit(Exchange, ImplicitAPI):
319
422
  async def fetch_markets(self, params={}) -> List[Market]:
320
423
  """
321
424
  retrieves data on all markets for whitebit
322
- :see: https://docs.whitebit.com/public/http-v4/#market-info
425
+
426
+ https://docs.whitebit.com/public/http-v4/#market-info
427
+
323
428
  :param dict [params]: extra parameters specific to the exchange API endpoint
324
429
  :returns dict[]: an array of objects representing market data
325
430
  """
431
+ if self.options['adjustForTimeDifference']:
432
+ await self.load_time_difference()
326
433
  markets = await self.v4PublicGetMarkets()
327
434
  #
328
435
  # [
@@ -439,46 +546,128 @@ class whitebit(Exchange, ImplicitAPI):
439
546
  async def fetch_currencies(self, params={}) -> Currencies:
440
547
  """
441
548
  fetches all available currencies on an exchange
442
- :see: https://docs.whitebit.com/public/http-v4/#asset-status-list
549
+
550
+ https://docs.whitebit.com/public/http-v4/#asset-status-list
551
+
443
552
  :param dict [params]: extra parameters specific to the exchange API endpoint
444
553
  :returns dict: an associative dictionary of currencies
445
554
  """
446
555
  response = await self.v4PublicGetAssets(params)
447
556
  #
448
- # "BTC": {
449
- # "name": "Bitcoin",
450
- # "unified_cryptoasset_id": 1,
451
- # "can_withdraw": True,
452
- # "can_deposit": True,
453
- # "min_withdraw": "0.001",
454
- # "max_withdraw": "2",
455
- # "maker_fee": "0.1",
456
- # "taker_fee": "0.1",
457
- # "min_deposit": "0.0001",
458
- # "max_deposit": "0",
459
- # },
557
+ # {
558
+ # BTC: {
559
+ # name: "Bitcoin",
560
+ # unified_cryptoasset_id: "1",
561
+ # can_withdraw: True,
562
+ # can_deposit: True,
563
+ # min_withdraw: "0.0003",
564
+ # max_withdraw: "0",
565
+ # maker_fee: "0.1",
566
+ # taker_fee: "0.1",
567
+ # min_deposit: "0.0001",
568
+ # max_deposit: "0",
569
+ # networks: {
570
+ # deposits: ["BTC",],
571
+ # withdraws: ["BTC",],
572
+ # default: "BTC",
573
+ # },
574
+ # confirmations: {
575
+ # BTC: "2",
576
+ # },
577
+ # limits: {
578
+ # deposit: {
579
+ # BTC: {min: "0.0001",},
580
+ # },
581
+ # withdraw: {
582
+ # BTC: {min: "0.0003",},
583
+ # },
584
+ # },
585
+ # currency_precision: "8",
586
+ # is_memo: False,
587
+ # },
588
+ # USD: {
589
+ # name: "United States Dollar",
590
+ # unified_cryptoasset_id: "6955",
591
+ # can_withdraw: True,
592
+ # can_deposit: True,
593
+ # min_withdraw: "10",
594
+ # max_withdraw: "10000",
595
+ # maker_fee: "0.1",
596
+ # taker_fee: "0.1",
597
+ # min_deposit: "10",
598
+ # max_deposit: "10000",
599
+ # networks: {
600
+ # deposits: ["USD",],
601
+ # withdraws: ["USD",],
602
+ # default: "USD",
603
+ # },
604
+ # providers: {
605
+ # deposits: ["ADVCASH",],
606
+ # withdraws: ["ADVCASH",],
607
+ # },
608
+ # limits: {
609
+ # deposit: {
610
+ # USD: { max: "10000", min: "10",},
611
+ # },
612
+ # withdraw: {
613
+ # USD: {max: "10000", min: "10",},
614
+ # },
615
+ # },
616
+ # currency_precision: "2",
617
+ # is_memo: False,
618
+ # }
619
+ # }
460
620
  #
461
621
  ids = list(response.keys())
462
622
  result: dict = {}
463
623
  for i in range(0, len(ids)):
464
624
  id = ids[i]
465
625
  currency = response[id]
466
- # breaks down in Python due to utf8 encoding issues on the exchange side
467
- # name = self.safe_string(currency, 'name')
468
- canDeposit = self.safe_bool(currency, 'can_deposit', True)
469
- canWithdraw = self.safe_bool(currency, 'can_withdraw', True)
470
- active = canDeposit and canWithdraw
626
+ # name = self.safe_string(currency, 'name') # breaks down in Python due to utf8 encoding issues on the exchange side
471
627
  code = self.safe_currency_code(id)
472
- result[code] = {
628
+ hasProvider = ('providers' in currency)
629
+ networks = {}
630
+ rawNetworks = self.safe_dict(currency, 'networks', {})
631
+ depositsNetworks = self.safe_list(rawNetworks, 'deposits', [])
632
+ withdrawsNetworks = self.safe_list(rawNetworks, 'withdraws', [])
633
+ networkLimits = self.safe_dict(currency, 'limits', {})
634
+ depositLimits = self.safe_dict(networkLimits, 'deposit', {})
635
+ withdrawLimits = self.safe_dict(networkLimits, 'withdraw', {})
636
+ allNetworks = self.array_concat(depositsNetworks, withdrawsNetworks)
637
+ for j in range(0, len(allNetworks)):
638
+ networkId = allNetworks[j]
639
+ networkCode = self.network_id_to_code(networkId)
640
+ networks[networkCode] = {
641
+ 'id': networkId,
642
+ 'network': networkCode,
643
+ 'active': None,
644
+ 'deposit': self.in_array(networkId, depositsNetworks),
645
+ 'withdraw': self.in_array(networkId, withdrawsNetworks),
646
+ 'fee': None,
647
+ 'precision': None,
648
+ 'limits': {
649
+ 'deposit': {
650
+ 'min': self.safe_number(depositLimits, 'min', None),
651
+ 'max': self.safe_number(depositLimits, 'max', None),
652
+ },
653
+ 'withdraw': {
654
+ 'min': self.safe_number(withdrawLimits, 'min', None),
655
+ 'max': self.safe_number(withdrawLimits, 'max', None),
656
+ },
657
+ },
658
+ }
659
+ result[code] = self.safe_currency_structure({
473
660
  'id': id,
474
661
  'code': code,
475
662
  'info': currency, # the original payload
476
663
  'name': None, # see the comment above
477
- 'active': active,
478
- 'deposit': canDeposit,
479
- 'withdraw': canWithdraw,
664
+ 'active': None,
665
+ 'deposit': self.safe_bool(currency, 'can_deposit'),
666
+ 'withdraw': self.safe_bool(currency, 'can_withdraw'),
480
667
  'fee': None,
481
- 'precision': None,
668
+ 'networks': None, # todo
669
+ 'type': 'fiat' if hasProvider else 'crypto',
670
+ 'precision': self.parse_number(self.parse_precision(self.safe_string(currency, 'currency_precision'))),
482
671
  'limits': {
483
672
  'amount': {
484
673
  'min': None,
@@ -488,15 +677,21 @@ class whitebit(Exchange, ImplicitAPI):
488
677
  'min': self.safe_number(currency, 'min_withdraw'),
489
678
  'max': self.safe_number(currency, 'max_withdraw'),
490
679
  },
680
+ 'deposit': {
681
+ 'min': self.safe_number(currency, 'min_deposit'),
682
+ 'max': self.safe_number(currency, 'max_deposit'),
683
+ },
491
684
  },
492
- }
685
+ })
493
686
  return result
494
687
 
495
688
  async def fetch_transaction_fees(self, codes: Strings = None, params={}):
496
689
  """
497
- * @deprecated
690
+ @deprecated
498
691
  please use fetchDepositWithdrawFees instead
499
- :see: https://docs.whitebit.com/public/http-v4/#fee
692
+
693
+ https://docs.whitebit.com/public/http-v4/#fee
694
+
500
695
  :param str[]|None codes: not used by fetchTransactionFees()
501
696
  :param dict [params]: extra parameters specific to the exchange API endpoint
502
697
  :returns dict: a list of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>`
@@ -548,7 +743,9 @@ class whitebit(Exchange, ImplicitAPI):
548
743
  async def fetch_deposit_withdraw_fees(self, codes: Strings = None, params={}):
549
744
  """
550
745
  fetch deposit and withdraw fees
551
- :see: https://docs.whitebit.com/public/http-v4/#fee
746
+
747
+ https://docs.whitebit.com/public/http-v4/#fee
748
+
552
749
  :param str[]|None codes: not used by fetchDepositWithdrawFees()
553
750
  :param dict [params]: extra parameters specific to the exchange API endpoint
554
751
  :returns dict: a list of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>`
@@ -690,7 +887,9 @@ class whitebit(Exchange, ImplicitAPI):
690
887
  async def fetch_trading_fees(self, params={}) -> TradingFees:
691
888
  """
692
889
  fetch the trading fees for multiple markets
693
- :see: https://docs.whitebit.com/public/http-v4/#asset-status-list
890
+
891
+ https://docs.whitebit.com/public/http-v4/#asset-status-list
892
+
694
893
  :param dict [params]: extra parameters specific to the exchange API endpoint
695
894
  :returns dict: a dictionary of `fee structures <https://docs.ccxt.com/#/?id=fee-structure>` indexed by market symbols
696
895
  """
@@ -735,7 +934,9 @@ class whitebit(Exchange, ImplicitAPI):
735
934
  async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
736
935
  """
737
936
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
738
- :see: https://docs.whitebit.com/public/http-v4/#market-activity
937
+
938
+ https://docs.whitebit.com/public/http-v4/#market-activity
939
+
739
940
  :param str symbol: unified symbol of the market to fetch the ticker for
740
941
  :param dict [params]: extra parameters specific to the exchange API endpoint
741
942
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -794,42 +995,79 @@ class whitebit(Exchange, ImplicitAPI):
794
995
  # "change": "2.12" # in percent
795
996
  # }
796
997
  #
797
- market = self.safe_market(None, market)
798
- last = self.safe_string(ticker, 'last_price')
998
+ # WS market_update
999
+ #
1000
+ # {
1001
+ # "open": "52853.04",
1002
+ # "close": "55913.88",
1003
+ # "high": "56272",
1004
+ # "low": "49549.67",
1005
+ # "volume": "57331.067185",
1006
+ # "deal": "3063860382.42985338",
1007
+ # "last": "55913.88",
1008
+ # "period": 86400
1009
+ # }
1010
+ # v2
1011
+ # {
1012
+ # lastUpdateTimestamp: '2025-01-02T09:16:36.000Z',
1013
+ # tradingPairs: 'ARB_USDC',
1014
+ # lastPrice: '0.7727',
1015
+ # lowestAsk: '0.7735',
1016
+ # highestBid: '0.7732',
1017
+ # baseVolume24h: '1555793.74',
1018
+ # quoteVolume24h: '1157602.622406',
1019
+ # tradesEnabled: True
1020
+ # }
1021
+ #
1022
+ marketId = self.safe_string(ticker, 'tradingPairs')
1023
+ market = self.safe_market(marketId, market)
1024
+ # last price is provided as "last" or "last_price"
1025
+ last = self.safe_string_n(ticker, ['last', 'last_price', 'lastPrice'])
1026
+ # if "close" is provided, use it, otherwise use <last>
1027
+ close = self.safe_string(ticker, 'close', last)
799
1028
  return self.safe_ticker({
800
1029
  'symbol': market['symbol'],
801
1030
  'timestamp': None,
802
1031
  'datetime': None,
803
1032
  'high': self.safe_string(ticker, 'high'),
804
1033
  'low': self.safe_string(ticker, 'low'),
805
- 'bid': self.safe_string(ticker, 'bid'),
1034
+ 'bid': self.safe_string_2(ticker, 'bid', 'highestBid'),
806
1035
  'bidVolume': None,
807
- 'ask': self.safe_string(ticker, 'ask'),
1036
+ 'ask': self.safe_string_2(ticker, 'ask', 'lowestAsk'),
808
1037
  'askVolume': None,
809
1038
  'vwap': None,
810
1039
  'open': self.safe_string(ticker, 'open'),
811
- 'close': last,
1040
+ 'close': close,
812
1041
  'last': last,
813
1042
  'previousClose': None,
814
1043
  'change': None,
815
1044
  'percentage': self.safe_string(ticker, 'change'),
816
1045
  'average': None,
817
- 'baseVolume': self.safe_string_2(ticker, 'base_volume', 'volume'),
818
- 'quoteVolume': self.safe_string_2(ticker, 'quote_volume', 'deal'),
1046
+ 'baseVolume': self.safe_string_n(ticker, ['base_volume', 'volume', 'baseVolume24h']),
1047
+ 'quoteVolume': self.safe_string_n(ticker, ['quote_volume', 'deal', 'quoteVolume24h']),
819
1048
  'info': ticker,
820
1049
  }, market)
821
1050
 
822
1051
  async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
823
1052
  """
824
1053
  fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
825
- :see: https://docs.whitebit.com/public/http-v4/#market-activity
826
- :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1054
+
1055
+ https://docs.whitebit.com/public/http-v4/#market-activity
1056
+
1057
+ :param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
827
1058
  :param dict [params]: extra parameters specific to the exchange API endpoint
1059
+ :param str [params.method]: either v2PublicGetTicker or v4PublicGetTicker default is v4PublicGetTicker
828
1060
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
829
1061
  """
830
1062
  await self.load_markets()
831
1063
  symbols = self.market_symbols(symbols)
832
- response = await self.v4PublicGetTicker(params)
1064
+ method = 'v4PublicGetTicker'
1065
+ method, params = self.handle_option_and_params(params, 'fetchTickers', 'method', method)
1066
+ response = None
1067
+ if method == 'v4PublicGetTicker':
1068
+ response = await self.v4PublicGetTicker(params)
1069
+ else:
1070
+ response = await self.v2PublicGetTicker(params)
833
1071
  #
834
1072
  # "BCH_RUB": {
835
1073
  # "base_id":1831,
@@ -841,6 +1079,9 @@ class whitebit(Exchange, ImplicitAPI):
841
1079
  # "change":"2.12"
842
1080
  # },
843
1081
  #
1082
+ resultList = self.safe_list(response, 'result')
1083
+ if resultList is not None:
1084
+ return self.parse_tickers(resultList, symbols)
844
1085
  marketIds = list(response.keys())
845
1086
  result: dict = {}
846
1087
  for i in range(0, len(marketIds)):
@@ -854,7 +1095,9 @@ class whitebit(Exchange, ImplicitAPI):
854
1095
  async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
855
1096
  """
856
1097
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
857
- :see: https://docs.whitebit.com/public/http-v4/#orderbook
1098
+
1099
+ https://docs.whitebit.com/public/http-v4/#orderbook
1100
+
858
1101
  :param str symbol: unified symbol of the market to fetch the order book for
859
1102
  :param int [limit]: the maximum amount of order book entries to return
860
1103
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -893,7 +1136,9 @@ class whitebit(Exchange, ImplicitAPI):
893
1136
  async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
894
1137
  """
895
1138
  get the list of most recent trades for a particular symbol
896
- :see: https://docs.whitebit.com/public/http-v4/#recent-trades
1139
+
1140
+ https://docs.whitebit.com/public/http-v4/#recent-trades
1141
+
897
1142
  :param str symbol: unified symbol of the market to fetch trades for
898
1143
  :param int [since]: timestamp in ms of the earliest trade to fetch
899
1144
  :param int [limit]: the maximum amount of trades to fetch
@@ -923,7 +1168,9 @@ class whitebit(Exchange, ImplicitAPI):
923
1168
  async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
924
1169
  """
925
1170
  fetch all trades made by the user
926
- :see: https://docs.whitebit.com/private/http-trade-v4/#query-executed-order-history
1171
+
1172
+ https://docs.whitebit.com/private/http-trade-v4/#query-executed-order-history
1173
+
927
1174
  :param str symbol: unified symbol of the market to fetch trades for
928
1175
  :param int [since]: timestamp in ms of the earliest trade to fetch
929
1176
  :param int [limit]: the maximum amount of trades to fetch
@@ -1013,6 +1260,7 @@ class whitebit(Exchange, ImplicitAPI):
1013
1260
  # "clientOrderId": "customId11",
1014
1261
  # "role": 2, # 1 = maker, 2 = taker
1015
1262
  # "deal": "0.00419198" # amount in money
1263
+ # "feeAsset": "USDT"
1016
1264
  # }
1017
1265
  #
1018
1266
  # fetchMyTrades
@@ -1028,6 +1276,7 @@ class whitebit(Exchange, ImplicitAPI):
1028
1276
  # "deal": "9.981007",
1029
1277
  # "fee": "0.009981007",
1030
1278
  # "orderId": 58166729555,
1279
+ # "feeAsset": "USDT"
1031
1280
  # }
1032
1281
  #
1033
1282
  market = self.safe_market(None, market)
@@ -1048,7 +1297,7 @@ class whitebit(Exchange, ImplicitAPI):
1048
1297
  if feeCost is not None:
1049
1298
  fee = {
1050
1299
  'cost': feeCost,
1051
- 'currency': market['quote'],
1300
+ 'currency': self.safe_currency_code(self.safe_string(trade, 'feeAsset')),
1052
1301
  }
1053
1302
  return self.safe_trade({
1054
1303
  'info': trade,
@@ -1069,7 +1318,9 @@ class whitebit(Exchange, ImplicitAPI):
1069
1318
  async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
1070
1319
  """
1071
1320
  fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
1072
- :see: https://docs.whitebit.com/public/http-v1/#kline
1321
+
1322
+ https://docs.whitebit.com/public/http-v1/#kline
1323
+
1073
1324
  :param str symbol: unified symbol of the market to fetch OHLCV data for
1074
1325
  :param str timeframe: the length of time each candle represents
1075
1326
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -1131,7 +1382,9 @@ class whitebit(Exchange, ImplicitAPI):
1131
1382
  async def fetch_status(self, params={}):
1132
1383
  """
1133
1384
  the latest known information on the availability of the exchange API
1134
- :see: https://docs.whitebit.com/public/http-v4/#server-status
1385
+
1386
+ https://docs.whitebit.com/public/http-v4/#server-status
1387
+
1135
1388
  :param dict [params]: extra parameters specific to the exchange API endpoint
1136
1389
  :returns dict: a `status structure <https://docs.ccxt.com/#/?id=exchange-status-structure>`
1137
1390
  """
@@ -1150,17 +1403,19 @@ class whitebit(Exchange, ImplicitAPI):
1150
1403
  'info': response,
1151
1404
  }
1152
1405
 
1153
- async def fetch_time(self, params={}):
1406
+ async def fetch_time(self, params={}) -> Int:
1154
1407
  """
1155
1408
  fetches the current integer timestamp in milliseconds from the exchange server
1156
- :see: https://docs.whitebit.com/public/http-v4/#server-time
1409
+
1410
+ https://docs.whitebit.com/public/http-v4/#server-time
1411
+
1157
1412
  :param dict [params]: extra parameters specific to the exchange API endpoint
1158
1413
  :returns int: the current integer timestamp in milliseconds from the exchange server
1159
1414
  """
1160
1415
  response = await self.v4PublicGetTime(params)
1161
1416
  #
1162
1417
  # {
1163
- # "time":1635467280514
1418
+ # "time":1737380046
1164
1419
  # }
1165
1420
  #
1166
1421
  return self.safe_integer(response, 'time')
@@ -1174,9 +1429,11 @@ class whitebit(Exchange, ImplicitAPI):
1174
1429
  :param dict [params]: extra parameters specific to the exchange API endpoint
1175
1430
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1176
1431
  """
1177
- params['cost'] = cost
1432
+ req = {
1433
+ 'cost': cost,
1434
+ }
1178
1435
  # only buy side is supported
1179
- return await self.create_order(symbol, 'market', side, 0, None, params)
1436
+ return await self.create_order(symbol, 'market', side, 0, None, self.extend(req, params))
1180
1437
 
1181
1438
  async def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}) -> Order:
1182
1439
  """
@@ -1191,18 +1448,24 @@ class whitebit(Exchange, ImplicitAPI):
1191
1448
  async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1192
1449
  """
1193
1450
  create a trade order
1194
- :see: https://docs.whitebit.com/private/http-trade-v4/#create-limit-order
1195
- :see: https://docs.whitebit.com/private/http-trade-v4/#create-market-order
1196
- :see: https://docs.whitebit.com/private/http-trade-v4/#create-buy-stock-market-order
1197
- :see: https://docs.whitebit.com/private/http-trade-v4/#create-stop-limit-order
1198
- :see: https://docs.whitebit.com/private/http-trade-v4/#create-stop-market-order
1451
+
1452
+ https://docs.whitebit.com/private/http-trade-v4/#create-limit-order
1453
+ https://docs.whitebit.com/private/http-trade-v4/#create-market-order
1454
+ https://docs.whitebit.com/private/http-trade-v4/#create-buy-stock-market-order
1455
+ https://docs.whitebit.com/private/http-trade-v4/#create-stop-limit-order
1456
+ https://docs.whitebit.com/private/http-trade-v4/#create-stop-market-order
1457
+
1199
1458
  :param str symbol: unified symbol of the market to create an order in
1200
1459
  :param str type: 'market' or 'limit'
1201
1460
  :param str side: 'buy' or 'sell'
1202
1461
  :param float amount: how much of currency you want to trade in units of base currency
1203
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1462
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1204
1463
  :param dict [params]: extra parameters specific to the exchange API endpoint
1205
1464
  :param float [params.cost]: *market orders only* the cost of the order in units of the base currency
1465
+ :param float [params.triggerPrice]: The price at which a trigger order is triggered at
1466
+ :param bool [params.postOnly]: If True, the order will only be posted to the order book and not executed immediately
1467
+ :param str [params.clientOrderId]: a unique id for the order
1468
+ :param str [params.marginMode]: 'cross' or 'isolated', for margin trading, uses self.options.defaultMarginMode if not passed, defaults to None/None/None
1206
1469
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1207
1470
  """
1208
1471
  await self.load_markets()
@@ -1230,8 +1493,8 @@ class whitebit(Exchange, ImplicitAPI):
1230
1493
  marketType = self.safe_string(market, 'type')
1231
1494
  isLimitOrder = type == 'limit'
1232
1495
  isMarketOrder = type == 'market'
1233
- stopPrice = self.safe_number_n(params, ['triggerPrice', 'stopPrice', 'activation_price'])
1234
- isStopOrder = (stopPrice is not None)
1496
+ triggerPrice = self.safe_number_n(params, ['triggerPrice', 'stopPrice', 'activation_price'])
1497
+ isStopOrder = (triggerPrice is not None)
1235
1498
  postOnly = self.is_post_only(isMarketOrder, False, params)
1236
1499
  marginMode, query = self.handle_margin_mode_and_params('createOrder', params)
1237
1500
  if postOnly:
@@ -1242,7 +1505,7 @@ class whitebit(Exchange, ImplicitAPI):
1242
1505
  useCollateralEndpoint = marginMode is not None or marketType == 'swap'
1243
1506
  response = None
1244
1507
  if isStopOrder:
1245
- request['activation_price'] = self.price_to_precision(symbol, stopPrice)
1508
+ request['activation_price'] = self.price_to_precision(symbol, triggerPrice)
1246
1509
  if isLimitOrder:
1247
1510
  # stop limit order
1248
1511
  request['price'] = self.price_to_precision(symbol, price)
@@ -1275,13 +1538,15 @@ class whitebit(Exchange, ImplicitAPI):
1275
1538
  async def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
1276
1539
  """
1277
1540
  edit a trade order
1278
- :see: https://docs.whitebit.com/private/http-trade-v4/#modify-order
1541
+
1542
+ https://docs.whitebit.com/private/http-trade-v4/#modify-order
1543
+
1279
1544
  :param str id: cancel order id
1280
1545
  :param str symbol: unified symbol of the market to create an order in
1281
1546
  :param str type: 'market' or 'limit'
1282
1547
  :param str side: 'buy' or 'sell'
1283
1548
  :param float amount: how much of currency you want to trade in units of base currency
1284
- :param float price: the price at which the order is to be fullfilled, in units of the base currency, ignored in market orders
1549
+ :param float price: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1285
1550
  :param dict [params]: extra parameters specific to the exchange API endpoint
1286
1551
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1287
1552
  """
@@ -1300,11 +1565,11 @@ class whitebit(Exchange, ImplicitAPI):
1300
1565
  # Update clientOrderId of the order
1301
1566
  request['clientOrderId'] = clientOrderId
1302
1567
  isLimitOrder = type == 'limit'
1303
- stopPrice = self.safe_number_n(params, ['triggerPrice', 'stopPrice', 'activation_price'])
1304
- isStopOrder = (stopPrice is not None)
1568
+ triggerPrice = self.safe_number_n(params, ['triggerPrice', 'stopPrice', 'activation_price'])
1569
+ isStopOrder = (triggerPrice is not None)
1305
1570
  params = self.omit(params, ['clOrdId', 'clientOrderId', 'triggerPrice', 'stopPrice'])
1306
1571
  if isStopOrder:
1307
- request['activation_price'] = self.price_to_precision(symbol, stopPrice)
1572
+ request['activation_price'] = self.price_to_precision(symbol, triggerPrice)
1308
1573
  if isLimitOrder:
1309
1574
  # stop limit order
1310
1575
  request['amount'] = self.amount_to_precision(symbol, amount)
@@ -1327,7 +1592,9 @@ class whitebit(Exchange, ImplicitAPI):
1327
1592
  async def cancel_order(self, id: str, symbol: Str = None, params={}):
1328
1593
  """
1329
1594
  cancels an open order
1330
- :see: https://docs.whitebit.com/private/http-trade-v4/#cancel-order
1595
+
1596
+ https://docs.whitebit.com/private/http-trade-v4/#cancel-order
1597
+
1331
1598
  :param str id: order id
1332
1599
  :param str symbol: unified symbol of the market the order was made in
1333
1600
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -1366,7 +1633,9 @@ class whitebit(Exchange, ImplicitAPI):
1366
1633
  async def cancel_all_orders(self, symbol: Str = None, params={}):
1367
1634
  """
1368
1635
  cancel all open orders
1369
- :see: https://docs.whitebit.com/private/http-trade-v4/#cancel-all-orders
1636
+
1637
+ https://docs.whitebit.com/private/http-trade-v4/#cancel-all-orders
1638
+
1370
1639
  :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
1371
1640
  :param dict [params]: extra parameters specific to the exchange API endpoint
1372
1641
  :param str [params.type]: market type, ['swap', 'spot']
@@ -1403,7 +1672,9 @@ class whitebit(Exchange, ImplicitAPI):
1403
1672
  async def cancel_all_orders_after(self, timeout: Int, params={}):
1404
1673
  """
1405
1674
  dead man's switch, cancel all orders after the given timeout
1406
- :see: https://docs.whitebit.com/private/http-trade-v4/#sync-kill-switch-timer
1675
+
1676
+ https://docs.whitebit.com/private/http-trade-v4/#sync-kill-switch-timer
1677
+
1407
1678
  :param number timeout: time in milliseconds, 0 represents cancel the timer
1408
1679
  :param dict [params]: extra parameters specific to the exchange API endpoint
1409
1680
  :param str [params.types]: Order types value. Example: "spot", "margin", "futures" or None
@@ -1458,8 +1729,10 @@ class whitebit(Exchange, ImplicitAPI):
1458
1729
  async def fetch_balance(self, params={}) -> Balances:
1459
1730
  """
1460
1731
  query for balance and get the amount of funds available for trading or funds locked in orders
1461
- :see: https://docs.whitebit.com/private/http-main-v4/#main-balance
1462
- :see: https://docs.whitebit.com/private/http-trade-v4/#trading-balance
1732
+
1733
+ https://docs.whitebit.com/private/http-main-v4/#main-balance
1734
+ https://docs.whitebit.com/private/http-trade-v4/#trading-balance
1735
+
1463
1736
  :param dict [params]: extra parameters specific to the exchange API endpoint
1464
1737
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
1465
1738
  """
@@ -1505,20 +1778,21 @@ class whitebit(Exchange, ImplicitAPI):
1505
1778
  async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1506
1779
  """
1507
1780
  fetch all unfilled currently open orders
1508
- :see: https://docs.whitebit.com/private/http-trade-v4/#query-unexecutedactive-orders
1509
- :param str symbol: unified market symbol
1781
+
1782
+ https://docs.whitebit.com/private/http-trade-v4/#query-unexecutedactive-orders
1783
+
1784
+ :param str [symbol]: unified market symbol
1510
1785
  :param int [since]: the earliest time in ms to fetch open orders for
1511
1786
  :param int [limit]: the maximum number of open order structures to retrieve
1512
1787
  :param dict [params]: extra parameters specific to the exchange API endpoint
1513
1788
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1514
1789
  """
1515
- if symbol is None:
1516
- raise ArgumentsRequired(self.id + ' fetchOpenOrders() requires a symbol argument')
1517
1790
  await self.load_markets()
1518
- market = self.market(symbol)
1519
- request: dict = {
1520
- 'market': market['id'],
1521
- }
1791
+ market = None
1792
+ request: dict = {}
1793
+ if symbol is not None:
1794
+ market = self.market(symbol)
1795
+ request['market'] = market['id']
1522
1796
  if limit is not None:
1523
1797
  request['limit'] = min(limit, 100)
1524
1798
  response = await self.v4PrivatePostOrders(self.extend(request, params))
@@ -1547,7 +1821,9 @@ class whitebit(Exchange, ImplicitAPI):
1547
1821
  async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1548
1822
  """
1549
1823
  fetches information on multiple closed orders made by the user
1550
- :see: https://docs.whitebit.com/private/http-trade-v4/#query-executed-orders
1824
+
1825
+ https://docs.whitebit.com/private/http-trade-v4/#query-executed-orders
1826
+
1551
1827
  :param str symbol: unified market symbol of the market orders were made in
1552
1828
  :param int [since]: the earliest time in ms to fetch orders for
1553
1829
  :param int [limit]: the maximum number of order structures to retrieve
@@ -1656,7 +1932,7 @@ class whitebit(Exchange, ImplicitAPI):
1656
1932
  if clientOrderId == '':
1657
1933
  clientOrderId = None
1658
1934
  price = self.safe_string(order, 'price')
1659
- stopPrice = self.safe_number(order, 'activation_price')
1935
+ triggerPrice = self.safe_number(order, 'activation_price')
1660
1936
  orderId = self.safe_string_2(order, 'orderId', 'id')
1661
1937
  type = self.safe_string(order, 'type')
1662
1938
  orderType = self.parse_order_type(type)
@@ -1689,8 +1965,7 @@ class whitebit(Exchange, ImplicitAPI):
1689
1965
  'side': side,
1690
1966
  'price': price,
1691
1967
  'type': orderType,
1692
- 'stopPrice': stopPrice,
1693
- 'triggerPrice': stopPrice,
1968
+ 'triggerPrice': triggerPrice,
1694
1969
  'amount': amount,
1695
1970
  'filled': filled,
1696
1971
  'remaining': remaining,
@@ -1703,7 +1978,9 @@ class whitebit(Exchange, ImplicitAPI):
1703
1978
  async def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1704
1979
  """
1705
1980
  fetch all the trades made from a single order
1706
- :see: https://docs.whitebit.com/private/http-trade-v4/#query-executed-order-deals
1981
+
1982
+ https://docs.whitebit.com/private/http-trade-v4/#query-executed-order-deals
1983
+
1707
1984
  :param str id: order id
1708
1985
  :param str symbol: unified market symbol
1709
1986
  :param int [since]: the earliest time in ms to fetch trades for
@@ -1744,11 +2021,13 @@ class whitebit(Exchange, ImplicitAPI):
1744
2021
  data = self.safe_list(response, 'records', [])
1745
2022
  return self.parse_trades(data, market)
1746
2023
 
1747
- async def fetch_deposit_address(self, code: str, params={}):
2024
+ async def fetch_deposit_address(self, code: str, params={}) -> DepositAddress:
1748
2025
  """
1749
2026
  fetch the deposit address for a currency associated with self account
1750
- :see: https://docs.whitebit.com/private/http-main-v4/#get-fiat-deposit-address
1751
- :see: https://docs.whitebit.com/private/http-main-v4/#get-cryptocurrency-deposit-address
2027
+
2028
+ https://docs.whitebit.com/private/http-main-v4/#get-fiat-deposit-address
2029
+ https://docs.whitebit.com/private/http-main-v4/#get-cryptocurrency-deposit-address
2030
+
1752
2031
  :param str code: unified currency code
1753
2032
  :param dict [params]: extra parameters specific to the exchange API endpoint
1754
2033
  :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
@@ -1806,17 +2085,73 @@ class whitebit(Exchange, ImplicitAPI):
1806
2085
  tag = self.safe_string(account, 'memo')
1807
2086
  self.check_address(address)
1808
2087
  return {
2088
+ 'info': response,
1809
2089
  'currency': code,
2090
+ 'network': None,
1810
2091
  'address': address,
1811
2092
  'tag': tag,
2093
+ }
2094
+
2095
+ async def create_deposit_address(self, code: str, params={}) -> DepositAddress:
2096
+ """
2097
+ create a currency deposit address
2098
+
2099
+ https://docs.whitebit.com/private/http-main-v4/#create-new-address-for-deposit
2100
+
2101
+ :param str code: unified currency code of the currency for the deposit address
2102
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2103
+ :param str [params.network]: the blockchain network to create a deposit address on
2104
+ :param str [params.type]: address type, available for specific currencies
2105
+ :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
2106
+ """
2107
+ await self.load_markets()
2108
+ currency = self.currency(code)
2109
+ request: dict = {
2110
+ 'ticker': currency['id'],
2111
+ }
2112
+ response = await self.v4PrivatePostMainAccountCreateNewAddress(self.extend(request, params))
2113
+ #
2114
+ # {
2115
+ # "account": {
2116
+ # "address": "GDTSOI56XNVAKJNJBLJGRNZIVOCIZJRBIDKTWSCYEYNFAZEMBLN75RMN",
2117
+ # "memo": "48565488244493"
2118
+ # },
2119
+ # "required": {
2120
+ # "maxAmount": "0",
2121
+ # "minAmount": "1",
2122
+ # "fixedFee": "0",
2123
+ # "flexFee": {
2124
+ # "maxFee": "0",
2125
+ # "minFee": "0",
2126
+ # "percent": "0"
2127
+ # }
2128
+ # }
2129
+ # }
2130
+ #
2131
+ data = self.safe_dict(response, 'account', {})
2132
+ return self.parse_deposit_address(data, currency)
2133
+
2134
+ def parse_deposit_address(self, depositAddress, currency: Currency = None) -> DepositAddress:
2135
+ #
2136
+ # {
2137
+ # "address": "GDTSOI56XNVAKJNJBLJGRNZIVOCIZJRBIDKTWSCYEYNFAZEMBLN75RMN",
2138
+ # "memo": "48565488244493"
2139
+ # },
2140
+ #
2141
+ return {
2142
+ 'info': depositAddress,
2143
+ 'currency': self.safe_currency_code(None, currency),
1812
2144
  'network': None,
1813
- 'info': response,
2145
+ 'address': self.safe_string(depositAddress, 'address'),
2146
+ 'tag': self.safe_string(depositAddress, 'memo'),
1814
2147
  }
1815
2148
 
1816
- async def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
2149
+ async def set_leverage(self, leverage: int, symbol: Str = None, params={}):
1817
2150
  """
1818
2151
  set the level of leverage for a market
1819
- :see: https://docs.whitebit.com/private/http-trade-v4/#change-collateral-account-leverage
2152
+
2153
+ https://docs.whitebit.com/private/http-trade-v4/#change-collateral-account-leverage
2154
+
1820
2155
  :param float leverage: the rate of leverage
1821
2156
  :param str symbol: unified market symbol
1822
2157
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -1838,7 +2173,9 @@ class whitebit(Exchange, ImplicitAPI):
1838
2173
  async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
1839
2174
  """
1840
2175
  transfer currency internally between wallets on the same account
1841
- :see: https://docs.whitebit.com/private/http-main-v4/#transfer-between-main-and-trade-balances
2176
+
2177
+ https://docs.whitebit.com/private/http-main-v4/#transfer-between-main-and-trade-balances
2178
+
1842
2179
  :param str code: unified currency code
1843
2180
  :param float amount: amount to transfer
1844
2181
  :param str fromAccount: account to transfer from - main, spot, collateral
@@ -1880,10 +2217,12 @@ class whitebit(Exchange, ImplicitAPI):
1880
2217
  'status': None,
1881
2218
  }
1882
2219
 
1883
- async def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
2220
+ async def withdraw(self, code: str, amount: float, address: str, tag: Str = None, params={}) -> Transaction:
1884
2221
  """
1885
2222
  make a withdrawal
1886
- :see: https://docs.whitebit.com/private/http-main-v4/#create-withdraw-request
2223
+
2224
+ https://docs.whitebit.com/private/http-main-v4/#create-withdraw-request
2225
+
1887
2226
  :param str code: unified currency code
1888
2227
  :param float amount: the amount to withdraw
1889
2228
  :param str address: the address to withdraw to
@@ -2006,7 +2345,9 @@ class whitebit(Exchange, ImplicitAPI):
2006
2345
  async def fetch_deposit(self, id: str, code: Str = None, params={}):
2007
2346
  """
2008
2347
  fetch information on a deposit
2009
- :see: https://docs.whitebit.com/private/http-main-v4/#get-depositwithdraw-history
2348
+
2349
+ https://docs.whitebit.com/private/http-main-v4/#get-depositwithdraw-history
2350
+
2010
2351
  :param str id: deposit id
2011
2352
  :param str code: not used by whitebit fetchDeposit()
2012
2353
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -2068,7 +2409,9 @@ class whitebit(Exchange, ImplicitAPI):
2068
2409
  async def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
2069
2410
  """
2070
2411
  fetch all deposits made to an account
2071
- :see: https://docs.whitebit.com/private/http-main-v4/#get-depositwithdraw-history
2412
+
2413
+ https://docs.whitebit.com/private/http-main-v4/#get-depositwithdraw-history
2414
+
2072
2415
  :param str code: unified currency code
2073
2416
  :param int [since]: the earliest time in ms to fetch deposits for
2074
2417
  :param int [limit]: the maximum number of deposits structures to retrieve
@@ -2128,10 +2471,12 @@ class whitebit(Exchange, ImplicitAPI):
2128
2471
  records = self.safe_list(response, 'records', [])
2129
2472
  return self.parse_transactions(records, currency, since, limit)
2130
2473
 
2131
- async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2474
+ async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
2132
2475
  """
2133
2476
  fetch the interest owed by the user for borrowing currency for margin trading
2134
- :see: https://docs.whitebit.com/private/http-trade-v4/#open-positions
2477
+
2478
+ https://docs.whitebit.com/private/http-trade-v4/#open-positions
2479
+
2135
2480
  :param str code: unified currency code
2136
2481
  :param str symbol: unified market symbol
2137
2482
  :param int [since]: the earliest time in ms to fetch borrrow interest for
@@ -2170,7 +2515,7 @@ class whitebit(Exchange, ImplicitAPI):
2170
2515
  interest = self.parse_borrow_interests(response, market)
2171
2516
  return self.filter_by_currency_since_limit(interest, code, since, limit)
2172
2517
 
2173
- def parse_borrow_interest(self, info: dict, market: Market = None):
2518
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
2174
2519
  #
2175
2520
  # {
2176
2521
  # "positionId": 191823,
@@ -2194,21 +2539,23 @@ class whitebit(Exchange, ImplicitAPI):
2194
2539
  symbol = self.safe_symbol(marketId, market, '_')
2195
2540
  timestamp = self.safe_timestamp(info, 'modifyDate')
2196
2541
  return {
2542
+ 'info': info,
2197
2543
  'symbol': symbol,
2198
- 'marginMode': 'cross',
2199
2544
  'currency': 'USDT',
2200
2545
  'interest': self.safe_number(info, 'unrealizedFunding'),
2201
2546
  'interestRate': 0.00098, # https://whitebit.com/fees
2202
2547
  'amountBorrowed': self.safe_number(info, 'amount'),
2548
+ 'marginMode': 'cross',
2203
2549
  'timestamp': timestamp,
2204
2550
  'datetime': self.iso8601(timestamp),
2205
- 'info': info,
2206
2551
  }
2207
2552
 
2208
- async def fetch_funding_rate(self, symbol: str, params={}):
2553
+ async def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
2209
2554
  """
2210
- :see: https://docs.whitebit.com/public/http-v4/#available-futures-markets-list
2211
2555
  fetch the current funding rate
2556
+
2557
+ https://docs.whitebit.com/public/http-v4/#available-futures-markets-list
2558
+
2212
2559
  :param str symbol: unified market symbol
2213
2560
  :param dict [params]: extra parameters specific to the exchange API endpoint
2214
2561
  :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
@@ -2218,13 +2565,15 @@ class whitebit(Exchange, ImplicitAPI):
2218
2565
  response = await self.fetch_funding_rates([symbol], params)
2219
2566
  return self.safe_value(response, symbol)
2220
2567
 
2221
- async def fetch_funding_rates(self, symbols: Strings = None, params={}):
2568
+ async def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
2222
2569
  """
2223
- :see: https://docs.whitebit.com/public/http-v4/#available-futures-markets-list
2224
2570
  fetch the funding rate for multiple markets
2571
+
2572
+ https://docs.whitebit.com/public/http-v4/#available-futures-markets-list
2573
+
2225
2574
  :param str[]|None symbols: list of unified market symbols
2226
2575
  :param dict [params]: extra parameters specific to the exchange API endpoint
2227
- :returns dict: a dictionary of `funding rates structures <https://docs.ccxt.com/#/?id=funding-rates-structure>`, indexe by market symbols
2576
+ :returns dict[]: a list of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rates-structure>`, indexed by market symbols
2228
2577
  """
2229
2578
  await self.load_markets()
2230
2579
  symbols = self.market_symbols(symbols)
@@ -2273,11 +2622,10 @@ class whitebit(Exchange, ImplicitAPI):
2273
2622
  # }
2274
2623
  # ]
2275
2624
  #
2276
- data = self.safe_value(response, 'result', [])
2277
- result = self.parse_funding_rates(data)
2278
- return self.filter_by_array(result, 'symbol', symbols)
2625
+ data = self.safe_list(response, 'result', [])
2626
+ return self.parse_funding_rates(data, symbols)
2279
2627
 
2280
- def parse_funding_rate(self, contract, market: Market = None):
2628
+ def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
2281
2629
  #
2282
2630
  # {
2283
2631
  # "ticker_id":"ADA_PERP",
@@ -2316,7 +2664,7 @@ class whitebit(Exchange, ImplicitAPI):
2316
2664
  indexPrice = self.safe_number(contract, 'indexPrice')
2317
2665
  interestRate = self.safe_number(contract, 'interestRate')
2318
2666
  fundingRate = self.safe_number(contract, 'funding_rate')
2319
- nextFundingTime = self.safe_integer(contract, 'next_funding_rate_timestamp')
2667
+ fundingTime = self.safe_integer(contract, 'next_funding_rate_timestamp')
2320
2668
  return {
2321
2669
  'info': contract,
2322
2670
  'symbol': symbol,
@@ -2326,26 +2674,107 @@ class whitebit(Exchange, ImplicitAPI):
2326
2674
  'timestamp': None,
2327
2675
  'datetime': None,
2328
2676
  'fundingRate': fundingRate,
2329
- 'fundingTimestamp': None,
2330
- 'fundingDatetime': self.iso8601(None),
2677
+ 'fundingTimestamp': fundingTime,
2678
+ 'fundingDatetime': self.iso8601(fundingTime),
2331
2679
  'nextFundingRate': None,
2332
- 'nextFundingTimestamp': nextFundingTime,
2333
- 'nextFundingDatetime': self.iso8601(nextFundingTime),
2680
+ 'nextFundingTimestamp': None,
2681
+ 'nextFundingDatetime': None,
2334
2682
  'previousFundingRate': None,
2335
2683
  'previousFundingTimestamp': None,
2336
2684
  'previousFundingDatetime': None,
2685
+ 'interval': None,
2337
2686
  }
2338
2687
 
2688
+ async def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[FundingHistory]:
2689
+ """
2690
+ fetch the history of funding payments paid and received on self account
2691
+
2692
+ https://docs.whitebit.com/private/http-trade-v4/#funding-history
2693
+
2694
+ :param str [symbol]: unified market symbol
2695
+ :param int [since]: the starting timestamp in milliseconds
2696
+ :param int [limit]: the number of entries to return
2697
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2698
+ :param int [params.until]: the latest time in ms to fetch funding history for
2699
+ :returns dict[]: a list of `funding history structures <https://docs.ccxt.com/#/?id=funding-history-structure>`
2700
+ """
2701
+ await self.load_markets()
2702
+ if symbol is None:
2703
+ raise ArgumentsRequired(self.id + ' fetchFundingHistory() requires a symbol argument')
2704
+ market = self.market(symbol)
2705
+ request: dict = {
2706
+ 'market': market['id'],
2707
+ }
2708
+ if since is not None:
2709
+ request['startDate'] = since
2710
+ if limit is not None:
2711
+ request['limit'] = since
2712
+ request, params = self.handle_until_option('endDate', request, params)
2713
+ response = await self.v4PrivatePostCollateralAccountFundingHistory(request)
2714
+ #
2715
+ # {
2716
+ # "records": [
2717
+ # {
2718
+ # "market": "BTC_PERP",
2719
+ # "fundingTime": "1708704000000",
2720
+ # "fundingRate": "0.00017674",
2721
+ # "fundingAmount": "-0.171053531892",
2722
+ # "positionAmount": "0.019",
2723
+ # "settlementPrice": "50938.2",
2724
+ # "rateCalculatedTime": "1708675200000"
2725
+ # },
2726
+ # ],
2727
+ # "limit": 100,
2728
+ # "offset": 0
2729
+ # }
2730
+ #
2731
+ data = self.safe_list(response, 'records', [])
2732
+ return self.parse_funding_histories(data, market, since, limit)
2733
+
2734
+ def parse_funding_history(self, contract, market: Market = None):
2735
+ #
2736
+ # {
2737
+ # "market": "BTC_PERP",
2738
+ # "fundingTime": "1708704000000",
2739
+ # "fundingRate": "0.00017674",
2740
+ # "fundingAmount": "-0.171053531892",
2741
+ # "positionAmount": "0.019",
2742
+ # "settlementPrice": "50938.2",
2743
+ # "rateCalculatedTime": "1708675200000"
2744
+ # }
2745
+ #
2746
+ marketId = self.safe_string(contract, 'market')
2747
+ timestamp = self.safe_integer(contract, 'fundingTime')
2748
+ return {
2749
+ 'info': contract,
2750
+ 'symbol': self.safe_symbol(marketId, market, None, 'swap'),
2751
+ 'code': None,
2752
+ 'timestamp': timestamp,
2753
+ 'datetime': self.iso8601(timestamp),
2754
+ 'id': None,
2755
+ 'amount': self.safe_number(contract, 'fundingAmount'),
2756
+ }
2757
+
2758
+ def parse_funding_histories(self, contracts, market=None, since: Int = None, limit: Int = None) -> List[FundingHistory]:
2759
+ result = []
2760
+ for i in range(0, len(contracts)):
2761
+ contract = contracts[i]
2762
+ result.append(self.parse_funding_history(contract, market))
2763
+ sorted = self.sort_by(result, 'timestamp')
2764
+ return self.filter_by_since_limit(sorted, since, limit)
2765
+
2339
2766
  async def fetch_deposits_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
2340
2767
  """
2341
2768
  fetch history of deposits and withdrawals
2342
- :see: https://github.com/whitebit-exchange/api-docs/blob/main/pages/private/http-main-v4.md#get-depositwithdraw-history
2769
+
2770
+ https://github.com/whitebit-exchange/api-docs/blob/main/pages/private/http-main-v4.md#get-depositwithdraw-history
2771
+
2343
2772
  :param str [code]: unified currency code for the currency of the deposit/withdrawals, default is None
2344
2773
  :param int [since]: timestamp in ms of the earliest deposit/withdrawal, default is None
2345
2774
  :param int [limit]: max number of deposit/withdrawals to return, default = 50, Min: 1, Max: 100
2346
2775
  :param dict [params]: extra parameters specific to the exchange API endpoint
2347
- *
2348
- * EXCHANGE SPECIFIC PARAMETERS
2776
+
2777
+ EXCHANGE SPECIFIC PARAMETERS
2349
2778
  :param number [params.transactionMethod]: Method. Example: 1 to display deposits / 2 to display withdraws. Do not send self parameter in order to receive both deposits and withdraws.
2350
2779
  :param str [params.address]: Can be used for filtering transactions by specific address or memo.
2351
2780
  :param str[] [params.addresses]: Can be used for filtering transactions by specific addresses or memos(max: 20).
@@ -2404,12 +2833,428 @@ class whitebit(Exchange, ImplicitAPI):
2404
2833
  records = self.safe_list(response, 'records')
2405
2834
  return self.parse_transactions(records, currency, since, limit)
2406
2835
 
2407
- def is_fiat(self, currency):
2836
+ async def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
2837
+ """
2838
+ fetch a quote for converting from one currency to another
2839
+
2840
+ https://docs.whitebit.com/private/http-trade-v4/#convert-estimate
2841
+
2842
+ :param str fromCode: the currency that you want to sell and convert from
2843
+ :param str toCode: the currency that you want to buy and convert into
2844
+ :param float amount: how much you want to trade in units of the from currency
2845
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2846
+ :returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
2847
+ """
2848
+ await self.load_markets()
2849
+ fromCurrency = self.currency(fromCode)
2850
+ toCurrency = self.currency(toCode)
2851
+ request: dict = {
2852
+ 'from': fromCode,
2853
+ 'to': toCode,
2854
+ 'amount': self.number_to_string(amount),
2855
+ 'direction': 'from',
2856
+ }
2857
+ response = await self.v4PrivatePostConvertEstimate(self.extend(request, params))
2858
+ #
2859
+ # {
2860
+ # "give": "4",
2861
+ # "receive": "0.00004762",
2862
+ # "rate": "0.0000119",
2863
+ # "id": "1740889",
2864
+ # "expireAt": 1741090147,
2865
+ # "from": "USDT",
2866
+ # "to": "BTC"
2867
+ # }
2868
+ #
2869
+ return self.parse_conversion(response, fromCurrency, toCurrency)
2870
+
2871
+ async def create_convert_trade(self, id: str, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
2872
+ """
2873
+ convert from one currency to another
2874
+
2875
+ https://docs.whitebit.com/private/http-trade-v4/#convert-confirm
2876
+
2877
+ :param str id: the id of the trade that you want to make
2878
+ :param str fromCode: the currency that you want to sell and convert from
2879
+ :param str toCode: the currency that you want to buy and convert into
2880
+ :param float [amount]: how much you want to trade in units of the from currency
2881
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2882
+ :returns dict: a `conversion structure <https://docs.ccxt.com/#/?id=conversion-structure>`
2883
+ """
2884
+ await self.load_markets()
2885
+ fromCurrency = self.currency(fromCode)
2886
+ toCurrency = self.currency(toCode)
2887
+ request: dict = {
2888
+ 'quoteId': id,
2889
+ }
2890
+ response = await self.v4PrivatePostConvertConfirm(self.extend(request, params))
2891
+ #
2892
+ # {
2893
+ # "finalGive": "4",
2894
+ # "finalReceive": "0.00004772"
2895
+ # }
2896
+ #
2897
+ return self.parse_conversion(response, fromCurrency, toCurrency)
2898
+
2899
+ async def fetch_convert_trade_history(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Conversion]:
2900
+ """
2901
+ fetch the users history of conversion trades
2902
+
2903
+ https://docs.whitebit.com/private/http-trade-v4/#convert-history
2904
+
2905
+ :param str [code]: the unified currency code
2906
+ :param int [since]: the earliest time in ms to fetch conversions for
2907
+ :param int [limit]: the maximum number of conversion structures to retrieve, default 20, max 200
2908
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2909
+ :param str [params.until]: the end time in ms
2910
+ :param str [params.fromTicker]: the currency that you sold and converted from
2911
+ :param str [params.toTicker]: the currency that you bought and converted into
2912
+ :param str [params.quoteId]: the quote id of the conversion
2913
+ :returns dict[]: a list of `conversion structures <https://docs.ccxt.com/#/?id=conversion-structure>`
2914
+ """
2915
+ await self.load_markets()
2916
+ request: dict = {}
2917
+ if code is not None:
2918
+ request['fromTicker'] = code
2919
+ if since is not None:
2920
+ start = self.parse_to_int(since / 1000)
2921
+ request['from'] = self.number_to_string(start)
2922
+ if limit is not None:
2923
+ request['limit'] = limit
2924
+ request, params = self.handle_until_option('to', request, params, 0.001)
2925
+ response = await self.v4PrivatePostConvertHistory(self.extend(request, params))
2926
+ #
2927
+ # {
2928
+ # "records": [
2929
+ # {
2930
+ # "id": "1741105",
2931
+ # "path": [
2932
+ # {
2933
+ # "from": "USDT",
2934
+ # "to": "BTC",
2935
+ # "rate": "0.00001193"
2936
+ # }
2937
+ # ],
2938
+ # "date": 1741090757,
2939
+ # "give": "4",
2940
+ # "receive": "0.00004772",
2941
+ # "rate": "0.00001193"
2942
+ # }
2943
+ # ],
2944
+ # "total": 1,
2945
+ # "limit": 100,
2946
+ # "offset": 0
2947
+ # }
2948
+ #
2949
+ rows = self.safe_list(response, 'records', [])
2950
+ return self.parse_conversions(rows, code, 'fromCurrency', 'toCurrency', since, limit)
2951
+
2952
+ def parse_conversion(self, conversion: dict, fromCurrency: Currency = None, toCurrency: Currency = None) -> Conversion:
2953
+ #
2954
+ # fetchConvertQuote
2955
+ #
2956
+ # {
2957
+ # "give": "4",
2958
+ # "receive": "0.00004762",
2959
+ # "rate": "0.0000119",
2960
+ # "id": "1740889",
2961
+ # "expireAt": 1741090147,
2962
+ # "from": "USDT",
2963
+ # "to": "BTC"
2964
+ # }
2965
+ #
2966
+ # createConvertTrade
2967
+ #
2968
+ # {
2969
+ # "finalGive": "4",
2970
+ # "finalReceive": "0.00004772"
2971
+ # }
2972
+ #
2973
+ # fetchConvertTradeHistory
2974
+ #
2975
+ # {
2976
+ # "id": "1741105",
2977
+ # "path": [
2978
+ # {
2979
+ # "from": "USDT",
2980
+ # "to": "BTC",
2981
+ # "rate": "0.00001193"
2982
+ # }
2983
+ # ],
2984
+ # "date": 1741090757,
2985
+ # "give": "4",
2986
+ # "receive": "0.00004772",
2987
+ # "rate": "0.00001193"
2988
+ # }
2989
+ #
2990
+ path = self.safe_list(conversion, 'path', [])
2991
+ first = self.safe_dict(path, 0, {})
2992
+ fromPath = self.safe_string(first, 'from')
2993
+ toPath = self.safe_string(first, 'to')
2994
+ timestamp = self.safe_timestamp_2(conversion, 'date', 'expireAt')
2995
+ fromCoin = self.safe_string(conversion, 'from', fromPath)
2996
+ fromCode = self.safe_currency_code(fromCoin, fromCurrency)
2997
+ toCoin = self.safe_string(conversion, 'to', toPath)
2998
+ toCode = self.safe_currency_code(toCoin, toCurrency)
2999
+ return {
3000
+ 'info': conversion,
3001
+ 'timestamp': timestamp,
3002
+ 'datetime': self.iso8601(timestamp),
3003
+ 'id': self.safe_string(conversion, 'id'),
3004
+ 'fromCurrency': fromCode,
3005
+ 'fromAmount': self.safe_number_2(conversion, 'give', 'finalGive'),
3006
+ 'toCurrency': toCode,
3007
+ 'toAmount': self.safe_number_2(conversion, 'receive', 'finalReceive'),
3008
+ 'price': self.safe_number(conversion, 'rate'),
3009
+ 'fee': None,
3010
+ }
3011
+
3012
+ async def fetch_position_history(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Position]:
3013
+ """
3014
+ fetches historical positions
3015
+
3016
+ https://docs.whitebit.com/private/http-trade-v4/#positions-history
3017
+
3018
+ :param str symbol: unified contract symbol
3019
+ :param int [since]: the earliest time in ms to fetch positions for
3020
+ :param int [limit]: the maximum amount of records to fetch
3021
+ :param dict [params]: extra parameters specific to the exchange api endpoint
3022
+ :param int [params.positionId]: the id of the requested position
3023
+ :returns dict[]: a list of `position structures <https://docs.ccxt.com/#/?id=position-structure>`
3024
+ """
3025
+ await self.load_markets()
3026
+ market = self.market(symbol)
3027
+ request: dict = {
3028
+ 'market': market['id'],
3029
+ }
3030
+ if since is not None:
3031
+ request['startDate'] = since
3032
+ if limit is not None:
3033
+ request['limit'] = since
3034
+ request, params = self.handle_until_option('endDate', request, params)
3035
+ response = await self.v4PrivatePostCollateralAccountPositionsHistory(self.extend(request, params))
3036
+ #
3037
+ # [
3038
+ # {
3039
+ # "positionId": 479975679,
3040
+ # "market": "BTC_PERP",
3041
+ # "openDate": 1741941025.309887,
3042
+ # "modifyDate": 1741941025.309887,
3043
+ # "amount": "0.001",
3044
+ # "basePrice": "82498.7",
3045
+ # "realizedFunding": "0",
3046
+ # "liquidationPrice": "0",
3047
+ # "liquidationState": null,
3048
+ # "orderDetail": {
3049
+ # "id": 1224727949521,
3050
+ # "tradeAmount": "0.001",
3051
+ # "price": "82498.7",
3052
+ # "tradeFee": "0.028874545",
3053
+ # "fundingFee": "0",
3054
+ # "realizedPnl": "-0.028874545"
3055
+ # }
3056
+ # }
3057
+ # ]
3058
+ #
3059
+ positions = self.parse_positions(response)
3060
+ return self.filter_by_symbol_since_limit(positions, symbol, since, limit)
3061
+
3062
+ async def fetch_positions(self, symbols: Strings = None, params={}) -> List[Position]:
3063
+ """
3064
+ fetch all open positions
3065
+
3066
+ https://docs.whitebit.com/private/http-trade-v4/#open-positions
3067
+
3068
+ :param str[] [symbols]: list of unified market symbols
3069
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3070
+ :returns dict[]: a list of `position structures <https://docs.ccxt.com/#/?id=position-structure>`
3071
+ """
3072
+ await self.load_markets()
3073
+ symbols = self.market_symbols(symbols)
3074
+ response = await self.v4PrivatePostCollateralAccountPositionsOpen(params)
3075
+ #
3076
+ # [
3077
+ # {
3078
+ # "positionId": 479975679,
3079
+ # "market": "BTC_PERP",
3080
+ # "openDate": 1741941025.3098869,
3081
+ # "modifyDate": 1741941025.3098869,
3082
+ # "amount": "0.001",
3083
+ # "basePrice": "82498.7",
3084
+ # "liquidationPrice": "70177.2",
3085
+ # "pnl": "0",
3086
+ # "pnlPercent": "0.00",
3087
+ # "margin": "4.2",
3088
+ # "freeMargin": "9.9",
3089
+ # "funding": "0",
3090
+ # "unrealizedFunding": "0",
3091
+ # "liquidationState": null,
3092
+ # "tpsl": null
3093
+ # }
3094
+ # ]
3095
+ #
3096
+ return self.parse_positions(response, symbols)
3097
+
3098
+ async def fetch_position(self, symbol: str, params={}) -> Position:
3099
+ """
3100
+ fetch data on a single open contract trade position
3101
+
3102
+ https://docs.whitebit.com/private/http-trade-v4/#open-positions
3103
+
3104
+ :param str symbol: unified market symbol of the market the position is held in
3105
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3106
+ :returns dict: a `position structure <https://docs.ccxt.com/#/?id=position-structure>`
3107
+ """
3108
+ await self.load_markets()
3109
+ market = self.market(symbol)
3110
+ request: dict = {
3111
+ 'symbol': market['id'],
3112
+ }
3113
+ response = await self.v4PrivatePostCollateralAccountPositionsOpen(self.extend(request, params))
3114
+ #
3115
+ # [
3116
+ # {
3117
+ # "positionId": 479975679,
3118
+ # "market": "BTC_PERP",
3119
+ # "openDate": 1741941025.3098869,
3120
+ # "modifyDate": 1741941025.3098869,
3121
+ # "amount": "0.001",
3122
+ # "basePrice": "82498.7",
3123
+ # "liquidationPrice": "70177.2",
3124
+ # "pnl": "0",
3125
+ # "pnlPercent": "0.00",
3126
+ # "margin": "4.2",
3127
+ # "freeMargin": "9.9",
3128
+ # "funding": "0",
3129
+ # "unrealizedFunding": "0",
3130
+ # "liquidationState": null,
3131
+ # "tpsl": null
3132
+ # }
3133
+ # ]
3134
+ #
3135
+ data = self.safe_dict(response, 0, {})
3136
+ return self.parse_position(data, market)
3137
+
3138
+ def parse_position(self, position: dict, market: Market = None) -> Position:
3139
+ #
3140
+ # fetchPosition, fetchPositions
3141
+ #
3142
+ # {
3143
+ # "positionId": 479975679,
3144
+ # "market": "BTC_PERP",
3145
+ # "openDate": 1741941025.3098869,
3146
+ # "modifyDate": 1741941025.3098869,
3147
+ # "amount": "0.001",
3148
+ # "basePrice": "82498.7",
3149
+ # "liquidationPrice": "70177.2",
3150
+ # "pnl": "0",
3151
+ # "pnlPercent": "0.00",
3152
+ # "margin": "4.2",
3153
+ # "freeMargin": "9.9",
3154
+ # "funding": "0",
3155
+ # "unrealizedFunding": "0",
3156
+ # "liquidationState": null,
3157
+ # "tpsl": null
3158
+ # }
3159
+ #
3160
+ # fetchPositionHistory
3161
+ #
3162
+ # {
3163
+ # "positionId": 479975679,
3164
+ # "market": "BTC_PERP",
3165
+ # "openDate": 1741941025.309887,
3166
+ # "modifyDate": 1741941025.309887,
3167
+ # "amount": "0.001",
3168
+ # "basePrice": "82498.7",
3169
+ # "realizedFunding": "0",
3170
+ # "liquidationPrice": "0",
3171
+ # "liquidationState": null,
3172
+ # "orderDetail": {
3173
+ # "id": 1224727949521,
3174
+ # "tradeAmount": "0.001",
3175
+ # "price": "82498.7",
3176
+ # "tradeFee": "0.028874545",
3177
+ # "fundingFee": "0",
3178
+ # "realizedPnl": "-0.028874545"
3179
+ # }
3180
+ # }
3181
+ #
3182
+ marketId = self.safe_string(position, 'market')
3183
+ timestamp = self.safe_timestamp(position, 'openDate')
3184
+ tpsl = self.safe_dict(position, 'tpsl', {})
3185
+ orderDetail = self.safe_dict(position, 'orderDetail', {})
3186
+ return self.safe_position({
3187
+ 'info': position,
3188
+ 'id': self.safe_string(position, 'positionId'),
3189
+ 'symbol': self.safe_symbol(marketId, market),
3190
+ 'notional': None,
3191
+ 'marginMode': None,
3192
+ 'liquidationPrice': self.safe_number(position, 'liquidationPrice'),
3193
+ 'entryPrice': self.safe_number(position, 'basePrice'),
3194
+ 'unrealizedPnl': self.safe_number(position, 'pnl'),
3195
+ 'realizedPnl': self.safe_number(orderDetail, 'realizedPnl'),
3196
+ 'percentage': self.safe_number(position, 'pnlPercent'),
3197
+ 'contracts': None,
3198
+ 'contractSize': None,
3199
+ 'markPrice': None,
3200
+ 'lastPrice': None,
3201
+ 'side': None,
3202
+ 'hedged': None,
3203
+ 'timestamp': timestamp,
3204
+ 'datetime': self.iso8601(timestamp),
3205
+ 'lastUpdateTimestamp': self.safe_timestamp(position, 'modifyDate'),
3206
+ 'maintenanceMargin': None,
3207
+ 'maintenanceMarginPercentage': None,
3208
+ 'collateral': self.safe_number(position, 'margin'),
3209
+ 'initialMargin': None,
3210
+ 'initialMarginPercentage': None,
3211
+ 'leverage': None,
3212
+ 'marginRatio': None,
3213
+ 'stopLossPrice': self.safe_number(tpsl, 'stopLoss'),
3214
+ 'takeProfitPrice': self.safe_number(tpsl, 'takeProfit'),
3215
+ })
3216
+
3217
+ async def fetch_cross_borrow_rate(self, code: str, params={}) -> CrossBorrowRate:
3218
+ """
3219
+ fetch the rate of interest to borrow a currency for margin trading
3220
+
3221
+ https://docs.whitebit.com/private/http-main-v4/#get-plans
3222
+
3223
+ :param str code: unified currency code
3224
+ :param dict [params]: extra parameters specific to the exchange API endpoint
3225
+ :returns dict: a `borrow rate structure <https://docs.ccxt.com/#/?id=borrow-rate-structure>`
3226
+ """
3227
+ await self.load_markets()
3228
+ currency = self.currency(code)
3229
+ request: dict = {
3230
+ 'ticker': currency['id'],
3231
+ }
3232
+ response = await self.v4PrivatePostMainAccountSmartPlans(self.extend(request, params))
3233
+ #
3234
+ #
3235
+ data = self.safe_list(response, 0, [])
3236
+ return self.parse_borrow_rate(data, currency)
3237
+
3238
+ def parse_borrow_rate(self, info, currency: Currency = None):
3239
+ #
3240
+ #
3241
+ currencyId = self.safe_string(info, 'ticker')
3242
+ percent = self.safe_string(info, 'percent')
3243
+ return {
3244
+ 'currency': self.safe_currency_code(currencyId, currency),
3245
+ 'rate': self.parse_number(Precise.string_div(percent, '100')),
3246
+ 'period': self.safe_integer(info, 'duration'),
3247
+ 'timestamp': None,
3248
+ 'datetime': None,
3249
+ 'info': info,
3250
+ }
3251
+
3252
+ def is_fiat(self, currency: str) -> bool:
2408
3253
  fiatCurrencies = self.safe_value(self.options, 'fiatCurrencies', [])
2409
3254
  return self.in_array(currency, fiatCurrencies)
2410
3255
 
2411
3256
  def nonce(self):
2412
- return self.milliseconds()
3257
+ return self.milliseconds() - self.options['timeDifference']
2413
3258
 
2414
3259
  def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
2415
3260
  query = self.omit(params, self.extract_params(path))
@@ -2445,21 +3290,24 @@ class whitebit(Exchange, ImplicitAPI):
2445
3290
  # For cases where we have a meaningful status
2446
3291
  # {"response":null,"status":422,"errors":{"orderId":["Finished order id 435453454535 not found on your account"]},"notification":null,"warning":"Finished order id 435453454535 not found on your account","_token":null}
2447
3292
  status = self.safe_string(response, 'status')
3293
+ errors = self.safe_value(response, 'errors')
2448
3294
  # {"code":10,"message":"Unauthorized request."}
2449
3295
  message = self.safe_string(response, 'message')
2450
3296
  # For these cases where we have a generic code variable error key
2451
3297
  # {"code":0,"message":"Validation failed","errors":{"amount":["Amount must be greater than 0"]}}
2452
3298
  codeNew = self.safe_integer(response, 'code')
2453
- hasErrorStatus = status is not None and status != '200'
3299
+ hasErrorStatus = status is not None and status != '200' and errors is not None
2454
3300
  if hasErrorStatus or codeNew is not None:
2455
3301
  feedback = self.id + ' ' + body
2456
3302
  errorInfo = message
2457
3303
  if hasErrorStatus:
2458
3304
  errorInfo = status
2459
3305
  else:
2460
- errorObject = self.safe_value(response, 'errors')
2461
- if errorObject is not None:
2462
- errorKey = list(errorObject.keys())[0]
3306
+ errorObject = self.safe_dict(response, 'errors', {})
3307
+ errorKeys = list(errorObject.keys())
3308
+ errorsLength = len(errorKeys)
3309
+ if errorsLength > 0:
3310
+ errorKey = errorKeys[0]
2463
3311
  errorMessageArray = self.safe_value(errorObject, errorKey, [])
2464
3312
  errorMessageLength = len(errorMessageArray)
2465
3313
  errorInfo = errorMessageArray[0] if (errorMessageLength > 0) else body