ccxt-ir 4.3.46.0.3__py2.py3-none-any.whl → 4.5.1__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (529) hide show
  1. ccxt/__init__.py +39 -35
  2. ccxt/abantether.py +8 -8
  3. ccxt/abstract/alpaca.py +4 -0
  4. ccxt/abstract/apex.py +31 -0
  5. ccxt/abstract/bigone.py +1 -1
  6. ccxt/abstract/binance.py +106 -48
  7. ccxt/abstract/binancecoinm.py +106 -48
  8. ccxt/abstract/binanceus.py +141 -83
  9. ccxt/abstract/binanceusdm.py +106 -48
  10. ccxt/abstract/bingx.py +50 -1
  11. ccxt/abstract/bitbank.py +5 -0
  12. ccxt/abstract/bitfinex.py +136 -65
  13. ccxt/abstract/bitflyer.py +1 -0
  14. ccxt/abstract/bitget.py +67 -0
  15. ccxt/abstract/bitmart.py +19 -1
  16. ccxt/abstract/bitopro.py +1 -0
  17. ccxt/abstract/bitrue.py +68 -68
  18. ccxt/abstract/bitstamp.py +1 -0
  19. ccxt/abstract/blofin.py +30 -0
  20. ccxt/abstract/btcbox.py +2 -0
  21. ccxt/abstract/bybit.py +28 -13
  22. ccxt/abstract/cex.py +28 -29
  23. ccxt/abstract/coinbaseexchange.py +1 -0
  24. ccxt/abstract/coinbaseinternational.py +1 -1
  25. ccxt/abstract/cryptocom.py +16 -0
  26. ccxt/abstract/cryptomus.py +20 -0
  27. ccxt/abstract/defx.py +69 -0
  28. ccxt/abstract/deribit.py +1 -0
  29. ccxt/abstract/derive.py +117 -0
  30. ccxt/abstract/digifinex.py +1 -0
  31. ccxt/abstract/ellipx.py +25 -0
  32. ccxt/abstract/foxbit.py +26 -0
  33. ccxt/abstract/gate.py +19 -0
  34. ccxt/abstract/gateio.py +19 -0
  35. ccxt/abstract/gemini.py +1 -0
  36. ccxt/abstract/hibachi.py +26 -0
  37. ccxt/abstract/hyperliquid.py +1 -1
  38. ccxt/abstract/independentreserve.py +6 -0
  39. ccxt/abstract/kraken.py +1 -0
  40. ccxt/abstract/krakenfutures.py +4 -0
  41. ccxt/abstract/kucoin.py +10 -0
  42. ccxt/abstract/kucoinfutures.py +18 -0
  43. ccxt/abstract/lbank.py +2 -1
  44. ccxt/abstract/luno.py +1 -0
  45. ccxt/abstract/mexc.py +2 -0
  46. ccxt/abstract/modetrade.py +119 -0
  47. ccxt/abstract/myokx.py +349 -0
  48. ccxt/abstract/oceanex.py +5 -0
  49. ccxt/abstract/okx.py +25 -0
  50. ccxt/abstract/okxus.py +349 -0
  51. ccxt/abstract/onetrading.py +0 -12
  52. ccxt/abstract/paradex.py +23 -0
  53. ccxt/abstract/phemex.py +2 -0
  54. ccxt/abstract/poloniex.py +36 -0
  55. ccxt/abstract/tradeogre.py +3 -1
  56. ccxt/abstract/upbit.py +51 -34
  57. ccxt/abstract/whitebit.py +16 -0
  58. ccxt/abstract/woo.py +64 -6
  59. ccxt/abstract/xt.py +10 -5
  60. ccxt/afratether.py +8 -8
  61. ccxt/alpaca.py +828 -51
  62. ccxt/apex.py +1875 -0
  63. ccxt/arzinja.py +7 -7
  64. ccxt/arzplus.py +9 -9
  65. ccxt/ascendex.py +501 -306
  66. ccxt/async_support/__init__.py +39 -35
  67. ccxt/async_support/abantether.py +8 -8
  68. ccxt/async_support/afratether.py +10 -10
  69. ccxt/async_support/alpaca.py +828 -51
  70. ccxt/async_support/apex.py +1875 -0
  71. ccxt/async_support/arzinja.py +10 -10
  72. ccxt/async_support/arzplus.py +12 -12
  73. ccxt/async_support/ascendex.py +502 -306
  74. ccxt/async_support/base/exchange.py +303 -89
  75. ccxt/async_support/base/ws/cache.py +9 -3
  76. ccxt/async_support/base/ws/client.py +173 -38
  77. ccxt/async_support/base/ws/future.py +25 -37
  78. ccxt/async_support/bequant.py +5 -3
  79. ccxt/async_support/bigone.py +279 -144
  80. ccxt/async_support/binance.py +2347 -1158
  81. ccxt/async_support/binancecoinm.py +9 -3
  82. ccxt/async_support/binanceus.py +17 -3
  83. ccxt/async_support/binanceusdm.py +9 -4
  84. ccxt/async_support/bingx.py +2962 -920
  85. ccxt/async_support/bit2c.py +147 -27
  86. ccxt/async_support/bitbank.py +151 -23
  87. ccxt/async_support/bitbns.py +104 -30
  88. ccxt/async_support/bitfinex.py +3291 -1113
  89. ccxt/async_support/bitflyer.py +202 -27
  90. ccxt/async_support/bitget.py +3683 -1538
  91. ccxt/async_support/bithumb.py +195 -38
  92. ccxt/async_support/bitimen.py +12 -12
  93. ccxt/async_support/bitir.py +38 -38
  94. ccxt/async_support/bitmart.py +1288 -350
  95. ccxt/async_support/bitmex.py +260 -75
  96. ccxt/async_support/bitopro.py +262 -62
  97. ccxt/async_support/bitpin.py +17 -16
  98. ccxt/async_support/bitrue.py +459 -290
  99. ccxt/async_support/bitso.py +199 -54
  100. ccxt/async_support/bitstamp.py +230 -96
  101. ccxt/async_support/bitteam.py +167 -25
  102. ccxt/async_support/{huobijp.py → bittrade.py} +158 -30
  103. ccxt/async_support/bitvavo.py +213 -49
  104. ccxt/async_support/blockchaincom.py +160 -46
  105. ccxt/async_support/blofin.py +502 -120
  106. ccxt/async_support/btcalpha.py +169 -31
  107. ccxt/async_support/btcbox.py +292 -23
  108. ccxt/async_support/btcmarkets.py +211 -58
  109. ccxt/async_support/btcturk.py +161 -38
  110. ccxt/async_support/bybit.py +1775 -1030
  111. ccxt/async_support/cex.py +1440 -1303
  112. ccxt/async_support/coinbase.py +724 -212
  113. ccxt/async_support/coinbaseadvanced.py +2 -1
  114. ccxt/async_support/coinbaseexchange.py +388 -89
  115. ccxt/async_support/coinbaseinternational.py +412 -57
  116. ccxt/async_support/coincatch.py +177 -78
  117. ccxt/async_support/coincheck.py +135 -19
  118. ccxt/async_support/coinex.py +606 -232
  119. ccxt/async_support/coinmate.py +189 -63
  120. ccxt/async_support/coinmetro.py +195 -54
  121. ccxt/async_support/coinone.py +158 -51
  122. ccxt/async_support/coinsph.py +336 -61
  123. ccxt/async_support/coinspot.py +151 -52
  124. ccxt/async_support/cryptocom.py +661 -111
  125. ccxt/async_support/cryptomus.py +1137 -0
  126. ccxt/async_support/defx.py +2071 -0
  127. ccxt/async_support/delta.py +299 -99
  128. ccxt/async_support/deribit.py +348 -126
  129. ccxt/async_support/derive.py +2572 -0
  130. ccxt/async_support/digifinex.py +430 -214
  131. ccxt/async_support/ellipx.py +2029 -0
  132. ccxt/async_support/eterex.py +10 -10
  133. ccxt/async_support/excoino.py +31 -31
  134. ccxt/async_support/exir.py +14 -14
  135. ccxt/async_support/exmo.py +344 -131
  136. ccxt/async_support/exnovin.py +10 -10
  137. ccxt/async_support/farhadexchange.py +12 -12
  138. ccxt/async_support/fmfwio.py +2 -1
  139. ccxt/async_support/foxbit.py +1935 -0
  140. ccxt/async_support/gate.py +1351 -529
  141. ccxt/async_support/gateio.py +2 -1
  142. ccxt/async_support/gemini.py +144 -39
  143. ccxt/async_support/hashkey.py +152 -109
  144. ccxt/async_support/hibachi.py +2080 -0
  145. ccxt/async_support/hitbtc.py +395 -167
  146. ccxt/async_support/hitobit.py +12 -12
  147. ccxt/async_support/hollaex.py +307 -119
  148. ccxt/async_support/htx.py +851 -383
  149. ccxt/async_support/huobi.py +2 -1
  150. ccxt/async_support/hyperliquid.py +1848 -536
  151. ccxt/async_support/independentreserve.py +288 -15
  152. ccxt/async_support/indodax.py +190 -33
  153. ccxt/async_support/jibitex.py +12 -12
  154. ccxt/async_support/kraken.py +795 -351
  155. ccxt/async_support/krakenfutures.py +214 -62
  156. ccxt/async_support/kucoin.py +715 -396
  157. ccxt/async_support/kucoinfutures.py +652 -89
  158. ccxt/async_support/latoken.py +217 -113
  159. ccxt/async_support/lbank.py +425 -97
  160. ccxt/async_support/luno.py +382 -35
  161. ccxt/async_support/mercado.py +113 -6
  162. ccxt/async_support/mexc.py +874 -437
  163. ccxt/async_support/modetrade.py +2818 -0
  164. ccxt/async_support/myokx.py +54 -0
  165. ccxt/async_support/ndax.py +221 -64
  166. ccxt/async_support/nobitex.py +32 -38
  167. ccxt/async_support/novadax.py +190 -34
  168. ccxt/async_support/oceanex.py +217 -28
  169. ccxt/async_support/okcoin.py +253 -145
  170. ccxt/async_support/okexchange.py +11 -11
  171. ccxt/async_support/okx.py +1088 -351
  172. ccxt/async_support/okxus.py +54 -0
  173. ccxt/async_support/ompfinex.py +32 -27
  174. ccxt/async_support/onetrading.py +213 -392
  175. ccxt/async_support/oxfun.py +245 -166
  176. ccxt/async_support/p2b.py +151 -29
  177. ccxt/async_support/paradex.py +562 -49
  178. ccxt/async_support/paymium.py +82 -19
  179. ccxt/async_support/phemex.py +713 -172
  180. ccxt/async_support/poloniex.py +1602 -283
  181. ccxt/async_support/probit.py +224 -95
  182. ccxt/async_support/ramzinex.py +34 -30
  183. ccxt/async_support/sarmayex.py +9 -9
  184. ccxt/async_support/sarrafex.py +13 -13
  185. ccxt/async_support/tabdeal.py +15 -14
  186. ccxt/async_support/tetherland.py +9 -9
  187. ccxt/async_support/timex.py +210 -51
  188. ccxt/async_support/tokocrypto.py +167 -47
  189. ccxt/async_support/tradeogre.py +266 -31
  190. ccxt/async_support/twox.py +9 -9
  191. ccxt/async_support/ubitex.py +12 -12
  192. ccxt/async_support/upbit.py +568 -165
  193. ccxt/async_support/vertex.py +160 -32
  194. ccxt/async_support/wallex.py +12 -12
  195. ccxt/async_support/wavesexchange.py +165 -30
  196. ccxt/async_support/whitebit.py +975 -127
  197. ccxt/async_support/woo.py +1918 -1016
  198. ccxt/async_support/woofipro.py +433 -141
  199. ccxt/async_support/xt.py +649 -193
  200. ccxt/async_support/yobit.py +195 -70
  201. ccxt/async_support/zaif.py +91 -15
  202. ccxt/async_support/zonda.py +151 -36
  203. ccxt/base/decimal_to_precision.py +14 -10
  204. ccxt/base/errors.py +49 -18
  205. ccxt/base/exchange.py +1556 -450
  206. ccxt/base/precise.py +10 -0
  207. ccxt/base/types.py +114 -6
  208. ccxt/bequant.py +5 -3
  209. ccxt/bigone.py +279 -144
  210. ccxt/binance.py +2347 -1158
  211. ccxt/binancecoinm.py +9 -3
  212. ccxt/binanceus.py +17 -3
  213. ccxt/binanceusdm.py +9 -4
  214. ccxt/bingx.py +2962 -920
  215. ccxt/bit2c.py +147 -27
  216. ccxt/bitbank.py +151 -23
  217. ccxt/bitbns.py +104 -30
  218. ccxt/bitfinex.py +3290 -1113
  219. ccxt/bitflyer.py +202 -27
  220. ccxt/bitget.py +3683 -1538
  221. ccxt/bithumb.py +194 -38
  222. ccxt/bitimen.py +9 -9
  223. ccxt/bitir.py +35 -35
  224. ccxt/bitmart.py +1288 -350
  225. ccxt/bitmex.py +260 -75
  226. ccxt/bitopro.py +262 -62
  227. ccxt/bitpin.py +15 -14
  228. ccxt/bitrue.py +459 -290
  229. ccxt/bitso.py +199 -54
  230. ccxt/bitstamp.py +230 -96
  231. ccxt/bitteam.py +167 -25
  232. ccxt/{huobijp.py → bittrade.py} +158 -30
  233. ccxt/bitvavo.py +213 -49
  234. ccxt/blockchaincom.py +160 -46
  235. ccxt/blofin.py +502 -120
  236. ccxt/btcalpha.py +169 -31
  237. ccxt/btcbox.py +291 -23
  238. ccxt/btcmarkets.py +211 -58
  239. ccxt/btcturk.py +161 -38
  240. ccxt/bybit.py +1775 -1030
  241. ccxt/cex.py +1439 -1303
  242. ccxt/coinbase.py +724 -212
  243. ccxt/coinbaseadvanced.py +2 -1
  244. ccxt/coinbaseexchange.py +388 -89
  245. ccxt/coinbaseinternational.py +412 -57
  246. ccxt/coincatch.py +177 -78
  247. ccxt/coincheck.py +135 -19
  248. ccxt/coinex.py +606 -232
  249. ccxt/coinmate.py +189 -63
  250. ccxt/coinmetro.py +194 -54
  251. ccxt/coinone.py +158 -51
  252. ccxt/coinsph.py +336 -61
  253. ccxt/coinspot.py +151 -52
  254. ccxt/cryptocom.py +661 -111
  255. ccxt/cryptomus.py +1137 -0
  256. ccxt/defx.py +2070 -0
  257. ccxt/delta.py +299 -99
  258. ccxt/deribit.py +348 -126
  259. ccxt/derive.py +2571 -0
  260. ccxt/digifinex.py +430 -214
  261. ccxt/ellipx.py +2029 -0
  262. ccxt/eterex.py +7 -7
  263. ccxt/excoino.py +29 -29
  264. ccxt/exir.py +11 -11
  265. ccxt/exmo.py +343 -131
  266. ccxt/exnovin.py +8 -8
  267. ccxt/farhadexchange.py +10 -10
  268. ccxt/fmfwio.py +2 -1
  269. ccxt/foxbit.py +1935 -0
  270. ccxt/gate.py +1351 -529
  271. ccxt/gateio.py +2 -1
  272. ccxt/gemini.py +144 -39
  273. ccxt/hashkey.py +152 -109
  274. ccxt/hibachi.py +2079 -0
  275. ccxt/hitbtc.py +395 -167
  276. ccxt/hitobit.py +9 -9
  277. ccxt/hollaex.py +307 -119
  278. ccxt/htx.py +851 -383
  279. ccxt/huobi.py +2 -1
  280. ccxt/hyperliquid.py +1848 -536
  281. ccxt/independentreserve.py +287 -15
  282. ccxt/indodax.py +190 -33
  283. ccxt/jibitex.py +9 -9
  284. ccxt/kraken.py +794 -351
  285. ccxt/krakenfutures.py +214 -62
  286. ccxt/kucoin.py +715 -396
  287. ccxt/kucoinfutures.py +652 -89
  288. ccxt/latoken.py +217 -113
  289. ccxt/lbank.py +425 -97
  290. ccxt/luno.py +382 -35
  291. ccxt/mercado.py +113 -6
  292. ccxt/mexc.py +873 -437
  293. ccxt/modetrade.py +2818 -0
  294. ccxt/myokx.py +54 -0
  295. ccxt/ndax.py +221 -64
  296. ccxt/nobitex.py +30 -36
  297. ccxt/novadax.py +190 -34
  298. ccxt/oceanex.py +217 -28
  299. ccxt/okcoin.py +253 -145
  300. ccxt/okexchange.py +9 -9
  301. ccxt/okx.py +1088 -351
  302. ccxt/okxus.py +54 -0
  303. ccxt/ompfinex.py +29 -24
  304. ccxt/onetrading.py +213 -392
  305. ccxt/oxfun.py +245 -166
  306. ccxt/p2b.py +151 -29
  307. ccxt/paradex.py +562 -49
  308. ccxt/paymium.py +82 -19
  309. ccxt/phemex.py +712 -172
  310. ccxt/poloniex.py +1601 -283
  311. ccxt/pro/__init__.py +76 -17
  312. ccxt/pro/alpaca.py +21 -6
  313. ccxt/pro/apex.py +984 -0
  314. ccxt/pro/ascendex.py +58 -10
  315. ccxt/pro/bequant.py +6 -1
  316. ccxt/pro/binance.py +728 -156
  317. ccxt/pro/binancecoinm.py +6 -2
  318. ccxt/pro/binanceus.py +8 -4
  319. ccxt/pro/binanceusdm.py +7 -2
  320. ccxt/pro/bingx.py +333 -142
  321. ccxt/pro/bitfinex.py +727 -262
  322. ccxt/pro/bitget.py +570 -79
  323. ccxt/pro/bithumb.py +20 -6
  324. ccxt/pro/bitmart.py +216 -87
  325. ccxt/pro/bitmex.py +47 -9
  326. ccxt/pro/bitopro.py +26 -14
  327. ccxt/pro/bitrue.py +22 -22
  328. ccxt/pro/bitstamp.py +54 -21
  329. ccxt/pro/{huobijp.py → bittrade.py} +7 -6
  330. ccxt/pro/bitvavo.py +191 -67
  331. ccxt/pro/blockchaincom.py +21 -8
  332. ccxt/pro/blofin.py +9 -1
  333. ccxt/pro/bybit.py +632 -245
  334. ccxt/pro/cex.py +59 -24
  335. ccxt/pro/coinbase.py +102 -73
  336. ccxt/pro/coinbaseadvanced.py +2 -1
  337. ccxt/pro/coinbaseexchange.py +8 -8
  338. ccxt/pro/coinbaseinternational.py +181 -25
  339. ccxt/pro/coincatch.py +6 -7
  340. ccxt/pro/coincheck.py +11 -6
  341. ccxt/pro/coinex.py +967 -665
  342. ccxt/pro/coinone.py +16 -9
  343. ccxt/pro/cryptocom.py +448 -45
  344. ccxt/pro/defx.py +831 -0
  345. ccxt/pro/deribit.py +150 -14
  346. ccxt/pro/derive.py +704 -0
  347. ccxt/pro/exmo.py +239 -6
  348. ccxt/pro/gate.py +623 -65
  349. ccxt/pro/gateio.py +2 -1
  350. ccxt/pro/gemini.py +27 -11
  351. ccxt/pro/hashkey.py +2 -2
  352. ccxt/pro/hitbtc.py +196 -91
  353. ccxt/pro/hollaex.py +23 -7
  354. ccxt/pro/htx.py +51 -14
  355. ccxt/pro/huobi.py +2 -1
  356. ccxt/pro/hyperliquid.py +591 -27
  357. ccxt/pro/independentreserve.py +9 -6
  358. ccxt/pro/kraken.py +640 -320
  359. ccxt/pro/krakenfutures.py +62 -35
  360. ccxt/pro/kucoin.py +267 -46
  361. ccxt/pro/kucoinfutures.py +165 -21
  362. ccxt/pro/lbank.py +102 -21
  363. ccxt/pro/luno.py +12 -8
  364. ccxt/pro/mexc.py +877 -111
  365. ccxt/pro/modetrade.py +1271 -0
  366. ccxt/pro/myokx.py +38 -0
  367. ccxt/pro/ndax.py +15 -2
  368. ccxt/pro/okcoin.py +23 -4
  369. ccxt/pro/okx.py +573 -98
  370. ccxt/pro/okxus.py +38 -0
  371. ccxt/pro/onetrading.py +30 -13
  372. ccxt/pro/oxfun.py +131 -27
  373. ccxt/pro/p2b.py +88 -22
  374. ccxt/pro/paradex.py +3 -3
  375. ccxt/pro/phemex.py +75 -21
  376. ccxt/pro/poloniex.py +124 -41
  377. ccxt/pro/probit.py +87 -80
  378. ccxt/pro/tradeogre.py +272 -0
  379. ccxt/pro/upbit.py +152 -12
  380. ccxt/pro/vertex.py +8 -3
  381. ccxt/pro/whitebit.py +58 -5
  382. ccxt/pro/woo.py +228 -37
  383. ccxt/pro/woofipro.py +106 -18
  384. ccxt/pro/xt.py +111 -5
  385. ccxt/probit.py +224 -95
  386. ccxt/protobuf/__init__.py +0 -0
  387. ccxt/protobuf/mexc/PrivateAccountV3Api_pb2.py +37 -0
  388. ccxt/protobuf/mexc/PrivateDealsV3Api_pb2.py +37 -0
  389. ccxt/protobuf/mexc/PrivateOrdersV3Api_pb2.py +37 -0
  390. ccxt/protobuf/mexc/PublicAggreBookTickerV3Api_pb2.py +37 -0
  391. ccxt/protobuf/mexc/PublicAggreDealsV3Api_pb2.py +39 -0
  392. ccxt/protobuf/mexc/PublicAggreDepthsV3Api_pb2.py +39 -0
  393. ccxt/protobuf/mexc/PublicBookTickerBatchV3Api_pb2.py +38 -0
  394. ccxt/protobuf/mexc/PublicBookTickerV3Api_pb2.py +37 -0
  395. ccxt/protobuf/mexc/PublicDealsV3Api_pb2.py +39 -0
  396. ccxt/protobuf/mexc/PublicIncreaseDepthsBatchV3Api_pb2.py +38 -0
  397. ccxt/protobuf/mexc/PublicIncreaseDepthsV3Api_pb2.py +39 -0
  398. ccxt/protobuf/mexc/PublicLimitDepthsV3Api_pb2.py +39 -0
  399. ccxt/protobuf/mexc/PublicMiniTickerV3Api_pb2.py +37 -0
  400. ccxt/protobuf/mexc/PublicMiniTickersV3Api_pb2.py +38 -0
  401. ccxt/protobuf/mexc/PublicSpotKlineV3Api_pb2.py +37 -0
  402. ccxt/protobuf/mexc/PushDataV3ApiWrapper_pb2.py +52 -0
  403. ccxt/protobuf/mexc/__init__.py +0 -0
  404. ccxt/ramzinex.py +32 -28
  405. ccxt/sarmayex.py +7 -7
  406. ccxt/sarrafex.py +10 -10
  407. ccxt/static_dependencies/__init__.py +1 -1
  408. ccxt/static_dependencies/lark/py.typed +0 -0
  409. ccxt/static_dependencies/marshmallow/py.typed +0 -0
  410. ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  411. ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  412. ccxt/tabdeal.py +13 -12
  413. ccxt/test/tests_async.py +261 -57
  414. ccxt/test/tests_helpers.py +1 -3
  415. ccxt/test/tests_init.py +4 -3
  416. ccxt/test/tests_sync.py +261 -57
  417. ccxt/tetherland.py +7 -7
  418. ccxt/timex.py +210 -51
  419. ccxt/tokocrypto.py +167 -47
  420. ccxt/tradeogre.py +266 -31
  421. ccxt/twox.py +7 -7
  422. ccxt/ubitex.py +9 -9
  423. ccxt/upbit.py +568 -165
  424. ccxt/vertex.py +160 -32
  425. ccxt/wallex.py +9 -9
  426. ccxt/wavesexchange.py +165 -30
  427. ccxt/whitebit.py +975 -127
  428. ccxt/woo.py +1917 -1016
  429. ccxt/woofipro.py +432 -141
  430. ccxt/xt.py +649 -193
  431. ccxt/yobit.py +194 -70
  432. ccxt/zaif.py +91 -15
  433. ccxt/zonda.py +151 -36
  434. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/METADATA +225 -73
  435. ccxt_ir-4.5.1.dist-info/RECORD +743 -0
  436. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/WHEEL +1 -1
  437. ccxt/__test__.py +0 -7
  438. ccxt/abstract/ace.py +0 -15
  439. ccxt/abstract/bitbay.py +0 -53
  440. ccxt/abstract/bitcoincom.py +0 -115
  441. ccxt/abstract/bitfinex2.py +0 -139
  442. ccxt/abstract/bitpanda.py +0 -35
  443. ccxt/abstract/bl3p.py +0 -19
  444. ccxt/abstract/coinlist.py +0 -54
  445. ccxt/abstract/currencycom.py +0 -68
  446. ccxt/abstract/hitbtc3.py +0 -115
  447. ccxt/abstract/idex.py +0 -26
  448. ccxt/abstract/kuna.py +0 -182
  449. ccxt/abstract/lykke.py +0 -29
  450. ccxt/abstract/poloniexfutures.py +0 -48
  451. ccxt/abstract/wazirx.py +0 -30
  452. ccxt/ace.py +0 -1012
  453. ccxt/async_support/ace.py +0 -1012
  454. ccxt/async_support/base/ws/aiohttp_client.py +0 -125
  455. ccxt/async_support/base/ws/fast_client.py +0 -96
  456. ccxt/async_support/bitbay.py +0 -17
  457. ccxt/async_support/bitcoincom.py +0 -17
  458. ccxt/async_support/bitfinex2.py +0 -3552
  459. ccxt/async_support/bitpanda.py +0 -16
  460. ccxt/async_support/bl3p.py +0 -485
  461. ccxt/async_support/coinlist.py +0 -2243
  462. ccxt/async_support/currencycom.py +0 -1950
  463. ccxt/async_support/hitbtc3.py +0 -16
  464. ccxt/async_support/idex.py +0 -1766
  465. ccxt/async_support/kuna.py +0 -1841
  466. ccxt/async_support/lykke.py +0 -1270
  467. ccxt/async_support/poloniexfutures.py +0 -1717
  468. ccxt/async_support/wazirx.py +0 -1224
  469. ccxt/bitbay.py +0 -17
  470. ccxt/bitcoincom.py +0 -17
  471. ccxt/bitfinex2.py +0 -3552
  472. ccxt/bitpanda.py +0 -16
  473. ccxt/bl3p.py +0 -485
  474. ccxt/coinlist.py +0 -2243
  475. ccxt/currencycom.py +0 -1950
  476. ccxt/hitbtc3.py +0 -16
  477. ccxt/idex.py +0 -1766
  478. ccxt/kuna.py +0 -1841
  479. ccxt/lykke.py +0 -1270
  480. ccxt/poloniexfutures.py +0 -1717
  481. ccxt/pro/bitcoincom.py +0 -34
  482. ccxt/pro/bitfinex2.py +0 -1083
  483. ccxt/pro/bitpanda.py +0 -15
  484. ccxt/pro/currencycom.py +0 -536
  485. ccxt/pro/idex.py +0 -672
  486. ccxt/pro/poloniexfutures.py +0 -990
  487. ccxt/pro/wazirx.py +0 -749
  488. ccxt/test/base/__init__.py +0 -29
  489. ccxt/test/base/test_account.py +0 -26
  490. ccxt/test/base/test_balance.py +0 -56
  491. ccxt/test/base/test_borrow_interest.py +0 -35
  492. ccxt/test/base/test_borrow_rate.py +0 -32
  493. ccxt/test/base/test_calculate_fee.py +0 -51
  494. ccxt/test/base/test_crypto.py +0 -127
  495. ccxt/test/base/test_currency.py +0 -76
  496. ccxt/test/base/test_datetime.py +0 -109
  497. ccxt/test/base/test_decimal_to_precision.py +0 -392
  498. ccxt/test/base/test_deep_extend.py +0 -68
  499. ccxt/test/base/test_deposit_withdrawal.py +0 -50
  500. ccxt/test/base/test_exchange_datetime_functions.py +0 -76
  501. ccxt/test/base/test_funding_rate_history.py +0 -29
  502. ccxt/test/base/test_last_price.py +0 -31
  503. ccxt/test/base/test_ledger_entry.py +0 -45
  504. ccxt/test/base/test_ledger_item.py +0 -48
  505. ccxt/test/base/test_leverage_tier.py +0 -33
  506. ccxt/test/base/test_liquidation.py +0 -50
  507. ccxt/test/base/test_margin_mode.py +0 -24
  508. ccxt/test/base/test_margin_modification.py +0 -35
  509. ccxt/test/base/test_market.py +0 -193
  510. ccxt/test/base/test_number.py +0 -411
  511. ccxt/test/base/test_ohlcv.py +0 -33
  512. ccxt/test/base/test_open_interest.py +0 -32
  513. ccxt/test/base/test_order.py +0 -64
  514. ccxt/test/base/test_order_book.py +0 -69
  515. ccxt/test/base/test_position.py +0 -60
  516. ccxt/test/base/test_shared_methods.py +0 -353
  517. ccxt/test/base/test_status.py +0 -24
  518. ccxt/test/base/test_throttle.py +0 -126
  519. ccxt/test/base/test_ticker.py +0 -92
  520. ccxt/test/base/test_trade.py +0 -47
  521. ccxt/test/base/test_trading_fee.py +0 -26
  522. ccxt/test/base/test_transaction.py +0 -39
  523. ccxt/test/test_async.py +0 -1649
  524. ccxt/test/test_sync.py +0 -1648
  525. ccxt/wazirx.py +0 -1224
  526. ccxt_ir-4.3.46.0.3.dist-info/RECORD +0 -773
  527. /ccxt/abstract/{huobijp.py → bittrade.py} +0 -0
  528. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info/licenses}/LICENSE.txt +0 -0
  529. {ccxt_ir-4.3.46.0.3.dist-info → ccxt_ir-4.5.1.dist-info}/top_level.txt +0 -0
