ccxt-ir 4.3.46.0.3__py2.py3-none-any.whl → 4.5.1__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 +8 -8
  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 +10 -10
  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 +32 -38
  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 +32 -27
  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 +34 -30
  183. ccxt/async_support/sarmayex.py +9 -9
  184. ccxt/async_support/sarrafex.py +13 -13
  185. ccxt/async_support/tabdeal.py +15 -14
  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 +30 -36
  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 +29 -24
  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 +32 -28
  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 +13 -12
  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.1.dist-info}/METADATA +225 -73
  435. ccxt_ir-4.5.1.dist-info/RECORD +743 -0
  436. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.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.1.dist-info/licenses}/LICENSE.txt +0 -0
  529. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/top_level.txt +0 -0
ccxt/async_support/okx.py CHANGED
@@ -7,9 +7,8 @@ from ccxt.async_support.base.exchange import Exchange
7
7
  from ccxt.abstract.okx import ImplicitAPI
8
8
  import asyncio
9
9
  import hashlib
10
- from ccxt.base.types import Account, Balances, Conversion, CrossBorrowRate, CrossBorrowRates, Currencies, Currency, Greeks, Int, Leverage, LeverageTier, MarginModification, Market, MarketInterface, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry, TransferEntries
10
+ from ccxt.base.types import Account, Any, Balances, BorrowInterest, Conversion, CrossBorrowRate, CrossBorrowRates, Currencies, Currency, DepositAddress, Greeks, Int, LedgerEntry, Leverage, LeverageTier, LongShortRatio, MarginModification, Market, Num, Option, OptionChain, Order, OrderBook, OrderRequest, CancellationRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, FundingRates, OpenInterests, Trade, TradingFeeInterface, Transaction, MarketInterface, TransferEntry
11
11
  from typing import List
12
- from typing import Any
13
12
  from ccxt.base.errors import ExchangeError
14
13
  from ccxt.base.errors import AuthenticationError
15
14
  from ccxt.base.errors import PermissionDenied
@@ -18,11 +17,13 @@ from ccxt.base.errors import AccountSuspended
18
17
  from ccxt.base.errors import ArgumentsRequired
19
18
  from ccxt.base.errors import BadRequest
20
19
  from ccxt.base.errors import BadSymbol
20
+ from ccxt.base.errors import OperationRejected
21
+ from ccxt.base.errors import ManualInteractionNeeded
22
+ from ccxt.base.errors import RestrictedLocation
21
23
  from ccxt.base.errors import InsufficientFunds
22
24
  from ccxt.base.errors import InvalidAddress
23
25
  from ccxt.base.errors import InvalidOrder
24
26
  from ccxt.base.errors import OrderNotFound
25
- from ccxt.base.errors import CancelPending
26
27
  from ccxt.base.errors import ContractUnavailable
27
28
  from ccxt.base.errors import NotSupported
28
29
  from ccxt.base.errors import NetworkError
@@ -32,13 +33,14 @@ from ccxt.base.errors import ExchangeNotAvailable
32
33
  from ccxt.base.errors import OnMaintenance
33
34
  from ccxt.base.errors import InvalidNonce
34
35
  from ccxt.base.errors import RequestTimeout
36
+ from ccxt.base.errors import CancelPending
35
37
  from ccxt.base.decimal_to_precision import TICK_SIZE
36
38
  from ccxt.base.precise import Precise
37
39
 
38
40
 
39
41
  class okx(Exchange, ImplicitAPI):
40
42
 
41
- def describe(self):
43
+ def describe(self) -> Any:
42
44
  return self.deep_extend(super(okx, self).describe(), {
43
45
  'id': 'okx',
44
46
  'name': 'OKX',
@@ -80,6 +82,7 @@ class okx(Exchange, ImplicitAPI):
80
82
  'createTriggerOrder': True,
81
83
  'editOrder': True,
82
84
  'fetchAccounts': True,
85
+ 'fetchAllGreeks': True,
83
86
  'fetchBalance': True,
84
87
  'fetchBidsAsks': None,
85
88
  'fetchBorrowInterest': True,
@@ -104,9 +107,11 @@ class okx(Exchange, ImplicitAPI):
104
107
  'fetchDepositWithdrawFee': 'emulated',
105
108
  'fetchDepositWithdrawFees': True,
106
109
  'fetchFundingHistory': True,
110
+ 'fetchFundingInterval': True,
111
+ 'fetchFundingIntervals': False,
107
112
  'fetchFundingRate': True,
108
113
  'fetchFundingRateHistory': True,
109
- 'fetchFundingRates': False,
114
+ 'fetchFundingRates': True,
110
115
  'fetchGreeks': True,
111
116
  'fetchIndexOHLCV': True,
112
117
  'fetchIsolatedBorrowRate': False,
@@ -116,15 +121,20 @@ class okx(Exchange, ImplicitAPI):
116
121
  'fetchLedgerEntry': None,
117
122
  'fetchLeverage': True,
118
123
  'fetchLeverageTiers': False,
124
+ 'fetchLongShortRatio': False,
125
+ 'fetchLongShortRatioHistory': True,
119
126
  'fetchMarginAdjustmentHistory': True,
120
127
  'fetchMarketLeverageTiers': True,
121
128
  'fetchMarkets': True,
122
129
  'fetchMarkOHLCV': True,
130
+ 'fetchMarkPrice': True,
131
+ 'fetchMarkPrices': True,
123
132
  'fetchMySettlementHistory': False,
124
133
  'fetchMyTrades': True,
125
134
  'fetchOHLCV': True,
126
135
  'fetchOpenInterest': True,
127
136
  'fetchOpenInterestHistory': True,
137
+ 'fetchOpenInterests': True,
128
138
  'fetchOpenOrder': None,
129
139
  'fetchOpenOrders': True,
130
140
  'fetchOption': True,
@@ -134,7 +144,6 @@ class okx(Exchange, ImplicitAPI):
134
144
  'fetchOrderBooks': False,
135
145
  'fetchOrders': False,
136
146
  'fetchOrderTrades': True,
137
- 'fetchPermissions': None,
138
147
  'fetchPosition': True,
139
148
  'fetchPositionHistory': 'emulated',
140
149
  'fetchPositions': True,
@@ -257,6 +266,7 @@ class okx(Exchange, ImplicitAPI):
257
266
  'rubik/stat/margin/loan-ratio': 4,
258
267
  # long/short
259
268
  'rubik/stat/contracts/long-short-account-ratio': 4,
269
+ 'rubik/stat/contracts/long-short-account-ratio-contract': 4,
260
270
  'rubik/stat/contracts/open-interest-volume': 4,
261
271
  'rubik/stat/option/open-interest-volume': 4,
262
272
  # put/call
@@ -278,6 +288,7 @@ class okx(Exchange, ImplicitAPI):
278
288
  'tradingBot/public/rsi-back-testing': 1,
279
289
  'asset/exchange-list': 5 / 3,
280
290
  'finance/staking-defi/eth/apy-history': 5 / 3,
291
+ 'finance/staking-defi/sol/apy-history': 5 / 3,
281
292
  'finance/savings/lending-rate-summary': 5 / 3,
282
293
  'finance/savings/lending-rate-history': 5 / 3,
283
294
  'finance/fixed-loan/lending-offers': 10 / 3,
@@ -292,6 +303,7 @@ class okx(Exchange, ImplicitAPI):
292
303
  'copytrading/public-preference-currency': 4,
293
304
  'copytrading/public-current-subpositions': 4,
294
305
  'copytrading/public-subpositions-history': 4,
306
+ 'support/announcements-types': 20,
295
307
  },
296
308
  },
297
309
  'private': {
@@ -324,7 +336,9 @@ class okx(Exchange, ImplicitAPI):
324
336
  'trade/easy-convert-currency-list': 20,
325
337
  'trade/easy-convert-history': 20,
326
338
  'trade/one-click-repay-currency-list': 20,
339
+ 'trade/one-click-repay-currency-list-v2': 20,
327
340
  'trade/one-click-repay-history': 20,
341
+ 'trade/one-click-repay-history-v2': 20,
328
342
  'trade/account-rate-limit': 1,
329
343
  # asset
330
344
  'asset/currencies': 5 / 3,
@@ -343,12 +357,14 @@ class okx(Exchange, ImplicitAPI):
343
357
  'asset/convert/history': 5 / 3,
344
358
  'asset/monthly-statement': 2,
345
359
  # account
360
+ 'account/instruments': 1,
346
361
  'account/balance': 2,
347
362
  'account/positions': 2,
348
363
  'account/positions-history': 100,
349
364
  'account/account-position-risk': 2,
350
365
  'account/bills': 5 / 3,
351
366
  'account/bills-archive': 5 / 3,
367
+ 'account/bills-history-archive': 2,
352
368
  'account/config': 4,
353
369
  'account/max-size': 1,
354
370
  'account/max-avail-size': 1,
@@ -373,6 +389,10 @@ class okx(Exchange, ImplicitAPI):
373
389
  'account/fixed-loan/borrowing-limit': 4,
374
390
  'account/fixed-loan/borrowing-quote': 5,
375
391
  'account/fixed-loan/borrowing-orders-list': 5,
392
+ 'account/spot-manual-borrow-repay': 10,
393
+ 'account/set-auto-repay': 4,
394
+ 'account/spot-borrow-repay-history': 4,
395
+ 'account/move-positions-history': 10,
376
396
  # subaccount
377
397
  'users/subaccount/list': 10,
378
398
  'account/subaccount/balances': 10 / 3,
@@ -382,6 +402,7 @@ class okx(Exchange, ImplicitAPI):
382
402
  'asset/subaccount/managed-subaccount-bills': 5 / 3,
383
403
  'users/entrust-subaccount-list': 10,
384
404
  'account/subaccount/interest-limits': 4,
405
+ 'users/subaccount/apikey': 10,
385
406
  # grid trading
386
407
  'tradingBot/grid/orders-algo-pending': 1,
387
408
  'tradingBot/grid/orders-algo-history': 1,
@@ -409,6 +430,9 @@ class okx(Exchange, ImplicitAPI):
409
430
  # eth staking
410
431
  'finance/staking-defi/eth/balance': 5 / 3,
411
432
  'finance/staking-defi/eth/purchase-redeem-history': 5 / 3,
433
+ 'finance/staking-defi/eth/product-info': 3,
434
+ 'finance/staking-defi/sol/balance': 5 / 3,
435
+ 'finance/staking-defi/sol/purchase-redeem-history': 5 / 3,
412
436
  # copytrading
413
437
  'copytrading/current-subpositions': 1,
414
438
  'copytrading/subpositions-history': 1,
@@ -436,6 +460,7 @@ class okx(Exchange, ImplicitAPI):
436
460
  # affiliate
437
461
  'affiliate/invitee/detail': 1,
438
462
  'users/partner/if-rebate': 1,
463
+ 'support/announcements': 4,
439
464
  },
440
465
  'post': {
441
466
  # rfq
@@ -456,6 +481,7 @@ class okx(Exchange, ImplicitAPI):
456
481
  'sprd/cancel-order': 1,
457
482
  'sprd/mass-cancel': 1,
458
483
  'sprd/amend-order': 1,
484
+ 'sprd/cancel-all-after': 10,
459
485
  # trade
460
486
  'trade/order': 1 / 3,
461
487
  'trade/batch-orders': 1 / 15,
@@ -471,6 +497,7 @@ class okx(Exchange, ImplicitAPI):
471
497
  'trade/cancel-advance-algos': 1,
472
498
  'trade/easy-convert': 20,
473
499
  'trade/one-click-repay': 20,
500
+ 'trade/one-click-repay-v2': 20,
474
501
  'trade/mass-cancel': 4,
475
502
  'trade/cancel-all-after': 10,
476
503
  # asset
@@ -502,11 +529,16 @@ class okx(Exchange, ImplicitAPI):
502
529
  'account/fixed-loan/amend-borrowing-order': 5,
503
530
  'account/fixed-loan/manual-reborrow': 5,
504
531
  'account/fixed-loan/repay-borrowing-order': 5,
532
+ 'account/bills-history-archive': 72000, # 12 req/day
533
+ 'account/move-positions': 10,
505
534
  # subaccount
506
535
  'users/subaccount/modify-apikey': 10,
507
536
  'asset/subaccount/transfer': 10,
508
537
  'users/subaccount/set-transfer-out': 10,
509
538
  'account/subaccount/set-loan-allocation': 4,
539
+ 'users/subaccount/create-subaccount': 10,
540
+ 'users/subaccount/subaccount-apikey': 10,
541
+ 'users/subaccount/delete-apikey': 10,
510
542
  # grid trading
511
543
  'tradingBot/grid/order-algo': 1,
512
544
  'tradingBot/grid/amend-order-algo': 1,
@@ -540,6 +572,8 @@ class okx(Exchange, ImplicitAPI):
540
572
  # eth staking
541
573
  'finance/staking-defi/eth/purchase': 5,
542
574
  'finance/staking-defi/eth/redeem': 5,
575
+ 'finance/staking-defi/sol/purchase': 5,
576
+ 'finance/staking-defi/sol/redeem': 5,
543
577
  # copytrading
544
578
  'copytrading/algo-order': 1,
545
579
  'copytrading/close-subposition': 1,
@@ -596,6 +630,7 @@ class okx(Exchange, ImplicitAPI):
596
630
  # General Class
597
631
  '1': ExchangeError, # Operation failed
598
632
  '2': ExchangeError, # Bulk operation partially succeeded
633
+ '4088': ManualInteractionNeeded, # {"code":"4088","data":[],"msg":"You can’t trade or deposit until you’ve verified your identity again. Head to Identity Verification to complete it."}
599
634
  '50000': BadRequest, # Body can not be empty
600
635
  '50001': OnMaintenance, # Matching engine upgrading. Please try again later
601
636
  '50002': BadRequest, # Json data format error
@@ -728,6 +763,7 @@ class okx(Exchange, ImplicitAPI):
728
763
  '51137': InvalidOrder, # Your opening price has triggered the limit price, and the max buy price is {0}
729
764
  '51138': InvalidOrder, # Your opening price has triggered the limit price, and the min sell price is {0}
730
765
  '51139': InvalidOrder, # Reduce-only feature is unavailable for the spot transactions by simple account
766
+ '51155': RestrictedLocation, # {"code":"1","data":[{"clOrdId":"e847xxx","ordId":"","sCode":"51155","sMsg":"You can't trade self pair or borrow self crypto due to local compliance restrictions. ","tag":"e847xxx","ts":"1753979177157"}],"inTime":"1753979177157408","msg":"All operations failed","outTime":"1753979177157874"}
731
767
  '51156': BadRequest, # You're leading trades in long/short mode and can't use self API endpoint to close positions
732
768
  '51159': BadRequest, # You're leading trades in buy/sell mode. If you want to place orders using self API endpoint, the orders must be in the same direction existing positions and open orders.
733
769
  '51162': InvalidOrder, # You have {instrument} open orders. Cancel these orders and try again
@@ -813,6 +849,9 @@ class okx(Exchange, ImplicitAPI):
813
849
  # SPOT/MARGIN error codes 54000-54999
814
850
  '54000': ExchangeError, # Margin transactions unavailable
815
851
  '54001': ExchangeError, # Only Multi-currency margin account can be set to borrow coins automatically
852
+ '54008': InvalidOrder, # This operation is disabled by the 'mass cancel order' endpoint. Please enable it using self endpoint.
853
+ '54009': InvalidOrder, # The range of {param0} should be [{param1}, {param2}].
854
+ '54011': InvalidOrder, # 200 Pre-market trading contracts are only allowed to reduce the number of positions within 1 hour before delivery. Please modify or cancel the order.
816
855
  # Trading bot Error Code from 55100 to 55999
817
856
  '55100': InvalidOrder, # Take profit % should be within the range of {parameter1}-{parameter2}
818
857
  '55101': InvalidOrder, # Stop loss % should be within the range of {parameter1}-{parameter2}
@@ -897,6 +936,11 @@ class okx(Exchange, ImplicitAPI):
897
936
  '59301': ExchangeError, # Margin adjustment failed for exceeding the max limit
898
937
  '59313': ExchangeError, # Unable to repay. You haven't borrowed any {ccy} {ccyPair} in Quick margin mode.
899
938
  '59401': ExchangeError, # Holdings already reached the limit
939
+ '59410': OperationRejected, # You can only borrow self crypto if it supports borrowing and borrowing is enabled.
940
+ '59411': InsufficientFunds, # Manual borrowing failed. Your account's free margin is insufficient
941
+ '59412': OperationRejected, # Manual borrowing failed. The amount exceeds your borrowing limit.
942
+ '59413': OperationRejected, # You didn't borrow self crypto. No repayment needed.
943
+ '59414': BadRequest, # Manual borrowing failed. The minimum borrowing limit is {param0}.needed.
900
944
  '59500': ExchangeError, # Only the APIKey of the main account has permission
901
945
  '59501': ExchangeError, # Only 50 APIKeys can be created per account
902
946
  '59502': ExchangeError, # Note name cannot be duplicate with the currently created APIKey note name
@@ -906,6 +950,11 @@ class okx(Exchange, ImplicitAPI):
906
950
  '59506': ExchangeError, # APIKey does not exist
907
951
  '59507': ExchangeError, # The two accounts involved in a transfer must be two different sub accounts under the same parent account
908
952
  '59508': AccountSuspended, # The sub account of {0} is suspended
953
+ '59515': ExchangeError, # You are currently not on the custody whitelist. Please contact customer service for assistance.
954
+ '59516': ExchangeError, # Please create the Copper custody funding account first.
955
+ '59517': ExchangeError, # Please create the Komainu custody funding account first.
956
+ '59518': ExchangeError, # You can’t create a sub-account using the API; please use the app or web.
957
+ '59519': ExchangeError, # You can’t use self function/feature while it's frozen, due to: {freezereason}
909
958
  '59642': BadRequest, # Lead and copy traders can only use margin-free or single-currency margin account modes
910
959
  '59643': ExchangeError, # Couldn’t switch account modes’re currently copying spot trades
911
960
  # WebSocket error Codes from 60000-63999
@@ -949,6 +998,22 @@ class okx(Exchange, ImplicitAPI):
949
998
  '70010': BadRequest, # Timestamp parameters need to be in Unix timestamp format in milliseconds.
950
999
  '70013': BadRequest, # endTs needs to be bigger than or equal to beginTs.
951
1000
  '70016': BadRequest, # Please specify your instrument settings for at least one instType.
1001
+ '70060': BadRequest, # The account doesn’t exist or the position side is incorrect. To and from accounts must be under the same main account.
1002
+ '70061': BadRequest, # To move position, please enter a position that’s opposite to your current side and is smaller than or equal to your current size.
1003
+ '70062': BadRequest, # account has reached the maximum number of position transfers allowed per day.
1004
+ '70064': BadRequest, # Position does not exist.
1005
+ '70065': BadRequest, # Couldn’t move position. Execution price cannot be determined
1006
+ '70066': BadRequest, # Moving positions isn't supported in spot mode. Switch to any other account mode and try again.
1007
+ '70067': BadRequest, # Moving positions isn't supported in margin trading.
1008
+ '1009': BadRequest, # Request message exceeds the maximum frame length
1009
+ '4001': AuthenticationError, # Login Failed
1010
+ '4002': BadRequest, # Invalid Request
1011
+ '4003': RateLimitExceeded, # APIKey subscription amount exceeds the limit 100
1012
+ '4004': NetworkError, # No data received in 30s
1013
+ '4005': ExchangeNotAvailable, # Buffer is full, cannot write data
1014
+ '4006': BadRequest, # Abnormal disconnection
1015
+ '4007': AuthenticationError, # API key has been updated or deleted. Please reconnect.
1016
+ '4008': RateLimitExceeded, # The number of subscribed channels exceeds the maximum limit.
952
1017
  },
