ccxt-ir 4.3.46.0.3__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 (529) hide show
  1. ccxt/__init__.py +39 -35
  2. ccxt/abantether.py +8 -8
  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 +8 -8
  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.3.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.3.dist-info → ccxt_ir-4.5.0.dist-info}/WHEEL +1 -1
  437. ccxt/__test__.py +0 -7
  438. ccxt/abstract/ace.py +0 -15
  439. ccxt/abstract/bitbay.py +0 -53
  440. ccxt/abstract/bitcoincom.py +0 -115
  441. ccxt/abstract/bitfinex2.py +0 -139
  442. ccxt/abstract/bitpanda.py +0 -35
  443. ccxt/abstract/bl3p.py +0 -19
  444. ccxt/abstract/coinlist.py +0 -54
  445. ccxt/abstract/currencycom.py +0 -68
  446. ccxt/abstract/hitbtc3.py +0 -115
  447. ccxt/abstract/idex.py +0 -26
  448. ccxt/abstract/kuna.py +0 -182
  449. ccxt/abstract/lykke.py +0 -29
  450. ccxt/abstract/poloniexfutures.py +0 -48
  451. ccxt/abstract/wazirx.py +0 -30
  452. ccxt/ace.py +0 -1012
  453. ccxt/async_support/ace.py +0 -1012
  454. ccxt/async_support/base/ws/aiohttp_client.py +0 -125
  455. ccxt/async_support/base/ws/fast_client.py +0 -96
  456. ccxt/async_support/bitbay.py +0 -17
  457. ccxt/async_support/bitcoincom.py +0 -17
  458. ccxt/async_support/bitfinex2.py +0 -3552
  459. ccxt/async_support/bitpanda.py +0 -16
  460. ccxt/async_support/bl3p.py +0 -485
  461. ccxt/async_support/coinlist.py +0 -2243
  462. ccxt/async_support/currencycom.py +0 -1950
  463. ccxt/async_support/hitbtc3.py +0 -16
  464. ccxt/async_support/idex.py +0 -1766
  465. ccxt/async_support/kuna.py +0 -1841
  466. ccxt/async_support/lykke.py +0 -1270
  467. ccxt/async_support/poloniexfutures.py +0 -1717
  468. ccxt/async_support/wazirx.py +0 -1224
  469. ccxt/bitbay.py +0 -17
  470. ccxt/bitcoincom.py +0 -17
  471. ccxt/bitfinex2.py +0 -3552
  472. ccxt/bitpanda.py +0 -16
  473. ccxt/bl3p.py +0 -485
  474. ccxt/coinlist.py +0 -2243
  475. ccxt/currencycom.py +0 -1950
  476. ccxt/hitbtc3.py +0 -16
  477. ccxt/idex.py +0 -1766
  478. ccxt/kuna.py +0 -1841
  479. ccxt/lykke.py +0 -1270
  480. ccxt/poloniexfutures.py +0 -1717
  481. ccxt/pro/bitcoincom.py +0 -34
  482. ccxt/pro/bitfinex2.py +0 -1083
  483. ccxt/pro/bitpanda.py +0 -15
  484. ccxt/pro/currencycom.py +0 -536
  485. ccxt/pro/idex.py +0 -672
  486. ccxt/pro/poloniexfutures.py +0 -990
  487. ccxt/pro/wazirx.py +0 -749
  488. ccxt/test/base/__init__.py +0 -29
  489. ccxt/test/base/test_account.py +0 -26
  490. ccxt/test/base/test_balance.py +0 -56
  491. ccxt/test/base/test_borrow_interest.py +0 -35
  492. ccxt/test/base/test_borrow_rate.py +0 -32
  493. ccxt/test/base/test_calculate_fee.py +0 -51
  494. ccxt/test/base/test_crypto.py +0 -127
  495. ccxt/test/base/test_currency.py +0 -76
  496. ccxt/test/base/test_datetime.py +0 -109
  497. ccxt/test/base/test_decimal_to_precision.py +0 -392
  498. ccxt/test/base/test_deep_extend.py +0 -68
  499. ccxt/test/base/test_deposit_withdrawal.py +0 -50
  500. ccxt/test/base/test_exchange_datetime_functions.py +0 -76
  501. ccxt/test/base/test_funding_rate_history.py +0 -29
  502. ccxt/test/base/test_last_price.py +0 -31
  503. ccxt/test/base/test_ledger_entry.py +0 -45
  504. ccxt/test/base/test_ledger_item.py +0 -48
  505. ccxt/test/base/test_leverage_tier.py +0 -33
  506. ccxt/test/base/test_liquidation.py +0 -50
  507. ccxt/test/base/test_margin_mode.py +0 -24
  508. ccxt/test/base/test_margin_modification.py +0 -35
  509. ccxt/test/base/test_market.py +0 -193
  510. ccxt/test/base/test_number.py +0 -411
  511. ccxt/test/base/test_ohlcv.py +0 -33
  512. ccxt/test/base/test_open_interest.py +0 -32
  513. ccxt/test/base/test_order.py +0 -64
  514. ccxt/test/base/test_order_book.py +0 -69
  515. ccxt/test/base/test_position.py +0 -60
  516. ccxt/test/base/test_shared_methods.py +0 -353
  517. ccxt/test/base/test_status.py +0 -24
  518. ccxt/test/base/test_throttle.py +0 -126
  519. ccxt/test/base/test_ticker.py +0 -92
  520. ccxt/test/base/test_trade.py +0 -47
  521. ccxt/test/base/test_trading_fee.py +0 -26
  522. ccxt/test/base/test_transaction.py +0 -39
  523. ccxt/test/test_async.py +0 -1649
  524. ccxt/test/test_sync.py +0 -1648
  525. ccxt/wazirx.py +0 -1224
  526. ccxt_ir-4.3.46.0.3.dist-info/RECORD +0 -773
  527. /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
  528. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.0.dist-info/licenses}/LICENSE.txt +0 -0
  529. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.0.dist-info}/top_level.txt +0 -0