ccxt/blofin.py CHANGED
@@ -6,7 +6,7 @@
6
6
  from ccxt.base.exchange import Exchange
7
7
  from ccxt.abstract.blofin import ImplicitAPI
8
8
  import hashlib
9
- from ccxt.base.types import Balances, Currency, Int, Leverage, Leverages, MarginMode, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, Trade, TradingFeeInterface, Transaction, TransferEntry
9
+ from ccxt.base.types import Any, Balances, Currency, Int, LedgerEntry, Leverage, Leverages, MarginMode, Market, Num, Order, OrderBook, OrderRequest, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, Trade, TradingFeeInterface, Transaction, TransferEntry
10
10
  from typing import List
11
11
  from ccxt.base.errors import ExchangeError
12
12
  from ccxt.base.errors import AuthenticationError
@@ -22,13 +22,14 @@ from ccxt.base.precise import Precise
22
22
 
23
23
  class blofin(Exchange, ImplicitAPI):
24
24
 
25
- def describe(self):
25
+ def describe(self) -> Any:
26
26
  return self.deep_extend(super(blofin, self).describe(), {
27
27
  'id': 'blofin',
28
28
  'name': 'BloFin',
29
29
  'countries': ['US'],
30
30
  'version': 'v1',
31
31
  'rateLimit': 100,
32
+ 'pro': True,
32
33
  'has': {
33
34
  'CORS': None,
34
35
  'spot': False,
@@ -56,6 +57,7 @@ class blofin(Exchange, ImplicitAPI):
56
57
  'createStopMarketOrder': False,
57
58
  'createStopOrder': False,
58
59
  'createTakeProfitOrder': True,
60
+ 'createTriggerOrder': True,
59
61
  'editOrder': False,
60
62
  'fetchAccounts': False,
61
63
  'fetchBalance': True,
@@ -65,7 +67,7 @@ class blofin(Exchange, ImplicitAPI):
65
67
  'fetchBorrowRateHistory': False,
66
68
  'fetchCanceledOrders': False,
67
69
  'fetchClosedOrder': False,
68
- 'fetchClosedOrders': False,
70
+ 'fetchClosedOrders': True,
69
71
  'fetchCrossBorrowRate': False,
70
72
  'fetchCrossBorrowRates': False,
71
73
  'fetchCurrencies': False,
@@ -103,13 +105,13 @@ class blofin(Exchange, ImplicitAPI):
103
105
  'fetchOpenInterestHistory': False,
104
106
  'fetchOpenOrder': None,
105
107
  'fetchOpenOrders': True,
106
- 'fetchOrder': True,
108
+ 'fetchOrder': None,
107
109
  'fetchOrderBook': True,
108
110
  'fetchOrderBooks': False,
109
111
  'fetchOrders': False,
110
112
  'fetchOrderTrades': True,
111
- 'fetchPermissions': None,
112
113
  'fetchPosition': True,
114
+ 'fetchPositionMode': True,
113
115
  'fetchPositions': True,
114
116
  'fetchPositionsForSymbol': False,
115
117
  'fetchPositionsRisk': False,
@@ -137,8 +139,8 @@ class blofin(Exchange, ImplicitAPI):
137
139
  'repayCrossMargin': False,
138
140
  'setLeverage': True,
139
141
  'setMargin': False,
140
- 'setMarginMode': False,
141
- 'setPositionMode': False,
142
+ 'setMarginMode': True,
143
+ 'setPositionMode': True,
142
144
  'signIn': False,
143
145
  'transfer': True,
144
146
  'withdraw': False,
@@ -153,20 +155,24 @@ class blofin(Exchange, ImplicitAPI):
153
155
  '2h': '2H',
154
156
  '4h': '4H',
155
157
  '6h': '6H',
158
+ '8h': '8H',
156
159
  '12h': '12H',
157
160
  '1d': '1D',
161
+ '3d': '3D',
158
162
  '1w': '1W',
159
163
  '1M': '1M',
160
- '3M': '3M',
161
164
  },
162
165
  'hostname': 'www.blofin.com',
163
166
  'urls': {
164
- 'logo': 'https://github.com/ccxt/ccxt/assets/43336371/255a7b29-341f-4d20-8342-fbfae4932807',
167
+ 'logo': 'https://github.com/user-attachments/assets/518cdf80-f05d-4821-a3e3-d48ceb41d73b',
165
168
  'api': {
166
169
  'rest': 'https://openapi.blofin.com',
167
170
  },
171
+ 'test': {
172
+ 'rest': 'https://demo-trading-openapi.blofin.com',
173
+ },
168
174
  'referral': {
169
- 'url': 'https://blofin.com/register?referral_code=jBd8U1',
175
+ 'url': 'https://blofin.com/register?referral_code=f79EsS',
170
176
  'discount': 0.05,
171
177
  },
172
178
  'www': 'https://www.blofin.com',
@@ -197,16 +203,36 @@ class blofin(Exchange, ImplicitAPI):
197
203
  'account/positions': 1,
198
204
  'account/leverage-info': 1,
199
205
  'account/margin-mode': 1,
206
+ 'account/position-mode': 1,
200
207
  'account/batch-leverage-info': 1,
201
208
  'trade/orders-tpsl-pending': 1,
209
+ 'trade/orders-algo-pending': 1,
202
210
  'trade/orders-history': 1,
203
211
  'trade/orders-tpsl-history': 1,
212
+ 'trade/orders-algo-history': 1, # todo new
213
+ 'trade/order/price-range': 1,
204
214
  'user/query-apikey': 1,
205
215
  'affiliate/basic': 1,
216
+ 'copytrading/instruments': 1,
217
+ 'copytrading/account/balance': 1,
218
+ 'copytrading/account/positions-by-order': 1,
219
+ 'copytrading/account/positions-details-by-order': 1,
220
+ 'copytrading/account/positions-by-contract': 1,
221
+ 'copytrading/account/position-mode': 1,
222
+ 'copytrading/account/leverage-info': 1,
223
+ 'copytrading/trade/orders-pending': 1,
224
+ 'copytrading/trade/pending-tpsl-by-contract': 1,
225
+ 'copytrading/trade/position-history-by-order': 1,
226
+ 'copytrading/trade/orders-history': 1,
227
+ 'copytrading/trade/pending-tpsl-by-order': 1,
206
228
  },
207
229
  'post': {
230
+ 'account/set-margin-mode': 1,
231
+ 'account/set-position-mode': 1,
208
232
  'trade/order': 1,
233
+ 'trade/order-algo': 1,
209
234
  'trade/cancel-order': 1,
235
+ 'trade/cancel-algo': 1,
210
236
  'account/set-leverage': 1,
211
237
  'trade/batch-orders': 1,
212
238
  'trade/order-tpsl': 1,
@@ -214,6 +240,16 @@ class blofin(Exchange, ImplicitAPI):
214
240
  'trade/cancel-tpsl': 1,
215
241
  'trade/close-position': 1,
216
242
  'asset/transfer': 1,
243
+ 'copytrading/account/set-position-mode': 1,
244
+ 'copytrading/account/set-leverage': 1,
245
+ 'copytrading/trade/place-order': 1,
246
+ 'copytrading/trade/cancel-order': 1,
247
+ 'copytrading/trade/place-tpsl-by-contract': 1,
248
+ 'copytrading/trade/cancel-tpsl-by-contract': 1,
249
+ 'copytrading/trade/place-tpsl-by-order': 1,
250
+ 'copytrading/trade/cancel-tpsl-by-order': 1,
251
+ 'copytrading/trade/close-position-by-order': 1,
252
+ 'copytrading/trade/close-position-by-contract': 1,
217
253
  },
218
254
  },
219
255
  },