953
1018
  'broad': {
954
1019
  'Internal Server Error': ExchangeNotAvailable, # {"code":500,"data":{},"detailMsg":"","error_code":"500","error_message":"Internal Server Error","msg":"Internal Server Error"}
@@ -970,71 +1035,64 @@ class okx(Exchange, ImplicitAPI):
970
1035
  'networks': {
971
1036
  'BTC': 'Bitcoin',
972
1037
  'BTCLN': 'Lightning',
1038
+ 'BTCLIGHTNING': 'Lightning',
973
1039
  'BEP20': 'BSC',
1040
+ 'BRC20': 'BRC20',
974
1041
  'ERC20': 'ERC20',
975
1042
  'TRC20': 'TRC20',
976
1043
  'CRC20': 'Crypto',
977
- # sorted
978
1044
  'ACA': 'Acala',
979
1045
  'ALGO': 'Algorand',
980
- 'BHP': 'BHP',
981
1046
  'APT': 'Aptos',
1047
+ 'SCROLL': 'Scroll',
982
1048
  'ARBONE': 'Arbitrum One',
983
- 'AVAXC': 'Avalanche C',
1049
+ 'AVAXC': 'Avalanche C-Chain',
984
1050
  'AVAXX': 'Avalanche X-Chain',
985
- 'ARK': 'ARK',
1051
+ 'BASE': 'Base',
1052
+ 'SUI': 'SUI',
1053
+ 'ZKSYNCERA': 'zkSync Era',
1054
+ 'LINEA': 'Linea',
986
1055
  'AR': 'Arweave',
987
1056
  'ASTR': 'Astar',
988
1057
  'BCH': 'BitcoinCash',
989
1058
  'BSV': 'Bitcoin SV',
990
- 'BTM': 'Bytom',
991
1059
  'ADA': 'Cardano',
992
1060
  'CSPR': 'Casper',
993
1061
  'CELO': 'CELO',
994
1062
  'XCH': 'Chia',
995
- 'CHZ': 'Chiliz',
1063
+ # 'CHZ': 'Chiliz', TBD: Chiliz 2.0 Chain vs Chiliz Chain
996
1064
  'ATOM': 'Cosmos',
997
- 'TRUE': 'TrueChain',
998
- 'DCR': 'Decred',
999
1065
  'DGB': 'Digibyte',
1000
1066
  'DOGE': 'Dogecoin',
1001
- 'XEC': 'XEC',
1002
1067
  'EGLD': 'Elrond',
1068
+ 'CFX': 'Conflux', # CFX_EVM is different
1003
1069
  'EOS': 'EOS',
1070
+ 'CORE': 'CORE',
1004
1071
  'ETC': 'Ethereum Classic',
1005
1072
  'ETHW': 'EthereumPow',
1006
- 'FTM': 'Fantom',
1073
+ # 'FTM': 'Fantom', 'Sonic' TBD
1007
1074
  'FIL': 'Filecoin',
1008
- 'FLOW': 'FLOW',
1009
- 'FSN': 'Fusion',
1010
1075
  'ONE': 'Harmony',
1011
1076
  'HBAR': 'Hedera',
1012
- 'HNT': 'Helium',
1013
- 'ZEN': 'Horizen',
1014
1077
  'ICX': 'ICON',
1015
1078
  'ICP': 'Dfinity',
1016
1079
  'IOST': 'IOST',
1017
1080
  'IOTA': 'MIOTA',
1018
- 'KDA': 'Kadena',
1019
- 'KAR': 'KAR',
1020
1081
  'KLAY': 'Klaytn',
1021
1082
  'KSM': 'Kusama',
1022
1083
  'LSK': 'Lisk',
1023
1084
  'LTC': 'Litecoin',
1024
1085
  'METIS': 'Metis',
1025
1086
  'MINA': 'Mina',
1026
- 'XMR': 'Monero',
1027
1087
  'GLRM': 'Moonbeam',
1028
1088
  'MOVR': 'Moonriver',
1029
1089
  'NANO': 'Nano',
1030
1090
  'NEAR': 'NEAR',
1031
- 'NAS': 'Nebulas',
1032
- 'NEM': 'New Economy Movement',
1033
1091
  'NULS': 'NULS',
1034
1092
  'OASYS': 'OASYS',
1035
- 'OKC': 'OKC',
1036
1093
  'ONT': 'Ontology',
1037
1094
  'OPTIMISM': 'Optimism',
1095
+ # 'OP': 'Optimism', or Optimism(V2), TBD
1038
1096
  'LAT': 'PlatON',
1039
1097
  'DOT': 'Polkadot',
1040
1098
  'MATIC': 'Polygon',
@@ -1047,34 +1105,54 @@ class okx(Exchange, ImplicitAPI):
1047
1105
  'XTZ': 'Tezos',
1048
1106
  'TON': 'TON',
1049
1107
  'THETA': 'Theta',
1050
- 'VSYS': 'VSYSTEMS',
1051
- 'WAVES': 'WAVES',
1052
1108
  'WAX': 'Wax',
1053
- 'ZEC': 'Zcash',
1054
1109
  'ZIL': 'Zilliqa',
1055
- 'ZKSYNC': 'ZKSYNC',
1056
- # 'NEON3': 'N3', # tbd
1057
- # undetermined : "CELO-TOKEN", "Digital Cash", Khala
1058
- # todo: uncomment below after consensus
1059
- # 'AELF': 'AELF',
1060
- # 'BITCOINDIAMOND': 'Bitcoin Diamond',
1061
- # 'BITCOINGOLD': 'BitcoinGold',
1062
- # 'YOYOW': 'YOYOW',
1063
- # 'QTUM': 'Quantum',
1064
- # 'INTCHAIN': 'INTCHAIN',
1065
- # 'YOUCHAIN': 'YOUCHAIN',
1066
- # 'RONIN': 'Ronin',
1067
- # 'OEC': 'OEC',
1068
- # 'WAYIKICHAIN': 'WGRT',
1069
- # 'MDNA': 'DNA',
1070
- # 'STEP': 'Step Network',
1071
- # 'EMINER': 'Eminer',
1072
- # 'CYBERMILES': 'CyberMiles',
1073
- # 'HYPERCASH': 'HyperCash',
1074
- # 'CONFLUX': 'Conflux',
1075
- # 'CORTEX': 'Cortex',
1076
- # 'TERRA': 'Terra',
1077
- # 'TERRACLASSIC': 'Terra Classic',
1110
+ # non-supported known network: CRP. KAVA, TAIKO, BOB, GNO, BLAST, RSK, SEI, MANTLE, HYPE, RUNE, OSMO, XIN, WEMIX, HT, FSN, NEO, TLOS, CANTO, SCRT, AURORA, XMR
1111
+ # others:
1112
+ # "OKTC",
1113
+ # "X Layer",
1114
+ # "Polygon(Bridged)",
1115
+ # "BTCK-OKTC",
1116
+ # "ETHK-OKTC",
1117
+ # "Starknet",
1118
+ # "LTCK-OKTC",
1119
+ # "XRPK-OKTC",
1120
+ # "BCHK-OKTC",
1121
+ # "ETCK-OKTC",
1122
+ # "Endurance Smart Chain",
1123
+ # "Berachain",
1124
+ # "CELO-TOKEN",
1125
+ # "CFX_EVM",
1126
+ # "Cortex",
1127
+ # "DAIK-OKTC",
1128
+ # "Dora Vota Mainnet",
1129
+ # "DOTK-OKTC",
1130
+ # "DYDX",
1131
+ # "AELF",
1132
+ # "Enjin Relay Chain",
1133
+ # "FEVM",
1134
+ # "FILK-OKTC",
1135
+ # "Flare",
1136
+ # "Gravity Alpha Mainnet",
1137
+ # "INJ",
1138
+ # "Story",
1139
+ # "LINKK-OKTC",
1140
+ # "Terra",
1141
+ # "Terra Classic",
1142
+ # "Terra Classic(USTC)",
1143
+ # "MERLIN Network",
1144
+ # "Layer 3",
1145
+ # "PI",
1146
+ # "Ronin",
1147
+ # "Quantum",
1148
+ # "SHIBK-OKTC",
1149
+ # "SUSHIK-OKTC",
1150
+ # "Celestia",
1151
+ # "TRXK-OKTC",
1152
+ # "UNIK-OKTC",
1153
+ # "Venom",
1154
+ # "WBTCK-OKTC",
1155
+ # "ZetaChain",
1078
1156
  },
1079
1157
  'fetchOpenInterestHistory': {
1080
1158
  'timeframes': {
@@ -1097,7 +1175,11 @@ class okx(Exchange, ImplicitAPI):
1097
1175
  },
1098
1176
  'createOrder': 'privatePostTradeBatchOrders', # or 'privatePostTradeOrder' or 'privatePostTradeOrderAlgo'
1099
1177
  'createMarketBuyOrderRequiresPrice': False,
1100
- 'fetchMarkets': ['spot', 'future', 'swap', 'option'], # spot, future, swap, option
1178
+ 'fetchMarkets': {
1179
+ 'types': ['spot', 'future', 'swap', 'option'], # spot, future, swap, option
1180
+ },
1181
+ 'timeDifference': 0, # the difference between system clock and exchange server clock
1182
+ 'adjustForTimeDifference': False, # controls the adjustment logic upon instantiation
1101
1183
  'defaultType': 'spot', # 'funding', 'spot', 'margin', 'future', 'swap', 'option'
1102
1184
  # 'fetchBalance': {
1103
1185
  # 'type': 'spot', # 'funding', 'trading', 'spot'
@@ -1164,6 +1246,101 @@ class okx(Exchange, ImplicitAPI):
1164
1246
  },
1165
1247
  'brokerId': 'e847386590ce4dBC',
1166
1248
  },
1249
+ 'features': {
1250
+ 'default': {
1251
+ 'sandbox': True,
1252
+ 'createOrder': {
1253
+ 'marginMode': True,
1254
+ 'triggerPrice': True,
1255
+ 'triggerPriceType': {
1256
+ 'last': True,
1257
+ 'mark': True,
1258
+ 'index': True,
1259
+ },
1260
+ 'triggerDirection': False,
1261
+ 'stopLossPrice': True,
1262
+ 'takeProfitPrice': True,
1263
+ 'attachedStopLossTakeProfit': {
1264
+ 'triggerPriceType': {
1265
+ 'last': True,
1266
+ 'mark': True,
1267
+ 'index': True,
1268
+ },
1269
+ 'price': True,
1270
+ },
1271
+ 'timeInForce': {
1272
+ 'IOC': True,
1273
+ 'FOK': True,
1274
+ 'PO': True,
1275
+ 'GTD': False,
1276
+ },
1277
+ 'hedged': True,
1278
+ 'trailing': True,
1279
+ 'iceberg': True, # todo implement
1280
+ 'leverage': False,
1281
+ 'selfTradePrevention': True, # todo implement
1282
+ 'marketBuyByCost': True,
1283
+ 'marketBuyRequiresPrice': False,
1284
+ },
1285
+ 'createOrders': {
1286
+ 'max': 20,
1287
+ },
1288
+ 'fetchMyTrades': {
1289
+ 'marginMode': False,
1290
+ 'daysBack': 90,
1291
+ 'limit': 100,
1292
+ 'untilDays': 10000,
1293
+ 'symbolRequired': False,
1294
+ },
1295
+ 'fetchOrder': {
1296
+ 'marginMode': False,
1297
+ 'trigger': True,
1298
+ 'trailing': True,
1299
+ 'symbolRequired': True,
1300
+ },
1301
+ 'fetchOpenOrders': {
1302
+ 'marginMode': False,
1303
+ 'limit': 100,
1304
+ 'trigger': True,
1305
+ 'trailing': True,
1306
+ 'symbolRequired': False,
1307
+ },
1308
+ 'fetchOrders': None, # not supported
1309
+ 'fetchClosedOrders': {
1310
+ 'marginMode': False,
1311
+ 'limit': 100,
1312
+ 'daysBack': 90, # 3 months
1313
+ 'daysBackCanceled': 1 / 12, # 2 hour
1314
+ 'untilDays': None,
1315
+ 'trigger': True,
1316
+ 'trailing': True,
1317
+ 'symbolRequired': False,
1318
+ },
1319
+ 'fetchOHLCV': {
1320
+ 'limit': 300,
1321
+ 'historical': 100,
1322
+ },
1323
+ },
1324
+ 'spot': {
1325
+ 'extends': 'default',
1326
+ },
1327
+ 'swap': {
1328
+ 'linear': {
1329
+ 'extends': 'default',
1330
+ },
1331
+ 'inverse': {
1332
+ 'extends': 'default',
1333
+ },
1334
+ },
1335
+ 'future': {
1336
+ 'linear': {
1337
+ 'extends': 'default',
1338
+ },
1339
+ 'inverse': {
1340
+ 'extends': 'default',
1341
+ },
1342
+ },
1343
+ },
1167
1344
  'commonCurrencies': {
1168
1345
  # the exchange refers to ERC20 version of Aeternity(AEToken)
1169
1346
  'AE': 'AET', # https://github.com/ccxt/ccxt/issues/4981
@@ -1254,7 +1431,9 @@ class okx(Exchange, ImplicitAPI):
1254
1431
  async def fetch_status(self, params={}):
1255
1432
  """
1256
1433
  the latest known information on the availability of the exchange API
1257
- :see: https://www.okx.com/docs-v5/en/#status-get-status
1434
+
1435
+ https://www.okx.com/docs-v5/en/#status-get-status
1436
+
1258
1437
  :param dict [params]: extra parameters specific to the exchange API endpoint
1259
1438
  :returns dict: a `status structure <https://docs.ccxt.com/#/?id=exchange-status-structure>`
1260
1439
  """
@@ -1303,10 +1482,12 @@ class okx(Exchange, ImplicitAPI):
1303
1482
  update['status'] = 'ok'
1304
1483
  return update
1305
1484
 
1306
- async def fetch_time(self, params={}):
1485
+ async def fetch_time(self, params={}) -> Int:
1307
1486
  """
1308
1487
  fetches the current integer timestamp in milliseconds from the exchange server
1309
- :see: https://www.okx.com/docs-v5/en/#public-data-rest-api-get-system-time
1488
+
1489
+ https://www.okx.com/docs-v5/en/#public-data-rest-api-get-system-time
1490
+
1310
1491
  :param dict [params]: extra parameters specific to the exchange API endpoint
1311
1492
  :returns int: the current integer timestamp in milliseconds from the exchange server
1312
1493
  """
@@ -1327,7 +1508,9 @@ class okx(Exchange, ImplicitAPI):
1327
1508
  async def fetch_accounts(self, params={}) -> List[Account]:
1328
1509
  """
1329
1510
  fetch all the accounts associated with a profile
1330
- :see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-account-configuration
1511
+
1512
+ https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-account-configuration
1513
+
1331
1514
  :param dict [params]: extra parameters specific to the exchange API endpoint
1332
1515
  :returns dict: a dictionary of `account structures <https://docs.ccxt.com/#/?id=account-structure>` indexed by the account type
1333
1516
  """
@@ -1366,14 +1549,26 @@ class okx(Exchange, ImplicitAPI):
1366
1549
  })
1367
1550
  return result
1368
1551
 
1552
+ def nonce(self):
1553
+ return self.milliseconds() - self.options['timeDifference']
1554
+
1369
1555
  async def fetch_markets(self, params={}) -> List[Market]:
1370
1556
  """
1371
1557
  retrieves data on all markets for okx
1372
- :see: https://www.okx.com/docs-v5/en/#rest-api-public-data-get-instruments
1558
+
1559
+ https://www.okx.com/docs-v5/en/#rest-api-public-data-get-instruments
1560
+
1373
1561
  :param dict [params]: extra parameters specific to the exchange API endpoint
1374
1562
  :returns dict[]: an array of objects representing market data
1375
1563
  """
1376
- types = self.safe_list(self.options, 'fetchMarkets', [])
1564
+ if self.options['adjustForTimeDifference']:
1565
+ await self.load_time_difference()
1566
+ types = ['spot', 'future', 'swap', 'option']
1567
+ fetchMarketsOption = self.safe_dict(self.options, 'fetchMarkets')
1568
+ if fetchMarketsOption is not None:
1569
+ types = self.safe_list(fetchMarketsOption, 'types', types)
1570
+ else:
1571
+ types = self.safe_list(self.options, 'fetchMarkets', types) # backward-support
1377
1572
  promises = []
1378
1573
  result = []
1379
1574
  for i in range(0, len(types)):
@@ -1422,6 +1617,7 @@ class okx(Exchange, ImplicitAPI):
1422
1617
  # "instType": "OPTION",
1423
1618
  # "lever": "",
1424
1619
  # "listTime": "1631262612280",
1620
+ # "contTdSwTime": "1631262812280",
1425
1621
  # "lotSz": "1",
1426
1622
  # "minSz": "1",
1427
1623
  # "optType": "P",
@@ -1442,8 +1638,8 @@ class okx(Exchange, ImplicitAPI):
1442
1638
  swap = (type == 'swap')
1443
1639
  option = (type == 'option')
1444
1640
  contract = swap or future or option
1445
- baseId = self.safe_string(market, 'baseCcy')
1446
- quoteId = self.safe_string(market, 'quoteCcy')
1641
+ baseId = self.safe_string(market, 'baseCcy', '') # defaulting to '' because some weird preopen markets have empty baseId
1642
+ quoteId = self.safe_string(market, 'quoteCcy', '')
1447
1643
  settleId = self.safe_string(market, 'settleCcy')
1448
1644
  settle = self.safe_currency_code(settleId)
1449
1645
  underlying = self.safe_string(market, 'uly')
@@ -1458,18 +1654,21 @@ class okx(Exchange, ImplicitAPI):
1458
1654
  strikePrice = None
1459
1655
  optionType = None
