ccxt-ir 4.3.46.0.2__py2.py3-none-any.whl → 4.5.0__py2.py3-none-any.whl

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