@@ -228,6 +264,96 @@ class blofin(Exchange, ImplicitAPI):
228
264
  'secret': True,
229
265
  'password': True,
230
266
  },
267
+ 'features': {
268
+ 'default': {
269
+ 'sandbox': False,
270
+ 'createOrder': {
271
+ 'timeInForce': {
272
+ 'IOC': True,
273
+ 'FOK': True,
274
+ 'PO': True,
275
+ 'GTD': False,
276
+ },
277
+ 'leverage': False,
278
+ 'marketBuyRequiresPrice': False,
279
+ 'marketBuyByCost': False,
280
+ 'selfTradePrevention': False,
281
+ 'trailing': False,
282
+ 'iceberg': False,
283
+ },
284
+ 'createOrders': {
285
+ 'max': 10,
286
+ },
287
+ 'fetchMyTrades': {
288
+ 'marginMode': False,
289
+ 'limit': 100,
290
+ 'daysBack': 100000,
291
+ 'untilDays': 100000,
292
+ 'symbolRequired': False,
293
+ },
294
+ 'fetchOrder': None,
295
+ 'fetchOpenOrders': {
296
+ 'marginMode': False,
297
+ 'limit': 100,
298
+ 'trigger': True,
299
+ 'trailing': False,
300
+ 'symbolRequired': False,
301
+ },
302
+ 'fetchOrders': None,
303
+ 'fetchClosedOrders': {
304
+ 'marginMode': False,
305
+ 'limit': 1000,
306
+ 'daysBack': 100000,
307
+ 'daysBackCanceled': 1,
308
+ 'untilDays': 100000,
309
+ 'trigger': True,
310
+ 'trailing': False,
311
+ 'symbolRequired': False,
312
+ },
313
+ 'fetchOHLCV': {
314
+ 'limit': 1440,
315
+ },
316
+ },
317
+ 'spot': {
318
+ 'extends': 'default',
319
+ 'createOrder': {
320
+ 'marginMode': False,
321
+ 'triggerPrice': False,
322
+ 'triggerPriceType': None,
323
+ 'triggerDirection': False,
324
+ 'stopLossPrice': False,
325
+ 'takeProfitPrice': False,
326
+ 'attachedStopLossTakeProfit': None,
327
+ 'hedged': False,
328
+ },
329
+ },
330
+ 'forDerivatives': {
331
+ 'extends': 'default',
332
+ 'createOrder': {
333
+ 'marginMode': True,
334
+ 'triggerPrice': False, # todo
335
+ 'triggerPriceType': None,
336
+ 'triggerDirection': False,
337
+ 'stopLossPrice': True,
338
+ 'takeProfitPrice': True,
339
+ 'attachedStopLossTakeProfit': {
340
+ 'triggerPriceType': None,
341
+ 'price': True,
342
+ },
343
+ 'hedged': True,
344
+ },
345
+ },
346
+ 'swap': {
347
+ 'linear': {
348
+ 'extends': 'forDerivatives',
349
+ },
350
+ 'inverse': None,
351
+ },
352
+ 'future': {
353
+ 'linear': None,
354
+ 'inverse': None,
355
+ },
356
+ },
231
357
  'exceptions': {
232
358
  'exact': {
233
359
  '400': BadRequest, # Body can not be empty
@@ -286,12 +412,19 @@ class blofin(Exchange, ImplicitAPI):
286
412
  'brokerId': 'ec6dd3a7dd982d0b',
287
413
  'accountsByType': {
288
414
  'swap': 'futures',
415
+ 'funding': 'funding',
289
416
  'future': 'futures',
417
+ 'copy_trading': 'copy_trading',
418
+ 'earn': 'earn',
419
+ 'spot': 'spot',
290
420
  },
291
421
  'accountsById': {
422
+ 'funding': 'funding',
292
423
  'futures': 'swap',
424
+ 'copy_trading': 'copy_trading',
425
+ 'earn': 'earn',
426
+ 'spot': 'spot',
293
427
  },
294
- 'sandboxMode': False,
295
428
  'defaultNetwork': 'ERC20',
296
429
  'defaultNetworks': {
297
430
  'ETH': 'ERC20',
@@ -360,7 +493,9 @@ class blofin(Exchange, ImplicitAPI):
360
493
  def fetch_markets(self, params={}) -> List[Market]:
361
494
  """
362
495
  retrieves data on all markets for blofin
363
- :see: https://blofin.com/docs#get-instruments
496
+
497
+ https://blofin.com/docs#get-instruments
498
+
364
499
  :param dict [params]: extra parameters specific to the exchange API endpoint
365
500
  :returns dict[]: an array of objects representing market data
366
501
  """
@@ -450,7 +585,9 @@ class blofin(Exchange, ImplicitAPI):
450
585
  def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
451
586
  """
452
587
  fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
453
- :see: https://blofin.com/docs#get-order-book
588
+
589
+ https://blofin.com/docs#get-order-book
590
+
454
591
  :param str symbol: unified symbol of the market to fetch the order book for
455
592
  :param int [limit]: the maximum amount of order book entries to return
456
593
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -492,6 +629,25 @@ class blofin(Exchange, ImplicitAPI):
492
629
  return self.parse_order_book(first, symbol, timestamp)
493
630
 
494
631
  def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
632
+ #
633
+ # response similar for REST & WS
634
+ #
635
+ # {
636
+ # instId: "ADA-USDT",
637
+ # ts: "1707736811486",
638
+ # last: "0.5315",
639
+ # lastSize: "4",
640
+ # askPrice: "0.5318",
641
+ # askSize: "248",
642
+ # bidPrice: "0.5315",
643
+ # bidSize: "63",
644
+ # open24h: "0.5555",
645
+ # high24h: "0.5563",
646
+ # low24h: "0.5315",
647
+ # volCurrency24h: "198560100",
648
+ # vol24h: "1985601",
649
+ # }
650
+ #
495
651
  timestamp = self.safe_integer(ticker, 'ts')
496
652
  marketId = self.safe_string(ticker, 'instId')
497
653
  market = self.safe_market(marketId, market, '-')
@@ -523,13 +679,17 @@ class blofin(Exchange, ImplicitAPI):
523
679
  'average': None,
524
680
  'baseVolume': baseVolume,
525
681
  'quoteVolume': quoteVolume,
682
+ 'indexPrice': self.safe_string(ticker, 'indexPrice'),
683
+ 'markPrice': self.safe_string(ticker, 'markPrice'),
526
684
  'info': ticker,
527
685
  }, market)
528
686
 
529
687
  def fetch_ticker(self, symbol: str, params={}) -> Ticker:
530
688
  """
531
689
  fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
532
- :see: https://blofin.com/docs#get-tickers
690
+
691
+ https://blofin.com/docs#get-tickers
692
+
533
693
  :param str symbol: unified symbol of the market to fetch the ticker for
534
694
  :param dict [params]: extra parameters specific to the exchange API endpoint
535
695
  :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -544,10 +704,33 @@ class blofin(Exchange, ImplicitAPI):
544
704
  first = self.safe_dict(data, 0, {})
545
705
  return self.parse_ticker(first, market)
546
706
 
707
+ def fetch_mark_price(self, symbol: str, params={}) -> Ticker:
708
+ """
709
+ fetches mark price for the market
710
+
711
+ https://docs.blofin.com/index.html#get-mark-price
712
+
713
+ :param str symbol: unified market symbol
714
+ :param dict [params]: extra parameters specific to the exchange API endpoint
715
+ :param str [params.subType]: "linear" or "inverse"
716
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
717
+ """
718
+ self.load_markets()
719
+ market = self.market(symbol)
720
+ request = {
721
+ 'symbol': market['id'],
722
+ }
723
+ response = self.publicGetMarketMarkPrice(self.extend(request, params))
724
+ data = self.safe_list(response, 'data', [])
725
+ first = self.safe_dict(data, 0, {})
726
+ return self.parse_ticker(first, market)
727
+
547
728
  def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
548
729
  """
549
730
  fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
550
- :see: https://blofin.com/docs#get-tickers
731
+
732
+ https://blofin.com/docs#get-tickers
733
+
551
734
  :param str[] [symbols]: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
552
735
  :param dict [params]: extra parameters specific to the exchange API endpoint
553
736
  :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
@@ -560,7 +743,8 @@ class blofin(Exchange, ImplicitAPI):
560
743
 
561
744
  def parse_trade(self, trade: dict, market: Market = None) -> Trade:
562
745
  #
563
- # fetch trades
746
+ # fetch trades(response similar for REST & WS)
747
+ #
564
748
  # {
565
749
  # "tradeId": "3263934920",
566
750
  # "instId": "LTC-USDT",
@@ -569,6 +753,7 @@ class blofin(Exchange, ImplicitAPI):
569
753
  # "side": "buy",
570
754
  # "ts": "1707232020854"
571
755
  # }
756
+ #
572
757
  # my trades
573
758
  # {
574
759
  # "instId": "LTC-USDT",
@@ -619,7 +804,9 @@ class blofin(Exchange, ImplicitAPI):
619
804
  def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
620
805
  """
621
806
  get the list of most recent trades for a particular symbol
622
- :see: https://blofin.com/docs#get-trades
807
+
808
+ https://blofin.com/docs#get-trades
809
+
623
810
  :param str symbol: unified symbol of the market to fetch trades for
624
811
  :param int [since]: timestamp in ms of the earliest trade to fetch
625
812
  :param int [limit]: the maximum amount of trades to fetch
@@ -672,7 +859,9 @@ class blofin(Exchange, ImplicitAPI):
672
859
  def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
673
860
  """
674
861
  fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
675
- :see: https://blofin.com/docs#get-candlesticks
862
+
863
+ https://blofin.com/docs#get-candlesticks
864
+
676
865
  :param str symbol: unified symbol of the market to fetch OHLCV data for
677
866
  :param str timeframe: the length of time each candle represents
678
867
  :param int [since]: timestamp in ms of the earliest candle to fetch
@@ -707,12 +896,15 @@ class blofin(Exchange, ImplicitAPI):
707
896
  def fetch_funding_rate_history(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}):
708
897
  """
709
898
  fetches historical funding rate prices
710
- :see: https://blofin.com/docs#get-funding-rate-history
899
+
900
+ https://blofin.com/docs#get-funding-rate-history
901
+
711
902
  :param str symbol: unified symbol of the market to fetch the funding rate history for
712
903
  :param int [since]: timestamp in ms of the earliest funding rate to fetch
713
904
  :param int [limit]: the maximum amount of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>` to fetch
714
905
  :param dict [params]: extra parameters specific to the exchange API endpoint
715
906
  :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)
907
+ :param int [params.until]: timestamp in ms of the latest funding rate to fetch
716
908
  :returns dict[]: a list of `funding rate structures <https://docs.ccxt.com/#/?id=funding-rate-history-structure>`
717
909
  """
718
910
  if symbol is None:
@@ -721,7 +913,7 @@ class blofin(Exchange, ImplicitAPI):
721
913
  paginate = False
722
914
  paginate, params = self.handle_option_and_params(params, 'fetchFundingRateHistory', 'paginate')
723
915
  if paginate:
724
- return self.fetch_paginated_call_deterministic('fetchFundingRateHistory', symbol, since, limit, '8h', params)
916
+ return self.fetch_paginated_call_deterministic('fetchFundingRateHistory', symbol, since, limit, '8h', params, 100)
725
917
  market = self.market(symbol)
726
918
  request: dict = {
727
919
  'instId': market['id'],
@@ -730,6 +922,10 @@ class blofin(Exchange, ImplicitAPI):
730
922
  request['before'] = max(since - 1, 0)
731
923
  if limit is not None:
732
924
  request['limit'] = limit
925
+ until = self.safe_integer(params, 'until')
926
+ if until is not None:
927
+ request['after'] = until
928
+ params = self.omit(params, 'until')
733
929
  response = self.publicGetMarketFundingRateHistory(self.extend(request, params))
734
930
  rates = []
735
931
  data = self.safe_list(response, 'data', [])
@@ -746,23 +942,16 @@ class blofin(Exchange, ImplicitAPI):
746
942
  sorted = self.sort_by(rates, 'timestamp')
747
943
  return self.filter_by_symbol_since_limit(sorted, market['symbol'], since, limit)
748
944
 
749
- def parse_funding_rate(self, contract, market: Market = None):
945
+ def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
750
946
  #
751
947
  # {
752
948
  # "fundingRate": "0.00027815",
753
949
  # "fundingTime": "1634256000000",
754
950
  # "instId": "BTC-USD-SWAP",
755
- # "instType": "SWAP",
756
- # "nextFundingRate": "0.00017",
757
- # "nextFundingTime": "1634284800000"
758
951
  # }
759
952
  #
760
- # in the response above nextFundingRate is actually two funding rates from now
761
- #
762
- nextFundingRateTimestamp = self.safe_integer(contract, 'nextFundingTime')
763
953
  marketId = self.safe_string(contract, 'instId')
764
954
  symbol = self.safe_symbol(marketId, market)
765
- nextFundingRate = self.safe_number(contract, 'nextFundingRate')
766
955
  fundingTime = self.safe_integer(contract, 'fundingTime')
767
956
  # > The current interest is 0.
768
957
  return {
@@ -777,18 +966,21 @@ class blofin(Exchange, ImplicitAPI):
777
966
  'fundingRate': self.safe_number(contract, 'fundingRate'),
778
967
  'fundingTimestamp': fundingTime,
779
968
  'fundingDatetime': self.iso8601(fundingTime),
780
- 'nextFundingRate': nextFundingRate,
781
- 'nextFundingTimestamp': nextFundingRateTimestamp,
782
- 'nextFundingDatetime': self.iso8601(nextFundingRateTimestamp),
969
+ 'nextFundingRate': None,
970
+ 'nextFundingTimestamp': None,
971
+ 'nextFundingDatetime': None,
783
972
  'previousFundingRate': None,
784
973
  'previousFundingTimestamp': None,
785
974
  'previousFundingDatetime': None,
975
+ 'interval': None,
786
976
  }
787
977
 
788
- def fetch_funding_rate(self, symbol: str, params={}):
978
+ def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
789
979
  """
790
980
  fetch the current funding rate
791
- :see: https://blofin.com/docs#get-funding-rate
981
+
982
+ https://blofin.com/docs#get-funding-rate
983
+
792
984
  :param str symbol: unified market symbol
793
985
  :param dict [params]: extra parameters specific to the exchange API endpoint
794
986
  :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
@@ -809,9 +1001,6 @@ class blofin(Exchange, ImplicitAPI):
809
1001
  # "fundingRate": "0.00027815",
810
1002
  # "fundingTime": "1634256000000",
811
1003
  # "instId": "BTC-USD-SWAP",
812
- # "instType": "SWAP",
813
- # "nextFundingRate": "0.00017",
814
- # "nextFundingTime": "1634284800000"
815
1004
  # }
816
1005
  # ],
817
1006
  # "msg": ""
@@ -821,13 +1010,16 @@ class blofin(Exchange, ImplicitAPI):
821
1010
  entry = self.safe_dict(data, 0, {})
822
1011
  return self.parse_funding_rate(entry, market)
823
1012
 
824
- def parse_balance_by_type(self, type, response):
825
- if type:
1013
+ def parse_balance_by_type(self, response):
1014
+ data = self.safe_list(response, 'data')
1015
+ if (data is not None) and isinstance(data, list):
826
1016
  return self.parse_funding_balance(response)
827
1017
  else:
828
- return self.parse_trading_balance(response)
1018
+ return self.parse_balance(response)
829
1019
 
830
- def parse_trading_balance(self, response):
1020
+ def parse_balance(self, response):
1021
+ #
1022
+ # "data" similar for REST & WS
831
1023
  #
832
1024
  # {
833
1025
  # "code": "0",
@@ -849,7 +1041,8 @@ class blofin(Exchange, ImplicitAPI):
849
1041
  # "orderFrozen": "14920.994472632597427761",
850
1042
  # "equityUsd": "10011254.077985990315787910",
851
1043
  # "isolatedUnrealizedPnl": "-22.151999999999999999952",
852
- # "bonus": "0"
1044
+ # "bonus": "0" # present only in REST
1045
+ # "unrealizedPnl": "0" # present only in WS
853
1046
  # }
854
1047
  # ]
855
1048
  # }
@@ -922,26 +1115,28 @@ class blofin(Exchange, ImplicitAPI):
922
1115
  def fetch_balance(self, params={}) -> Balances:
923
1116
  """
924
1117
  query for balance and get the amount of funds available for trading or funds locked in orders
925
- :see: https://blofin.com/docs#get-balance
926
- :see: https://blofin.com/docs#get-futures-account-balance
1118
+
1119
+ https://blofin.com/docs#get-balance
1120
+ https://blofin.com/docs#get-futures-account-balance
1121
+
927
1122
  :param dict [params]: extra parameters specific to the exchange API endpoint
928
1123
  :param str [params.accountType]: the type of account to fetch the balance for, either 'funding' or 'futures' or 'copy_trading' or 'earn'
929
1124
  :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
930
1125
  """
931
1126
  self.load_markets()
932
- accountType = self.safe_string_2(params, 'accountType', 'type')
933
- params = self.omit(params, ['accountType', 'type'])
1127
+ accountType = None
1128
+ accountType, params = self.handle_option_and_params_2(params, 'fetchBalance', 'accountType', 'type')
934
1129
  request: dict = {
935
1130
  }
936
1131
  response = None
937
- if accountType is not None:
1132
+ if accountType is not None and accountType != 'swap':
938
1133
  options = self.safe_dict(self.options, 'accountsByType', {})
939
1134
  parsedAccountType = self.safe_string(options, accountType, accountType)
940
1135
  request['accountType'] = parsedAccountType
941
1136
  response = self.privateGetAssetBalances(self.extend(request, params))
942
1137
  else:
943
1138
  response = self.privateGetAccountBalance(self.extend(request, params))
944
- return self.parse_balance_by_type(accountType, response)
1139
+ return self.parse_balance_by_type(response)
945
1140
 
946
1141
  def create_order_request(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
947
1142
  market = self.market(symbol)
@@ -955,7 +1150,11 @@ class blofin(Exchange, ImplicitAPI):
955
1150
  marginMode = None
956
1151
  marginMode, params = self.handle_margin_mode_and_params('createOrder', params, 'cross')
957
1152
  request['marginMode'] = marginMode
1153
+ triggerPrice = self.safe_string(params, 'triggerPrice')
958
1154
  timeInForce = self.safe_string(params, 'timeInForce', 'GTC')
1155
+ isHedged = self.safe_bool(params, 'hedged', False)
1156
+ if isHedged:
1157
+ request['positionSide'] = 'long' if (side == 'buy') else 'short'
959
1158
  isMarketOrder = type == 'market'
960
1159
  params = self.omit(params, ['timeInForce'])
961
1160
  ioc = (timeInForce == 'IOC') or (type == 'ioc')
@@ -963,14 +1162,15 @@ class blofin(Exchange, ImplicitAPI):
963
1162
  if isMarketOrder or marketIOC:
964
1163
  request['orderType'] = 'market'
965
1164
  else:
966
- request['price'] = self.price_to_precision(symbol, price)
1165
+ key = 'orderPrice' if (triggerPrice is not None) else 'price'
1166
+ request[key] = self.price_to_precision(symbol, price)
967
1167
  postOnly = False
968
1168
  postOnly, params = self.handle_post_only(isMarketOrder, type == 'post_only', params)
969
1169
  if postOnly:
970
1170
  request['type'] = 'post_only'
971
1171
  stopLoss = self.safe_dict(params, 'stopLoss')
972
1172
  takeProfit = self.safe_dict(params, 'takeProfit')
973
- params = self.omit(params, ['stopLoss', 'takeProfit'])
1173
+ params = self.omit(params, ['stopLoss', 'takeProfit', 'hedged'])
974
1174
  isStopLoss = stopLoss is not None
975
1175
  isTakeProfit = takeProfit is not None
976
1176
  if isStopLoss or isTakeProfit:
@@ -984,6 +1184,11 @@ class blofin(Exchange, ImplicitAPI):
984
1184
  request['tpTriggerPrice'] = self.price_to_precision(symbol, tpTriggerPrice)
985
1185
  tpPrice = self.safe_string(takeProfit, 'price', '-1')
986
1186
  request['tpOrderPrice'] = self.price_to_precision(symbol, tpPrice)
1187
+ elif triggerPrice is not None:
1188
+ request['orderType'] = 'trigger'
1189
+ request['triggerPrice'] = self.price_to_precision(symbol, triggerPrice)
1190
+ if isMarketOrder:
1191
+ request['orderPrice'] = '-1'
987
1192
  return self.extend(request, params)
988
1193
 
989
1194
  def parse_order_status(self, status: Str):
@@ -998,6 +1203,8 @@ class blofin(Exchange, ImplicitAPI):
998
1203
  return self.safe_string(statuses, status, status)
999
1204
 
1000
1205
  def parse_order(self, order: dict, market: Market = None) -> Order:
1206
+ #
1207
+ # response similar for REST & WS
1001
1208
  #
1002
1209
  # {
1003
1210
  # "orderId": "2075628533",
@@ -1026,9 +1233,12 @@ class blofin(Exchange, ImplicitAPI):
1026
1233
  # "cancelSource": "not_canceled",
1027
1234
  # "cancelSourceReason": null,
1028
1235
  # "brokerId": "ec6dd3a7dd982d0b"
1236
+ # "filled_amount": "1.000000000000000000", # filledAmount in "ws" watchOrders
1237
+ # "cancelSource": "", # only in WS
1238
+ # "instType": "SWAP", # only in WS
1029
1239
  # }
1030
1240
  #
1031
- id = self.safe_string_2(order, 'tpslId', 'orderId')
1241
+ id = self.safe_string_n(order, ['tpslId', 'orderId', 'algoId'])
1032
1242
  timestamp = self.safe_integer(order, 'createTime')
1033
1243
  lastUpdateTimestamp = self.safe_integer(order, 'updateTime')
1034
1244
  lastTradeTimestamp = self.safe_integer(order, 'fillTime')
@@ -1112,20 +1322,24 @@ class blofin(Exchange, ImplicitAPI):
1112
1322
  def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}) -> Order:
1113
1323
  """
1114
1324
  create a trade order
1115
- :see: https://blofin.com/docs#place-order
1116
- :see: https://blofin.com/docs#place-tpsl-order
1325
+
1326
+ https://blofin.com/docs#place-order
1327
+ https://blofin.com/docs#place-tpsl-order
1328
+
1117
1329
  :param str symbol: unified symbol of the market to create an order in
1118
1330
  :param str type: 'market' or 'limit' or 'post_only' or 'ioc' or 'fok'
1119
1331
  :param str side: 'buy' or 'sell'
1120
1332
  :param float amount: how much of currency you want to trade in units of base currency
1121
- :param float [price]: the price at which the order is to be fullfilled, in units of the quote currency, ignored in market orders
1333
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1122
1334
  :param dict [params]: extra parameters specific to the exchange API endpoint
1335
+ :param str [params.triggerPrice]: the trigger price for a trigger order
1123
1336
  :param bool [params.reduceOnly]: a mark to reduce the position size for margin, swap and future orders
1124
1337
  :param bool [params.postOnly]: True to place a post only order
1125
1338
  :param str [params.marginMode]: 'cross' or 'isolated', default is 'cross'
1126
1339
  :param float [params.stopLossPrice]: stop loss trigger price(will use privatePostTradeOrderTpsl)
1127
1340
  :param float [params.takeProfitPrice]: take profit trigger price(will use privatePostTradeOrderTpsl)
1128
- :param str [param.positionSide]: *stopLossPrice/takeProfitPrice orders only* 'long' or 'short' or 'net' default is 'net'
1341
+ :param str [params.positionSide]: *stopLossPrice/takeProfitPrice orders only* 'long' or 'short' or 'net' default is 'net'
1342
+ :param boolean [params.hedged]: if True, the positionSide will be set to long/short instead of net, default is False
1129
1343
  :param str [params.clientOrderId]: a unique id for the order
1130
1344
  :param dict [params.takeProfit]: *takeProfit object in params* containing the triggerPrice at which the attached take profit order will be triggered
1131
1345
  :param float [params.takeProfit.triggerPrice]: take profit trigger price
@@ -1143,14 +1357,25 @@ class blofin(Exchange, ImplicitAPI):
1143
1357
  method, params = self.handle_option_and_params(params, 'createOrder', 'method', 'privatePostTradeOrder')
1144
1358
  isStopLossPriceDefined = self.safe_string(params, 'stopLossPrice') is not None
1145
1359
  isTakeProfitPriceDefined = self.safe_string(params, 'takeProfitPrice') is not None
1360
+ isTriggerOrder = self.safe_string(params, 'triggerPrice') is not None
1146
1361
  isType2Order = (isStopLossPriceDefined or isTakeProfitPriceDefined)
1147
1362
  response = None
1363
+ reduceOnly = self.safe_bool(params, 'reduceOnly')
1364
+ if reduceOnly is not None:
1365
+ params['reduceOnly'] = 'true' if reduceOnly else 'false'
1148
1366
  if tpsl or (method == 'privatePostTradeOrderTpsl') or isType2Order:
1149
1367
  tpslRequest = self.create_tpsl_order_request(symbol, type, side, amount, price, params)
1150
1368
  response = self.privatePostTradeOrderTpsl(tpslRequest)
1369
+ elif isTriggerOrder or (method == 'privatePostTradeOrderAlgo'):
1370
+ triggerRequest = self.create_order_request(symbol, type, side, amount, price, params)
1371
+ response = self.privatePostTradeOrderAlgo(triggerRequest)
1151
1372
  else:
1152
1373
  request = self.create_order_request(symbol, type, side, amount, price, params)
1153
1374
  response = self.privatePostTradeOrder(request)
1375
+ if isTriggerOrder or (method == 'privatePostTradeOrderAlgo'):
1376
+ dataDict = self.safe_dict(response, 'data', {})
1377
+ triggerOrder = self.parse_order(dataDict, market)
1378
+ return triggerOrder
1154
1379
  data = self.safe_list(response, 'data', [])
1155
1380
  first = self.safe_dict(data, 0)
1156
1381
  order = self.parse_order(first, market)
@@ -1193,12 +1418,15 @@ class blofin(Exchange, ImplicitAPI):
1193
1418
  def cancel_order(self, id: str, symbol: Str = None, params={}):
1194
1419
  """
1195
1420
  cancels an open order
1196
- :see: https://blofin.com/docs#cancel-order
1197
- :see: https://blofin.com/docs#cancel-tpsl-order
1421
+
1422
+ https://blofin.com/docs#cancel-order
1423
+ https://blofin.com/docs#cancel-tpsl-order
1424
+
1198
1425
  :param str id: order id
1199
1426
  :param str symbol: unified symbol of the market the order was made in
1200
1427
  :param dict [params]: extra parameters specific to the exchange API endpoint
1201
- :param boolean [params.trigger]: True if cancelling a trigger/conditional order/tp sl orders
1428
+ :param boolean [params.trigger]: True if cancelling a trigger/conditional
1429
+ :param boolean [params.tpsl]: True if cancelling a tpsl order
1202
1430
  :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1203
1431
  """
1204
1432
  if symbol is None:
@@ -1208,20 +1436,27 @@ class blofin(Exchange, ImplicitAPI):
1208
1436
  request: dict = {
1209
1437
  'instId': market['id'],
1210
1438
  }
1211
- isTrigger = self.safe_bool_n(params, ['stop', 'trigger', 'tpsl'], False)
1439
+ isTrigger = self.safe_bool_n(params, ['trigger'], False)
1440
+ isTpsl = self.safe_bool_2(params, 'tpsl', 'TPSL', False)
1212
1441
  clientOrderId = self.safe_string(params, 'clientOrderId')
1213
1442
  if clientOrderId is not None:
1214
1443
  request['clientOrderId'] = clientOrderId
1215
1444
  else:
1216
- if not isTrigger:
1445
+ if not isTrigger and not isTpsl:
1217
1446
  request['orderId'] = str(id)
1218
- else:
1447
+ elif isTpsl:
1219
1448
  request['tpslId'] = str(id)
1449
+ elif isTrigger:
1450
+ request['algoId'] = str(id)
1220
1451
  query = self.omit(params, ['orderId', 'clientOrderId', 'stop', 'trigger', 'tpsl'])
1221
- if isTrigger:
1452
+ if isTpsl:
1222
1453
  tpslResponse = self.cancel_orders([id], symbol, params)
1223
1454
  first = self.safe_dict(tpslResponse, 0)
1224
1455
  return first
1456
+ elif isTrigger:
1457
+ triggerResponse = self.privatePostTradeCancelAlgo(self.extend(request, query))
1458
+ triggerData = self.safe_dict(triggerResponse, 'data')
1459
+ return self.parse_order(triggerData, market)
1225
1460
  response = self.privatePostTradeCancelOrder(self.extend(request, query))
1226
1461
  data = self.safe_list(response, 'data', [])
1227
1462
  order = self.safe_dict(data, 0)
@@ -1230,8 +1465,11 @@ class blofin(Exchange, ImplicitAPI):
1230
1465
  def create_orders(self, orders: List[OrderRequest], params={}) -> List[Order]:
1231
1466
  """
1232
1467
  create a list of trade orders
1233
- :see: https://blofin.com/docs#place-multiple-orders
1468
+
1469
+ https://blofin.com/docs#place-multiple-orders
1470
+
1234
1471
  :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
1472
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1235
1473
  :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1236
1474
  """
1237
1475
  self.load_markets()
@@ -1254,13 +1492,16 @@ class blofin(Exchange, ImplicitAPI):
1254
1492
  def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1255
1493
  """
1256
1494
  Fetch orders that are still open
1257
- :see: https://blofin.com/docs#get-active-orders
1258
- :see: https://blofin.com/docs#get-active-tpsl-orders
1495
+
1496
+ https://blofin.com/docs#get-active-orders
1497
+ https://blofin.com/docs#get-active-tpsl-orders
1498
+ https://docs.blofin.com/index.html#get-active-algo-orders
1499
+
1259
1500
  :param str symbol: unified market symbol
1260
1501
  :param int [since]: the earliest time in ms to fetch open orders for
1261
1502
  :param int [limit]: the maximum number of open orders structures to retrieve
1262
1503
  :param dict [params]: extra parameters specific to the exchange API endpoint
1263
- :param bool [params.stop]: True if fetching trigger or conditional orders
1504
+ :param bool [params.trigger]: True if fetching trigger or conditional orders
1264
1505
  :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)
1265
1506
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1266
1507
  """
@@ -1277,13 +1518,17 @@ class blofin(Exchange, ImplicitAPI):
1277
1518
  request['instId'] = market['id']
1278
1519
  if limit is not None:
1279
1520
  request['limit'] = limit # default 100, max 100
1280
- isStop = self.safe_bool_n(params, ['stop', 'trigger', 'tpsl', 'TPSL'], False)
1521
+ isTrigger = self.safe_bool_n(params, ['stop', 'trigger'], False)
1522
+ isTpSl = self.safe_bool_2(params, 'tpsl', 'TPSL', False)
1281
1523
  method: Str = None
1282
1524
  method, params = self.handle_option_and_params(params, 'fetchOpenOrders', 'method', 'privateGetTradeOrdersPending')
1283
1525
  query = self.omit(params, ['method', 'stop', 'trigger', 'tpsl', 'TPSL'])
1284
1526
  response = None
1285
- if isStop or (method == 'privateGetTradeOrdersTpslPending'):
1527
+ if isTpSl or (method == 'privateGetTradeOrdersTpslPending'):
1286
1528
  response = self.privateGetTradeOrdersTpslPending(self.extend(request, query))
1529
+ elif isTrigger or (method == 'privateGetTradeOrdersAlgoPending'):
1530
+ request['orderType'] = 'trigger'
1531
+ response = self.privateGetTradeOrdersAlgoPending(self.extend(request, query))
1287
1532
  else:
1288
1533
  response = self.privateGetTradeOrdersPending(self.extend(request, query))
1289
1534
  data = self.safe_list(response, 'data', [])
@@ -1292,7 +1537,9 @@ class blofin(Exchange, ImplicitAPI):
1292
1537
  def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
1293
1538
  """
1294
1539
  fetch all trades made by the user
1295
- :see: https://blofin.com/docs#get-trade-history
1540
+
1541
+ https://blofin.com/docs#get-trade-history
1542
+
1296
1543
  :param str symbol: unified market symbol
1297
1544
  :param int [since]: the earliest time in ms to fetch trades for
1298
1545
  :param int [limit]: the maximum number of trades structures to retrieve
@@ -1322,7 +1569,9 @@ class blofin(Exchange, ImplicitAPI):
1322
1569
  def fetch_deposits(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
1323
1570
  """
1324
1571
  fetch all deposits made to an account
1325
- :see: https://blofin.com/docs#get-deposite-history
1572
+
1573
+ https://blofin.com/docs#get-deposite-history
1574
+
1326
1575
  :param str code: unified currency code
1327
1576
  :param int [since]: the earliest time in ms to fetch deposits for
1328
1577
  :param int [limit]: the maximum number of deposits structures to retrieve
@@ -1354,7 +1603,9 @@ class blofin(Exchange, ImplicitAPI):
1354
1603
  def fetch_withdrawals(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Transaction]:
1355
1604
  """
1356
1605
  fetch all withdrawals made from an account
1357
- :see: https://blofin.com/docs#get-withdraw-history
1606
+
1607
+ https://blofin.com/docs#get-withdraw-history
1608
+
1358
1609
  :param str code: unified currency code
1359
1610
  :param int [since]: the earliest time in ms to fetch withdrawals for
1360
1611
  :param int [limit]: the maximum number of withdrawals structures to retrieve
@@ -1383,18 +1634,20 @@ class blofin(Exchange, ImplicitAPI):
1383
1634
  data = self.safe_list(response, 'data', [])
1384
1635
  return self.parse_transactions(data, currency, since, limit, params)
1385
1636
 
1386
- def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}):
1637
+ def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
1387
1638
  """
1388
- fetch the history of changes, actions done by the user or operations that altered balance of the user
1389
- :see: https://blofin.com/docs#get-funds-transfer-history
1390
- :param str code: unified currency code, default is None
1639
+ fetch the history of changes, actions done by the user or operations that altered the balance of the user
1640
+
1641
+ https://blofin.com/docs#get-funds-transfer-history
1642
+
1643
+ :param str [code]: unified currency code, default is None
1391
1644
  :param int [since]: timestamp in ms of the earliest ledger entry, default is None
1392
- :param int [limit]: max number of ledger entrys to return, default is None
1645
+ :param int [limit]: max number of ledger entries to return, default is None
1393
1646
  :param dict [params]: extra parameters specific to the exchange API endpoint
1394
1647
  :param str [params.marginMode]: 'cross' or 'isolated'
1395
1648
  :param int [params.until]: the latest time in ms to fetch entries for
1396
- :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)
1397
- :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger-structure>`
1649
+ :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)
1650
+ :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger>`
1398
1651
  """