1460
1656
  if contract:
1461
- symbol = symbol + ':' + settle
1462
- expiry = self.safe_integer(market, 'expTime')
1657
+ if settle is not None:
1658
+ symbol = symbol + ':' + settle
1463
1659
  if future:
1464
- ymd = self.yymmdd(expiry)
1465
- symbol = symbol + '-' + ymd
1660
+ expiry = self.safe_integer(market, 'expTime')
1661
+ if expiry is not None:
1662
+ ymd = self.yymmdd(expiry)
1663
+ symbol = symbol + '-' + ymd
1466
1664
  elif option:
1665
+ expiry = self.safe_integer(market, 'expTime')
1467
1666
  strikePrice = self.safe_string(market, 'stk')
1468
1667
  optionType = self.safe_string(market, 'optType')
1469
- ymd = self.yymmdd(expiry)
1470
- symbol = symbol + '-' + ymd + '-' + strikePrice + '-' + optionType
1471
- optionType = 'put' if (optionType == 'P') else 'call'
1472
- tickSize = self.safe_string(market, 'tickSz')
1668
+ if expiry is not None:
1669
+ ymd = self.yymmdd(expiry)
1670
+ symbol = symbol + '-' + ymd + '-' + strikePrice + '-' + optionType
1671
+ optionType = 'put' if (optionType == 'P') else 'call'
1473
1672
  fees = self.safe_dict_2(self.fees, type, 'trading', {})
1474
1673
  maxLeverage = self.safe_string(market, 'lever', '1')
1475
1674
  maxLeverage = Precise.string_max(maxLeverage, '1')
@@ -1496,12 +1695,12 @@ class okx(Exchange, ImplicitAPI):
1496
1695
  'contractSize': self.safe_number(market, 'ctVal') if contract else None,
1497
1696
  'expiry': expiry,
1498
1697
  'expiryDatetime': self.iso8601(expiry),
1499
- 'strike': strikePrice,
1698
+ 'strike': self.parse_number(strikePrice),
1500
1699
  'optionType': optionType,
1501
- 'created': self.safe_integer(market, 'listTime'),
1700
+ 'created': self.safe_integer_2(market, 'contTdSwTime', 'listTime'), # contTdSwTime is public trading start time, while listTime considers pre-trading too
1502
1701
  'precision': {
1503
1702
  'amount': self.safe_number(market, 'lotSz'),
1504
- 'price': self.parse_number(tickSize),
1703
+ 'price': self.safe_number(market, 'tickSz'),
1505
1704
  },