ccxt/apex.py ADDED
@@ -0,0 +1,1875 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
+ # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
+
6
+ from ccxt.base.exchange import Exchange
7
+ from ccxt.abstract.apex import ImplicitAPI
8
+ import hashlib
9
+ import math
10
+ from ccxt.base.types import Account, Any, Balances, Currencies, Currency, Int, Market, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, MarketInterface, TransferEntry
11
+ from typing import List
12
+ from ccxt.base.errors import ExchangeError
13
+ from ccxt.base.errors import ArgumentsRequired
14
+ from ccxt.base.errors import BadRequest
15
+ from ccxt.base.errors import InvalidOrder
16
+ from ccxt.base.errors import RateLimitExceeded
17
+ from ccxt.base.decimal_to_precision import TRUNCATE
18
+ from ccxt.base.decimal_to_precision import TICK_SIZE
19
+ from ccxt.base.precise import Precise
20
+
21
+
22
+ class apex(Exchange, ImplicitAPI):
23
+
24
+ def describe(self) -> Any:
25
+ return self.deep_extend(super(apex, self).describe(), {
26
+ 'id': 'apex',
27
+ 'name': 'Apex',
28
+ 'countries': [],
29
+ 'version': 'v3',
30
+ 'rateLimit': 20, # 600 requests per minute, 10 request per second
31
+ 'certified': False,
32
+ 'pro': True,
33
+ 'dex': True,
34
+ 'has': {
35
+ 'CORS': None,
36
+ 'spot': False,
37
+ 'margin': False,
38
+ 'swap': True,
39
+ 'future': False,
40
+ 'option': False,
41
+ 'addMargin': False,
42
+ 'borrowCrossMargin': False,
43
+ 'borrowIsolatedMargin': False,
44
+ 'cancelAllOrders': True,
45
+ 'cancelAllOrdersAfter': False,
46
+ 'cancelOrder': True,
47
+ 'cancelOrders': False,
48
+ 'cancelOrdersForSymbols': False,
49
+ 'closeAllPositions': False,
50
+ 'closePosition': False,
51
+ 'createMarketBuyOrderWithCost': False,
52
+ 'createMarketOrderWithCost': False,
53
+ 'createMarketSellOrderWithCost': False,
54
+ 'createOrder': True,
55
+ 'createOrders': False,
56
+ 'createPostOnlyOrder': True,
57
+ 'createReduceOnlyOrder': True,
58
+ 'createStopOrder': True,
59
+ 'createTriggerOrder': True,
60
+ 'editOrder': False,
61
+ 'fetchAccounts': True,
62
+ 'fetchBalance': True,
63
+ 'fetchBorrowInterest': False,
64
+ 'fetchBorrowRateHistories': False,
65
+ 'fetchBorrowRateHistory': False,
66
+ 'fetchCanceledAndClosedOrders': False,
67
+ 'fetchCanceledOrders': False,
68
+ 'fetchClosedOrders': False,
69
+ 'fetchCrossBorrowRate': False,
70
+ 'fetchCrossBorrowRates': False,
71
+ 'fetchCurrencies': True,
72
+ 'fetchDepositAddress': False,
73
+ 'fetchDepositAddresses': False,
74
+ 'fetchDeposits': False,
75
+ 'fetchDepositWithdrawFee': False,
76
+ 'fetchDepositWithdrawFees': False,
77
+ 'fetchFundingHistory': True,
78
+ 'fetchFundingRate': False,
79
+ 'fetchFundingRateHistory': True,
80
+ 'fetchFundingRates': False,
81
+ 'fetchIndexOHLCV': False,
82
+ 'fetchIsolatedBorrowRate': False,
83
+ 'fetchIsolatedBorrowRates': False,
84
+ 'fetchLedger': False,
85
+ 'fetchLeverage': False,
86
+ 'fetchLeverageTiers': False,
87
+ 'fetchLiquidations': False,
88
+ 'fetchMarginMode': False,
89
+ 'fetchMarketLeverageTiers': False,
90
+ 'fetchMarkets': True,
91
+ 'fetchMarkOHLCV': False,
92
+ 'fetchMyLiquidations': False,
93
+ 'fetchMyTrades': True,
94
+ 'fetchOHLCV': True,
95
+ 'fetchOpenInterest': True,
96
+ 'fetchOpenInterestHistory': False,
97
+ 'fetchOpenInterests': False,
98
+ 'fetchOpenOrders': True,
99
+ 'fetchOrder': True,
100
+ 'fetchOrderBook': True,
101
+ 'fetchOrders': True,
102
+ 'fetchOrderTrades': True,
103
+ 'fetchPosition': False,
104
+ 'fetchPositionMode': False,
105
+ 'fetchPositions': True,
106
+ 'fetchPositionsRisk': False,
107
+ 'fetchPremiumIndexOHLCV': False,
108
+ 'fetchTicker': True,
109
+ 'fetchTickers': True,
110
+ 'fetchTime': True,
111
+ 'fetchTrades': True,
112
+ 'fetchTradingFee': False,
113
+ 'fetchTradingFees': False,
114
+ 'fetchTransfer': True,
115
+ 'fetchTransfers': True,
116
+ 'fetchWithdrawal': False,
117
+ 'fetchWithdrawals': False,
118
+ 'reduceMargin': False,
119
+ 'repayCrossMargin': False,
120
+ 'repayIsolatedMargin': False,
121
+ 'sandbox': True,
122
+ 'setLeverage': True,
123
+ 'setMarginMode': False,
124
+ 'setPositionMode': False,
125
+ 'transfer': False,
126
+ 'withdraw': False,
127
+ },
128
+ 'timeframes': {
129
+ '1m': '1',
130
+ '5m': '5',
131
+ '15m': '15',
132
+ '30m': '30',
133
+ '1h': '60',
134
+ '2h': '120',
135
+ '4h': '240',
136
+ '6h': '360',
137
+ '12h': '720',
138
+ '1d': 'D',
139
+ '1w': 'W',
140
+ '1M': 'M',
141
+ },
142
+ 'hostname': 'omni.apex.exchange',
143
+ 'urls': {
144
+ 'logo': 'https://github.com/user-attachments/assets/fef8f2f7-4265-46aa-965e-33a91881cb00',
145
+ 'api': {
146
+ 'public': 'https://{hostname}/api',
147
+ 'private': 'https://{hostname}/api',
148
+ },
149
+ 'test': {
150
+ 'public': 'https://testnet.omni.apex.exchange/api',
151
+ 'private': 'https://testnet.omni.apex.exchange/api',
152
+ },
153
+ 'www': 'https://apex.exchange/',
154
+ 'doc': 'https://api-docs.pro.apex.exchange',
155
+ 'fees': 'https://apex-pro.gitbook.io/apex-pro/apex-omni-live-now/trading-perpetual-contracts/trading-fees',
156
+ 'referral': 'https://omni.apex.exchange/trade',
157
+ },
158
+ 'api': {
159
+ 'public': {
160
+ 'get': {
161
+ 'v3/symbols': 1,
162
+ 'v3/history-funding': 1,
163
+ 'v3/ticker': 1,
164
+ 'v3/klines': 1,
165
+ 'v3/trades': 1,
166
+ 'v3/depth': 1,
167
+ 'v3/time': 1,
168
+ 'v3/data/all-ticker-info': 1,
169
+ },
170
+ },
171
+ 'private': {
172
+ 'get': {
173
+ 'v3/account': 1,
174
+ 'v3/account-balance': 1,
175
+ 'v3/fills': 1,
176
+ 'v3/order-fills': 1,
177
+ 'v3/order': 1,
178
+ 'v3/history-orders': 1,
179
+ 'v3/order-by-client-order-id': 1,
180
+ 'v3/funding': 1,
181
+ 'v3/historical-pnl': 1,
182
+ 'v3/open-orders': 1,
183
+ 'v3/transfers': 1,
184
+ 'v3/transfer': 1,
185
+ },
186
+ 'post': {
187
+ 'v3/delete-open-orders': 1,
188
+ 'v3/delete-client-order-id': 1,
189
+ 'v3/delete-order': 1,
190
+ 'v3/order': 1,
191
+ 'v3/set-initial-margin-rate': 1,
192
+ 'v3/transfer-out': 1,
193
+ 'v3/contract-transfer-out': 1,
194
+ },
195
+ },
196
+ },
197
+ 'httpExceptions': {
198
+ '403': RateLimitExceeded, # Forbidden -- You request too many times
199
+ },
200
+ 'exceptions': {
201
+ # Uncodumented explanation of error strings:
202
+ # - oc_diff: order cost needed to place self order
203
+ # - new_oc: total order cost of open orders including the order you are trying to open
204
+ # - ob: order balance - the total cost of current open orders
205
+ # - ab: available balance
206
+ 'exact': {
207
+ '20006': 'apikey sign error', # apikey sign error
208
+ '20016': 'request para error', # apikey sign error
209
+ '10001': BadRequest,
210
+ },
211
+ 'broad': {
212
+ 'ORDER_PRICE_MUST_GREETER_ZERO': InvalidOrder,
213
+ 'ORDER_POSSIBLE_LEAD_TO_ACCOUNT_LIQUIDATED': InvalidOrder,
214
+ 'ORDER_WITH_THIS_PRICE_CANNOT_REDUCE_POSITION_ONLY': InvalidOrder,
215
+ },
216
+ },
217
+ 'fees': {
218
+ 'swap': {
219
+ 'taker': self.parse_number('0.0005'),
220
+ 'maker': self.parse_number('0.0002'),
221
+ },
222
+ },
223
+ 'requiredCredentials': {
224
+ 'apiKey': True,
225
+ 'secret': True,
226
+ 'walletAddress': False,
227
+ 'privateKey': False,
228
+ 'password': True,
229
+ },
230
+ 'precisionMode': TICK_SIZE,
231
+ 'commonCurrencies': {},
232
+ 'options': {
233
+ 'defaultType': 'swap',
234
+ 'defaultSlippage': 0.05,
235
+ 'brokerId': '6956',
236
+ },
237
+ 'features': {
238
+ 'default': {
239
+ 'sandbox': True,
240
+ 'createOrder': {
241
+ 'marginMode': False,
242
+ 'triggerPrice': True,
243
+ 'triggerPriceType': None,
244
+ 'triggerDirection': False,
245
+ 'stopLossPrice': False, # todo
246
+ 'takeProfitPrice': False, # todo
247
+ 'attachedStopLossTakeProfit': None,
248
+ 'timeInForce': {
249
+ 'IOC': True,
250
+ 'FOK': True,
251
+ 'PO': True,
252
+ 'GTD': True,
253
+ },
254
+ 'hedged': False,
255
+ 'selfTradePrevention': False,
256
+ 'trailing': True, # todo unify
257
+ 'leverage': False,
258
+ 'marketBuyByCost': False,
259
+ 'marketBuyRequiresPrice': False,
260
+ 'iceberg': False,
261
+ },
262
+ 'createOrders': None,
263
+ 'fetchMyTrades': {
264
+ 'marginMode': False,
265
+ 'limit': 500,
266
+ 'daysBack': 100000,
267
+ 'untilDays': 100000,
268
+ 'symbolRequired': False,
269
+ },
270
+ 'fetchOrder': {
271
+ 'marginMode': False,
272
+ 'trigger': False,
273
+ 'trailing': False,
274
+ 'symbolRequired': False,
275
+ },
276
+ 'fetchOpenOrders': {
277
+ 'marginMode': False,
278
+ 'limit': None,
279
+ 'trigger': False,
280
+ 'trailing': False,
281
+ 'symbolRequired': False,
282
+ },
283
+ 'fetchOrders': {
284
+ 'marginMode': False,
285
+ 'limit': 100,
286
+ 'daysBack': 100000,
287
+ 'untilDays': 100000,
288
+ 'trigger': False,
289
+ 'trailing': False,
290
+ 'symbolRequired': False,
291
+ },
292
+ 'fetchClosedOrders': None,
293
+ 'fetchOHLCV': {
294
+ 'limit': 200,
295
+ },
296
+ },
297
+ 'swap': {
298
+ 'linear': {
299
+ 'extends': 'default',
300
+ },
301
+ 'inverse': None,
302
+ },
303
+ },
304
+ })
305
+
306
+ def fetch_time(self, params={}):
307
+ """
308
+ fetches the current integer timestamp in milliseconds from the exchange server
309
+
310
+ https://api-docs.pro.apex.exchange/#publicapi-v3-for-omni-get-system-time-v3
311
+
312
+ :param dict [params]: extra parameters specific to the exchange API endpoint
313
+ :returns int: the current integer timestamp in milliseconds from the exchange server
314
+ """
315
+ response = self.publicGetV3Time(params)
316
+ data = self.safe_dict(response, 'data', {})
317
+ #
318
+ # {
319
+ # "data": {
320
+ # "time": 1738837534454
321
+ # }
322
+ # }
323
+ return self.safe_integer(data, 'time')
324
+
325
+ def parse_balance(self, response) -> Balances:
326
+ #
327
+ # {
328
+ # "totalEquityValue": "100.000000",
329
+ # "availableBalance": "100.000000",
330
+ # "initialMargin": "100.000000",
331
+ # "maintenanceMargin": "100.000000",
332
+ # "symbolToOraclePrice": {
333
+ # "BTC-USDC": {
334
+ # "oraclePrice": "20000",
335
+ # "createdTime": 124566
336
+ # }
337
+ # }
338
+ # }
339
+ #
340
+ timestamp = self.milliseconds()
341
+ result: dict = {
342
+ 'info': response,
343
+ 'timestamp': timestamp,
344
+ 'datetime': self.iso8601(timestamp),
345
+ }
346
+ code = 'USDT'
347
+ account = self.account()
348
+ account['free'] = self.safe_string(response, 'availableBalance')
349
+ account['total'] = self.safe_string(response, 'totalEquityValue')
350
+ result[code] = account
351
+ return self.safe_balance(result)
352
+
353
+ def fetch_balance(self, params={}) -> Balances:
354
+ """
355
+ query for account info
356
+
357
+ https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-get-retrieve-user-account-balance
358
+
359
+ :param dict [params]: extra parameters specific to the exchange API endpoint
360
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
361
+ """
362
+ self.load_markets()
363
+ response = self.privateGetV3AccountBalance(params)
364
+ data = self.safe_dict(response, 'data', {})
365
+ return self.parse_balance(data)
366
+
367
+ def parse_account(self, account: dict) -> Account:
368
+ accountId = self.safe_string(account, 'id', '0')
369
+ return {
370
+ 'id': accountId,
371
+ 'type': None,
372
+ 'code': None,
373
+ 'info': account,
374
+ }
375
+
376
+ def fetch_account(self, params={}) -> Account:
377
+ """
378
+ query for balance and get the amount of funds available for trading or funds locked in orders
379
+
380
+ https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-get-retrieve-user-account-data
381
+
382
+ :param dict [params]: extra parameters specific to the exchange API endpoint
383
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
384
+ """
385
+ self.load_markets()
386
+ response = self.privateGetV3Account(params)
387
+ data = self.safe_dict(response, 'data', {})
388
+ return self.parse_account(data)
389
+
390
+ def fetch_currencies(self, params={}) -> Currencies:
391
+ """
392
+ fetches all available currencies on an exchange
393
+
394
+ https://api-docs.pro.apex.exchange/#publicapi-v3-for-omni-get-all-config-data-v3
395
+
396
+ :param dict [params]: extra parameters specific to the exchange API endpoint
397
+ :returns dict: an associative dictionary of currencies
398
+ """
399
+ response = self.publicGetV3Symbols(params)
400
+ data = self.safe_dict(response, 'data', {})
401
+ spotConfig = self.safe_dict(data, 'spotConfig', {})
402
+ multiChain = self.safe_dict(spotConfig, 'multiChain', {})
403
+ # "spotConfig": {
404
+ # "assets": [
405
+ # {
406
+ # "tokenId": "141",
407
+ # "token": "USDT",
408
+ # "displayName": "Tether USD Coin",
409
+ # "decimals": 18,
410
+ # "showStep": "0.01",
411
+ # "iconUrl": "https://static-pro.apex.exchange/chains/chain_tokens/Ethereum/Ethereum_USDT.svg",
412
+ # "l2WithdrawFee": "0",
413
+ # "enableCollateral": True,
414
+ # "enableCrossCollateral": False,
415
+ # "crossCollateralDiscountRate": null,
416
+ # "isGray": False
417
+ # }
418
+ # ],
419
+ # "multiChain": {
420
+ # "chains": [
421
+ # {
422
+ # "chain": "Arbitrum One",
423
+ # "chainId": "9",
424
+ # "chainType": "0",
425
+ # "l1ChainId": "42161",
426
+ # "chainIconUrl": "https://static-pro.apex.exchange/chains/chain_logos/Arbitrum.svg",
427
+ # "contractAddress": "0x3169844a120c0f517b4eb4a750c08d8518c8466a",
428
+ # "swapContractAddress": "0x9e07b6Aef1bbD9E513fc2Eb8873e311E80B4f855",
429
+ # "stopDeposit": False,
430
+ # "feeLess": False,
431
+ # "gasLess": False,
432
+ # "gasToken": "ETH",
433
+ # "dynamicFee": True,
434
+ # "gasTokenDecimals": 18,
435
+ # "feeGasLimit": 300000,
436
+ # "blockTimeSeconds": 2,
437
+ # "rpcUrl": "https://arb.pro.apex.exchange",
438
+ # "minSwapUsdtAmount": "",
439
+ # "maxSwapUsdtAmount": "",
440
+ # "webRpcUrl": "https://arb.pro.apex.exchange",
441
+ # "webTxUrl": "https://arbiscan.io/tx/",
442
+ # "backupRpcUrl": "https://arb-mainnet.g.alchemy.com/v2/rGlYUbRHtUav5mfeThCPtsV9GLPt2Xq5",
443
+ # "txConfirm": 20,
444
+ # "withdrawGasFeeLess": False,
445
+ # "tokens": [
446
+ # {
447
+ # "decimals": 6,
448
+ # "iconUrl": "https://static-pro.apex.exchange/chains/chain_tokens/Arbitrum/Arbitrum_USDT.svg",
449
+ # "token": "USDT",
450
+ # "tokenAddress": "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9",
451
+ # "pullOff": False,
452
+ # "withdrawEnable": True,
453
+ # "slippage": "",
454
+ # "isDefaultToken": False,
455
+ # "displayToken": "USDT",
456
+ # "needResetApproval": True,
457
+ # "minFee": "2",
458
+ # "maxFee": "40",
459
+ # "feeRate": "0.0001",
460
+ # "maxWithdraw": "",
461
+ # "minDeposit": "",
462
+ # "minWithdraw": "",
463
+ # "maxFastWithdrawAmount": "40000",
464
+ # "minFastWithdrawAmount": "1",
465
+ # "isGray": False
466
+ # },
467
+ # {
468
+ # "decimals": 6,
469
+ # "iconUrl": "https://static-pro.apex.exchange/chains/chain_tokens/Arbitrum/Arbitrum_USDC.svg",
470
+ # "token": "USDC",
471
+ # "tokenAddress": "0xaf88d065e77c8cc2239327c5edb3a432268e5831",
472
+ # "pullOff": False,
473
+ # "withdrawEnable": True,
474
+ # "slippage": "",
475
+ # "isDefaultToken": False,
476
+ # "displayToken": "USDC",
477
+ # "needResetApproval": True,
478
+ # "minFee": "2",
479
+ # "maxFee": "20",
480
+ # "feeRate": "0.0001",
481
+ # "maxWithdraw": "",
482
+ # "minDeposit": "",
483
+ # "minWithdraw": "",
484
+ # "maxFastWithdrawAmount": "1",
485
+ # "minFastWithdrawAmount": "1",
486
+ # "isGray": False
487
+ # }
488
+ # ]
489
+ # }
490
+ # ]
491
+ # }
492
+ rows = self.safe_list(spotConfig, 'assets', [])
493
+ chains = self.safe_list(multiChain, 'chains', [])
494
+ result: dict = {}
495
+ for i in range(0, len(rows)):
496
+ currency = rows[i]
497
+ currencyId = self.safe_string(currency, 'token')
498
+ code = self.safe_currency_code(currencyId)
499
+ name = self.safe_string(currency, 'displayName')
500
+ networks: dict = {}
501
+ for j in range(0, len(chains)):
502
+ chain = chains[j]
503
+ tokens = self.safe_list(chain, 'tokens', [])
504
+ for f in range(0, len(tokens)):
505
+ token = tokens[f]
506
+ tokenName = self.safe_string(token, 'token')
507
+ if tokenName == currencyId:
508
+ networkId = self.safe_string(chain, 'chainId')
509
+ networkCode = self.network_id_to_code(networkId)
510
+ networks[networkCode] = {
511
+ 'info': chain,
512
+ 'id': networkId,
513
+ 'network': networkCode,
514
+ 'active': None,
515
+ 'deposit': not self.safe_bool(chain, 'depositDisable'),
516
+ 'withdraw': self.safe_bool(token, 'withdrawEnable'),
517
+ 'fee': self.safe_number(token, 'minFee'),
518
+ 'precision': self.parse_number(self.parse_precision(self.safe_string(token, 'decimals'))),
519
+ 'limits': {
520
+ 'withdraw': {
521
+ 'min': self.safe_number(token, 'minWithdraw'),
522
+ 'max': None,
523
+ },
524
+ 'deposit': {
525
+ 'min': self.safe_number(chain, 'minDeposit'),
526
+ 'max': None,
527
+ },
528
+ },
529
+ }
530
+ networkKeys = list(networks.keys())
531
+ networksLength = len(networkKeys)
532
+ emptyChains = networksLength == 0 # non-functional coins
533
+ valueForEmpty = False if emptyChains else None
534
+ result[code] = self.safe_currency_structure({
535
+ 'info': currency,
536
+ 'code': code,
537
+ 'id': currencyId,
538
+ 'type': 'crypto',
539
+ 'name': name,
540
+ 'active': None,
541
+ 'deposit': valueForEmpty,
542
+ 'withdraw': valueForEmpty,
543
+ 'fee': None,
544
+ 'precision': None,
545
+ 'limits': {
546
+ 'amount': {
547
+ 'min': None,
548
+ 'max': None,
549
+ },
550
+ 'withdraw': {
551
+ 'min': None,
552
+ 'max': None,
553
+ },
554
+ 'deposit': {
555
+ 'min': None,
556
+ 'max': None,
557
+ },
558
+ },
559
+ 'networks': networks,
560
+ })
561
+ return result
562
+
563
+ def fetch_markets(self, params={}) -> List[Market]:
564
+ """
565
+ retrieves data on all markets for apex
566
+
567
+ https://api-docs.pro.apex.exchange/#publicapi-v3-for-omni-get-all-config-data-v3
568
+
569
+ :param dict [params]: extra parameters specific to the exchange API endpoint
570
+ :returns dict[]: an array of objects representing market data
571
+ """
572
+ response = self.publicGetV3Symbols(params)
573
+ data = self.safe_dict(response, 'data', {})
574
+ contractConfig = self.safe_dict(data, 'contractConfig', {})
575
+ perpetualContract = self.safe_list(contractConfig, 'perpetualContract', [])
576
+ # {
577
+ # "perpetualContract":[
578
+ # {
579
+ # "baselinePositionValue": "50000.0000",
580
+ # "crossId": 30002,
581
+ # "crossSymbolId": 10,
582
+ # "crossSymbolName": "BTCUSDT",
583
+ # "digitMerge": "0.1,0.2,0.4,1,2",
584
+ # "displayMaxLeverage": "100",
585
+ # "displayMinLeverage": "1",
586
+ # "enableDisplay": True,
587
+ # "enableOpenPosition": True,
588
+ # "enableTrade": True,
589
+ # "fundingImpactMarginNotional": "6",
590
+ # "fundingInterestRate": "0.0003",
591
+ # "incrementalInitialMarginRate": "0.00250",
592
+ # "incrementalMaintenanceMarginRate": "0.00100",
593
+ # "incrementalPositionValue": "50000.0000",
594
+ # "initialMarginRate": "0.01",
595
+ # "maintenanceMarginRate": "0.005",
596
+ # "maxOrderSize": "50",
597
+ # "maxPositionSize": "100",
598
+ # "minOrderSize": "0.0010",
599
+ # "maxMarketPriceRange": "0.025",
600
+ # "settleAssetId": "USDT",
601
+ # "baseTokenId": "BTC",
602
+ # "stepSize": "0.001",
603
+ # "symbol": "BTC-USDT",
604
+ # "symbolDisplayName": "BTCUSDT",
605
+ # "tickSize": "0.1",
606
+ # "maxMaintenanceMarginRate": "0.5000",
607
+ # "maxPositionValue": "5000000.0000",
608
+ # "tagIconUrl": "https://static-pro.apex.exchange/icon/LABLE_HOT.svg",
609
+ # "tag": "HOT",
610
+ # "riskTip": False,
611
+ # "defaultInitialMarginRate": "0.05",
612
+ # "klineStartTime": 0,
613
+ # "maxMarketSizeBuffer": "0.98",
614
+ # "enableFundingSettlement": True,
615
+ # "indexPriceDecimals": 2,
616
+ # "indexPriceVarRate": "0.001",
617
+ # "openPositionOiLimitRate": "0.05",
618
+ # "fundingMaxRate": "0.000234",
619
+ # "fundingMinRate": "-0.000234",
620
+ # "fundingMaxValue": "",
621
+ # "enableFundingMxValue": True,
622
+ # "l2PairId": "50001",
623
+ # "settleTimeStamp": 0,
624
+ # "isPrelaunch": False,
625
+ # "riskLimitConfig": {},
626
+ # "category": "L1"
627
+ # }
628
+ # ]
629
+ # }
630
+ return self.parse_markets(perpetualContract)
631
+
632
+ def parse_market(self, market: dict) -> Market:
633
+ id = self.safe_string(market, 'symbol')
634
+ id2 = self.safe_string(market, 'crossSymbolName')
635
+ quoteId = self.safe_string(market, 'l2PairId')
636
+ baseId = self.safe_string(market, 'baseTokenId')
637
+ quote = self.safe_string(market, 'settleAssetId')
638
+ base = self.safe_currency_code(baseId)
639
+ settleId = self.safe_string(market, 'settleAssetId')
640
+ settle = self.safe_currency_code(settleId)
641
+ symbol = baseId + '/' + quote + ':' + settle
642
+ expiry = 0
643
+ takerFee = self.parse_number('0.0002')
644
+ makerFee = self.parse_number('0.0005')
645
+ return self.safe_market_structure({
646
+ 'id': id,
647
+ 'id2': id2,
648
+ 'symbol': symbol,
649
+ 'base': base,
650
+ 'quote': quote,
651
+ 'settle': settle,
652
+ 'baseId': baseId,
653
+ 'quoteId': quoteId,
654
+ 'settleId': settleId,
655
+ 'type': 'swap',
656
+ 'spot': False,
657
+ 'margin': None,
658
+ 'swap': True,
659
+ 'future': False,
660
+ 'option': False,
661
+ 'active': self.safe_bool(market, 'enableTrade'),
662
+ 'contract': True,
663
+ 'linear': True,
664
+ 'inverse': False,
665
+ 'taker': takerFee,
666
+ 'maker': makerFee,
667
+ 'contractSize': self.safe_number(market, 'minOrderSize'),
668
+ 'expiry': None if (expiry == 0) else expiry,
669
+ 'expiryDatetime': None if (expiry == 0) else self.iso8601(expiry),
670
+ 'strike': None,
671
+ 'optionType': None,
672
+ 'precision': {
673
+ 'amount': self.safe_number(market, 'stepSize'),
674
+ 'price': self.safe_number(market, 'tickSize'),
675
+ },
676
+ 'limits': {
677
+ 'leverage': {
678
+ 'min': self.safe_number(market, 'displayMinLeverage'),
679
+ 'max': self.safe_number(market, 'displayMaxLeverage'),
680
+ },
681
+ 'amount': {
682
+ 'min': self.safe_number(market, 'minOrderSize'),
683
+ 'max': self.safe_number(market, 'maxOrderSize'),
684
+ },
685
+ 'price': {
686
+ 'min': None,
687
+ 'max': None,
688
+ },
689
+ 'cost': {
690
+ 'min': None,
691
+ 'max': None,
692
+ },
693
+ },
694
+ 'created': None,
695
+ 'info': market,
696
+ })
697
+
698
+ def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
699
+ #
700
+ # {
701
+ # "symbol": "BTCUSDT",
702
+ # "price24hPcnt": "0.450141",
703
+ # "lastPrice": "43511.50",
704
+ # "highPrice24h": "43513.50",
705
+ # "lowPrice24h": "29996.00",
706
+ # "markPrice": "43513.50",
707
+ # "indexPrice": "40828.94",
708
+ # "openInterest": "2036854775808",
709
+ # "turnover24h": "5626085.23749999",
710
+ # "volume24h": "169.317",
711
+ # "fundingRate": "0",
712
+ # "predictedFundingRate": "0",
713
+ # "nextFundingTime": "10:00:00",
714
+ # "tradeCount": 100
715
+ # }
716
+ #
717
+ timestamp = self.milliseconds()
718
+ marketId = self.safe_string(ticker, 'symbol')
719
+ market = self.safe_market(marketId, market)
720
+ symbol = self.safe_symbol(marketId, market)
721
+ last = self.safe_string(ticker, 'lastPrice')
722
+ percentage = self.safe_string(ticker, 'price24hPcnt')
723
+ quoteVolume = self.safe_string(ticker, 'turnover24h')
724
+ baseVolume = self.safe_string(ticker, 'volume24h')
725
+ high = self.safe_string(ticker, 'highPrice24h')
726
+ low = self.safe_string(ticker, 'lowPrice24h')
727
+ return self.safe_ticker({
728
+ 'symbol': symbol,
729
+ 'timestamp': timestamp,
730
+ 'datetime': self.iso8601(timestamp),
731
+ 'high': high,
732
+ 'low': low,
733
+ 'bid': None,
734
+ 'bidVolume': None,
735
+ 'ask': None,
736
+ 'askVolume': None,
737
+ 'vwap': None,
738
+ 'open': None,
739
+ 'close': last,
740
+ 'last': last,
741
+ 'previousClose': None,
742
+ 'change': None,
743
+ 'percentage': percentage,
744
+ 'average': None,
745
+ 'baseVolume': baseVolume,
746
+ 'quoteVolume': quoteVolume,
747
+ 'markPrice': self.safe_string(ticker, 'markPrice'),
748
+ 'indexPrice': self.safe_string(ticker, 'indexPrice'),
749
+ 'info': ticker,
750
+ }, market)
751
+
752
+ def fetch_ticker(self, symbol: str, params={}) -> Ticker:
753
+ """
754
+ fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
755
+
756
+ https://api-docs.pro.apex.exchange/#publicapi-v3-for-omni-get-ticker-data-v3
757
+
758
+ :param str symbol: unified symbol of the market to fetch the ticker for
759
+ :param dict [params]: extra parameters specific to the exchange API endpoint
760
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
761
+ """
762
+ self.load_markets()
763
+ market = self.market(symbol)
764
+ request: dict = {
765
+ 'symbol': market['id2'],
766
+ }
767
+ response = self.publicGetV3Ticker(self.extend(request, params))
768
+ tickers = self.safe_list(response, 'data', [])
769
+ rawTicker = self.safe_dict(tickers, 0, {})
770
+ return self.parse_ticker(rawTicker, market)
771
+
772
+ def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
773
+ """
774
+ fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
775
+
776
+ https://api-docs.pro.apex.exchange/#publicapi-v3-for-omni-get-ticker-data-v3
777
+
778
+ :param str symbols: unified symbol of the market to fetch the ticker for
779
+ :param dict [params]: extra parameters specific to the exchange API endpoint
780
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
781
+ """
782
+ self.load_markets()
783
+ response = self.publicGetV3DataAllTickerInfo(params)
784
+ tickers = self.safe_list(response, 'data', [])
785
+ return self.parse_tickers(tickers, symbols)
786
+
787
+ def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
788
+ """
789
+ fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
790
+
791
+ https://api-docs.pro.apex.exchange/#publicapi-v3-for-omni-get-candlestick-chart-data-v3
792
+
793
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
794
+ :param str timeframe: the length of time each candle represents
795
+ :param int [since]: timestamp in ms of the earliest candle to fetch
796
+ :param int [limit]: the maximum amount of candles to fetch
797
+ :param dict [params]: extra parameters specific to the exchange API endpoint
798
+ :param int [params.until]: timestamp in ms of the latest candle to fetch
799
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
800
+ """
801
+ self.load_markets()
802
+ market = self.market(symbol)
803
+ request: dict = {
804
+ 'interval': self.safe_string(self.timeframes, timeframe, timeframe),
805
+ 'symbol': market['id2'],
806
+ }
807
+ if limit is None:
808
+ limit = 200 # default is 200 when requested with `since`
809
+ request['limit'] = limit # max 200, default 200
810
+ request, params = self.handle_until_option('end', request, params)
811
+ if since is not None:
812
+ request['start'] = since
813
+ response = self.publicGetV3Klines(self.extend(request, params))
814
+ data = self.safe_dict(response, 'data', {})
815
+ OHLCVs = self.safe_list(data, market['id2'], [])
816
+ return self.parse_ohlcvs(OHLCVs, market, timeframe, since, limit)
817
+
818
+ def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
819
+ #
820
+ # {
821
+ # "start": 1647511440000,
822
+ # "symbol": "BTC-USD",
823
+ # "interval": "1",
824
+ # "low": "40000",
825
+ # "high": "45000",
826
+ # "open": "45000",
827
+ # "close": "40000",
828
+ # "volume": "1.002",
829
+ # "turnover": "3"
830
+ # } {"s":"BTCUSDT","i":"1","t":1741265880000,"c":"90235","h":"90235","l":"90156","o":"90156","v":"0.052","tr":"4690.4466"}
831
+ #
832
+ return [
833
+ self.safe_integer_n(ohlcv, ['start', 't']),
834
+ self.safe_number_n(ohlcv, ['open', 'o']),
835
+ self.safe_number_n(ohlcv, ['high', 'h']),
836
+ self.safe_number_n(ohlcv, ['low', 'l']),
837
+ self.safe_number_n(ohlcv, ['close', 'c']),
838
+ self.safe_number_n(ohlcv, ['volume', 'v']),
839
+ ]
840
+
841
+ def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
842
+ """
843
+ fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
844
+
845
+ https://api-docs.pro.apex.exchange/#publicapi-v3-for-omni-get-market-depth-v3
846
+
847
+ :param str symbol: unified symbol of the market to fetch the order book for
848
+ :param int [limit]: the maximum amount of order book entries to return
849
+ :param dict [params]: extra parameters specific to the exchange API endpoint
850
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
851
+ """
852
+ self.load_markets()
853
+ market = self.market(symbol)
854
+ request: dict = {
855
+ 'symbol': market['id2'],
856
+ }
857
+ if limit is None:
858
+ limit = 100 # default is 200 when requested with `since`
859
+ request['limit'] = limit # max 100, default 100
860
+ response = self.publicGetV3Depth(self.extend(request, params))
861
+ #
862
+ # {
863
+ # "a": [
864
+ # [
865
+ # "96576.3",
866
+ # "0.399"
867
+ # ],
868
+ # [
869
+ # "96577.6",
870
+ # "0.106"
871
+ # ]
872
+ # ],
873
+ # "b": [
874
+ # [
875
+ # "96565.2",
876
+ # "0.131"
877
+ # ],
878
+ # [
879
+ # "96565.1",
880
+ # "0.038"
881
+ # ]
882
+ # ],
883
+ # "s": "BTCUSDT",
884
+ # "u": 18665465
885
+ # }
886
+ #
887
+ data = self.safe_dict(response, 'data', {})
888
+ timestamp = self.milliseconds()
889
+ orderbook = self.parse_order_book(data, market['symbol'], timestamp, 'b', 'a')
890
+ orderbook['nonce'] = self.safe_integer(data, 'u')
891
+ return orderbook
892
+
893
+ def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
894
+ """
895
+ get the list of most recent trades for a particular symbol
896
+
897
+ https://api-docs.pro.apex.exchange/#publicapi-v3-for-omni-get-newest-trading-data-v3
898
+
899
+ :param str symbol: unified symbol of the market to fetch trades for
900
+ :param int [since]: timestamp in ms of the earliest trade to fetch
901
+ :param int [limit]: the maximum amount of trades to fetch
902
+ :param dict [params]: extra parameters specific to the exchange API endpoint
903
+ :param int [params.until]: the latest time in ms to fetch trades for
904
+ :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times
905
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
906
+ """
907
+ self.load_markets()
908
+ market = self.market(symbol)
909
+ request: dict = {
910
+ 'symbol': market['id2'],
911
+ }
912
+ if limit is None:
913
+ limit = 500 # default is 50
914
+ request['limit'] = limit
915
+ response = self.publicGetV3Trades(self.extend(request, params))
916
+ #
917
+ # [
918
+ # {
919
+ # "i": "993f7f85-9215-5723-9078-2186ae140847",
920
+ # "p": "96534.3",
921
+ # "S": "Sell",
922
+ # "v": "0.261",
923
+ # "s": "BTCUSDT",
924
+ # "T": 1739118072710
925
+ # },
926
+ # {
927
+ # "i": "c947c9cf-8c18-5784-89c3-91bdf86ddde8",
928
+ # "p": "96513.5",
929
+ # "S": "Sell",
930
+ # "v": "0.042",
931
+ # "s": "BTCUSDT",
932
+ # "T": 1739118075944
933
+ # }
934
+ # ]
935
+ #
936
+ trades = self.safe_list(response, 'data', [])
937
+ return self.parse_trades(trades, market, since, limit)
938
+
939
+ def parse_trade(self, trade: dict, market: Market = None) -> Trade:
940
+ #
941
+ # [
942
+ # {
943
+ # "i": "993f7f85-9215-5723-9078-2186ae140847",
944
+ # "p": "96534.3",
945
+ # "S": "Sell",
946
+ # "v": "0.261",
947
+ # "s": "BTCUSDT",
948
+ # "T": 1739118072710
949
+ # }
950
+ # ]
951
+ #
952
+ marketId = self.safe_string_n(trade, ['s', 'symbol'])
953
+ market = self.safe_market(marketId, market)
954
+ id = self.safe_string_n(trade, ['i', 'id'])
955
+ timestamp = self.safe_integer_n(trade, ['t', 'T', 'createdAt'])
956
+ priceString = self.safe_string_n(trade, ['p', 'price'])
957
+ amountString = self.safe_string_n(trade, ['v', 'size'])
958
+ side = self.safe_string_lower_n(trade, ['S', 'side'])
959
+ type = self.safe_string_n(trade, ['type'])
960
+ fee = self.safe_string_n(trade, ['fee'])
961
+ return self.safe_trade({
962
+ 'info': trade,
963
+ 'id': id,
964
+ 'order': None,
965
+ 'timestamp': timestamp,
966
+ 'datetime': self.iso8601(timestamp),
967
+ 'symbol': market['symbol'],
968
+ 'type': type,
969
+ 'takerOrMaker': None,
970
+ 'side': side,
971
+ 'price': priceString,
972
+ 'amount': amountString,
973
+ 'cost': None,
974
+ 'fee': fee,
975
+ }, market)
976
+
977
+ def fetch_open_interest(self, symbol: str, params={}):
978
+ """
979
+ retrieves the open interest of a contract trading pair
980
+
981
+ https://api-docs.pro.apex.exchange/#publicapi-v3-for-omni-get-ticker-data-v3
982
+
983
+ :param str symbol: unified CCXT market symbol
984
+ :param dict [params]: exchange specific parameters
985
+ :returns dict} an open interest structure{@link https://docs.ccxt.com/#/?id=open-interest-structure:
986
+ """
987
+ self.load_markets()
988
+ market = self.market(symbol)
989
+ request: dict = {
990
+ 'symbol': market['id2'],
991
+ }
992
+ response = self.publicGetV3Ticker(self.extend(request, params))
993
+ tickers = self.safe_list(response, 'data', [])
994
+ rawTicker = self.safe_dict(tickers, 0, {})
995
+ return self.parse_open_interest(rawTicker, market)
996
+
997
+ def parse_open_interest(self, interest, market: Market = None):
998
+ #
999
+ # {
1000
+ # "symbol": "BTCUSDT",
1001
+ # "price24hPcnt": "0.450141",
1002
+ # "lastPrice": "43511.50",
1003
+ # "highPrice24h": "43513.50",
1004
+ # "lowPrice24h": "29996.00",
1005
+ # "markPrice": "43513.50",
1006
+ # "indexPrice": "40828.94",
1007
+ # "openInterest": "2036854775808",
1008
+ # "turnover24h": "5626085.23749999",
1009
+ # "volume24h": "169.317",
1010
+ # "fundingRate": "0",
1011
+ # "predictedFundingRate": "0",
1012
+ # "nextFundingTime": "10:00:00",
1013
+ # "tradeCount": 100
1014
+ # }
1015
+ #
1016
+ timestamp = self.milliseconds()
1017
+ marketId = self.safe_string(interest, 'symbol')
1018
+ market = self.safe_market(marketId, market)
1019
+ symbol = self.safe_symbol(marketId, market)
1020
+ return self.safe_open_interest({
1021
+ 'symbol': symbol,
1022
+ 'openInterestAmount': self.safe_string(interest, 'openInterest'),
1023
+ 'openInterestValue': None,
1024
+ 'timestamp': timestamp,
1025
+ 'datetime': self.iso8601(timestamp),
1026
+ 'info': interest,
1027
+ }, market)
1028
+
1029
+ def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1030
+ """
1031
+ fetches historical funding rate prices
1032
+
1033
+ https://api-docs.pro.apex.exchange/#publicapi-v3-for-omni-get-funding-rate-history-v3
1034
+
1035
+ :param str symbol: unified symbol of the market to fetch the funding rate history for
1036
+ :param int [since]: timestamp in ms of the earliest funding rate to fetch
1037
+ :param int [limit]: the maximum amount of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>` to fetch
1038
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1039
+ :param int [params.until]: timestamp in ms of the latest funding rate
1040
+ :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
1041
+ :returns dict[]: a list of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>`
1042
+ """
1043
+ if symbol is None:
1044
+ raise ArgumentsRequired(self.id + ' fetchFundingRateHistory() requires a symbol argument')
1045
+ self.load_markets()
1046
+ request: dict = {}
1047
+ market = self.market(symbol)
1048
+ request['symbol'] = market['id']
1049
+ if since is not None:
1050
+ request['beginTimeInclusive'] = since
1051
+ if limit is not None:
1052
+ request['limit'] = limit
1053
+ page = self.safe_integer(params, 'page')
1054
+ if page is not None:
1055
+ request['page'] = page
1056
+ endTimeExclusive = self.safe_integer_n(params, ['endTime', 'endTimeExclusive', 'until'])
1057
+ if endTimeExclusive is not None:
1058
+ request['endTimeExclusive'] = endTimeExclusive
1059
+ response = self.publicGetV3HistoryFunding(self.extend(request, params))
1060
+ #
1061
+ # {
1062
+ # "historyFunds": [
1063
+ # {
1064
+ # "symbol": "BTC-USD",
1065
+ # "rate": "0.0000125000",
1066
+ # "price": "31297.5000008009374142",
1067
+ # "fundingTime": 12315555,
1068
+ # "fundingTimestamp": 12315555
1069
+ # }
1070
+ # ],
1071
+ # "totalSize": 11
1072
+ # }
1073
+ #
1074
+ rates = []
1075
+ data = self.safe_dict(response, 'data', {})
1076
+ resultList = self.safe_list(data, 'historyFunds', [])
1077
+ for i in range(0, len(resultList)):
1078
+ entry = resultList[i]
1079
+ timestamp = self.safe_integer(entry, 'fundingTimestamp')
1080
+ marketId = self.safe_string(entry, 'symbol')
1081
+ rates.append({
1082
+ 'info': entry,
1083
+ 'symbol': self.safe_symbol(marketId, market),
1084
+ 'fundingRate': self.safe_number(entry, 'rate'),
1085
+ 'timestamp': timestamp,
1086
+ 'datetime': self.iso8601(timestamp),
1087
+ })
1088
+ sorted = self.sort_by(rates, 'timestamp')
1089
+ return self.filter_by_symbol_since_limit(sorted, symbol, since, limit)
1090
+
1091
+ def parse_order(self, order: dict, market: Market = None) -> Order:
1092
+ #
1093
+ # {
1094
+ # "id": "1234",
1095
+ # "clientId": "1234",
1096
+ # "accountId": "12345",
1097
+ # "symbol": "BTC-USD",
1098
+ # "side": "SELL",
1099
+ # "price": "18000",
1100
+ # "limitFee": "100",
1101
+ # "fee": "100",
1102
+ # "triggerPrice": "1.2",
1103
+ # "trailingPercent": "0.12",
1104
+ # "size": "100",
1105
+ # "remainingSize": "100",
1106
+ # "type": "LIMIT",
1107
+ # "createdAt": 1647502440973,
1108
+ # "updatedTime": 1647502440973,
1109
+ # "expiresAt": 1647502440973,
1110
+ # "status": "PENDING",
1111
+ # "timeInForce": "GOOD_TIL_CANCEL",
1112
+ # "postOnly": False,
1113
+ # "reduceOnly": False,
1114
+ # "stopPnl": False,
1115
+ # "latestMatchFillPrice": "reason",
1116
+ # "cumMatchFillSize": "0.1",
1117
+ # "cumMatchFillValue": "1000",
1118
+ # "cumMatchFillFee": "1",
1119
+ # "cumSuccessFillSize": "0.1",
1120
+ # "cumSuccessFillValue": "1000",
1121
+ # "cumSuccessFillFee": "1",
1122
+ # "triggerPriceType": "INDEX",
1123
+ # "isOpenTpslOrder": True,
1124
+ # "isSetOpenTp": True,
1125
+ # "isSetOpenSl": False,
1126
+ # "openTpParam": {
1127
+ # "side": "SELL",
1128
+ # "price": "18000",
1129
+ # "limitFee": "100",
1130
+ # "clientOrderId": "111100",
1131
+ # "triggerPrice": "1.2",
1132
+ # "trailingPercent": "0.12",
1133
+ # "size": "100"
1134
+ # },
1135
+ # "openSlParam": {
1136
+ # "side": "SELL",
1137
+ # "price": "18000",
1138
+ # "limitFee": "100",
1139
+ # "clientOrderId": "111100",
1140
+ # "triggerPrice": "1.2",
1141
+ # "trailingPercent": "0.12",
1142
+ # "size": "100"
1143
+ # }
1144
+ # }
1145
+ #
1146
+ timestamp = self.safe_integer(order, 'createdAt')
1147
+ orderId = self.safe_string(order, 'id')
1148
+ clientOrderId = self.safe_string(order, 'clientId')
1149
+ marketId = self.safe_string(order, 'symbol')
1150
+ market = self.safe_market(marketId, market)
1151
+ symbol = market['symbol']
1152
+ price = self.safe_string(order, 'price')
1153
+ amount = self.safe_string(order, 'size')
1154
+ orderType = self.safe_string(order, 'type')
1155
+ status = self.safe_string(order, 'status')
1156
+ side = self.safe_string_lower(order, 'side')
1157
+ # average = self.omit_zero(self.safe_string(order, 'avg_fill_price'))
1158
+ remaining = self.omit_zero(self.safe_string(order, 'remainingSize'))
1159
+ lastUpdateTimestamp = self.safe_integer(order, 'updatedTime')
1160
+ return self.safe_order({
1161
+ 'id': orderId,
1162
+ 'clientOrderId': clientOrderId,
1163
+ 'timestamp': timestamp,
1164
+ 'datetime': self.iso8601(timestamp),
1165
+ 'lastTradeTimestamp': None,
1166
+ 'lastUpdateTimestamp': lastUpdateTimestamp,
1167
+ 'status': self.parse_order_status(status),
1168
+ 'symbol': symbol,
1169
+ 'type': self.parse_order_type(orderType),
1170
+ 'timeInForce': self.parse_time_in_force(self.safe_string(order, 'timeInForce')),
1171
+ 'postOnly': self.safe_bool(order, 'postOnly'),
1172
+ 'reduceOnly': self.safe_bool(order, 'reduceOnly'),
1173
+ 'side': side,
1174
+ 'price': price,
1175
+ 'triggerPrice': self.safe_string(order, 'triggerPrice'),
1176
+ 'takeProfitPrice': None,
1177
+ 'stopLossPrice': None,
1178
+ 'average': None,
1179
+ 'amount': amount,
1180
+ 'filled': None,
1181
+ 'remaining': remaining,
1182
+ 'cost': None,
1183
+ 'trades': None,
1184
+ 'fee': {
1185
+ 'cost': self.safe_string(order, 'fee'),
1186
+ 'currency': market['settleId'],
1187
+ },
1188
+ 'info': order,
1189
+ }, market)
1190
+
1191
+ def parse_time_in_force(self, timeInForce: Str):
1192
+ timeInForces: dict = {
1193
+ 'GOOD_TIL_CANCEL': 'GOOD_TIL_CANCEL',
1194
+ 'FILL_OR_KILL': 'FILL_OR_KILL',
1195
+ 'IMMEDIATE_OR_CANCEL': 'IMMEDIATE_OR_CANCEL',
1196
+ 'POST_ONLY': 'POST_ONLY',
1197
+ }
1198
+ return self.safe_string(timeInForces, timeInForce, None)
1199
+
1200
+ def parse_order_status(self, status: Str):
1201
+ if status is not None:
1202
+ statuses: dict = {
1203
+ 'PENDING': 'open',
1204
+ 'OPEN': 'open',
1205
+ 'FILLED': 'filled',
1206
+ 'CANCELING': 'canceled',
1207
+ 'CANCELED': 'canceled',
1208
+ 'UNTRIGGERED': 'open',
1209
+ }
1210
+ return self.safe_string(statuses, status, status)
1211
+ return status
1212
+
1213
+ def parse_order_type(self, type: Str):
1214
+ types: dict = {
1215
+ 'LIMIT': 'LIMIT',
1216
+ 'MARKET': 'MARKET',
1217
+ 'STOP_LIMIT': 'STOP_LIMIT',
1218
+ 'STOP_MARKET': 'STOP_MARKET',
1219
+ 'TAKE_PROFIT_LIMIT': 'TAKE_PROFIT_LIMIT',
1220
+ 'TAKE_PROFIT_MARKET': 'TAKE_PROFIT_MARKET',
1221
+ }
1222
+ return self.safe_string_upper(types, type, type)
1223
+
1224
+ def safe_market(self, marketId: Str = None, market: Market = None, delimiter: Str = None, marketType: Str = None) -> MarketInterface:
1225
+ if market is None and marketId is not None:
1226
+ if marketId in self.markets:
1227
+ market = self.markets[marketId]
1228
+ elif marketId in self.markets_by_id:
1229
+ market = self.markets_by_id[marketId]
1230
+ else:
1231
+ newMarketId = self.add_hyphen_before_usdt(marketId)
1232
+ if newMarketId in self.markets_by_id:
1233
+ markets = self.markets_by_id[newMarketId]
1234
+ numMarkets = len(markets)
1235
+ if numMarkets > 0:
1236
+ if self.markets_by_id[newMarketId][0]['id2'] == marketId:
1237
+ market = self.markets_by_id[newMarketId][0]
1238
+ return super(apex, self).safe_market(marketId, market, delimiter, marketType)
1239
+
1240
+ def generate_random_client_id_omni(self, _accountId: str):
1241
+ accountId = _accountId or str(self.rand_number(12))
1242
+ return 'apexomni-' + accountId + '-' + str(self.milliseconds()) + '-' + str(self.rand_number(6))
1243
+
1244
+ def add_hyphen_before_usdt(self, symbol: str):
1245
+ uppercaseSymbol = symbol.upper()
1246
+ index = uppercaseSymbol.find('USDT')
1247
+ symbolChar = self.safe_string(symbol, index - 1)
1248
+ if index > 0 and symbolChar != '-':
1249
+ return symbol[0:index] + '-' + symbol[index:]
1250
+ return symbol
1251
+
1252
+ def get_seeds(self):
1253
+ seeds = self.safe_string(self.options, 'seeds')
1254
+ if seeds is None:
1255
+ raise ArgumentsRequired(self.id + ' the "seeds" key is required in the options to access private endpoints. You can find it in API Management > Omni Key, and then set it.options["seeds"] = XXXX')
1256
+ return seeds
1257
+
1258
+ def get_account_id(self):
1259
+ accountId = self.safe_string(self.options, 'accountId', '0')
1260
+ if accountId == '0':
1261
+ accountData = self.fetch_account()
1262
+ self.options['accountId'] = self.safe_string(accountData, 'id', '0')
1263
+ return self.options['accountId']
1264
+
1265
+ def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1266
+ """
1267
+ create a trade order
1268
+
1269
+ https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-post-creating-orders
1270
+
1271
+ :param str symbol: unified symbol of the market to create an order in
1272
+ :param str type: 'market' or 'limit'
1273
+ :param str side: 'buy' or 'sell'
1274
+ :param float amount: how much of currency you want to trade in units of base currency
1275
+ :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1276
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1277
+ :param float [params.triggerPrice]: The price a trigger order is triggered at
1278
+ :param str [params.timeInForce]: "GTC", "IOC", or "POST_ONLY"
1279
+ :param bool [params.postOnly]: True or False
1280
+ :param bool [params.reduceOnly]: Ensures that the executed order does not flip the opened position.
1281
+ :param str [params.clientOrderId]: a unique id for the order
1282
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1283
+ """
1284
+ self.load_markets()
1285
+ market = self.market(symbol)
1286
+ orderType = type.upper()
1287
+ orderSide = side.upper()
1288
+ orderSize = self.amount_to_precision(symbol, amount)
1289
+ orderPrice = '0'
1290
+ if price is not None:
1291
+ orderPrice = self.price_to_precision(symbol, price)
1292
+ fees = self.safe_dict(self.fees, 'swap', {})
1293
+ taker = self.safe_number(fees, 'taker', 0.0005)
1294
+ maker = self.safe_number(fees, 'maker', 0.0002)
1295
+ limitFee = self.decimal_to_precision(Precise.string_add(Precise.string_mul(Precise.string_mul(orderPrice, orderSize), str(taker)), str(market['precision']['price'])), TRUNCATE, market['precision']['price'], self.precisionMode, self.paddingMode)
1296
+ timeNow = self.milliseconds()
1297
+ # triggerPrice = self.safe_string_2(params, 'triggerPrice', 'stopPrice')
1298
+ isMarket = orderType == 'MARKET'
1299
+ if isMarket and (price is None):
1300
+ raise ArgumentsRequired(self.id + ' createOrder() requires a price argument for market orders')
1301
+ timeInForce = self.safe_string_upper(params, 'timeInForce')
1302
+ postOnly = self.is_post_only(isMarket, None, params)
1303
+ if timeInForce is None:
1304
+ timeInForce = 'GOOD_TIL_CANCEL'
1305
+ if not isMarket:
1306
+ if postOnly:
1307
+ timeInForce = 'POST_ONLY'
1308
+ elif timeInForce == 'ioc':
1309
+ timeInForce = 'IMMEDIATE_OR_CANCEL'
1310
+ params = self.omit(params, 'timeInForce')
1311
+ params = self.omit(params, 'postOnly')
1312
+ clientOrderId = self.safe_string_n(params, ['clientId', 'clientOrderId', 'client_order_id'])
1313
+ accountId = self.get_account_id()
1314
+ if clientOrderId is None:
1315
+ clientOrderId = self.generate_random_client_id_omni(accountId)
1316
+ params = self.omit(params, ['clientId', 'clientOrderId', 'client_order_id'])
1317
+ orderToSign = {
1318
+ 'accountId': accountId,
1319
+ 'slotId': clientOrderId,
1320
+ 'nonce': clientOrderId,
1321
+ 'pairId': market['quoteId'],
1322
+ 'size': orderSize,
1323
+ 'price': orderPrice,
1324
+ 'direction': orderSide,
1325
+ 'makerFeeRate': str(maker),
1326
+ 'takerFeeRate': str(taker),
1327
+ }
1328
+ signature = self.get_zk_contract_signature_obj(self.remove0x_prefix(self.get_seeds()), orderToSign)
1329
+ request: dict = {
1330
+ 'symbol': market['id'],
1331
+ 'side': orderSide,
1332
+ 'type': orderType, # LIMIT/MARKET/STOP_LIMIT/STOP_MARKET
1333
+ 'size': orderSize,
1334
+ 'price': orderPrice,
1335
+ 'limitFee': limitFee,
1336
+ 'expiration': int(math.floor(timeNow / 1000 + 30 * 24 * 60 * 60)),
1337
+ 'timeInForce': timeInForce,
1338
+ 'clientId': clientOrderId,
1339
+ 'brokerId': self.safe_string(self.options, 'brokerId', '6956'),
1340
+ }
1341
+ request['signature'] = signature
1342
+ response = self.privatePostV3Order(self.extend(request, params))
1343
+ data = self.safe_dict(response, 'data', {})
1344
+ return self.parse_order(data, market)
1345
+
1346
+ def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
1347
+ """
1348
+ transfer currency internally between wallets on the same account
1349
+ :param str code: unified currency code
1350
+ :param float amount: amount to transfer
1351
+ :param str fromAccount: account to transfer from
1352
+ :param str toAccount: account to transfer to
1353
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1354
+ :param str [params.transferId]: UUID, which is unique across the platform
1355
+ :returns dict: a `transfer structure <https://docs.ccxt.com/#/?id=transfer-structure>`
1356
+ """
1357
+ self.load_markets()
1358
+ configResponse = self.publicGetV3Symbols(params)
1359
+ configData = self.safe_dict(configResponse, 'data', {})
1360
+ contractConfig = self.safe_dict(configData, 'contractConfig', {})
1361
+ contractAssets = self.safe_list(contractConfig, 'assets', [])
1362
+ spotConfig = self.safe_dict(configData, 'spotConfig', {})
1363
+ spotAssets = self.safe_list(spotConfig, 'assets', [])
1364
+ globalConfig = self.safe_dict(spotConfig, 'global', {})
1365
+ receiverAddress = self.safe_string(globalConfig, 'contractAssetPoolEthAddress', '')
1366
+ receiverZkAccountId = self.safe_string(globalConfig, 'contractAssetPoolZkAccountId', '')
1367
+ receiverSubAccountId = self.safe_string(globalConfig, 'contractAssetPoolSubAccount', '')
1368
+ receiverAccountId = self.safe_string(globalConfig, 'contractAssetPoolAccountId', '')
1369
+ accountResponse = self.privateGetV3Account(params)
1370
+ accountData = self.safe_dict(accountResponse, 'data', {})
1371
+ spotAccount = self.safe_dict(accountData, 'spotAccount', {})
1372
+ zkAccountId = self.safe_string(spotAccount, 'zkAccountId', '')
1373
+ subAccountId = self.safe_string(spotAccount, 'defaultSubAccountId', '0')
1374
+ subAccounts = self.safe_list(spotAccount, 'subAccounts', [])
1375
+ nonce = '0'
1376
+ if len(subAccounts) > 0:
1377
+ nonce = self.safe_string(subAccounts[0], 'nonce', '0')
1378
+ ethAddress = self.safe_string(accountData, 'ethereumAddress', '')
1379
+ accountId = self.safe_string(accountData, 'id', '')
1380
+ currency = {}
1381
+ assets = []
1382
+ if fromAccount is not None and fromAccount.lower() == 'contract':
1383
+ assets = contractAssets
1384
+ else:
1385
+ assets = spotAssets
1386
+ for i in range(0, len(assets)):
1387
+ if self.safe_string(assets[i], 'token', '') == code:
1388
+ currency = assets[i]
1389
+ tokenId = self.safe_string(currency, 'tokenId', '')
1390
+ amountNumber = self.parse_to_int(amount * (math.pow(10, self.safe_number(currency, 'decimals', 0))))
1391
+ timestampSeconds = self.parse_to_int(self.milliseconds() / 1000)
1392
+ clientOrderId = self.safe_string_n(params, ['clientId', 'clientOrderId', 'client_order_id'])
1393
+ if clientOrderId is None:
1394
+ clientOrderId = self.generate_random_client_id_omni(self.safe_string(self.options, 'accountId'))
1395
+ params = self.omit(params, ['clientId', 'clientOrderId', 'client_order_id'])
1396
+ if fromAccount is not None and fromAccount.lower() == 'contract':
1397
+ formattedUint32 = '4294967295'
1398
+ zkSignAccountId = Precise.string_mod(accountId, formattedUint32)
1399
+ expireTime = timestampSeconds + 3600 * 24 * 28
1400
+ orderToSign = {
1401
+ 'zkAccountId': zkSignAccountId,
1402
+ 'receiverAddress': ethAddress,
1403
+ 'subAccountId': subAccountId,
1404
+ 'receiverSubAccountId': subAccountId,
1405
+ 'tokenId': tokenId,
1406
+ 'amount': str(amountNumber),
1407
+ 'fee': '0',
1408
+ 'nonce': clientOrderId,
1409
+ 'timestampSeconds': expireTime,
1410
+ 'isContract': True,
1411
+ }
1412
+ signature = self.get_zk_transfer_signature_obj(self.remove0x_prefix(self.get_seeds()), orderToSign)
1413
+ request: dict = {
1414
+ 'amount': amount,
1415
+ 'expireTime': expireTime,
1416
+ 'clientWithdrawId': clientOrderId,
1417
+ 'signature': signature,
1418
+ 'token': code,
1419
+ 'ethAddress': ethAddress,
1420
+ }
1421
+ response = self.privatePostV3ContractTransferOut(self.extend(request, params))
1422
+ data = self.safe_dict(response, 'data', {})
1423
+ currentTime = self.milliseconds()
1424
+ return self.extend(self.parse_transfer(data, self.currency(code)), {
1425
+ 'timestamp': currentTime,
1426
+ 'datetime': self.iso8601(currentTime),
1427
+ 'amount': self.parse_number(amount),
1428
+ 'fromAccount': 'contract',
1429
+ 'toAccount': 'spot',
1430
+ })
1431
+ else:
1432
+ orderToSign = {
1433
+ 'zkAccountId': zkAccountId,
1434
+ 'receiverAddress': receiverAddress,
1435
+ 'subAccountId': subAccountId,
1436
+ 'receiverSubAccountId': receiverSubAccountId,
1437
+ 'tokenId': tokenId,
1438
+ 'amount': str(amountNumber),
1439
+ 'fee': '0',
1440
+ 'nonce': nonce,
1441
+ 'timestampSeconds': timestampSeconds,
1442
+ }
1443
+ signature = self.get_zk_transfer_signature_obj(self.remove0x_prefix(self.get_seeds()), orderToSign)
1444
+ request: dict = {
1445
+ 'amount': str(amount),
1446
+ 'timestamp': timestampSeconds,
1447
+ 'clientTransferId': clientOrderId,
1448
+ 'signature': signature,
1449
+ 'zkAccountId': zkAccountId,
1450
+ 'subAccountId': subAccountId,
1451
+ 'fee': '0',
1452
+ 'token': code,
1453
+ 'tokenId': tokenId,
1454
+ 'receiverAccountId': receiverAccountId,
1455
+ 'receiverZkAccountId': receiverZkAccountId,
1456
+ 'receiverSubAccountId': receiverSubAccountId,
1457
+ 'receiverAddress': receiverAddress,
1458
+ 'nonce': nonce,
1459
+ }
1460
+ response = self.privatePostV3TransferOut(self.extend(request, params))
1461
+ data = self.safe_dict(response, 'data', {})
1462
+ currentTime = self.milliseconds()
1463
+ return self.extend(self.parse_transfer(data, self.currency(code)), {
1464
+ 'timestamp': currentTime,
1465
+ 'datetime': self.iso8601(currentTime),
1466
+ 'amount': self.parse_number(amount),
1467
+ 'fromAccount': 'spot',
1468
+ 'toAccount': 'contract',
1469
+ })
1470
+
1471
+ def parse_transfer(self, transfer: dict, currency: Currency = None) -> TransferEntry:
1472
+ currencyId = self.safe_string(transfer, 'coin')
1473
+ timestamp = self.safe_integer(transfer, 'timestamp')
1474
+ fromAccount = self.safe_string(transfer, 'fromAccount')
1475
+ toAccount = self.safe_string(transfer, 'toAccount')
1476
+ return {
1477
+ 'info': transfer,
1478
+ 'id': self.safe_string_n(transfer, ['transferId', 'id']),
1479
+ 'timestamp': timestamp,
1480
+ 'datetime': self.iso8601(timestamp),
1481
+ 'currency': self.safe_currency_code(currencyId, currency),
1482
+ 'amount': self.safe_number(transfer, 'amount'),
1483
+ 'fromAccount': fromAccount,
1484
+ 'toAccount': toAccount,
1485
+ 'status': self.safe_string(transfer, 'status'),
1486
+ }
1487
+
1488
+ def cancel_all_orders(self, symbol: Str = None, params={}) -> List[Order]:
1489
+ """
1490
+ cancel all open orders in a market
1491
+
1492
+ https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-post-cancel-all-open-orders
1493
+
1494
+ :param str symbol: unified market symbol of the market to cancel orders in
1495
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1496
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1497
+ """
1498
+ self.load_markets()
1499
+ market = None
1500
+ request: dict = {}
1501
+ if symbol is not None:
1502
+ market = self.market(symbol)
1503
+ request['symbol'] = market['id']
1504
+ response = self.privatePostV3DeleteOpenOrders(self.extend(request, params))
1505
+ data = self.safe_dict(response, 'data', {})
1506
+ return [self.parse_order(data, market)]
1507
+
1508
+ def cancel_order(self, id: str, symbol: Str = None, params={}):
1509
+ """
1510
+ cancels an open order
1511
+
1512
+ https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-post-cancel-order
1513
+
1514
+ :param str id: order id
1515
+ @param symbol
1516
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1517
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1518
+ """
1519
+ request: dict = {}
1520
+ clientOrderId = self.safe_string_n(params, ['clientId', 'clientOrderId', 'client_order_id'])
1521
+ response = None
1522
+ if clientOrderId is not None:
1523
+ request['id'] = clientOrderId
1524
+ params = self.omit(params, ['clientId', 'clientOrderId', 'client_order_id'])
1525
+ response = self.privatePostV3DeleteClientOrderId(self.extend(request, params))
1526
+ else:
1527
+ request['id'] = id
1528
+ response = self.privatePostV3DeleteOrder(self.extend(request, params))
1529
+ data = self.safe_dict(response, 'data', {})
1530
+ return self.safe_order(data)
1531
+
1532
+ def fetch_order(self, id: str, symbol: Str = None, params={}):
1533
+ """
1534
+ fetches information on an order made by the user
1535
+
1536
+ https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-get-order-id
1537
+ https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-get-order-by-clientorderid
1538
+
1539
+ :param str id: the order id
1540
+ :param str symbol: unified symbol of the market the order was made in
1541
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1542
+ :param str [params.clientOrderId]: a unique id for the order
1543
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1544
+ """
1545
+ self.load_markets()
1546
+ request: dict = {}
1547
+ clientOrderId = self.safe_string_n(params, ['clientId', 'clientOrderId', 'client_order_id'])
1548
+ response = None
1549
+ if clientOrderId is not None:
1550
+ request['id'] = clientOrderId
1551
+ params = self.omit(params, ['clientId', 'clientOrderId', 'client_order_id'])
1552
+ response = self.privateGetV3OrderByClientOrderId(self.extend(request, params))
1553
+ else:
1554
+ request['id'] = id
1555
+ response = self.privateGetV3Order(self.extend(request, params))
1556
+ data = self.safe_dict(response, 'data', {})
1557
+ return self.parse_order(data)
1558
+
1559
+ def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1560
+ """
1561
+ fetches information on multiple orders made by the user
1562
+
1563
+ https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-get-open-orders
1564
+
1565
+ :param str symbol: unified market symbol of the market orders were made in
1566
+ :param int [since]: the earliest time in ms to fetch orders for
1567
+ :param int [limit]: the maximum number of order structures to retrieve
1568
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1569
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1570
+ """
1571
+ self.load_markets()
1572
+ response = self.privateGetV3OpenOrders(params)
1573
+ orders = self.safe_list(response, 'data', [])
1574
+ return self.parse_orders(orders, None, since, limit)
1575
+
1576
+ def fetch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1577
+ """
1578
+ fetches information on multiple orders made by the user *classic accounts only*
1579
+
1580
+ https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-get-all-order-history
1581
+
1582
+ :param str symbol: unified market symbol of the market orders were made in
1583
+ :param int [since]: the earliest time in ms to fetch orders for
1584
+ :param int [limit]: the maximum number of order structures to retrieve, default 100
1585
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1586
+ :param dict [params.until]: end time, ms
1587
+ :param boolean [params.status]: "PENDING", "OPEN", "FILLED", "CANCELED", "EXPIRED", "UNTRIGGERED"
1588
+ :param boolean [params.side]: BUY or SELL
1589
+ :param str [params.type]: "LIMIT", "MARKET","STOP_LIMIT", "STOP_MARKET", "TAKE_PROFIT_LIMIT","TAKE_PROFIT_MARKET"
1590
+ :param str [params.orderType]: "ACTIVE","CONDITION","HISTORY"
1591
+ :param boolean [params.page]: Page numbers start from 0
1592
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1593
+ """
1594
+ self.load_markets()
1595
+ request: dict = {}
1596
+ market = None
1597
+ if symbol is not None:
1598
+ market = self.market(symbol)
1599
+ request['symbol'] = market['id']
1600
+ if since is not None:
1601
+ request['beginTimeInclusive'] = since
1602
+ if limit is not None:
1603
+ request['limit'] = limit
1604
+ endTimeExclusive = self.safe_integer_n(params, ['endTime', 'endTimeExclusive', 'until'])
1605
+ if endTimeExclusive is not None:
1606
+ request['endTimeExclusive'] = endTimeExclusive
1607
+ params = self.omit(params, ['endTime', 'endTimeExclusive', 'until'])
1608
+ response = self.privateGetV3HistoryOrders(self.extend(request, params))
1609
+ data = self.safe_dict(response, 'data', {})
1610
+ orders = self.safe_list(data, 'orders', [])
1611
+ return self.parse_orders(orders, market, since, limit)
1612
+
1613
+ def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1614
+ """
1615
+ fetch all the trades made from a single order
1616
+
1617
+ https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-get-trade-history
1618
+
1619
+ :param str id: order id
1620
+ :param str symbol: unified market symbol
1621
+ :param int [since]: the earliest time in ms to fetch trades for
1622
+ :param int [limit]: the maximum number of trades to retrieve
1623
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1624
+ :returns dict[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
1625
+ """
1626
+ self.load_markets()
1627
+ request: dict = {}
1628
+ clientOrderId = self.safe_string_2(params, 'clientOrderId', 'clientId')
1629
+ if clientOrderId is not None:
1630
+ request['clientOrderId'] = clientOrderId
1631
+ else:
1632
+ request['orderId'] = id
1633
+ params = self.omit(params, ['clientOrderId', 'clientId'])
1634
+ response = self.privateGetV3OrderFills(self.extend(request, params))
1635
+ data = self.safe_dict(response, 'data', {})
1636
+ orders = self.safe_list(data, 'orders', [])
1637
+ return self.parse_trades(orders, None, since, limit)
1638
+
1639
+ def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1640
+ """
1641
+ fetches information on multiple orders made by the user *classic accounts only*
1642
+
1643
+ https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-get-trade-history
1644
+
1645
+ :param str symbol: unified market symbol of the market orders were made in
1646
+ :param int [since]: the earliest time in ms to fetch orders for
1647
+ :param int [limit]: the maximum number of order structures to retrieve, default 100
1648
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1649
+ :param dict [params.until]: end time
1650
+ :param boolean [params.side]: BUY or SELL
1651
+ :param str [params.orderType]: "LIMIT", "MARKET","STOP_LIMIT", "STOP_MARKET", "TAKE_PROFIT_LIMIT","TAKE_PROFIT_MARKET"
1652
+ :param boolean [params.page]: Page numbers start from 0
1653
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=trade-structure>`
1654
+ """
1655
+ self.load_markets()
1656
+ request: dict = {}
1657
+ market = None
1658
+ if symbol is not None:
1659
+ market = self.market(symbol)
1660
+ request['symbol'] = market['id']
1661
+ if since is not None:
1662
+ request['beginTimeInclusive'] = since
1663
+ if limit is not None:
1664
+ request['limit'] = limit
1665
+ endTimeExclusive = self.safe_integer_n(params, ['endTime', 'endTimeExclusive', 'until'])
1666
+ if endTimeExclusive is not None:
1667
+ request['endTimeExclusive'] = endTimeExclusive
1668
+ params = self.omit(params, ['endTime', 'endTimeExclusive', 'until'])
1669
+ response = self.privateGetV3Fills(self.extend(request, params))
1670
+ data = self.safe_dict(response, 'data', {})
1671
+ orders = self.safe_list(data, 'orders', [])
1672
+ return self.parse_trades(orders, market, since, limit)
1673
+
1674
+ def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
1675
+ """
1676
+ fetches information on multiple orders made by the user *classic accounts only*
1677
+
1678
+ https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-get-funding-rate
1679
+
1680
+ :param str symbol: unified market symbol of the market orders were made in
1681
+ :param int [since]: the earliest time in ms to fetch orders for
1682
+ :param int [limit]: the maximum number of order structures to retrieve, default 100
1683
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1684
+ :param dict [params.until]: end time, ms
1685
+ :param boolean [params.side]: BUY or SELL
1686
+ :param boolean [params.page]: Page numbers start from 0
1687
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=funding-history-structure>`
1688
+ """
1689
+ self.load_markets()
1690
+ request: dict = {}
1691
+ market = None
1692
+ if symbol is not None:
1693
+ market = self.market(symbol)
1694
+ request['symbol'] = market['id']
1695
+ if since is not None:
1696
+ request['beginTimeInclusive'] = since
1697
+ if limit is not None:
1698
+ request['limit'] = limit
1699
+ endTimeExclusive = self.safe_integer_n(params, ['endTime', 'endTimeExclusive', 'until'])
1700
+ if endTimeExclusive is not None:
1701
+ params = self.omit(params, ['endTime', 'endTimeExclusive', 'until'])
1702
+ request['endTimeExclusive'] = endTimeExclusive
1703
+ response = self.privateGetV3Funding(self.extend(request, params))
1704
+ data = self.safe_dict(response, 'data', {})
1705
+ fundingValues = self.safe_list(data, 'fundingValues', [])
1706
+ return self.parse_incomes(fundingValues, market, since, limit)
1707
+
1708
+ def parse_income(self, income, market: Market = None):
1709
+ #
1710
+ # {
1711
+ # "id": "1234",
1712
+ # "symbol": "BTC-USDT",
1713
+ # "fundingValue": "10000",
1714
+ # "rate": "0.0000125000",
1715
+ # "positionSize": "500",
1716
+ # "price": "90",
1717
+ # "side": "LONG",
1718
+ # "status": "SUCCESS",
1719
+ # "fundingTime": 1647502440973,
1720
+ # "transactionId": "1234556"
1721
+ # }
1722
+ #
1723
+ marketId = self.safe_string(income, 'symbol')
1724
+ market = self.safe_market(marketId, market, None, 'contract')
1725
+ code = 'USDT'
1726
+ timestamp = self.safe_integer(income, 'fundingTime')
1727
+ return {
1728
+ 'info': income,
1729
+ 'symbol': self.safe_symbol(marketId, market),
1730
+ 'code': code,
1731
+ 'timestamp': timestamp,
1732
+ 'datetime': self.iso8601(timestamp),
1733
+ 'id': self.safe_string(income, 'id'),
1734
+ 'amount': self.safe_number(income, 'fundingValue'),
1735
+ 'rate': self.safe_number(income, 'rate'),
1736
+ }
1737
+
1738
+ def set_leverage(self, leverage: int, symbol: Str = None, params={}):
1739
+ """
1740
+ set the level of leverage for a market
1741
+
1742
+ https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-post-sets-the-initial-margin-rate-of-a-contract
1743
+
1744
+ :param float leverage: the rate of leverage
1745
+ :param str symbol: unified market symbol
1746
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1747
+ :returns dict: response from the exchange
1748
+ """
1749
+ if symbol is None:
1750
+ raise ArgumentsRequired(self.id + ' setLeverage() requires a symbol argument')
1751
+ self.load_markets()
1752
+ market = self.market(symbol)
1753
+ leverageString = self.number_to_string(leverage)
1754
+ initialMarginRate = Precise.string_div('1', leverageString, 4)
1755
+ request: dict = {
1756
+ 'symbol': market['id'],
1757
+ 'initialMarginRate': initialMarginRate,
1758
+ }
1759
+ response = self.privatePostV3SetInitialMarginRate(self.extend(request, params))
1760
+ data = self.safe_dict(response, 'data', {})
1761
+ return data
1762
+
1763
+ def fetch_positions(self, symbols: Strings = None, params={}) -> List[Position]:
1764
+ """
1765
+ fetch all open positions
1766
+
1767
+ https://api-docs.pro.apex.exchange/#privateapi-v3-for-omni-get-retrieve-user-account-data
1768
+
1769
+ :param str[] [symbols]: list of unified market symbols
1770
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1771
+ :returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
1772
+ """
1773
+ self.load_markets()
1774
+ response = self.privateGetV3Account(params)
1775
+ data = self.safe_dict(response, 'data', {})
1776
+ positions = self.safe_list(data, 'positions', [])
1777
+ return self.parse_positions(positions, symbols)
1778
+
1779
+ def parse_position(self, position: dict, market: Market = None):
1780
+ #
1781
+ # {
1782
+ # "symbol": "BTC-USDT",
1783
+ # "status": "",
1784
+ # "side": "LONG",
1785
+ # "size": "0.000",
1786
+ # "entryPrice": "0.00",
1787
+ # "exitPrice": "",
1788
+ # "createdAt": 1690366452416,
1789
+ # "updatedTime": 1690366452416,
1790
+ # "fee": "0.000000",
1791
+ # "fundingFee": "0.000000",
1792
+ # "lightNumbers": "",
1793
+ # "customInitialMarginRate": "0"
1794
+ # }
1795
+ marketId = self.safe_string(position, 'symbol')
1796
+ market = self.safe_market(marketId, market)
1797
+ symbol = market['symbol']
1798
+ side = self.safe_string_lower(position, 'side')
1799
+ quantity = self.safe_string(position, 'size')
1800
+ timestamp = self.safe_integer(position, 'updatedTime')
1801
+ leverage = 20
1802
+ customInitialMarginRate = self.safe_string_n(position, ['customInitialMarginRate', 'customImr'], '0')
1803
+ if self.precision_from_string(customInitialMarginRate) != 0:
1804
+ leverage = self.parse_to_int(Precise.string_div('1', customInitialMarginRate, 4))
1805
+ return self.safe_position({
1806
+ 'info': position,
1807
+ 'id': self.safe_string(position, 'id'),
1808
+ 'symbol': symbol,
1809
+ 'entryPrice': self.safe_string(position, 'entryPrice'),
1810
+ 'markPrice': None,
1811
+ 'notional': None,
1812
+ 'collateral': None,
1813
+ 'unrealizedPnl': None,
1814
+ 'side': side,
1815
+ 'contracts': self.parse_number(quantity),
1816
+ 'contractSize': None,
1817
+ 'timestamp': timestamp,
1818
+ 'datetime': self.iso8601(timestamp),
1819
+ 'hedged': None,
1820
+ 'maintenanceMargin': None,
1821
+ 'maintenanceMarginPercentage': None,
1822
+ 'initialMargin': None,
1823
+ 'initialMarginPercentage': None,
1824
+ 'leverage': leverage,
1825
+ 'liquidationPrice': None,
1826
+ 'marginRatio': None,
1827
+ 'marginMode': None,
1828
+ 'percentage': None,
1829
+ })
1830
+
1831
+ def sign(self, path, api='public', method='GET', params={}, headers=None, body=None):
1832
+ url = self.implode_hostname(self.urls['api'][api]) + '/' + path
1833
+ headers = {
1834
+ 'User-Agent': 'apex-CCXT',
1835
+ 'Accept': 'application/json',
1836
+ 'Content-Type': 'application/x-www-form-urlencoded',
1837
+ }
1838
+ signPath = '/api/' + path
1839
+ signBody = body
1840
+ if method.upper() != 'POST':
1841
+ if params:
1842
+ signPath += '?' + self.rawencode(params)
1843
+ url += '?' + self.rawencode(params)
1844
+ else:
1845
+ sortedQuery = self.keysort(params)
1846
+ signBody = self.rawencode(sortedQuery)
1847
+ if api == 'private':
1848
+ self.check_required_credentials()
1849
+ timestamp = str(self.milliseconds())
1850
+ messageString = timestamp + method.upper() + signPath
1851
+ if signBody is not None:
1852
+ messageString = messageString + signBody
1853
+ signature = self.hmac(self.encode(messageString), self.encode(self.string_to_base64(self.secret)), hashlib.sha256, 'base64')
1854
+ headers['APEX-SIGNATURE'] = signature
1855
+ headers['APEX-API-KEY'] = self.apiKey
1856
+ headers['APEX-TIMESTAMP'] = timestamp
1857
+ headers['APEX-PASSPHRASE'] = self.password
1858
+ return {'url': url, 'method': method, 'body': signBody, 'headers': headers}
1859
+
1860
+ def handle_errors(self, code: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
1861
+ #
1862
+ # {"code":3,"msg":"Order price must be greater than 0. Order price is 0.","key":"ORDER_PRICE_MUST_GREETER_ZERO","detail":{"price":"0"}}
1863
+ # {"code":400,"msg":"strconv.ParseInt: parsing \"dsfdfsd\": invalid syntax","timeCost":5320995}
1864
+ #
1865
+ if response is None:
1866
+ return None
1867
+ errorCode = self.safe_integer(response, 'code')
1868
+ if errorCode is not None and errorCode != 0:
1869
+ feedback = self.id + ' ' + body
1870
+ message = self.safe_string_2(response, 'key', 'msg')
1871
+ self.throw_broadly_matched_exception(self.exceptions['broad'], message, feedback)
1872
+ status = str(code)
1873
+ self.throw_exactly_matched_exception(self.exceptions['exact'], status, feedback)
1874
+ raise ExchangeError(feedback)
1875
+ return None