1399
1652
  self.load_markets()
1400
1653
  paginate = False
@@ -1524,34 +1777,32 @@ class blofin(Exchange, ImplicitAPI):
1524
1777
  }
1525
1778
  return self.safe_string(types, type, type)
1526
1779
 
1527
- def parse_ledger_entry(self, item: dict, currency: Currency = None):
1528
- id = self.safe_string(item, 'transferId')
1529
- referenceId = self.safe_string(item, 'clientId')
1530
- fromAccount = self.safe_string(item, 'fromAccount')
1531
- toAccount = self.safe_string(item, 'toAccount')
1532
- type = self.parse_ledger_entry_type(self.safe_string(item, 'type'))
1533
- code = self.safe_currency_code(self.safe_string(item, 'currency'), currency)
1534
- amountString = self.safe_string(item, 'amount')
1535
- amount = self.parse_number(amountString)
1780
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
1781
+ currencyId = self.safe_string(item, 'currency')
1782
+ code = self.safe_currency_code(currencyId, currency)
1783
+ currency = self.safe_currency(currencyId, currency)
1536
1784
  timestamp = self.safe_integer(item, 'ts')
1537
- status = 'ok'
1538
- return {
1539
- 'id': id,
1785
+ return self.safe_ledger_entry({
1540
1786
  'info': item,
1787
+ 'id': self.safe_string(item, 'transferId'),
1788
+ 'direction': None,
1789
+ 'account': None,
1790
+ 'referenceId': self.safe_string(item, 'clientId'),
1791
+ 'referenceAccount': None,
1792
+ 'type': self.parse_ledger_entry_type(self.safe_string(item, 'type')),
1793
+ 'currency': code,
1794
+ 'amount': self.safe_number(item, 'amount'),
1541
1795
  'timestamp': timestamp,
1542
1796
  'datetime': self.iso8601(timestamp),
1543
- 'fromAccount': fromAccount,
1544
- 'toAccount': toAccount,
1545
- 'type': type,
1546
- 'currency': code,
1547
- 'amount': amount,
1548
- 'clientId': referenceId, # balance before
1549
- 'status': status,
1550
- }
1797
+ 'before': None,
1798
+ 'after': None,
1799
+ 'status': 'ok',
1800
+ 'fee': None,
1801
+ }, currency)
1551
1802
 