1506
1705
  'limits': {
1507
1706
  'leverage': {
@@ -1579,18 +1778,12 @@ class okx(Exchange, ImplicitAPI):
1579
1778
  dataResponse = self.safe_list(response, 'data', [])
1580
1779
  return self.parse_markets(dataResponse)
1581
1780
 
1582
- def safe_network(self, networkId):
1583
- networksById: dict = {
1584
- 'Bitcoin': 'BTC',
1585
- 'Omni': 'OMNI',
1586
- 'TRON': 'TRC20',
1587
- }
1588
- return self.safe_string(networksById, networkId, networkId)
1589
-
1590
1781
  async def fetch_currencies(self, params={}) -> Currencies:
1591
1782
  """
1592
1783
  fetches all available currencies on an exchange
1593
- :see: https://www.okx.com/docs-v5/en/#rest-api-funding-get-currencies
1784
+
1785
+ https://www.okx.com/docs-v5/en/#rest-api-funding-get-currencies
1786
+
1594
1787
  :param dict [params]: extra parameters specific to the exchange API endpoint
1595
1788
  :returns dict: an associative dictionary of currencies
1596
1789
  """
@@ -1660,70 +1853,63 @@ class okx(Exchange, ImplicitAPI):
1660
1853
  code = currency['code']
1661
1854
  chains = dataByCurrencyId[currencyId]
1662
1855
  networks: dict = {}
1663
- currencyActive = False
1664
- depositEnabled = False
1665
- withdrawEnabled = False
1666
- maxPrecision = None
1667
- for j in range(0, len(chains)):
1856
+ type = 'crypto'
1857
+ chainsLength = len(chains)
1858
+ for j in range(0, chainsLength):
1668
1859
  chain = chains[j]
1669
- canDeposit = self.safe_bool(chain, 'canDep')
1670
- depositEnabled = canDeposit if (canDeposit) else depositEnabled
1671
- canWithdraw = self.safe_bool(chain, 'canWd')
1672
- withdrawEnabled = canWithdraw if (canWithdraw) else withdrawEnabled
1673
- canInternal = self.safe_bool(chain, 'canInternal')
1674
- active = True if (canDeposit and canWithdraw and canInternal) else False
1675
- currencyActive = active if (active) else currencyActive
1676
- networkId = self.safe_string(chain, 'chain')
1677
- if (networkId is not None) and (networkId.find('-') >= 0):
1678
- parts = networkId.split('-')
1679
- chainPart = self.safe_string(parts, 1, networkId)
1680
- networkCode = self.network_id_to_code(chainPart, currency['code'])
1681
- precision = self.parse_precision(self.safe_string(chain, 'wdTickSz'))
1682
- if maxPrecision is None:
1683
- maxPrecision = precision
1684
- else:
1685
- maxPrecision = Precise.string_min(maxPrecision, precision)
1686
- networks[networkCode] = {
1687
- 'id': networkId,
1688
- 'network': networkCode,
1689
- 'active': active,
1690
- 'deposit': canDeposit,
1691
- 'withdraw': canWithdraw,
1692
- 'fee': self.safe_number(chain, 'minFee'),
1693
- 'precision': self.parse_number(precision),
1694
- 'limits': {
1695
- 'withdraw': {
1696
- 'min': self.safe_number(chain, 'minWd'),
1697
- 'max': self.safe_number(chain, 'maxWd'),
1698
- },
1860
+ # allow empty string for rare fiat-currencies, e.g. TRY
1861
+ networkId = self.safe_string(chain, 'chain', '') # USDT-BEP20, USDT-Avalance-C, etc
1862
+ if networkId == '':
1863
+ # only happens for fiat 'TRY' currency
1864
+ type = 'fiat'
1865
+ idParts = networkId.split('-')
1866
+ parts = self.array_slice(idParts, 1)
1867
+ chainPart = '-'.join(parts)
1868
+ networkCode = self.network_id_to_code(chainPart, currency['code'])
1869
+ networks[networkCode] = {
1870
+ 'id': networkId,
1871
+ 'network': networkCode,
1872
+ 'active': None,
1873
+ 'deposit': self.safe_bool(chain, 'canDep'),
1874
+ 'withdraw': self.safe_bool(chain, 'canWd'),
1875
+ 'fee': self.safe_number(chain, 'fee'),
1876
+ 'precision': self.parse_number(self.parse_precision(self.safe_string(chain, 'wdTickSz'))),
1877
+ 'limits': {
1878
+ 'withdraw': {
1879
+ 'min': self.safe_number(chain, 'minWd'),
1880
+ 'max': self.safe_number(chain, 'maxWd'),
1699
1881
  },
1700
- 'info': chain,
1701
- }
1882
+ },
1883
+ 'info': chain,
1884
+ }
1702
1885
  firstChain = self.safe_dict(chains, 0, {})
1703
- result[code] = {
1704
- 'info': None,
1886
+ result[code] = self.safe_currency_structure({
1887
+ 'info': chains,
1705
1888
  'code': code,
1706
1889
  'id': currencyId,
1707
1890
  'name': self.safe_string(firstChain, 'name'),
1708
- 'active': currencyActive,
1709
- 'deposit': depositEnabled,
1710
- 'withdraw': withdrawEnabled,
1891
+ 'active': None,
1892
+ 'deposit': None,
1893
+ 'withdraw': None,
1711
1894
  'fee': None,
1712
- 'precision': self.parse_number(maxPrecision),
1895
+ 'precision': None,
1713
1896
  'limits': {
1714
1897
  'amount': {
1715
1898
  'min': None,
1716
1899
  'max': None,
1717
1900
  },
1718
1901
  },
1902
+ 'type': type,
1719
1903
  'networks': networks,
1720
- }
1904
+ })
1721
1905
  return result
1722
1906
 
1723
1907
  async def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
1724
1908
  """
1725
1909
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
1726
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-order-book
1910
+
1911
+ https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-order-book
1912
+
1727
1913
  :param str symbol: unified symbol of the market to fetch the order book for
1728
1914
  :param int [limit]: the maximum amount of order book entries to return
1729
1915
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -1774,6 +1960,13 @@ class okx(Exchange, ImplicitAPI):
1774
1960
  return self.parse_order_book(first, symbol, timestamp)
1775
1961
 
1776
1962
  def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
1963
+ #
1964
+ # {
1965
+ # "instType":"SWAP",
1966
+ # "instId":"BTC-USDT-SWAP",
1967
+ # "markPx":"200",
1968
+ # "ts":"1597026383085"
1969
+ # }
1777
1970
  #
1778
1971
  # {
1779
1972
  # "instType": "SPOT",
@@ -1793,6 +1986,16 @@ class okx(Exchange, ImplicitAPI):
1793
1986
  # "sodUtc0": "0.07872",
1794
1987
  # "sodUtc8": "0.07345"
1795
1988
  # }
1989
+ # {
1990
+ # instId: 'LTC-USDT',
1991
+ # idxPx: '65.74',
1992
+ # open24h: '65.37',
1993
+ # high24h: '66.15',
1994
+ # low24h: '64.97',
1995
+ # sodUtc0: '65.68',
1996
+ # sodUtc8: '65.54',
1997
+ # ts: '1728467346900'
1998
+ # },
1796
1999
  #
1797
2000
  timestamp = self.safe_integer(ticker, 'ts')
1798
2001
  marketId = self.safe_string(ticker, 'instId')
@@ -1825,13 +2028,17 @@ class okx(Exchange, ImplicitAPI):
1825
2028
  'average': None,
1826
2029
  'baseVolume': baseVolume,
1827
2030
  'quoteVolume': quoteVolume,
2031
+ 'markPrice': self.safe_string(ticker, 'markPx'),
2032
+ 'indexPrice': self.safe_string(ticker, 'idxPx'),
1828
2033
  'info': ticker,
1829
2034
  }, market)
1830
2035
 
1831
2036
  async def fetch_ticker(self, symbol: str, params={}) -> Ticker:
1832
2037
  """
1833
2038
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
1834
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-ticker
2039
+
2040
+ https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-ticker
2041
+
1835
2042
  :param str symbol: unified symbol of the market to fetch the ticker for
1836
2043
  :param dict [params]: extra parameters specific to the exchange API endpoint
1837
2044
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -1875,7 +2082,9 @@ class okx(Exchange, ImplicitAPI):
1875
2082
  async def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
1876
2083
  """
1877
2084
  fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
1878
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-tickers
2085
+
2086
+ https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-tickers
2087
+
1879
2088
  :param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
1880
2089
  :param dict [params]: extra parameters specific to the exchange API endpoint
1881
2090
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -1925,6 +2134,68 @@ class okx(Exchange, ImplicitAPI):
1925
2134
  tickers = self.safe_list(response, 'data', [])
1926
2135
  return self.parse_tickers(tickers, symbols)
1927
2136
 
2137
+ async def fetch_mark_price(self, symbol: str, params={}) -> Ticker:
2138
+ """
2139
+ fetches mark price for the market
2140
+
2141
+ https://www.okx.com/docs-v5/en/#public-data-rest-api-get-mark-price
2142
+
2143
+ :param str symbol: unified symbol of the market to fetch the ticker for
2144
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2145
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
2146
+ """
2147
+ await self.load_markets()
2148
+ market = self.market(symbol)
2149
+ request: dict = {
2150
+ 'instId': market['id'],
2151
+ }
2152
+ response = await self.publicGetPublicMarkPrice(self.extend(request, params))
2153
+ #
2154
+ # {
2155
+ # "code": "0",
2156
+ # "data": [
2157
+ # {
2158
+ # "instId": "ETH-USDT",
2159
+ # "instType": "MARGIN",
2160
+ # "markPx": "2403.98",
2161
+ # "ts": "1728578500703"
2162
+ # }
2163
+ # ],
2164
+ # "msg": ""
2165
+ # }
2166
+ #
2167
+ data = self.safe_list(response, 'data')
2168
+ return self.parse_ticker(self.safe_dict(data, 0), market)
2169
+
2170
+ async def fetch_mark_prices(self, symbols: Strings = None, params={}) -> Tickers:
2171
+ """
2172
+ fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
2173
+
2174
+ https://www.okx.com/docs-v5/en/#public-data-rest-api-get-mark-price
2175
+
2176
+ :param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
2177
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2178
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
2179
+ """
2180
+ await self.load_markets()
2181
+ symbols = self.market_symbols(symbols)
2182
+ market = self.get_market_from_symbols(symbols)
2183
+ marketType = None
2184
+ marketType, params = self.handle_market_type_and_params('fetchTickers', market, params, 'swap')
2185
+ request: dict = {
2186
+ 'instType': self.convert_to_instrument_type(marketType),
2187
+ }
2188
+ if marketType == 'option':
2189
+ defaultUnderlying = self.safe_string(self.options, 'defaultUnderlying', 'BTC-USD')
2190
+ currencyId = self.safe_string_2(params, 'uly', 'marketId', defaultUnderlying)
2191
+ if currencyId is None:
2192
+ raise ArgumentsRequired(self.id + ' fetchMarkPrices() requires an underlying uly or marketId parameter for options markets')
2193
+ else:
2194
+ request['uly'] = currencyId
2195
+ response = await self.publicGetPublicMarkPrice(self.extend(request, params))
2196
+ tickers = self.safe_list(response, 'data', [])
2197
+ return self.parse_tickers(tickers, symbols)
2198
+
1928
2199
  def parse_trade(self, trade: dict, market: Market = None) -> Trade:
1929
2200
  #
1930
2201
  # public fetchTrades
@@ -2018,12 +2289,15 @@ class okx(Exchange, ImplicitAPI):
2018
2289
  async def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
2019
2290
  """
2020
2291
  get the list of most recent trades for a particular symbol
2021
- :see: https://www.okx.com/docs-v5/en/#rest-api-market-data-get-trades
2022
- :see: https://www.okx.com/docs-v5/en/#rest-api-public-data-get-option-trades
2292
+
2293
+ https://www.okx.com/docs-v5/en/#rest-api-market-data-get-trades
2294
+ https://www.okx.com/docs-v5/en/#rest-api-public-data-get-option-trades
2295
+
2023
2296
  :param str symbol: unified symbol of the market to fetch trades for
2024
2297
  :param int [since]: timestamp in ms of the earliest trade to fetch
2025
2298
  :param int [limit]: the maximum amount of trades to fetch
2026
2299
  :param dict [params]: extra parameters specific to the exchange API endpoint
2300
+ :param str [params.method]: 'publicGetMarketTrades' or 'publicGetMarketHistoryTrades' default is 'publicGetMarketTrades'
2027
2301
  :param boolean [params.paginate]: *only applies to publicGetMarketHistoryTrades* default False, when True will automatically paginate by calling self endpoint multiple times
2028
2302
  :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
2029
2303
  """
@@ -2114,12 +2388,14 @@ class okx(Exchange, ImplicitAPI):
2114
2388
  async def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
2115
2389
  """
2116
2390
  fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
2117
- :see: https://www.okx.com/docs-v5/en/#rest-api-market-data-get-candlesticks
2118
- :see: https://www.okx.com/docs-v5/en/#rest-api-market-data-get-candlesticks-history
2119
- :see: https://www.okx.com/docs-v5/en/#rest-api-market-data-get-mark-price-candlesticks
2120
- :see: https://www.okx.com/docs-v5/en/#rest-api-market-data-get-mark-price-candlesticks-history
2121
- :see: https://www.okx.com/docs-v5/en/#rest-api-market-data-get-index-candlesticks
2122
- :see: https://www.okx.com/docs-v5/en/#rest-api-market-data-get-index-candlesticks-history
2391
+
2392
+ https://www.okx.com/docs-v5/en/#rest-api-market-data-get-candlesticks
2393
+ https://www.okx.com/docs-v5/en/#rest-api-market-data-get-candlesticks-history
2394
+ https://www.okx.com/docs-v5/en/#rest-api-market-data-get-mark-price-candlesticks
2395
+ https://www.okx.com/docs-v5/en/#rest-api-market-data-get-mark-price-candlesticks-history
2396
+ https://www.okx.com/docs-v5/en/#rest-api-market-data-get-index-candlesticks
2397
+ https://www.okx.com/docs-v5/en/#rest-api-market-data-get-index-candlesticks-history
2398
+
2123
2399
  :param str symbol: unified symbol of the market to fetch OHLCV data for
2124
2400
  :param str timeframe: the length of time each candle represents
2125
2401
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -2142,6 +2418,8 @@ class okx(Exchange, ImplicitAPI):
2142
2418
  timezone = self.safe_string(options, 'timezone', 'UTC')
2143
2419
  if limit is None:
2144
2420
  limit = 100 # default 100, max 100
2421
+ else:
2422
+ limit = min(limit, 300) # max 100
2145
2423
  duration = self.parse_timeframe(timeframe)
2146
2424
  bar = self.safe_string(self.timeframes, timeframe, timeframe)
2147
2425
  if (timezone == 'UTC') and (duration >= 21600): # if utc and timeframe >= 6h
@@ -2159,6 +2437,7 @@ class okx(Exchange, ImplicitAPI):
2159
2437
  historyBorder = now - ((1440 - 1) * durationInMilliseconds)
2160
2438
  if since < historyBorder:
2161
2439
  defaultType = 'HistoryCandles'
2440
+ limit = min(limit, 100) # max 100 for historical endpoint
2162
2441
  startTime = max(since - 1, 0)
2163
2442
  request['before'] = startTime
2164
2443
  request['after'] = self.sum(since, durationInMilliseconds * limit)
@@ -2204,7 +2483,9 @@ class okx(Exchange, ImplicitAPI):
2204
2483
  async def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
2205
2484
  """
2206
2485
  fetches historical funding rate prices
2207
- :see: https://www.okx.com/docs-v5/en/#public-data-rest-api-get-funding-rate-history
2486
+
2487
+ https://www.okx.com/docs-v5/en/#public-data-rest-api-get-funding-rate-history
2488
+
2208
2489
  :param str symbol: unified symbol of the market to fetch the funding rate history for
2209
2490
  :param int [since]: timestamp in ms of the earliest funding rate to fetch
2210
2491
  :param int [limit]: the maximum amount of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>` to fetch
@@ -2285,11 +2566,11 @@ class okx(Exchange, ImplicitAPI):
2285
2566
  # it may be incorrect to use total, free and used for swap accounts
2286
2567
  eq = self.safe_string(balance, 'eq')
2287
2568
  availEq = self.safe_string(balance, 'availEq')
2288
- if (eq is None) or (availEq is None):
2569
+ account['total'] = eq
2570
+ if availEq is None:
2289
2571
  account['free'] = self.safe_string(balance, 'availBal')
2290
2572
  account['used'] = self.safe_string(balance, 'frozenBal')
2291
2573
  else:
2292
- account['total'] = eq
2293
2574
  account['free'] = availEq
2294
2575
  result[code] = account
2295
2576
  result['timestamp'] = timestamp
@@ -2338,7 +2619,9 @@ class okx(Exchange, ImplicitAPI):
2338
2619
  async def fetch_trading_fee(self, symbol: str, params={}) -> TradingFeeInterface:
2339
2620
  """
2340
2621
  fetch the trading fees for a market
2341
- :see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-fee-rates
2622
+
2623
+ https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-fee-rates
2624
+
2342
2625
  :param str symbol: unified market symbol
2343
2626
  :param dict [params]: extra parameters specific to the exchange API endpoint
2344
2627
  :returns dict: a `fee structure <https://docs.ccxt.com/#/?id=fee-structure>`
@@ -2383,8 +2666,10 @@ class okx(Exchange, ImplicitAPI):
2383
2666
  async def fetch_balance(self, params={}) -> Balances:
2384
2667
  """
2385
2668
  query for balance and get the amount of funds available for trading or funds locked in orders
2386
- :see: https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-balance
2387
- :see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-balance
2669
+
2670
+ https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-balance
2671
+ https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-balance
2672
+
2388
2673
  :param dict [params]: extra parameters specific to the exchange API endpoint
2389
2674
  :param str [params.type]: wallet type, ['funding' or 'trading'] default is 'trading'
2390
2675
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
@@ -2505,7 +2790,9 @@ class okx(Exchange, ImplicitAPI):
2505
2790
 
2506
2791
  async def create_market_buy_order_with_cost(self, symbol: str, cost: float, params={}):
2507
2792
  """
2508
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-order
2793
+
2794
+ https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-order
2795
+
2509
2796
  create a market buy order by providing the symbol and cost
2510
2797
  :param str symbol: unified symbol of the market to create an order in
2511
2798
  :param float cost: how much you want to trade in units of the quote currency
@@ -2516,13 +2803,17 @@ class okx(Exchange, ImplicitAPI):
2516
2803
  market = self.market(symbol)
2517
2804
  if not market['spot']:
2518
2805
  raise NotSupported(self.id + ' createMarketBuyOrderWithCost() supports spot markets only')
2519
- params['createMarketBuyOrderRequiresPrice'] = False
2520
- params['tgtCcy'] = 'quote_ccy'
2521
- return await self.create_order(symbol, 'market', 'buy', cost, None, params)
2806
+ req = {
2807
+ 'createMarketBuyOrderRequiresPrice': False,
2808
+ 'tgtCcy': 'quote_ccy',
2809
+ }
2810
+ return await self.create_order(symbol, 'market', 'buy', cost, None, self.extend(req, params))
2522
2811
 
2523
2812
  async def create_market_sell_order_with_cost(self, symbol: str, cost: float, params={}):
2524
2813
  """
2525
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-order
2814
+
2815
+ https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-order
2816
+
2526
2817
  create a market buy order by providing the symbol and cost
2527
2818
  :param str symbol: unified symbol of the market to create an order in
2528
2819
  :param float cost: how much you want to trade in units of the quote currency
@@ -2533,9 +2824,11 @@ class okx(Exchange, ImplicitAPI):
2533
2824
  market = self.market(symbol)
2534
2825
  if not market['spot']:
2535
2826
  raise NotSupported(self.id + ' createMarketSellOrderWithCost() supports spot markets only')
2536
- params['createMarketBuyOrderRequiresPrice'] = False
2537
- params['tgtCcy'] = 'quote_ccy'
2538
- return await self.create_order(symbol, 'market', 'sell', cost, None, params)
2827
+ req = {
2828
+ 'createMarketBuyOrderRequiresPrice': False,
2829
+ 'tgtCcy': 'quote_ccy',
2830
+ }
2831
+ return await self.create_order(symbol, 'market', 'sell', cost, None, self.extend(req, params))
2539
2832
 
2540
2833
  def create_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
2541
2834
  market = self.market(symbol)
@@ -2675,7 +2968,8 @@ class okx(Exchange, ImplicitAPI):
2675
2968
  stopLossTriggerPrice = self.safe_value_n(stopLoss, ['triggerPrice', 'stopPrice', 'slTriggerPx'])
2676
2969
  if stopLossTriggerPrice is None:
2677
2970
  raise InvalidOrder(self.id + ' createOrder() requires a trigger price in params["stopLoss"]["triggerPrice"], or params["stopLoss"]["stopPrice"], or params["stopLoss"]["slTriggerPx"] for a stop loss order')
2678
- request['slTriggerPx'] = self.price_to_precision(symbol, stopLossTriggerPrice)
2971
+ slTriggerPx = self.price_to_precision(symbol, stopLossTriggerPrice)
2972
+ request['slTriggerPx'] = slTriggerPx
2679
2973
  stopLossLimitPrice = self.safe_value_n(stopLoss, ['price', 'stopLossPrice', 'slOrdPx'])
2680
2974
  stopLossOrderType = self.safe_string(stopLoss, 'type')
2681
2975
  if stopLossOrderType is not None:
@@ -2741,13 +3035,25 @@ class okx(Exchange, ImplicitAPI):
2741
3035
  # tpOrdKind is 'condition' which is the default
2742
3036
  if twoWayCondition:
2743
3037
  request['ordType'] = 'oco'
3038
+ if side == 'sell':
3039
+ request = self.omit(request, 'tgtCcy')
3040
+ if self.safe_string(request, 'tdMode') == 'cash':
3041
+ # for some reason tdMode = cash throws
3042
+ # {"code":"1","data":[{"algoClOrdId":"","algoId":"","clOrdId":"","sCode":"51000","sMsg":"Parameter tdMode error ","tag":""}],"msg":""}
3043
+ request['tdMode'] = marginMode
2744
3044
  if takeProfitPrice is not None:
2745
3045
  request['tpTriggerPx'] = self.price_to_precision(symbol, takeProfitPrice)
2746
- request['tpOrdPx'] = '-1' if (tpOrdPx is None) else self.price_to_precision(symbol, tpOrdPx)
3046
+ tpOrdPxReq = '-1'
3047
+ if tpOrdPx is not None:
3048
+ tpOrdPxReq = self.price_to_precision(symbol, tpOrdPx)
3049
+ request['tpOrdPx'] = tpOrdPxReq
2747
3050
  request['tpTriggerPxType'] = tpTriggerPxType
2748
3051
  if stopLossPrice is not None:
2749
3052
  request['slTriggerPx'] = self.price_to_precision(symbol, stopLossPrice)
2750
- request['slOrdPx'] = '-1' if (slOrdPx is None) else self.price_to_precision(symbol, slOrdPx)
3053
+ slOrdPxReq = '-1'
3054
+ if slOrdPx is not None:
3055
+ slOrdPxReq = self.price_to_precision(symbol, slOrdPx)
3056
+ request['slOrdPx'] = slOrdPxReq
2751
3057
  request['slTriggerPxType'] = slTriggerPxType
2752
3058
  if clientOrderId is None:
2753
3059
  brokerId = self.safe_string(self.options, 'brokerId')
@@ -2762,14 +3068,16 @@ class okx(Exchange, ImplicitAPI):
2762
3068
  async def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
2763
3069
  """
2764
3070
  create a trade order
2765
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-order
2766
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-multiple-orders
2767
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-place-algo-order
3071
+
3072
+ https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-order
3073
+ https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-multiple-orders
3074
+ https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-place-algo-order
3075
+
2768
3076
  :param str symbol: unified symbol of the market to create an order in
2769
3077
  :param str type: 'market' or 'limit'
2770
3078
  :param str side: 'buy' or 'sell'
2771
3079
  :param float amount: how much of currency you want to trade in units of base currency
2772
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
3080
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
2773
3081
  :param dict [params]: extra parameters specific to the exchange API endpoint
2774
3082
  :param bool [params.reduceOnly]: a mark to reduce the position size for margin, swap and future orders
2775
3083
  :param bool [params.postOnly]: True to place a post only order
@@ -2784,7 +3092,8 @@ class okx(Exchange, ImplicitAPI):
2784
3092
  :param str [params.positionSide]: if position mode is one-way: set to 'net', if position mode is hedge-mode: set to 'long' or 'short'
2785
3093
  :param str [params.trailingPercent]: the percent to trail away from the current market price
2786
3094
  :param str [params.tpOrdKind]: 'condition' or 'limit', the default is 'condition'
2787
- :param str [params.hedged]: True/false, to automatically set exchange-specific params needed when trading in hedge mode
3095
+ :param bool [params.hedged]: *swap and future only* True for hedged mode, False for one way mode
3096
+ :param str [params.marginMode]: 'cross' or 'isolated', the default is 'cross'
2788
3097
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
2789
3098
  """
2790
3099
  await self.load_markets()
@@ -2818,8 +3127,11 @@ class okx(Exchange, ImplicitAPI):
2818
3127
  async def create_orders(self, orders: List[OrderRequest], params={}):
2819
3128
  """
2820
3129
  create a list of trade orders
2821
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-multiple-orders
3130
+
3131
+ https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-place-multiple-orders
3132
+
2822
3133
  :param Array orders: list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params
3134
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2823
3135
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
2824
3136
  """
2825
3137
  await self.load_markets()
@@ -2934,20 +3246,22 @@ class okx(Exchange, ImplicitAPI):
2934
3246
  if not isAlgoOrder:
2935
3247
  if price is not None:
2936
3248
  request['newPx'] = self.price_to_precision(symbol, price)
2937
- params = self.omit(params, ['clOrdId', 'clientOrderId', 'takeProfitPrice', 'stopLossPrice', 'stopLoss', 'takeProfit'])
3249
+ params = self.omit(params, ['clOrdId', 'clientOrderId', 'takeProfitPrice', 'stopLossPrice', 'stopLoss', 'takeProfit', 'postOnly'])
2938
3250
  return self.extend(request, params)
2939
3251
 
2940
3252
  async def edit_order(self, id: str, symbol: str, type: OrderType, side: OrderSide, amount: Num = None, price: Num = None, params={}):
2941
3253
  """
2942
3254
  edit a trade order
2943
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-amend-order
2944
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-amend-algo-order
3255
+
3256
+ https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-amend-order
3257
+ https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-amend-algo-order
3258
+
2945
3259
  :param str id: order id
2946
3260
  :param str symbol: unified symbol of the market to create an order in
2947
3261
  :param str type: 'market' or 'limit'
2948
3262
  :param str side: 'buy' or 'sell'
2949
3263
  :param float amount: how much of the currency you want to trade in units of the base currency
2950
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
3264
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
2951
3265
  :param dict [params]: extra parameters specific to the exchange API endpoint
2952
3266
  :param str [params.clientOrderId]: client order id, uses id if not passed
2953
3267
  :param float [params.stopLossPrice]: stop loss trigger price
@@ -3003,8 +3317,10 @@ class okx(Exchange, ImplicitAPI):
3003
3317
  async def cancel_order(self, id: str, symbol: Str = None, params={}):
3004
3318
  """
3005
3319
  cancels an open order
3006
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-cancel-order
3007
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-cancel-algo-order
3320
+
3321
+ https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-cancel-order
3322
+ https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-cancel-algo-order
3323
+
3008
3324
  :param str id: order id
3009
3325
  :param str symbol: unified symbol of the market the order was made in
3010
3326
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -3014,11 +3330,11 @@ class okx(Exchange, ImplicitAPI):
3014
3330
  """
3015
3331
  if symbol is None:
3016
3332
  raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol argument')
3017
- stop = self.safe_value_2(params, 'stop', 'trigger')
3333
+ trigger = self.safe_value_2(params, 'stop', 'trigger')
3018
3334
  trailing = self.safe_bool(params, 'trailing', False)
3019
- if stop or trailing:
3335
+ if trigger or trailing:
3020
3336
  orderInner = await self.cancel_orders([id], symbol, params)
3021
- return self.safe_value(orderInner, 0)
3337
+ return self.safe_dict(orderInner, 0)
3022
3338
  await self.load_markets()
3023
3339
  market = self.market(symbol)
3024
3340
  request: dict = {
@@ -3040,7 +3356,7 @@ class okx(Exchange, ImplicitAPI):
3040
3356
 
3041
3357
  def parse_ids(self, ids):
3042
3358
  """
3043
- * @ignore
3359
+ @ignore
3044
3360
  :param string[]|str ids: order ids
3045
3361
  :returns str[]: list of order ids
3046
3362
  """
@@ -3052,8 +3368,10 @@ class okx(Exchange, ImplicitAPI):
3052
3368
  async def cancel_orders(self, ids, symbol: Str = None, params={}):
3053
3369
  """
3054
3370
  cancel multiple orders
3055
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-cancel-multiple-orders
3056
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-cancel-algo-order
3371
+
3372
+ https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-cancel-multiple-orders
3373
+ https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-cancel-algo-order
3374
+
3057
3375
  :param str[] ids: order ids
3058
3376
  :param str symbol: unified market symbol
3059
3377
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -3072,9 +3390,9 @@ class okx(Exchange, ImplicitAPI):
3072
3390
  method = self.safe_string(params, 'method', defaultMethod)
3073
3391
  clientOrderIds = self.parse_ids(self.safe_value_2(params, 'clOrdId', 'clientOrderId'))
3074
3392
  algoIds = self.parse_ids(self.safe_value(params, 'algoId'))
3075
- stop = self.safe_value_2(params, 'stop', 'trigger')
3393
+ trigger = self.safe_value_2(params, 'stop', 'trigger')
3076
3394
  trailing = self.safe_bool(params, 'trailing', False)
3077
- if stop or trailing:
3395
+ if trigger or trailing:
3078
3396
  method = 'privatePostTradeCancelAlgos'
3079
3397
  if clientOrderIds is None:
3080
3398
  ids = self.parse_ids(ids)
@@ -3085,7 +3403,7 @@ class okx(Exchange, ImplicitAPI):
3085
3403
  'instId': market['id'],
3086
3404
  })
3087
3405
  for i in range(0, len(ids)):
3088
- if trailing or stop:
3406
+ if trailing or trigger:
3089
3407
  request.append({
3090
3408
  'algoId': ids[i],
3091
3409
  'instId': market['id'],
@@ -3141,9 +3459,11 @@ class okx(Exchange, ImplicitAPI):
3141
3459
  async def cancel_orders_for_symbols(self, orders: List[CancellationRequest], params={}):
3142
3460
  """
3143
3461
  cancel multiple orders for multiple symbols
3144
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-cancel-multiple-orders
3145
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-cancel-algo-order
3146
- :param CancellationRequest[] orders: each order should contain the parameters required by cancelOrder namely id and symbol
3462
+
3463
+ https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-cancel-multiple-orders
3464
+ https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-post-cancel-algo-order
3465
+
3466
+ :param CancellationRequest[] orders: each order should contain the parameters required by cancelOrder namely id and symbol, example [{"id": "a", "symbol": "BTC/USDT"}, {"id": "b", "symbol": "ETH/USDT"}]
3147
3467
  :param dict [params]: extra parameters specific to the exchange API endpoint
3148
3468
  :param boolean [params.trigger]: whether the order is a stop/trigger order
3149
3469
  :param boolean [params.trailing]: set to True if you want to cancel trailing orders
@@ -3154,9 +3474,9 @@ class okx(Exchange, ImplicitAPI):
3154
3474
  options = self.safe_dict(self.options, 'cancelOrders', {})
3155
3475
  defaultMethod = self.safe_string(options, 'method', 'privatePostTradeCancelBatchOrders')
3156
3476
  method = self.safe_string(params, 'method', defaultMethod)
3157
- stop = self.safe_bool_2(params, 'stop', 'trigger')
3477
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
3158
3478
  trailing = self.safe_bool(params, 'trailing', False)
3159
- isStopOrTrailing = stop or trailing
3479
+ isStopOrTrailing = trigger or trailing
3160
3480
  if isStopOrTrailing:
3161
3481
  method = 'privatePostTradeCancelAlgos'
3162
3482
  for i in range(0, len(orders)):
@@ -3215,7 +3535,9 @@ class okx(Exchange, ImplicitAPI):
3215
3535
  async def cancel_all_orders_after(self, timeout: Int, params={}):
3216
3536
  """
3217
3537
  dead man's switch, cancel all orders after the given timeout
3218
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-cancel-all-after
3538
+
3539
+ https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-cancel-all-after
3540
+
3219
3541
  :param number timeout: time in milliseconds, 0 represents cancel the timer
3220
3542
  :param dict [params]: extra parameters specific to the exchange API endpoint
3221
3543
  :returns dict: the api result
@@ -3309,6 +3631,84 @@ class okx(Exchange, ImplicitAPI):
3309
3631
  # "uTime": "1621910749815"
3310
3632
  # }
3311
3633
  #
3634
+ # watchOrders & fetchClosedOrders
3635
+ #
3636
+ # {
3637
+ # "algoClOrdId": "",
3638
+ # "algoId": "",
3639
+ # "attachAlgoClOrdId": "",
3640
+ # "attachAlgoOrds": [],
3641
+ # "cancelSource": "",
3642
+ # "cancelSourceReason": "", # not present in WS, but present in fetchClosedOrders
3643
+ # "category": "normal",
3644
+ # "ccy": "", # empty in WS, but eg. `USDT` in fetchClosedOrders
3645
+ # "clOrdId": "",
3646
+ # "cTime": "1751705801423",
3647
+ # "feeCcy": "USDT",
3648
+ # "instId": "LINK-USDT-SWAP",
3649
+ # "instType": "SWAP",
3650
+ # "isTpLimit": "false",
3651
+ # "lever": "3",
3652
+ # "linkedAlgoOrd": {"algoId": ""},
3653
+ # "ordId": "2657625147249614848",
3654
+ # "ordType": "limit",
3655
+ # "posSide": "net",
3656
+ # "px": "13.142",
3657
+ # "pxType": "",
3658
+ # "pxUsd": "",
3659
+ # "pxVol": "",
3660
+ # "quickMgnType": "",
3661
+ # "rebate": "0",
3662
+ # "rebateCcy": "USDT",
3663
+ # "reduceOnly": "true",
3664
+ # "side": "sell",
3665
+ # "slOrdPx": "",
3666
+ # "slTriggerPx": "",
3667
+ # "slTriggerPxType": "",
3668
+ # "source": "",
3669
+ # "stpId": "",
3670
+ # "stpMode": "cancel_maker",
3671
+ # "sz": "0.1",
3672
+ # "tag": "",
3673
+ # "tdMode": "isolated",
3674
+ # "tgtCcy": "",
3675
+ # "tpOrdPx": "",
3676
+ # "tpTriggerPx": "",
3677
+ # "tpTriggerPxType": "",
3678
+ # "uTime": "1751705807467",
3679
+ # "reqId": "", # field present only in WS
3680
+ # "msg": "", # field present only in WS
3681
+ # "amendResult": "", # field present only in WS
3682
+ # "amendSource": "", # field present only in WS
3683
+ # "code": "0", # field present only in WS
3684
+ # "fillFwdPx": "", # field present only in WS
3685
+ # "fillMarkVol": "", # field present only in WS
3686
+ # "fillPxUsd": "", # field present only in WS
3687
+ # "fillPxVol": "", # field present only in WS
3688
+ # "lastPx": "13.142", # field present only in WS
3689
+ # "notionalUsd": "1.314515408", # field present only in WS
3690
+ #
3691
+ # #### these below fields are empty on first omit from websocket, because of "creation" event. however, if order is executed, it also immediately sends another update with these fields filled ###
3692
+ #
3693
+ # "pnl": "-0.0001",
3694
+ # "accFillSz": "0.1",
3695
+ # "avgPx": "13.142",
3696
+ # "state": "filled",
3697
+ # "fee": "-0.00026284",
3698
+ # "fillPx": "13.142",
3699
+ # "tradeId": "293429690",
3700
+ # "fillSz": "0.1",
3701
+ # "fillTime": "1751705807467",
3702
+ # "fillNotionalUsd": "1.314515408", # field present only in WS
3703
+ # "fillPnl": "-0.0001", # field present only in WS
3704
+ # "fillFee": "-0.00026284", # field present only in WS
3705
+ # "fillFeeCcy": "USDT", # field present only in WS
3706
+ # "execType": "M", # field present only in WS
3707
+ # "fillMarkPx": "13.141", # field present only in WS
3708
+ # "fillIdxPx": "13.147" # field present only in WS
3709
+ # }
3710
+ #
3711
+ #
3312
3712
  # Algo Order fetchOpenOrders, fetchCanceledOrders, fetchClosedOrders
3313
3713
  #
3314
3714
  # {
@@ -3416,7 +3816,6 @@ class okx(Exchange, ImplicitAPI):
3416
3816
  clientOrderId = None # fix empty clientOrderId string
3417
3817
  stopLossPrice = self.safe_number_2(order, 'slTriggerPx', 'slOrdPx')
3418
3818
  takeProfitPrice = self.safe_number_2(order, 'tpTriggerPx', 'tpOrdPx')
3419
- stopPrice = self.safe_number_n(order, ['triggerPx', 'moveTriggerPx'])
3420
3819
  reduceOnlyRaw = self.safe_string(order, 'reduceOnly')
3421
3820
  reduceOnly = False
3422
3821
  if reduceOnly is not None:
@@ -3437,8 +3836,7 @@ class okx(Exchange, ImplicitAPI):
3437
3836
  'price': price,
3438
3837
  'stopLossPrice': stopLossPrice,
3439
3838
  'takeProfitPrice': takeProfitPrice,
3440
- 'stopPrice': stopPrice,
3441
- 'triggerPrice': stopPrice,
3839
+ 'triggerPrice': self.safe_number_n(order, ['triggerPx', 'moveTriggerPx']),
3442
3840
  'average': average,
3443
3841
  'cost': cost,
3444
3842
  'amount': amount,
@@ -3453,8 +3851,10 @@ class okx(Exchange, ImplicitAPI):
3453
3851
  async def fetch_order(self, id: str, symbol: Str = None, params={}):
3454
3852
  """
3455
3853
  fetch an order by the id
3456
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-order-details
3457
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-get-algo-order-details
3854
+
3855
+ https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-order-details
3856
+ https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-get-algo-order-details
3857
+
3458
3858
  :param str id: the order id
3459
3859
  :param str symbol: unified market symbol
3460
3860
  :param dict [params]: extra and exchange specific parameters
@@ -3475,8 +3875,8 @@ class okx(Exchange, ImplicitAPI):
3475
3875
  options = self.safe_value(self.options, 'fetchOrder', {})
3476
3876
  defaultMethod = self.safe_string(options, 'method', 'privateGetTradeOrder')
3477
3877
  method = self.safe_string(params, 'method', defaultMethod)
3478
- stop = self.safe_value_2(params, 'stop', 'trigger')
3479
- if stop:
3878
+ trigger = self.safe_value_2(params, 'stop', 'trigger')
3879
+ if trigger:
3480
3880
  method = 'privateGetTradeOrderAlgo'
3481
3881
  if clientOrderId is not None:
3482
3882
  request['algoClOrdId'] = clientOrderId
@@ -3596,13 +3996,15 @@ class okx(Exchange, ImplicitAPI):
3596
3996
  async def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
3597
3997
  """
3598
3998
  fetch all unfilled currently open orders
3599
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-order-list
3600
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-get-algo-order-list
3999
+
4000
+ https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-order-list
4001
+ https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-get-algo-order-list
4002
+
3601
4003
  :param str symbol: unified market symbol
3602
4004
  :param int [since]: the earliest time in ms to fetch open orders for
3603
4005
  :param int [limit]: the maximum number of open orders structures to retrieve
3604
4006
  :param dict [params]: extra parameters specific to the exchange API endpoint
3605
- :param bool [params.stop]: True if fetching trigger or conditional orders
4007
+ :param bool [params.trigger]: True if fetching trigger or conditional orders
3606
4008
  :param str [params.ordType]: "conditional", "oco", "trigger", "move_order_stop", "iceberg", or "twap"
3607
4009
  :param str [params.algoId]: Algo ID "'433845797218942976'"
3608
4010
  :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)
@@ -3635,13 +4037,13 @@ class okx(Exchange, ImplicitAPI):
3635
4037
  defaultMethod = self.safe_string(options, 'method', 'privateGetTradeOrdersPending')
3636
4038
  method = self.safe_string(params, 'method', defaultMethod)
3637
4039
  ordType = self.safe_string(params, 'ordType')
3638
- stop = self.safe_value_2(params, 'stop', 'trigger')
4040
+ trigger = self.safe_value_2(params, 'stop', 'trigger')
3639
4041
  trailing = self.safe_bool(params, 'trailing', False)
3640
- if trailing or stop or (ordType in algoOrderTypes):
4042
+ if trailing or trigger or (ordType in algoOrderTypes):
3641
4043
  method = 'privateGetTradeOrdersAlgoPending'
3642
4044
  if trailing:
3643
4045
  request['ordType'] = 'move_order_stop'
3644
- elif stop and (ordType is None):
4046
+ elif trigger and (ordType is None):
3645
4047
  request['ordType'] = 'trigger'
3646
4048
  query = self.omit(params, ['method', 'stop', 'trigger', 'trailing'])
3647
4049
  response = None
@@ -3750,13 +4152,15 @@ class okx(Exchange, ImplicitAPI):
3750
4152
  async def fetch_canceled_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
3751
4153
  """
3752
4154
  fetches information on multiple canceled orders made by the user
3753
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-order-history-last-7-days
3754
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-get-algo-order-history
4155
+
4156
+ https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-order-history-last-7-days
4157
+ https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-get-algo-order-history
4158
+
3755
4159
  :param str symbol: unified market symbol of the market orders were made in
3756
4160
  :param int [since]: timestamp in ms of the earliest order, default is None
3757
4161
  :param int [limit]: max number of orders to return, default is None
3758
4162
  :param dict [params]: extra parameters specific to the exchange API endpoint
3759
- :param bool [params.stop]: True if fetching trigger or conditional orders
4163
+ :param bool [params.trigger]: True if fetching trigger or conditional orders
3760
4164
  :param str [params.ordType]: "conditional", "oco", "trigger", "move_order_stop", "iceberg", or "twap"
3761
4165
  :param str [params.algoId]: Algo ID "'433845797218942976'"
3762
4166
  :param int [params.until]: timestamp in ms to fetch orders for
@@ -3791,18 +4195,18 @@ class okx(Exchange, ImplicitAPI):
3791
4195
  defaultMethod = self.safe_string(options, 'method', 'privateGetTradeOrdersHistory')
3792
4196
  method = self.safe_string(params, 'method', defaultMethod)
3793
4197
  ordType = self.safe_string(params, 'ordType')
3794
- stop = self.safe_value_2(params, 'stop', 'trigger')
4198
+ trigger = self.safe_value_2(params, 'stop', 'trigger')
3795
4199
  trailing = self.safe_bool(params, 'trailing', False)
3796
4200
  if trailing:
3797
4201
  method = 'privateGetTradeOrdersAlgoHistory'
3798
4202
  request['ordType'] = 'move_order_stop'
3799
- elif stop or (ordType in algoOrderTypes):
4203
+ elif trigger or (ordType in algoOrderTypes):
3800
4204
  method = 'privateGetTradeOrdersAlgoHistory'
3801
4205
  algoId = self.safe_string(params, 'algoId')
3802
4206
  if algoId is not None:
3803
4207
  request['algoId'] = algoId
3804
4208
  params = self.omit(params, 'algoId')
3805
- if stop:
4209
+ if trigger:
3806
4210
  if ordType is None:
3807
4211
  raise ArgumentsRequired(self.id + ' fetchCanceledOrders() requires an "ordType" string parameter, "conditional", "oco", "trigger", "move_order_stop", "iceberg", or "twap"')
3808
4212
  else:
@@ -3923,9 +4327,11 @@ class okx(Exchange, ImplicitAPI):
3923
4327
  async def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
3924
4328
  """
3925
4329
  fetches information on multiple closed orders made by the user
3926
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-order-history-last-7-days
3927
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-get-algo-order-history
3928
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-order-history-last-3-months
4330
+
4331
+ https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-order-history-last-7-days
4332
+ https://www.okx.com/docs-v5/en/#order-book-trading-algo-trading-get-algo-order-history
4333
+ https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-order-history-last-3-months
4334
+
3929
4335
  :param str symbol: unified market symbol of the market orders were made in
3930
4336
  :param int [since]: the earliest time in ms to fetch orders for
3931
4337
  :param int [limit]: the maximum number of order structures to retrieve
@@ -3970,14 +4376,14 @@ class okx(Exchange, ImplicitAPI):
3970
4376
  defaultMethod = self.safe_string(options, 'method', 'privateGetTradeOrdersHistory')
3971
4377
  method = self.safe_string(params, 'method', defaultMethod)
3972
4378
  ordType = self.safe_string(params, 'ordType')
3973
- stop = self.safe_bool_2(params, 'stop', 'trigger')
4379
+ trigger = self.safe_bool_2(params, 'stop', 'trigger')
3974
4380
  trailing = self.safe_bool(params, 'trailing', False)
3975
- if trailing or stop or (ordType in algoOrderTypes):
4381
+ if trailing or trigger or (ordType in algoOrderTypes):
3976
4382
  method = 'privateGetTradeOrdersAlgoHistory'
3977
4383
  request['state'] = 'effective'
3978
4384
  if trailing:
3979
4385
  request['ordType'] = 'move_order_stop'
3980
- elif stop:
4386
+ elif trigger:
3981
4387
  if ordType is None:
3982
4388
  request['ordType'] = 'trigger'
3983
4389
  else:
@@ -4097,7 +4503,9 @@ class okx(Exchange, ImplicitAPI):
4097
4503
  async def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
4098
4504
  """
4099
4505
  fetch all trades made by the user
4100
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-transaction-details-last-3-months
4506
+
4507
+ https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-transaction-details-last-3-months
4508
+
4101
4509
  :param str symbol: unified market symbol
4102
4510
  :param int [since]: the earliest time in ms to fetch trades for
4103
4511
  :param int [limit]: the maximum number of trades structures to retrieve
@@ -4163,7 +4571,9 @@ class okx(Exchange, ImplicitAPI):
4163
4571
  async def fetch_order_trades(self, id: str, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
4164
4572
  """
4165
4573
  fetch all the trades made from a single order
4166
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-transaction-details-last-3-months
4574
+
4575
+ https://www.okx.com/docs-v5/en/#order-book-trading-trade-get-transaction-details-last-3-months
4576
+
4167
4577
  :param str id: order id
4168
4578
  :param str symbol: unified market symbol
4169
4579
  :param int [since]: the earliest time in ms to fetch trades for
@@ -4180,20 +4590,22 @@ class okx(Exchange, ImplicitAPI):
4180
4590
  }
4181
4591
  return await self.fetch_my_trades(symbol, since, limit, self.extend(request, params))
4182
4592
 
4183
- async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
4593
+ async def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
4184
4594
  """
4185
4595
  fetch the history of changes, actions done by the user or operations that altered balance of the user
4186
- :see: https://www.okx.com/docs-v5/en/#rest-api-account-get-bills-details-last-7-days
4187
- :see: https://www.okx.com/docs-v5/en/#rest-api-account-get-bills-details-last-3-months
4188
- :see: https://www.okx.com/docs-v5/en/#rest-api-funding-asset-bills-details
4189
- :param str code: unified currency code, default is None
4596
+
4597
+ https://www.okx.com/docs-v5/en/#rest-api-account-get-bills-details-last-7-days
4598
+ https://www.okx.com/docs-v5/en/#rest-api-account-get-bills-details-last-3-months
4599
+ https://www.okx.com/docs-v5/en/#rest-api-funding-asset-bills-details
4600
+
4601
+ :param str [code]: unified currency code, default is None
4190
4602
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
4191
- :param int [limit]: max number of ledger entrys to return, default is None
4603
+ :param int [limit]: max number of ledger entries to return, default is None
4192
4604
  :param dict [params]: extra parameters specific to the exchange API endpoint
4193
4605
  :param str [params.marginMode]: 'cross' or 'isolated'
4194
4606
  :param int [params.until]: the latest time in ms to fetch entries for
4195
- :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)
4196
- :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
4607
+ :param boolean [params.paginate]: default False, when True will automatically paginate by calling self endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
4608
+ :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger>`
4197
4609
  """
4198
4610
  await self.load_markets()
4199
4611
  paginate = False
@@ -4308,7 +4720,7 @@ class okx(Exchange, ImplicitAPI):
4308
4720
  }
4309
4721
  return self.safe_string(types, type, type)
4310
4722
 
4311
- def parse_ledger_entry(self, item: dict, currency: Currency = None):
4723
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
4312
4724
  #
4313
4725
  # privateGetAccountBills, privateGetAccountBillsArchive
4314
4726
  #
@@ -4345,14 +4757,9 @@ class okx(Exchange, ImplicitAPI):
4345
4757
  # "ts": "1597026383085"
4346
4758
  # }
4347
4759
  #
4348
- id = self.safe_string(item, 'billId')
4349
- account = None
4350
- referenceId = self.safe_string(item, 'ordId')
4351
- referenceAccount = None
4352
- type = self.parse_ledger_entry_type(self.safe_string(item, 'type'))
4353
- code = self.safe_currency_code(self.safe_string(item, 'ccy'), currency)
4354
- amountString = self.safe_string(item, 'balChg')
4355
- amount = self.parse_number(amountString)
4760
+ currencyId = self.safe_string(item, 'ccy')
4761
+ code = self.safe_currency_code(currencyId, currency)
4762
+ currency = self.safe_currency(currencyId, currency)
4356
4763
  timestamp = self.safe_integer(item, 'ts')
4357
4764
  feeCostString = self.safe_string(item, 'fee')
4358
4765
  fee = None
@@ -4361,31 +4768,27 @@ class okx(Exchange, ImplicitAPI):
4361
4768
  'cost': self.parse_number(Precise.string_neg(feeCostString)),
4362
4769
  'currency': code,
4363
4770
  }
4364
- before = None
4365
- afterString = self.safe_string(item, 'bal')
4366
- after = self.parse_number(afterString)
4367
- status = 'ok'
4368
4771
  marketId = self.safe_string(item, 'instId')
4369
4772
  symbol = self.safe_symbol(marketId, None, '-')
4370
- return {
4371
- 'id': id,
4773
+ return self.safe_ledger_entry({
4372
4774
  'info': item,
4775
+ 'id': self.safe_string(item, 'billId'),
4373
4776
  'timestamp': timestamp,
4374
4777
  'datetime': self.iso8601(timestamp),
4375
- 'account': account,
4376
- 'referenceId': referenceId,
4377
- 'referenceAccount': referenceAccount,
4378
- 'type': type,
4778
+ 'account': None,
4779
+ 'referenceId': self.safe_string(item, 'ordId'),
4780
+ 'referenceAccount': None,
4781
+ 'type': self.parse_ledger_entry_type(self.safe_string(item, 'type')),
4379
4782
  'currency': code,
4380
4783
  'symbol': symbol,
4381
- 'amount': amount,
4382
- 'before': before, # balance before
4383
- 'after': after, # balance after
4384
- 'status': status,
4784
+ 'amount': self.safe_number(item, 'balChg'),
4785
+ 'before': None,
4786
+ 'after': self.safe_number(item, 'bal'),
4787
+ 'status': 'ok',
4385
4788
  'fee': fee,
4386
- }
4789
+ }, currency)
4387
4790
 
4388
- def parse_deposit_address(self, depositAddress, currency: Currency = None):
4791
+ def parse_deposit_address(self, depositAddress, currency: Currency = None) -> DepositAddress:
4389
4792
  #
4390
4793
  # {
4391
4794
  # "addr": "okbtothemoon",
@@ -4473,17 +4876,19 @@ class okx(Exchange, ImplicitAPI):
4473
4876
  networkCode = self.network_id_to_code(network, code)
4474
4877
  self.check_address(address)
4475
4878
  return {
4879
+ 'info': depositAddress,
4476
4880
  'currency': code,
4881
+ 'network': networkCode,
4477
4882
  'address': address,
4478
4883
  'tag': tag,
4479
- 'network': networkCode,
4480
- 'info': depositAddress,
4481
4884
  }
4482
4885
 
4483
- async def fetch_deposit_addresses_by_network(self, code: str, params={}):
4886
+ async def fetch_deposit_addresses_by_network(self, code: str, params={}) -> List[DepositAddress]:
4484
4887
  """
4485
4888
  fetch a dictionary of addresses for a currency, indexed by network
4486
- :see: https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-deposit-address
4889
+
4890
+ https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-deposit-address
4891
+
4487
4892
  :param str code: unified currency code of the currency for the deposit address
4488
4893
  :param dict [params]: extra parameters specific to the exchange API endpoint
4489
4894
  :returns dict: a dictionary of `address structures <https://docs.ccxt.com/#/?id=address-structure>` indexed by the network
@@ -4520,43 +4925,42 @@ class okx(Exchange, ImplicitAPI):
4520
4925
  parsed = self.parse_deposit_addresses(filtered, [currency['code']], False)
4521
4926
  return self.index_by(parsed, 'network')
4522
4927
 
4523
- async def fetch_deposit_address(self, code: str, params={}):
4928
+ async def fetch_deposit_address(self, code: str, params={}) -> DepositAddress:
4524
4929
  """
4525
4930
  fetch the deposit address for a currency associated with self account
4526
- :see: https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-deposit-address
4931
+
4932
+ https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-deposit-address
4933
+
4527
4934
  :param str code: unified currency code
4528
4935
  :param dict [params]: extra parameters specific to the exchange API endpoint
4936
+ :param str [params.network]: the network name for the deposit address
4529
4937
  :returns dict: an `address structure <https://docs.ccxt.com/#/?id=address-structure>`
4530
4938
  """
4531
- rawNetwork = self.safe_string_upper(params, 'network')
4532
- networks = self.safe_value(self.options, 'networks', {})
4533
- network = self.safe_string(networks, rawNetwork, rawNetwork)
4939
+ await self.load_markets()
4940
+ rawNetwork = self.safe_string(params, 'network') # some networks are like "Dora Vota Mainnet"
4534
4941
  params = self.omit(params, 'network')
4942
+ code = self.safe_currency_code(code)
4943
+ network = self.network_id_to_code(rawNetwork, code)
4535
4944
  response = await self.fetch_deposit_addresses_by_network(code, params)
4536
- result = None
4537
- if network is None:
4538
- result = self.safe_value(response, code)
4945
+ if network is not None:
4946
+ result = self.safe_dict(response, network)
4539
4947
  if result is None:
4540
- alias = self.safe_string(networks, code, code)
4541
- result = self.safe_value(response, alias)
4542
- if result is None:
4543
- defaultNetwork = self.safe_string(self.options, 'defaultNetwork', 'ERC20')
4544
- result = self.safe_value(response, defaultNetwork)
4545
- if result is None:
4546
- values = list(response.values())
4547
- result = self.safe_value(values, 0)
4548
- if result is None:
4549
- raise InvalidAddress(self.id + ' fetchDepositAddress() cannot find deposit address for ' + code)
4948
+ raise InvalidAddress(self.id + ' fetchDepositAddress() cannot find ' + network + ' deposit address for ' + code)
4550
4949
  return result
4551
- result = self.safe_value(response, network)
4552
- if result is None:
4553
- raise InvalidAddress(self.id + ' fetchDepositAddress() cannot find ' + network + ' deposit address for ' + code)
4554
- return result
4950
+ codeNetwork = self.network_id_to_code(code, code)
4951
+ if codeNetwork in response:
4952
+ return response[codeNetwork]
4953
+ # if the network is not specified, return the first address
4954
+ keys = list(response.keys())
4955
+ first = self.safe_string(keys, 0)
4956
+ return self.safe_dict(response, first)
4555
4957
 
4556
- async def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
4958
+ async def withdraw(self, code: str, amount: float, address: str, tag: Str = None, params={}) -> Transaction:
4557
4959
  """
4558
4960
  make a withdrawal
4559
- :see: https://www.okx.com/docs-v5/en/#funding-account-rest-api-withdrawal
4961
+
4962
+ https://www.okx.com/docs-v5/en/#funding-account-rest-api-withdrawal
4963
+
4560
4964
  :param str code: unified currency code
4561
4965
  :param float amount: the amount to withdraw
4562
4966
  :param str address: the address to withdraw to
@@ -4585,7 +4989,7 @@ class okx(Exchange, ImplicitAPI):
4585
4989
  fee = self.safe_string(params, 'fee')
4586
4990
  if fee is None:
4587
4991
  currencies = await self.fetch_currencies()
4588
- self.currencies = self.deep_extend(self.currencies, currencies)
4992
+ self.currencies = self.map_to_safe_map(self.deep_extend(self.currencies, currencies))
4589
4993
  targetNetwork = self.safe_dict(currency['networks'], self.network_id_to_code(network), {})
4590
4994
  fee = self.safe_string(targetNetwork, 'fee')
4591
4995
  if fee is None:
@@ -4613,7 +5017,9 @@ class okx(Exchange, ImplicitAPI):
4613
5017
  async def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
4614
5018
  """
4615
5019
  fetch all deposits made to an account
4616
- :see: https://www.okx.com/docs-v5/en/#rest-api-funding-get-deposit-history
5020
+
5021
+ https://www.okx.com/docs-v5/en/#rest-api-funding-get-deposit-history
5022
+
4617
5023
  :param str code: unified currency code
4618
5024
  :param int [since]: the earliest time in ms to fetch deposits for
4619
5025
  :param int [limit]: the maximum number of deposits structures to retrieve
@@ -4688,7 +5094,9 @@ class okx(Exchange, ImplicitAPI):
4688
5094
  async def fetch_deposit(self, id: str, code: Str = None, params={}):
4689
5095
  """
4690
5096
  fetch data on a currency deposit via the deposit id
4691
- :see: https://www.okx.com/docs-v5/en/#rest-api-funding-get-deposit-history
5097
+
5098
+ https://www.okx.com/docs-v5/en/#rest-api-funding-get-deposit-history
5099
+
4692
5100
  :param str id: deposit id
4693
5101
  :param str code: filter by currency code
4694
5102
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -4710,7 +5118,9 @@ class okx(Exchange, ImplicitAPI):
4710
5118
  async def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
4711
5119
  """
4712
5120
  fetch all withdrawals made from an account
4713
- :see: https://www.okx.com/docs-v5/en/#rest-api-funding-get-withdrawal-history
5121
+
5122
+ https://www.okx.com/docs-v5/en/#rest-api-funding-get-withdrawal-history
5123
+
4714
5124
  :param str code: unified currency code
4715
5125
  :param int [since]: the earliest time in ms to fetch withdrawals for
4716
5126
  :param int [limit]: the maximum number of withdrawals structures to retrieve
@@ -4777,7 +5187,9 @@ class okx(Exchange, ImplicitAPI):
4777
5187
  async def fetch_withdrawal(self, id: str, code: Str = None, params={}):
4778
5188
  """
4779
5189
  fetch data on a currency withdrawal via the withdrawal id
4780
- :see: https://www.okx.com/docs-v5/en/#rest-api-funding-get-withdrawal-history
5190
+
5191
+ https://www.okx.com/docs-v5/en/#rest-api-funding-get-withdrawal-history
5192
+
4781
5193
  :param str id: withdrawal id
4782
5194
  :param str code: unified currency code of the currency withdrawn, default is None
4783
5195
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -4958,7 +5370,9 @@ class okx(Exchange, ImplicitAPI):
4958
5370
  async def fetch_leverage(self, symbol: str, params={}) -> Leverage:
4959
5371
  """
4960
5372
  fetch the set leverage for a market
4961
- :see: https://www.okx.com/docs-v5/en/#rest-api-account-get-leverage
5373
+
5374
+ https://www.okx.com/docs-v5/en/#rest-api-account-get-leverage
5375
+
4962
5376
  :param str symbol: unified market symbol
4963
5377
  :param dict [params]: extra parameters specific to the exchange API endpoint
4964
5378
  :param str [params.marginMode]: 'cross' or 'isolated'
@@ -5022,7 +5436,9 @@ class okx(Exchange, ImplicitAPI):
5022
5436
  async def fetch_position(self, symbol: str, params={}):
5023
5437
  """
5024
5438
  fetch data on a single open contract trade position
5025
- :see: https://www.okx.com/docs-v5/en/#rest-api-account-get-positions
5439
+
5440
+ https://www.okx.com/docs-v5/en/#rest-api-account-get-positions
5441
+
5026
5442
  :param str symbol: unified market symbol of the market the position is held in, default is None
5027
5443
  :param dict [params]: extra parameters specific to the exchange API endpoint
5028
5444
  :param str [params.instType]: MARGIN, SWAP, FUTURES, OPTION
@@ -5091,10 +5507,12 @@ class okx(Exchange, ImplicitAPI):
5091
5507
  return None
5092
5508
  return self.parse_position(position, market)
5093
5509
 
5094
- async def fetch_positions(self, symbols: Strings = None, params={}):
5510
+ async def fetch_positions(self, symbols: Strings = None, params={}) -> List[Position]:
5095
5511
  """
5096
- :see: https://www.okx.com/docs-v5/en/#rest-api-account-get-positions
5097
- :see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-positions-history history
5512
+
5513
+ https://www.okx.com/docs-v5/en/#rest-api-account-get-positions
5514
+ https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-positions-history history
5515
+
5098
5516
  fetch all open positions
5099
5517
  :param str[]|None symbols: list of unified market symbols
5100
5518
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -5173,11 +5591,13 @@ class okx(Exchange, ImplicitAPI):
5173
5591
  result = []
5174
5592
  for i in range(0, len(positions)):
5175
5593
  result.append(self.parse_position(positions[i]))
5176
- return self.filter_by_array_positions(result, 'symbol', symbols, False)
5594
+ return self.filter_by_array_positions(result, 'symbol', self.market_symbols(symbols), False)
5177
5595
 
5178
5596
  async def fetch_positions_for_symbol(self, symbol: str, params={}):
5179
5597
  """
5180
- :see: https://www.okx.com/docs-v5/en/#rest-api-account-get-positions
5598
+
5599
+ https://www.okx.com/docs-v5/en/#rest-api-account-get-positions
5600
+
5181
5601
  fetch all open positions for specific symbol
5182
5602
  :param str symbol: unified market symbol
5183
5603
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -5347,7 +5767,9 @@ class okx(Exchange, ImplicitAPI):
5347
5767
  async def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
5348
5768
  """
5349
5769
  transfer currency internally between wallets on the same account
5350
- :see: https://www.okx.com/docs-v5/en/#rest-api-funding-funds-transfer
5770
+
5771
+ https://www.okx.com/docs-v5/en/#rest-api-funding-funds-transfer
5772
+
5351
5773
  :param str code: unified currency code
5352
5774
  :param float amount: amount to transfer
5353
5775
  :param str fromAccount: account to transfer from
@@ -5514,10 +5936,12 @@ class okx(Exchange, ImplicitAPI):
5514
5936
  transfer = self.safe_dict(data, 0)
5515
5937
  return self.parse_transfer(transfer)
5516
5938
 
5517
- async def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> TransferEntries:
5939
+ async def fetch_transfers(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[TransferEntry]:
5518
5940
  """
5519
5941
  fetch a history of internal transfers made on an account
5520
- :see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-bills-details-last-3-months
5942
+
5943
+ https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-bills-details-last-3-months
5944
+
5521
5945
  :param str code: unified currency code of the currency transferred
5522
5946
  :param int [since]: the earliest time in ms to fetch transfers for
5523
5947
  :param int [limit]: the maximum number of transfers structures to retrieve
@@ -5599,7 +6023,7 @@ class okx(Exchange, ImplicitAPI):
5599
6023
  if clientOrderId is None:
5600
6024
  params['clOrdId'] = brokerId + self.uuid16()
5601
6025
  params['tag'] = brokerId
5602
- timestamp = self.iso8601(self.milliseconds())
6026
+ timestamp = self.iso8601(self.nonce())
5603
6027
  headers = {
5604
6028
  'OK-ACCESS-KEY': self.apiKey,
5605
6029
  'OK-ACCESS-PASSPHRASE': self.password,
@@ -5623,7 +6047,7 @@ class okx(Exchange, ImplicitAPI):
5623
6047
  headers['OK-ACCESS-SIGN'] = signature
5624
6048
  return {'url': url, 'method': method, 'body': body, 'headers': headers}
5625
6049
 
5626
- def parse_funding_rate(self, contract, market: Market = None):
6050
+ def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
5627
6051
  #
5628
6052
  # {
5629
6053
  # "fundingRate": "0.00027815",
@@ -5657,6 +6081,9 @@ class okx(Exchange, ImplicitAPI):
5657
6081
  symbol = self.safe_symbol(marketId, market)
5658
6082
  nextFundingRate = self.safe_number(contract, 'nextFundingRate')
5659
6083
  fundingTime = self.safe_integer(contract, 'fundingTime')
6084
+ fundingTimeString = self.safe_string(contract, 'fundingTime')
6085
+ nextFundingTimeString = self.safe_string(contract, 'nextFundingTime')
6086
+ millisecondsInterval = Precise.string_sub(nextFundingTimeString, fundingTimeString)
5660
6087
  # https://www.okx.com/support/hc/en-us/articles/360053909272-Ⅸ-Introduction-to-perpetual-swap-funding-fee
5661
6088
  # > The current interest is 0.
5662
6089
  return {
@@ -5677,12 +6104,37 @@ class okx(Exchange, ImplicitAPI):
5677
6104
  'previousFundingRate': None,
5678
6105
  'previousFundingTimestamp': None,
5679
6106
  'previousFundingDatetime': None,
6107
+ 'interval': self.parse_funding_interval(millisecondsInterval),
6108
+ }
6109
+
6110
+ def parse_funding_interval(self, interval):
6111
+ intervals: dict = {
6112
+ '3600000': '1h',
6113
+ '14400000': '4h',
6114
+ '28800000': '8h',
6115
+ '57600000': '16h',
6116
+ '86400000': '24h',
5680
6117
  }
6118
+ return self.safe_string(intervals, interval, interval)
6119
+
6120
+ async def fetch_funding_interval(self, symbol: str, params={}) -> FundingRate:
6121
+ """
6122
+ fetch the current funding rate interval
6123
+
6124
+ https://www.okx.com/docs-v5/en/#public-data-rest-api-get-funding-rate
6125
+
6126
+ :param str symbol: unified market symbol
6127
+ :param dict [params]: extra parameters specific to the exchange API endpoint
6128
+ :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
6129
+ """
6130
+ return await self.fetch_funding_rate(symbol, params)
5681
6131
 
5682
- async def fetch_funding_rate(self, symbol: str, params={}):
6132
+ async def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
5683
6133
  """
5684
6134
  fetch the current funding rate
5685
- :see: https://www.okx.com/docs-v5/en/#public-data-rest-api-get-funding-rate
6135
+
6136
+ https://www.okx.com/docs-v5/en/#public-data-rest-api-get-funding-rate
6137
+
5686
6138
  :param str symbol: unified market symbol
5687
6139
  :param dict [params]: extra parameters specific to the exchange API endpoint
5688
6140
  :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
@@ -5715,10 +6167,45 @@ class okx(Exchange, ImplicitAPI):
5715
6167
  entry = self.safe_dict(data, 0, {})
5716
6168
  return self.parse_funding_rate(entry, market)
5717
6169
 
6170
+ async def fetch_funding_rates(self, symbols: Strings = None, params={}) -> FundingRates:
6171
+ """
6172
+ fetches the current funding rates for multiple symbols
6173
+
6174
+ https://www.okx.com/docs-v5/en/#public-data-rest-api-get-funding-rate
6175
+
6176
+ :param str[] symbols: unified market symbols
6177
+ :param dict [params]: extra parameters specific to the exchange API endpoint
6178
+ :returns dict: a dictionary of `funding rates structure <https://docs.ccxt.com/#/?id=funding-rates-structure>`
6179
+ """
6180
+ await self.load_markets()
6181
+ symbols = self.market_symbols(symbols, 'swap', True)
6182
+ request: dict = {'instId': 'ANY'}
6183
+ response = await self.publicGetPublicFundingRate(self.extend(request, params))
6184
+ #
6185
+ # {
6186
+ # "code": "0",
6187
+ # "data": [
6188
+ # {
6189
+ # "fundingRate": "0.00027815",
6190
+ # "fundingTime": "1634256000000",
6191
+ # "instId": "BTC-USD-SWAP",
6192
+ # "instType": "SWAP",
6193
+ # "nextFundingRate": "0.00017",
6194
+ # "nextFundingTime": "1634284800000"
6195
+ # }
6196
+ # ],
6197
+ # "msg": ""
6198
+ # }
6199
+ #
6200
+ data = self.safe_list(response, 'data', [])
6201
+ return self.parse_funding_rates(data, symbols)
6202
+
5718
6203
  async def fetch_funding_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
5719
6204
  """
5720
6205
  fetch the history of funding payments paid and received on self account
5721
- :see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-bills-details-last-3-months
6206
+
6207
+ https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-bills-details-last-3-months
6208
+
5722
6209
  :param str symbol: unified market symbol
5723
6210
  :param int [since]: the earliest time in ms to fetch funding history for
5724
6211
  :param int [limit]: the maximum number of funding history structures to retrieve
@@ -5865,15 +6352,17 @@ class okx(Exchange, ImplicitAPI):
5865
6352
  sorted = self.sort_by(result, 'timestamp')
5866
6353
  return self.filter_by_symbol_since_limit(sorted, symbol, since, limit)
5867
6354
 
5868
- async def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
6355
+ async def set_leverage(self, leverage: int, symbol: Str = None, params={}):
5869
6356
  """
5870
6357
  set the level of leverage for a market
5871
- :see: https://www.okx.com/docs-v5/en/#rest-api-account-set-leverage
6358
+
6359
+ https://www.okx.com/docs-v5/en/#rest-api-account-set-leverage
6360
+
5872
6361
  :param float leverage: the rate of leverage
5873
6362
  :param str symbol: unified market symbol
5874
6363
  :param dict [params]: extra parameters specific to the exchange API endpoint
5875
6364
  :param str [params.marginMode]: 'cross' or 'isolated'
5876
- :param str [params.posSide]: 'long' or 'short' for isolated margin long/short mode on futures and swap markets
6365
+ :param str [params.posSide]: 'long' or 'short' or 'net' for isolated margin long/short mode on futures and swap markets, default is 'net'
5877
6366
  :returns dict: response from the exchange
5878
6367
  """
5879
6368
  if symbol is None:
@@ -5895,12 +6384,11 @@ class okx(Exchange, ImplicitAPI):
5895
6384
  'mgnMode': marginMode,
5896
6385
  'instId': market['id'],
5897
6386
  }
5898
- posSide = self.safe_string(params, 'posSide')
6387
+ posSide = self.safe_string(params, 'posSide', 'net')
5899
6388
  if marginMode == 'isolated':
5900
- if posSide is None:
5901
- raise ArgumentsRequired(self.id + ' setLeverage() requires a posSide argument for isolated margin')
5902
6389
  if posSide != 'long' and posSide != 'short' and posSide != 'net':
5903
6390
  raise BadRequest(self.id + ' setLeverage() requires the posSide argument to be either "long", "short" or "net"')
6391
+ request['posSide'] = posSide
5904
6392
  response = await self.privatePostAccountSetLeverage(self.extend(request, params))
5905
6393
  #
5906
6394
  # {
@@ -5920,11 +6408,13 @@ class okx(Exchange, ImplicitAPI):
5920
6408
 
5921
6409
  async def fetch_position_mode(self, symbol: Str = None, params={}):
5922
6410
  """
5923
- :see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-account-configuration
6411
+
6412
+ https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-account-configuration
6413
+
5924
6414
  fetchs the position mode, hedged or one way, hedged for binance is set identically for all linear markets or all inverse markets
5925
6415
  :param str symbol: unified symbol of the market to fetch the order book for
5926
6416
  :param dict [params]: extra parameters specific to the exchange API endpoint
5927
- :param str [param.accountId]: if you have multiple accounts, you must specify the account id to fetch the position mode
6417
+ :param str [params.accountId]: if you have multiple accounts, you must specify the account id to fetch the position mode
5928
6418
  :returns dict: an object detailing whether the market is in hedged or one-way mode
5929
6419
  """
5930
6420
  accounts = await self.fetch_accounts()
@@ -5951,7 +6441,9 @@ class okx(Exchange, ImplicitAPI):
5951
6441
  async def set_position_mode(self, hedged: bool, symbol: Str = None, params={}):
5952
6442
  """
5953
6443
  set hedged to True or False for a market
5954
- :see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-set-position-mode
6444
+
6445
+ https://www.okx.com/docs-v5/en/#trading-account-rest-api-set-position-mode
6446
+
5955
6447
  :param bool hedged: set to True to use long_short_mode, False for net_mode
5956
6448
  :param str symbol: not used by okx setPositionMode
5957
6449
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -5982,7 +6474,9 @@ class okx(Exchange, ImplicitAPI):
5982
6474
  async def set_margin_mode(self, marginMode: str, symbol: Str = None, params={}):
5983
6475
  """
5984
6476
  set margin mode to 'cross' or 'isolated'
5985
- :see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-set-leverage
6477
+
6478
+ https://www.okx.com/docs-v5/en/#trading-account-rest-api-set-leverage
6479
+
5986
6480
  :param str marginMode: 'cross' or 'isolated'
5987
6481
  :param str symbol: unified market symbol
5988
6482
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -6027,7 +6521,9 @@ class okx(Exchange, ImplicitAPI):
6027
6521
  async def fetch_cross_borrow_rates(self, params={}) -> CrossBorrowRates:
6028
6522
  """
6029
6523
  fetch the borrow interest rates of all currencies
6030
- :see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-interest-rate
6524
+
6525
+ https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-interest-rate
6526
+
6031
6527
  :param dict [params]: extra parameters specific to the exchange API endpoint
6032
6528
  :returns dict: a list of `borrow rate structures <https://docs.ccxt.com/#/?id=borrow-rate-structure>`
6033
6529
  """
@@ -6054,7 +6550,9 @@ class okx(Exchange, ImplicitAPI):
6054
6550
  async def fetch_cross_borrow_rate(self, code: str, params={}) -> CrossBorrowRate:
6055
6551
  """
6056
6552
  fetch the rate of interest to borrow a currency for margin trading
6057
- :see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-interest-rate
6553
+
6554
+ https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-interest-rate
6555
+
6058
6556
  :param str code: unified currency code
6059
6557
  :param dict [params]: extra parameters specific to the exchange API endpoint
6060
6558
  :returns dict: a `borrow rate structure <https://docs.ccxt.com/#/?id=borrow-rate-structure>`
@@ -6122,26 +6620,20 @@ class okx(Exchange, ImplicitAPI):
6122
6620
  if not (code in borrowRateHistories):
6123
6621
  borrowRateHistories[code] = []
6124
6622
  borrowRateStructure = self.parse_borrow_rate(item)
6125
- borrowRateHistories[code].append(borrowRateStructure)
6623
+ borrrowRateCode = borrowRateHistories[code]
6624
+ borrrowRateCode.append(borrowRateStructure)
6126
6625
  keys = list(borrowRateHistories.keys())
6127
6626
  for i in range(0, len(keys)):
6128
6627
  code = keys[i]
6129
6628
  borrowRateHistories[code] = self.filter_by_currency_since_limit(borrowRateHistories[code], code, since, limit)
6130
6629
  return borrowRateHistories
6131
6630
 
6132
- def parse_borrow_rate_history(self, response, code, since, limit):
6133
- result = []
6134
- for i in range(0, len(response)):
6135
- item = response[i]
6136
- borrowRate = self.parse_borrow_rate(item)
6137
- result.append(borrowRate)
6138
- sorted = self.sort_by(result, 'timestamp')
6139
- return self.filter_by_currency_since_limit(sorted, code, since, limit)
6140
-
6141
6631
  async def fetch_borrow_rate_histories(self, codes=None, since: Int = None, limit: Int = None, params={}):
6142
6632
  """
6143
6633
  retrieves a history of a multiple currencies borrow interest rate at specific time slots, returns all currencies if no symbols passed, default is None
6144
- :see: https://www.okx.com/docs-v5/en/#financial-product-savings-get-public-borrow-history-public
6634
+
6635
+ https://www.okx.com/docs-v5/en/#financial-product-savings-get-public-borrow-history-public
6636
+
6145
6637
  :param str[]|None codes: list of unified currency codes, default is None
6146
6638
  :param int [since]: timestamp in ms of the earliest borrowRate, default is None
6147
6639
  :param int [limit]: max number of borrow rate prices to return, default is None
@@ -6180,7 +6672,9 @@ class okx(Exchange, ImplicitAPI):
6180
6672
  async def fetch_borrow_rate_history(self, code: str, since: Int = None, limit: Int = None, params={}):
6181
6673
  """
6182
6674
  retrieves a history of a currencies borrow interest rate at specific time slots
6183
- :see: https://www.okx.com/docs-v5/en/#financial-product-savings-get-public-borrow-history-public
6675
+
6676
+ https://www.okx.com/docs-v5/en/#financial-product-savings-get-public-borrow-history-public
6677
+
6184
6678
  :param str code: unified currency code
6185
6679
  :param int [since]: timestamp for the earliest borrow rate
6186
6680
  :param int [limit]: the maximum number of `borrow rate structures <https://docs.ccxt.com/#/?id=borrow-rate-structure>` to retrieve
@@ -6326,7 +6820,9 @@ class okx(Exchange, ImplicitAPI):
6326
6820
  async def reduce_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
6327
6821
  """
6328
6822
  remove margin from a position
6329
- :see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-increase-decrease-margin
6823
+
6824
+ https://www.okx.com/docs-v5/en/#trading-account-rest-api-increase-decrease-margin
6825
+
6330
6826
  :param str symbol: unified market symbol
6331
6827
  :param float amount: the amount of margin to remove
6332
6828
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -6337,7 +6833,9 @@ class okx(Exchange, ImplicitAPI):
6337
6833
  async def add_margin(self, symbol: str, amount: float, params={}) -> MarginModification:
6338
6834
  """
6339
6835
  add margin
6340
- :see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-increase-decrease-margin
6836
+
6837
+ https://www.okx.com/docs-v5/en/#trading-account-rest-api-increase-decrease-margin
6838
+
6341
6839
  :param str symbol: unified market symbol
6342
6840
  :param float amount: amount of margin to add
6343
6841
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -6348,7 +6846,9 @@ class okx(Exchange, ImplicitAPI):
6348
6846
  async def fetch_market_leverage_tiers(self, symbol: str, params={}) -> List[LeverageTier]:
6349
6847
  """
6350
6848
  retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes for a single market
6351
- :see: https://www.okx.com/docs-v5/en/#rest-api-public-data-get-position-tiers
6849
+
6850
+ https://www.okx.com/docs-v5/en/#rest-api-public-data-get-position-tiers
6851
+
6352
6852
  :param str symbol: unified market symbol
6353
6853
  :param dict [params]: extra parameters specific to the exchange API endpoint
6354
6854
  :param str [params.marginMode]: 'cross' or 'isolated'
@@ -6399,7 +6899,7 @@ class okx(Exchange, ImplicitAPI):
6399
6899
 
6400
6900
  def parse_market_leverage_tiers(self, info, market: Market = None) -> List[LeverageTier]:
6401
6901
  """
6402
- * @ignore
6902
+ @ignore
6403
6903
  :param dict info: Exchange response for 1 market
6404
6904
  :param dict market: CCXT market
6405
6905
  """
@@ -6424,8 +6924,10 @@ class okx(Exchange, ImplicitAPI):
6424
6924
  tiers = []
6425
6925
  for i in range(0, len(info)):
6426
6926
  tier = info[i]
6927
+ marketId = self.safe_string(tier, 'instId')
6427
6928
  tiers.append({
6428
6929
  'tier': self.safe_integer(tier, 'tier'),
6930
+ 'symbol': self.safe_symbol(marketId, market),
6429
6931
  'currency': market['quote'],
6430
6932
  'minNotional': self.safe_number(tier, 'minSz'),
6431
6933
  'maxNotional': self.safe_number(tier, 'maxSz'),
@@ -6435,10 +6937,12 @@ class okx(Exchange, ImplicitAPI):
6435
6937
  })
6436
6938
  return tiers
6437
6939
 
6438
- async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
6940
+ async def fetch_borrow_interest(self, code: Str = None, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[BorrowInterest]:
6439
6941
  """
6440
- fetch the interest owed by the user for borrowing currency for margin trading
6441
- :see: https://www.okx.com/docs-v5/en/#rest-api-account-get-interest-accrued-data
6942
+ fetch the interest owed b the user for borrowing currency for margin trading
6943
+
6944
+ https://www.okx.com/docs-v5/en/#rest-api-account-get-interest-accrued-data
6945
+
6442
6946
  :param str code: the unified currency code for the currency of the interest
6443
6947
  :param str symbol: the market symbol of an isolated margin market, if None, the interest for cross margin markets is returned
6444
6948
  :param int [since]: timestamp in ms of the earliest time to receive interest records for
@@ -6491,27 +6995,29 @@ class okx(Exchange, ImplicitAPI):
6491
6995
  interest = self.parse_borrow_interests(data)
6492
6996
  return self.filter_by_currency_since_limit(interest, code, since, limit)
6493
6997
 
6494
- def parse_borrow_interest(self, info: dict, market: Market = None):
6998
+ def parse_borrow_interest(self, info: dict, market: Market = None) -> BorrowInterest:
6495
6999
  instId = self.safe_string(info, 'instId')
6496
7000
  if instId is not None:
6497
7001
  market = self.safe_market(instId, market)
6498
7002
  timestamp = self.safe_integer(info, 'ts')
6499
7003
  return {
7004
+ 'info': info,
6500
7005
  'symbol': self.safe_string(market, 'symbol'),
6501
- 'marginMode': self.safe_string(info, 'mgnMode'),
6502
7006
  'currency': self.safe_currency_code(self.safe_string(info, 'ccy')),
6503
7007
  'interest': self.safe_number(info, 'interest'),
6504
7008
  'interestRate': self.safe_number(info, 'interestRate'),
6505
7009
  'amountBorrowed': self.safe_number(info, 'liab'),
7010
+ 'marginMode': self.safe_string(info, 'mgnMode'),
6506
7011
  'timestamp': timestamp, # Interest accrued time
6507
7012
  'datetime': self.iso8601(timestamp),
6508
- 'info': info,
6509
7013
  }
6510
7014
 
6511
7015
  async def borrow_cross_margin(self, code: str, amount: float, params={}):
6512
7016
  """
6513
7017
  create a loan to borrow margin(need to be VIP 5 and above)
6514
- :see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-vip-loans-borrow-and-repay
7018
+
7019
+ https://www.okx.com/docs-v5/en/#trading-account-rest-api-vip-loans-borrow-and-repay
7020
+
6515
7021
  :param str code: unified currency code of the currency to borrow
6516
7022
  :param float amount: the amount to borrow
6517
7023
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -6547,7 +7053,9 @@ class okx(Exchange, ImplicitAPI):
6547
7053
  async def repay_cross_margin(self, code: str, amount, params={}):
6548
7054
  """
6549
7055
  repay borrowed margin and interest
6550
- :see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-vip-loans-borrow-and-repay
7056
+
7057
+ https://www.okx.com/docs-v5/en/#trading-account-rest-api-vip-loans-borrow-and-repay
7058
+
6551
7059
  :param str code: unified currency code of the currency to repay
6552
7060
  :param float amount: the amount to repay
6553
7061
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -6612,7 +7120,9 @@ class okx(Exchange, ImplicitAPI):
6612
7120
  async def fetch_open_interest(self, symbol: str, params={}):
6613
7121
  """
6614
7122
  Retrieves the open interest of a currency
6615
- :see: https://www.okx.com/docs-v5/en/#rest-api-public-data-get-open-interest
7123
+
7124
+ https://www.okx.com/docs-v5/en/#rest-api-public-data-get-open-interest
7125
+
6616
7126
  :param str symbol: Unified CCXT market symbol
6617
7127
  :param dict [params]: exchange specific parameters
6618
7128
  :returns dict} an open interest structure{@link https://docs.ccxt.com/#/?id=open-interest-structure:
@@ -6647,11 +7157,66 @@ class okx(Exchange, ImplicitAPI):
6647
7157
  data = self.safe_list(response, 'data', [])
6648
7158
  return self.parse_open_interest(data[0], market)
6649
7159
 
7160
+ async def fetch_open_interests(self, symbols: Strings = None, params={}) -> OpenInterests:
7161
+ """
7162
+ Retrieves the open interests of some currencies
7163
+
7164
+ https://www.okx.com/docs-v5/en/#rest-api-public-data-get-open-interest
7165
+
7166
+ :param str[] symbols: Unified CCXT market symbols
7167
+ :param dict [params]: exchange specific parameters
7168
+ :param str params['instType']: Instrument type, options: 'SWAP', 'FUTURES', 'OPTION', default to 'SWAP'
7169
+ :param str params['uly']: Underlying, Applicable to FUTURES/SWAP/OPTION, if instType is 'OPTION', either uly or instFamily is required
7170
+ :param str params['instFamily']: Instrument family, Applicable to FUTURES/SWAP/OPTION, if instType is 'OPTION', either uly or instFamily is required
7171
+ :returns dict: an dictionary of `open interest structures <https://docs.ccxt.com/#/?id=open-interest-structure>`
7172
+ """
7173
+ await self.load_markets()
7174
+ symbols = self.market_symbols(symbols, None, True, True)
7175
+ market = None
7176
+ if symbols is not None:
7177
+ market = self.market(symbols[0])
7178
+ marketType = None
7179
+ marketType, params = self.handle_sub_type_and_params('fetchOpenInterests', market, params, 'swap')
7180
+ instType = 'SWAP'
7181
+ if marketType == 'future':
7182
+ instType = 'FUTURES'
7183
+ elif instType == 'option':
7184
+ instType = 'OPTION'
7185
+ request: dict = {'instType': instType}
7186
+ uly = self.safe_string(params, 'uly')
7187
+ if uly is not None:
7188
+ request['uly'] = uly
7189
+ instFamily = self.safe_string(params, 'instFamily')
7190
+ if instFamily is not None:
7191
+ request['instFamily'] = instFamily
7192
+ if instType == 'OPTION' and uly is None and instFamily is None:
7193
+ raise BadRequest(self.id + ' fetchOpenInterests() requires either uly or instFamily parameter for OPTION markets')
7194
+ response = await self.publicGetPublicOpenInterest(self.extend(request, params))
7195
+ #
7196
+ # {
7197
+ # "code": "0",
7198
+ # "data": [
7199
+ # {
7200
+ # "instId": "BTC-USDT-SWAP",
7201
+ # "instType": "SWAP",
7202
+ # "oi": "2125419",
7203
+ # "oiCcy": "21254.19",
7204
+ # "ts": "1664005108969"
7205
+ # }
7206
+ # ],
7207
+ # "msg": ""
7208
+ # }
7209
+ #
7210
+ data = self.safe_list(response, 'data', [])
7211
+ return self.parse_open_interests(data, symbols)
7212
+
6650
7213
  async def fetch_open_interest_history(self, symbol: str, timeframe='1d', since: Int = None, limit: Int = None, params={}):
6651
7214
  """
6652
7215
  Retrieves the open interest history of a currency
6653
- :see: https://www.okx.com/docs-v5/en/#rest-api-trading-data-get-contracts-open-interest-and-volume
6654
- :see: https://www.okx.com/docs-v5/en/#rest-api-trading-data-get-options-open-interest-and-volume
7216
+
7217
+ https://www.okx.com/docs-v5/en/#rest-api-trading-data-get-contracts-open-interest-and-volume
7218
+ https://www.okx.com/docs-v5/en/#rest-api-trading-data-get-options-open-interest-and-volume
7219
+
6655
7220
  :param str symbol: Unified CCXT currency code or unified symbol
6656
7221
  :param str timeframe: "5m", "1h", or "1d" for option only "1d" or "8h"
6657
7222
  :param int [since]: The time in ms of the earliest record to retrieve unix timestamp
@@ -6707,7 +7272,7 @@ class okx(Exchange, ImplicitAPI):
6707
7272
  # }
6708
7273
  #
6709
7274
  data = self.safe_list(response, 'data', [])
6710
- return self.parse_open_interests(data, None, since, limit)
7275
+ return self.parse_open_interests_history(data, None, since, limit)
6711
7276
 
6712
7277
  def parse_open_interest(self, interest, market: Market = None):
6713
7278
  #
@@ -6726,6 +7291,7 @@ class okx(Exchange, ImplicitAPI):
6726
7291
  # "instType": "OPTION",
6727
7292
  # "oi": "300",
6728
7293
  # "oiCcy": "3",
7294
+ # "oiUsd": "3",
6729
7295
  # "ts": "1684551166251"
6730
7296
  # }
6731
7297
  #
@@ -6748,7 +7314,7 @@ class okx(Exchange, ImplicitAPI):
6748
7314
  else:
6749
7315
  baseVolume = self.safe_number(interest, 'oiCcy')
6750
7316
  openInterestAmount = self.safe_number(interest, 'oi')
6751
- openInterestValue = self.safe_number(interest, 'oiCcy')
7317
+ openInterestValue = self.safe_number(interest, 'oiUsd')
6752
7318
  return self.safe_open_interest({
6753
7319
  'symbol': self.safe_symbol(id),
6754
7320
  'baseVolume': baseVolume, # deprecated
@@ -6771,13 +7337,19 @@ class okx(Exchange, ImplicitAPI):
6771
7337
  async def fetch_deposit_withdraw_fees(self, codes: Strings = None, params={}):
6772
7338
  """
6773
7339
  fetch deposit and withdraw fees
6774
- :see: https://www.okx.com/docs-v5/en/#rest-api-funding-get-currencies
7340
+
7341
+ https://www.okx.com/docs-v5/en/#rest-api-funding-get-currencies
7342
+
6775
7343
  :param str[]|None codes: list of unified currency codes
6776
7344
  :param dict [params]: extra parameters specific to the exchange API endpoint
6777
7345
  :returns dict[]: a list of `fees structures <https://docs.ccxt.com/#/?id=fee-structure>`
6778
7346
  """
6779
7347
  await self.load_markets()
6780
- response = await self.privateGetAssetCurrencies(params)
7348
+ request = {}
7349
+ if codes is not None:
7350
+ ids = self.currency_ids(codes)
7351
+ request['ccy'] = ','.join(ids)
7352
+ response = await self.privateGetAssetCurrencies(self.extend(request, params))
6781
7353
  #
6782
7354
  # {
6783
7355
  # "code": "0",
@@ -6858,9 +7430,11 @@ class okx(Exchange, ImplicitAPI):
6858
7430
  depositWithdrawFees[code] = self.deposit_withdraw_fee({})
6859
7431
  depositWithdrawFees[code]['info'][currencyId] = feeInfo
6860
7432
  chain = self.safe_string(feeInfo, 'chain')
7433
+ if chain is None:
7434
+ continue
6861
7435
  chainSplit = chain.split('-')
6862
7436
  networkId = self.safe_value(chainSplit, 1)
6863
- withdrawFee = self.safe_number(feeInfo, 'minFee')
7437
+ withdrawFee = self.safe_number(feeInfo, 'fee')
6864
7438
  withdrawResult: dict = {
6865
7439
  'fee': withdrawFee,
6866
7440
  'percentage': False if (withdrawFee is not None) else None,
@@ -6884,7 +7458,9 @@ class okx(Exchange, ImplicitAPI):
6884
7458
  async def fetch_settlement_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
6885
7459
  """
6886
7460
  fetches historical settlement records
6887
- :see: https://www.okx.com/docs-v5/en/#rest-api-public-data-get-delivery-exercise-history
7461
+
7462
+ https://www.okx.com/docs-v5/en/#rest-api-public-data-get-delivery-exercise-history
7463
+
6888
7464
  :param str symbol: unified market symbol to fetch the settlement history for
6889
7465
  :param int [since]: timestamp in ms
6890
7466
  :param int [limit]: number of records
@@ -6977,7 +7553,9 @@ class okx(Exchange, ImplicitAPI):
6977
7553
  async def fetch_underlying_assets(self, params={}):
6978
7554
  """
6979
7555
  fetches the market ids of underlying assets for a specific contract market type
6980
- :see: https://www.okx.com/docs-v5/en/#public-data-rest-api-get-underlying
7556
+
7557
+ https://www.okx.com/docs-v5/en/#public-data-rest-api-get-underlying
7558
+
6981
7559
  :param dict [params]: exchange specific params
6982
7560
  :param str [params.type]: the contract market type, 'option', 'swap' or 'future', the default is 'option'
6983
7561
  :returns dict[]: a list of `underlying assets <https://docs.ccxt.com/#/?id=underlying-assets-structure>`
@@ -7011,7 +7589,9 @@ class okx(Exchange, ImplicitAPI):
7011
7589
  async def fetch_greeks(self, symbol: str, params={}) -> Greeks:
7012
7590
  """
7013
7591
  fetches an option contracts greeks, financial metrics used to measure the factors that affect the price of an options contract
7014
- :see: https://www.okx.com/docs-v5/en/#public-data-rest-api-get-option-market-data
7592
+
7593
+ https://www.okx.com/docs-v5/en/#public-data-rest-api-get-option-market-data
7594
+
7015
7595
  :param str symbol: unified symbol of the market to fetch greeks for
7016
7596
  :param dict [params]: extra parameters specific to the exchange API endpoint
7017
7597
  :returns dict: a `greeks structure <https://docs.ccxt.com/#/?id=greeks-structure>`
@@ -7063,6 +7643,76 @@ class okx(Exchange, ImplicitAPI):
7063
7643
  return self.parse_greeks(entry, market)
7064
7644
  return None
7065
7645
 
7646
+ async def fetch_all_greeks(self, symbols: Strings = None, params={}) -> List[Greeks]:
7647
+ """
7648
+ fetches all option contracts greeks, financial metrics used to measure the factors that affect the price of an options contract
7649
+
7650
+ https://www.okx.com/docs-v5/en/#public-data-rest-api-get-option-market-data
7651
+
7652
+ :param str[] [symbols]: unified symbols of the markets to fetch greeks for, all markets are returned if not assigned
7653
+ :param dict [params]: extra parameters specific to the exchange API endpoint
7654
+ :param str params['uly']: Underlying, either uly or instFamily is required
7655
+ :param str params['instFamily']: Instrument family, either uly or instFamily is required
7656
+ :returns dict: a `greeks structure <https://docs.ccxt.com/#/?id=greeks-structure>`
7657
+ """
7658
+ await self.load_markets()
7659
+ request: dict = {}
7660
+ symbols = self.market_symbols(symbols, None, True, True, True)
7661
+ symbolsLength = None
7662
+ if symbols is not None:
7663
+ symbolsLength = len(symbols)
7664
+ if (symbols is None) or (symbolsLength != 1):
7665
+ uly = self.safe_string(params, 'uly')
7666
+ if uly is not None:
7667
+ request['uly'] = uly
7668
+ instFamily = self.safe_string(params, 'instFamily')
7669
+ if instFamily is not None:
7670
+ request['instFamily'] = instFamily
7671
+ if (uly is None) and (instFamily is None):
7672
+ raise BadRequest(self.id + ' fetchAllGreeks() requires either a uly or instFamily parameter')
7673
+ market = None
7674
+ if symbols is not None:
7675
+ if symbolsLength == 1:
7676
+ market = self.market(symbols[0])
7677
+ marketId = market['id']
7678
+ optionParts = marketId.split('-')
7679
+ request['uly'] = market['info']['uly']
7680
+ request['instFamily'] = market['info']['instFamily']
7681
+ request['expTime'] = self.safe_string(optionParts, 2)
7682
+ params = self.omit(params, ['uly', 'instFamily'])
7683
+ response = await self.publicGetPublicOptSummary(self.extend(request, params))
7684
+ #
7685
+ # {
7686
+ # "code": "0",
7687
+ # "data": [
7688
+ # {
7689
+ # "askVol": "0",
7690
+ # "bidVol": "0",
7691
+ # "delta": "0.5105464486882039",
7692
+ # "deltaBS": "0.7325502184143025",
7693
+ # "fwdPx": "37675.80158694987186",
7694
+ # "gamma": "-0.13183515090501083",
7695
+ # "gammaBS": "0.000024139685826358558",
7696
+ # "instId": "BTC-USD-240329-32000-C",
7697
+ # "instType": "OPTION",
7698
+ # "lever": "4.504428015946619",
7699
+ # "markVol": "0.5916253554539876",
7700
+ # "realVol": "0",
7701
+ # "theta": "-0.0004202992014012855",
7702
+ # "thetaBS": "-18.52354631567909",
7703
+ # "ts": "1699586421976",
7704
+ # "uly": "BTC-USD",
7705
+ # "vega": "0.0020207455080045846",
7706
+ # "vegaBS": "74.44022302387287",
7707
+ # "volLv": "0.5948549730405797"
7708
+ # },
7709
+ # ],
7710
+ # "msg": ""
7711
+ # }
7712
+ #
7713
+ data = self.safe_list(response, 'data', [])
7714
+ return self.parse_all_greeks(data, symbols)
7715
+
7066
7716
  def parse_greeks(self, greeks: dict, market: Market = None) -> Greeks:
7067
7717
  #
7068
7718
  # {
@@ -7115,15 +7765,17 @@ class okx(Exchange, ImplicitAPI):
7115
7765
  async def close_position(self, symbol: str, side: OrderSide = None, params={}) -> Order:
7116
7766
  """
7117
7767
  closes open positions for a market
7118
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-close-positions
7768
+
7769
+ https://www.okx.com/docs-v5/en/#order-book-trading-trade-post-close-positions
7770
+
7119
7771
  :param str symbol: Unified CCXT market symbol
7120
7772
  :param str [side]: 'buy' or 'sell', leave in net mode
7121
7773
  :param dict [params]: extra parameters specific to the okx api endpoint
7122
7774
  :param str [params.clientOrderId]: a unique identifier for the order
7123
7775
  :param str [params.marginMode]: 'cross' or 'isolated', default is 'cross
7124
7776
  :param str [params.code]: *required in the case of closing cross MARGIN position for Single-currency margin* margin currency
7125
- *
7126
- * EXCHANGE SPECIFIC PARAMETERS
7777
+
7778
+ EXCHANGE SPECIFIC PARAMETERS
7127
7779
  :param boolean [params.autoCxl]: whether any pending orders for closing out needs to be automatically canceled when close position via a market order. False or True, the default is False
7128
7780
  :param str [params.tag]: order tag a combination of case-sensitive alphanumerics, all numbers, or all letters of up to 16 characters
7129
7781
  :returns dict[]: `A list of position structures <https://docs.ccxt.com/#/?id=position-structure>`
@@ -7175,7 +7827,9 @@ class okx(Exchange, ImplicitAPI):
7175
7827
  async def fetch_option(self, symbol: str, params={}) -> Option:
7176
7828
  """
7177
7829
  fetches option data that is commonly found in an option chain
7178
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-ticker
7830
+
7831
+ https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-ticker
7832
+
7179
7833
  :param str symbol: unified market symbol
7180
7834
  :param dict [params]: extra parameters specific to the exchange API endpoint
7181
7835
  :returns dict: an `option chain structure <https://docs.ccxt.com/#/?id=option-chain-structure>`
@@ -7219,8 +7873,10 @@ class okx(Exchange, ImplicitAPI):
7219
7873
  async def fetch_option_chain(self, code: str, params={}) -> OptionChain:
7220
7874
  """
7221
7875
  fetches data for an underlying asset that is commonly found in an option chain
7222
- :see: https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-tickers
7223
- :param str currency: base currency to fetch an option chain for
7876
+
7877
+ https://www.okx.com/docs-v5/en/#order-book-trading-market-data-get-tickers
7878
+
7879
+ :param str code: base currency to fetch an option chain for
7224
7880
  :param dict [params]: extra parameters specific to the exchange API endpoint
7225
7881
  :param str [params.uly]: the underlying asset, can be obtained from fetchUnderlyingAssets()
7226
7882
  :returns dict: a list of `option chain structures <https://docs.ccxt.com/#/?id=option-chain-structure>`
@@ -7308,7 +7964,9 @@ class okx(Exchange, ImplicitAPI):
7308
7964
  async def fetch_convert_quote(self, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
7309
7965
  """
7310
7966
  fetch a quote for converting from one currency to another
7311
- :see: https://www.okx.com/docs-v5/en/#funding-account-rest-api-estimate-quote
7967
+
7968
+ https://www.okx.com/docs-v5/en/#funding-account-rest-api-estimate-quote
7969
+
7312
7970
  :param str fromCode: the currency that you want to sell and convert from
7313
7971
  :param str toCode: the currency that you want to buy and convert into
7314
7972
  :param float [amount]: how much you want to trade in units of the from currency
@@ -7358,7 +8016,9 @@ class okx(Exchange, ImplicitAPI):
7358
8016
  async def create_convert_trade(self, id: str, fromCode: str, toCode: str, amount: Num = None, params={}) -> Conversion:
7359
8017
  """
7360
8018
  convert from one currency to another
7361
- :see: https://www.okx.com/docs-v5/en/#funding-account-rest-api-convert-trade
8019
+
8020
+ https://www.okx.com/docs-v5/en/#funding-account-rest-api-convert-trade
8021
+
7362
8022
  :param str id: the id of the trade that you want to make
7363
8023
  :param str fromCode: the currency that you want to sell and convert from
7364
8024
  :param str toCode: the currency that you want to buy and convert into
@@ -7409,7 +8069,9 @@ class okx(Exchange, ImplicitAPI):
7409
8069
  async def fetch_convert_trade(self, id: str, code: Str = None, params={}) -> Conversion:
7410
8070
  """
7411
8071
  fetch the data for a conversion trade
7412
- :see: https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-convert-history
8072
+
8073
+ https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-convert-history
8074
+
7413
8075
  :param str id: the id of the trade that you want to fetch
7414
8076
  :param str [code]: the unified currency code of the conversion trade
7415
8077
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -7456,7 +8118,9 @@ class okx(Exchange, ImplicitAPI):
7456
8118
  async def fetch_convert_trade_history(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Conversion]:
7457
8119
  """
7458
8120
  fetch the users history of conversion trades
7459
- :see: https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-convert-history
8121
+
8122
+ https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-convert-history
8123
+
7460
8124
  :param str [code]: the unified currency code
7461
8125
  :param int [since]: the earliest time in ms to fetch conversions for
7462
8126
  :param int [limit]: the maximum number of conversion structures to retrieve
@@ -7570,7 +8234,9 @@ class okx(Exchange, ImplicitAPI):
7570
8234
  async def fetch_convert_currencies(self, params={}) -> Currencies:
7571
8235
  """
7572
8236
  fetches all available currencies that can be converted
7573
- :see: https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-convert-currencies
8237
+
8238
+ https://www.okx.com/docs-v5/en/#funding-account-rest-api-get-convert-currencies
8239
+
7574
8240
  :param dict [params]: extra parameters specific to the exchange API endpoint
7575
8241
  :returns dict: an associative dictionary of currencies
7576
8242
  """
@@ -7665,10 +8331,14 @@ class okx(Exchange, ImplicitAPI):
7665
8331
  async def fetch_margin_adjustment_history(self, symbol: Str = None, type: Str = None, since: Num = None, limit: Num = None, params={}) -> List[MarginModification]:
7666
8332
  """
7667
8333
  fetches the history of margin added or reduced from contract isolated positions
7668
- :see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-bills-details-last-7-days
7669
- :see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-bills-details-last-3-months
8334
+
8335
+ https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-bills-details-last-7-days
8336
+ https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-bills-details-last-3-months
8337
+
7670
8338
  :param str [symbol]: not used by okx fetchMarginAdjustmentHistory
7671
8339
  :param str [type]: "add" or "reduce"
8340
+ :param int [since]: the earliest time in ms to fetch margin adjustment history for
8341
+ :param int [limit]: the maximum number of entries to retrieve
7672
8342
  :param dict params: extra parameters specific to the exchange api endpoint
7673
8343
  :param boolean [params.auto]: True if fetching auto margin increases
7674
8344
  :returns dict[]: a list of `margin structures <https://docs.ccxt.com/#/?id=margin-loan-structure>`
@@ -7755,14 +8425,16 @@ class okx(Exchange, ImplicitAPI):
7755
8425
  async def fetch_positions_history(self, symbols: Strings = None, since: Int = None, limit: Int = None, params={}) -> List[Position]:
7756
8426
  """
7757
8427
  fetches historical positions
7758
- :see: https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-positions-history
8428
+
8429
+ https://www.okx.com/docs-v5/en/#trading-account-rest-api-get-positions-history
8430
+
7759
8431
  :param str [symbols]: unified market symbols
7760
8432
  :param int [since]: timestamp in ms of the earliest position to fetch
7761
8433
  :param int [limit]: the maximum amount of records to fetch, default=100, max=100
7762
8434
  :param dict params: extra parameters specific to the exchange api endpoint
7763
8435
  :param str [params.marginMode]: "cross" or "isolated"
7764
- *
7765
- * EXCHANGE SPECIFIC PARAMETERS
8436
+
8437
+ EXCHANGE SPECIFIC PARAMETERS
7766
8438
  :param str [params.instType]: margin, swap, futures or option
7767
8439
  :param str [params.type]: the type of latest close position 1: close position partially, 2:close all, 3:liquidation, 4:partial liquidation; 5:adl, is it is the latest type if there are several types for the same position
7768
8440
  :param str [params.posId]: position id, there is attribute expiration, the posid will be expired if it is more than 30 days after the last full close position, then position will use new posid
@@ -7825,3 +8497,68 @@ class okx(Exchange, ImplicitAPI):
7825
8497
  data = self.safe_list(response, 'data')
7826
8498
  positions = self.parse_positions(data, symbols, params)
7827
8499
  return self.filter_by_since_limit(positions, since, limit)
8500
+
8501
+ async def fetch_long_short_ratio_history(self, symbol: Str = None, timeframe: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LongShortRatio]:
8502
+ """
8503
+ fetches the long short ratio history for a unified market symbol
8504
+
8505
+ https://www.okx.com/docs-v5/en/#trading-statistics-rest-api-get-contract-long-short-ratio
8506
+
8507
+ :param str symbol: unified symbol of the market to fetch the long short ratio for
8508
+ :param str [timeframe]: the period for the ratio
8509
+ :param int [since]: the earliest time in ms to fetch ratios for
8510
+ :param int [limit]: the maximum number of long short ratio structures to retrieve
8511
+ :param dict [params]: extra parameters specific to the exchange API endpoint
8512
+ :param int [params.until]: timestamp in ms of the latest ratio to fetch
8513
+ :returns dict[]: an array of `long short ratio structures <https://docs.ccxt.com/#/?id=long-short-ratio-structure>`
8514
+ """
8515
+ await self.load_markets()
8516
+ market = self.market(symbol)
8517
+ request: dict = {
8518
+ 'instId': market['id'],
8519
+ }
8520
+ until = self.safe_string_2(params, 'until', 'end')
8521
+ params = self.omit(params, 'until')
8522
+ if until is not None:
8523
+ request['end'] = until
8524
+ if timeframe is not None:
8525
+ request['period'] = timeframe
8526
+ if since is not None:
8527
+ request['begin'] = since
8528
+ if limit is not None:
8529
+ request['limit'] = limit
8530
+ response = await self.publicGetRubikStatContractsLongShortAccountRatioContract(self.extend(request, params))
8531
+ #
8532
+ # {
8533
+ # "code": "0",
8534
+ # "data": [
8535
+ # ["1729323600000", "0.9398602814619824"],
8536
+ # ["1729323300000", "0.9398602814619824"],
8537
+ # ["1729323000000", "0.9398602814619824"],
8538
+ # ],
8539
+ # "msg": ""
8540
+ # }
8541
+ #
8542
+ data = self.safe_list(response, 'data', [])
8543
+ result = []
8544
+ for i in range(0, len(data)):
8545
+ entry = data[i]
8546
+ result.append({
8547
+ 'timestamp': self.safe_string(entry, 0),
8548
+ 'longShortRatio': self.safe_string(entry, 1),
8549
+ })
8550
+ return self.parse_long_short_ratio_history(result, market)
8551
+
8552
+ def parse_long_short_ratio(self, info: dict, market: Market = None) -> LongShortRatio:
8553
+ timestamp = self.safe_integer(info, 'timestamp')
8554
+ symbol = None
8555
+ if market is not None:
8556
+ symbol = market['symbol']
8557
+ return {
8558
+ 'info': info,
8559
+ 'symbol': symbol,
8560
+ 'timestamp': timestamp,
8561
+ 'datetime': self.iso8601(timestamp),
8562
+ 'timeframe': None,
8563
+ 'longShortRatio': self.safe_number(info, 'longShortRatio'),
8564
+ }