1552
1803
  def parse_ids(self, ids):
1553
1804
  """
1554
- * @ignore
1805
+ @ignore
1555
1806
  :param string[]|str ids: order ids
1556
1807
  :returns str[]: list of order ids
1557
1808
  """
@@ -1563,7 +1814,9 @@ class blofin(Exchange, ImplicitAPI):
1563
1814
  def cancel_orders(self, ids, symbol: Str = None, params={}):
1564
1815
  """
1565
1816
  cancel multiple orders
1566
- :see: https://blofin.com/docs#cancel-multiple-orders
1817
+
1818
+ https://blofin.com/docs#cancel-multiple-orders
1819
+
1567
1820
  :param str[] ids: order ids
1568
1821
  :param str symbol: unified market symbol
1569
1822
  :param dict [params]: extra parameters specific to the exchange API endpoint
@@ -1581,8 +1834,8 @@ class blofin(Exchange, ImplicitAPI):
1581
1834
  method = self.safe_string(params, 'method', defaultMethod)
1582
1835
  clientOrderIds = self.parse_ids(self.safe_value(params, 'clientOrderId'))
1583
1836
  tpslIds = self.parse_ids(self.safe_value(params, 'tpslId'))
1584
- stop = self.safe_bool_n(params, ['stop', 'trigger', 'tpsl'])
1585
- if stop:
1837
+ trigger = self.safe_bool_n(params, ['stop', 'trigger', 'tpsl'])
1838
+ if trigger:
1586
1839
  method = 'privatePostTradeCancelTpsl'
1587
1840
  if clientOrderIds is None:
1588
1841
  ids = self.parse_ids(ids)
@@ -1593,7 +1846,7 @@ class blofin(Exchange, ImplicitAPI):
1593
1846
  'instId': market['id'],
1594
1847
  })
1595
1848
  for i in range(0, len(ids)):
1596
- if stop:
1849
+ if trigger:
1597
1850
  request.append({
1598
1851
  'tpslId': ids[i],
1599
1852
  'instId': market['id'],
@@ -1620,7 +1873,9 @@ class blofin(Exchange, ImplicitAPI):
1620
1873
  def transfer(self, code: str, amount: float, fromAccount: str, toAccount: str, params={}) -> TransferEntry:
1621
1874
  """
1622
1875
  transfer currency internally between wallets on the same account
1623
- :see: https://blofin.com/docs#funds-transfer
1876
+
1877
+ https://blofin.com/docs#funds-transfer
1878
+
1624
1879
  :param str code: unified currency code
1625
1880
  :param float amount: amount to transfer
1626
1881
  :param str fromAccount: account to transfer from(funding, swap, copy_trading, earn)
@@ -1660,7 +1915,9 @@ class blofin(Exchange, ImplicitAPI):
1660
1915
  def fetch_position(self, symbol: str, params={}) -> Position:
1661
1916
  """
1662
1917
  fetch data on a single open contract trade position
1663
- :see: https://blofin.com/docs#get-positions
1918
+
1919
+ https://blofin.com/docs#get-positions
1920
+
1664
1921
  :param str symbol: unified market symbol of the market the position is held in, default is None
1665
1922
  :param dict [params]: extra parameters specific to the exchange API endpoint
1666
1923
  :param str [params.instType]: MARGIN, SWAP, FUTURES, OPTION
@@ -1681,7 +1938,9 @@ class blofin(Exchange, ImplicitAPI):
1681
1938
  def fetch_positions(self, symbols: Strings = None, params={}) -> List[Position]:
1682
1939
  """
1683
1940
  fetch data on a single open contract trade position
1684
- :see: https://blofin.com/docs#get-positions
1941
+
1942
+ https://blofin.com/docs#get-positions
1943
+
1685
1944
  :param str[] [symbols]: list of unified market symbols
1686
1945
  :param dict [params]: extra parameters specific to the exchange API endpoint
1687
1946
  :param str [params.instType]: MARGIN, SWAP, FUTURES, OPTION
@@ -1695,6 +1954,32 @@ class blofin(Exchange, ImplicitAPI):
1695
1954
  return self.filter_by_array_positions(result, 'symbol', symbols, False)
1696
1955
 
1697
1956
  def parse_position(self, position: dict, market: Market = None):
1957
+ #
1958
+ # response similar for REST & WS
1959
+ #
1960
+ # {
1961
+ # instType: 'SWAP',
1962
+ # instId: 'LTC-USDT',
1963
+ # marginMode: 'cross',
1964
+ # positionId: '644159',
1965
+ # positionSide: 'net',
1966
+ # positions: '1',
1967
+ # availablePositions: '1',
1968
+ # averagePrice: '68.16',
1969
+ # unrealizedPnl: '0.80631223',
1970
+ # unrealizedPnlRatio: '0.03548909463028169',
1971
+ # leverage: '3',
1972
+ # liquidationPrice: '10.116655172370356435',
1973
+ # markPrice: '68.96',
1974
+ # initialMargin: '22.988770743333333333',
1975
+ # margin: '', # self field might not exist in rest response
1976
+ # marginRatio: '152.523509620342499273',
1977
+ # maintenanceMargin: '0.34483156115',
1978
+ # adl: '4',
1979
+ # createTime: '1707235776528',
1980
+ # updateTime: '1707235776528'
1981
+ # }
1982
+ #
1698
1983
  marketId = self.safe_string(position, 'instId')
1699
1984
  market = self.safe_market(marketId, market)
1700
1985
  symbol = market['symbol']
@@ -1778,7 +2063,9 @@ class blofin(Exchange, ImplicitAPI):
1778
2063
  def fetch_leverages(self, symbols: Strings = None, params={}) -> Leverages:
1779
2064
  """
1780
2065
  fetch the set leverage for all contract markets
1781
- :see: https://docs.blofin.com/index.html#get-multiple-leverage
2066
+
2067
+ https://docs.blofin.com/index.html#get-multiple-leverage
2068
+
1782
2069
  :param str[] symbols: a list of unified market symbols, required on blofin
1783
2070
  :param dict [params]: extra parameters specific to the exchange API endpoint
1784
2071
  :param str [params.marginMode]: 'cross' or 'isolated'
@@ -1826,7 +2113,9 @@ class blofin(Exchange, ImplicitAPI):
1826
2113
  def fetch_leverage(self, symbol: str, params={}) -> Leverage:
1827
2114
  """
1828
2115
  fetch the set leverage for a market
1829
- :see: https://docs.blofin.com/index.html#get-leverage
2116
+
2117
+ https://docs.blofin.com/index.html#get-leverage
2118
+
1830
2119
  :param str symbol: unified market symbol
1831
2120
  :param dict [params]: extra parameters specific to the exchange API endpoint
1832
2121
  :param str [params.marginMode]: 'cross' or 'isolated'
@@ -1870,14 +2159,17 @@ class blofin(Exchange, ImplicitAPI):
1870
2159
  'shortLeverage': leverageValue,
1871
2160
  }
1872
2161
 
1873
- def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
2162
+ def set_leverage(self, leverage: int, symbol: Str = None, params={}):
1874
2163
  """
1875
2164
  set the level of leverage for a market
1876
- :see: https://blofin.com/docs#set-leverage
2165
+
2166
+ https://blofin.com/docs#set-leverage
2167
+
1877
2168
  :param int leverage: the rate of leverage
1878
2169
  :param str symbol: unified market symbol
1879
2170
  :param dict [params]: extra parameters specific to the exchange API endpoint
1880
2171
  :param str [params.marginMode]: 'cross' or 'isolated'
2172
+ :param str [params.positionSide]: 'long' or 'short' - required for hedged mode in isolated margin
1881
2173
  :returns dict: response from the exchange
1882
2174
  """
1883
2175
  if symbol is None:
@@ -1903,15 +2195,17 @@ class blofin(Exchange, ImplicitAPI):
1903
2195
  def close_position(self, symbol: str, side: OrderSide = None, params={}) -> Order:
1904
2196
  """
1905
2197
  closes open positions for a market
1906
- :see: https://blofin.com/docs#close-positions
2198
+
2199
+ https://blofin.com/docs#close-positions
2200
+
1907
2201
  :param str symbol: Unified CCXT market symbol
1908
2202
  :param str [side]: 'buy' or 'sell', leave in net mode
1909
2203
  :param dict [params]: extra parameters specific to the blofin api endpoint
1910
2204
  :param str [params.clientOrderId]: a unique identifier for the order
1911
2205
  :param str [params.marginMode]: 'cross' or 'isolated', default is 'cross
1912
2206
  :param str [params.code]: *required in the case of closing cross MARGIN position for Single-currency margin* margin currency
1913
- *
1914
- * EXCHANGE SPECIFIC PARAMETERS
2207
+
2208
+ EXCHANGE SPECIFIC PARAMETERS
1915
2209
  :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
1916
2210
  :param str [params.tag]: order tag a combination of case-sensitive alphanumerics, all numbers, or all letters of up to 16 characters
1917
2211
  :returns dict[]: `A list of position structures <https://docs.ccxt.com/#/?id=position-structure>`
@@ -1933,13 +2227,15 @@ class blofin(Exchange, ImplicitAPI):
1933
2227
  def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1934
2228
  """
1935
2229
  fetches information on multiple closed orders made by the user
1936
- :see: https://blofin.com/docs#get-order-history
1937
- :see: https://blofin.com/docs#get-tpsl-order-history
2230
+
2231
+ https://blofin.com/docs#get-order-history
2232
+ https://blofin.com/docs#get-tpsl-order-history
2233
+
1938
2234
  :param str symbol: unified market symbol of the market orders were made in
1939
2235
  :param int [since]: the earliest time in ms to fetch orders for
1940
2236
  :param int [limit]: the maximum number of orde structures to retrieve
1941
2237
  :param dict [params]: extra parameters specific to the exchange API endpoint
1942
- :param bool [params.stop]: True if fetching trigger or conditional orders
2238
+ :param bool [params.trigger]: True if fetching trigger or conditional orders
1943
2239
  :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)
1944
2240
  :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1945
2241
  """
@@ -1958,12 +2254,12 @@ class blofin(Exchange, ImplicitAPI):
1958
2254
  request['limit'] = limit # default 100, max 100
1959
2255
  if since is not None:
1960
2256
  request['begin'] = since
1961
- isStop = self.safe_bool_n(params, ['stop', 'trigger', 'tpsl', 'TPSL'], False)
2257
+ isTrigger = self.safe_bool_n(params, ['stop', 'trigger', 'tpsl', 'TPSL'], False)
1962
2258
  method: Str = None
1963
2259
  method, params = self.handle_option_and_params(params, 'fetchOpenOrders', 'method', 'privateGetTradeOrdersHistory')
1964
2260
  query = self.omit(params, ['method', 'stop', 'trigger', 'tpsl', 'TPSL'])
1965
2261
  response = None
1966
- if (isStop) or (method == 'privateGetTradeOrdersTpslHistory'):
2262
+ if (isTrigger) or (method == 'privateGetTradeOrdersTpslHistory'):
1967
2263
  response = self.privateGetTradeOrdersTpslHistory(self.extend(request, query))
1968
2264
  else:
1969
2265
  response = self.privateGetTradeOrdersHistory(self.extend(request, query))
@@ -1973,7 +2269,9 @@ class blofin(Exchange, ImplicitAPI):
1973
2269
  def fetch_margin_mode(self, symbol: str, params={}) -> MarginMode:
1974
2270
  """
1975
2271
  fetches the margin mode of a trading pair
1976
- :see: https://docs.blofin.com/index.html#get-margin-mode
2272
+
2273
+ https://docs.blofin.com/index.html#get-margin-mode
2274
+
1977
2275
  :param str symbol: unified symbol of the market to fetch the margin mode for
1978
2276
  :param dict [params]: extra parameters specific to the exchange API endpoint
1979
2277
  :returns dict: a `margin mode structure <https://docs.ccxt.com/#/?id=margin-mode-structure>`
@@ -1993,13 +2291,97 @@ class blofin(Exchange, ImplicitAPI):
1993
2291
  data = self.safe_dict(response, 'data', {})
1994
2292
  return self.parse_margin_mode(data, market)
1995
2293
 
1996
- def parse_margin_mode(self, marginMode: dict, market=None) -> MarginMode:
2294
+ def parse_margin_mode(self, marginMode: dict, market: Market = None) -> MarginMode:
1997
2295
  return {
1998
2296
  'info': marginMode,
1999
- 'symbol': market['symbol'],
2297
+ 'symbol': self.safe_string(market, 'symbol'),
2000
2298
  'marginMode': self.safe_string(marginMode, 'marginMode'),
2001
2299
  }
2002
2300
 
2301
+ def set_margin_mode(self, marginMode: str, symbol: Str = None, params={}):
2302
+ """
2303
+ set margin mode to 'cross' or 'isolated'
2304
+
2305
+ https://docs.blofin.com/index.html#set-margin-mode
2306
+
2307
+ :param str marginMode: 'cross' or 'isolated'
2308
+ :param str [symbol]: unified market symbol(not used in blofin setMarginMode)
2309
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2310
+ :returns dict: response from the exchange
2311
+ """
2312
+ self.check_required_argument('setMarginMode', marginMode, 'marginMode', ['cross', 'isolated'])
2313
+ self.load_markets()
2314
+ market = None
2315
+ if symbol is not None:
2316
+ market = self.market(symbol)
2317
+ request: dict = {
2318
+ 'marginMode': marginMode,
2319
+ }
2320
+ response = self.privatePostAccountSetMarginMode(self.extend(request, params))
2321
+ #
2322
+ # {
2323
+ # "code": "0",
2324
+ # "msg": "success",
2325
+ # "data": {
2326
+ # "marginMode": "isolated"
2327
+ # }
2328
+ # }
2329
+ #
2330
+ data = self.safe_dict(response, 'data', {})
2331
+ return self.parse_margin_mode(data, market)
2332
+
2333
+ def fetch_position_mode(self, symbol: Str = None, params={}):
2334
+ """
2335
+ fetchs the position mode, hedged or one way
2336
+
2337
+ https://docs.blofin.com/index.html#get-position-mode
2338
+
2339
+ :param str [symbol]: unified symbol of the market to fetch the position mode for(not used in blofin fetchPositionMode)
2340
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2341
+ :returns dict: an object detailing whether the market is in hedged or one-way mode
2342
+ """
2343
+ response = self.privateGetAccountPositionMode(params)
2344
+ data = self.safe_dict(response, 'data', {})
2345
+ positionMode = self.safe_string(data, 'positionMode')
2346
+ #
2347
+ # {
2348
+ # "code": "0",
2349
+ # "msg": "success",
2350
+ # "data": {
2351
+ # "positionMode": "long_short_mode"
2352
+ # }
2353
+ # }
2354
+ #
2355
+ return {
2356
+ 'info': data,
2357
+ 'hedged': positionMode == 'long_short_mode',
2358
+ }
2359
+
2360
+ def set_position_mode(self, hedged: bool, symbol: Str = None, params={}):
2361
+ """
2362
+ set hedged to True or False for a market
2363
+
2364
+ https://docs.blofin.com/index.html#set-position-mode
2365
+
2366
+ :param bool hedged: set to True to use hedged mode, False for one-way mode
2367
+ :param str [symbol]: not used by blofin setPositionMode()
2368
+ :param dict [params]: extra parameters specific to the exchange API endpoint
2369
+ :returns dict: response from the exchange
2370
+ """
2371
+ request: dict = {
2372
+ 'positionMode': 'long_short_mode' if hedged else 'net_mode',
2373
+ }
2374
+ #
2375
+ # {
2376
+ # "code": "0",
2377
+ # "msg": "success",
2378
+ # "data": {
2379
+ # "positionMode": "net_mode"
2380
+ # }
2381
+ # }
2382
+ #
2383
+ return self.privatePostAccountSetPositionMode(self.extend(request, params))
2384
+
2003
2385
  def handle_errors(self, httpCode: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
2004
2386
  if response is None:
2005
2387
  return None # fallback to default error handler