ccxt 4.2.77__py2.py3-none-any.whl → 4.4.48__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 (546) hide show
  1. ccxt/__init__.py +36 -14
  2. ccxt/abstract/alpaca.py +4 -0
  3. ccxt/abstract/bigone.py +1 -1
  4. ccxt/abstract/binance.py +112 -48
  5. ccxt/abstract/binancecoinm.py +112 -48
  6. ccxt/abstract/binanceus.py +147 -83
  7. ccxt/abstract/binanceusdm.py +112 -48
  8. ccxt/abstract/bingx.py +133 -78
  9. ccxt/abstract/bitbank.py +5 -0
  10. ccxt/abstract/bitfinex.py +136 -65
  11. ccxt/abstract/bitfinex1.py +69 -0
  12. ccxt/abstract/bitflyer.py +1 -0
  13. ccxt/abstract/bitget.py +8 -1
  14. ccxt/abstract/bitmart.py +13 -1
  15. ccxt/abstract/bitopro.py +1 -0
  16. ccxt/abstract/bitpanda.py +0 -12
  17. ccxt/abstract/bitrue.py +3 -3
  18. ccxt/abstract/bitstamp.py +26 -3
  19. ccxt/abstract/blofin.py +24 -0
  20. ccxt/abstract/btcbox.py +1 -0
  21. ccxt/abstract/bybit.py +29 -14
  22. ccxt/abstract/cex.py +28 -29
  23. ccxt/abstract/coinbase.py +6 -0
  24. ccxt/abstract/coinbaseadvanced.py +94 -0
  25. ccxt/abstract/{coinbasepro.py → coinbaseexchange.py} +1 -0
  26. ccxt/abstract/coinbaseinternational.py +1 -1
  27. ccxt/abstract/coincatch.py +94 -0
  28. ccxt/abstract/coinex.py +233 -123
  29. ccxt/abstract/coinmetro.py +1 -0
  30. ccxt/abstract/cryptocom.py +14 -0
  31. ccxt/abstract/defx.py +69 -0
  32. ccxt/abstract/deribit.py +1 -0
  33. ccxt/abstract/digifinex.py +1 -0
  34. ccxt/abstract/ellipx.py +25 -0
  35. ccxt/abstract/gate.py +20 -0
  36. ccxt/abstract/gateio.py +20 -0
  37. ccxt/abstract/gemini.py +1 -0
  38. ccxt/abstract/hashkey.py +67 -0
  39. ccxt/abstract/hyperliquid.py +1 -1
  40. ccxt/abstract/independentreserve.py +6 -0
  41. ccxt/abstract/kraken.py +4 -3
  42. ccxt/abstract/krakenfutures.py +4 -0
  43. ccxt/abstract/kucoin.py +24 -0
  44. ccxt/abstract/kucoinfutures.py +34 -0
  45. ccxt/abstract/luno.py +2 -0
  46. ccxt/abstract/mexc.py +4 -0
  47. ccxt/abstract/myokx.py +340 -0
  48. ccxt/abstract/oceanex.py +5 -0
  49. ccxt/abstract/okx.py +30 -0
  50. ccxt/abstract/onetrading.py +0 -12
  51. ccxt/abstract/oxfun.py +34 -0
  52. ccxt/abstract/paradex.py +40 -0
  53. ccxt/abstract/phemex.py +1 -0
  54. ccxt/abstract/upbit.py +4 -0
  55. ccxt/abstract/vertex.py +19 -0
  56. ccxt/abstract/whitebit.py +31 -1
  57. ccxt/abstract/woo.py +6 -2
  58. ccxt/abstract/woofipro.py +119 -0
  59. ccxt/abstract/xt.py +153 -0
  60. ccxt/abstract/zonda.py +6 -0
  61. ccxt/ace.py +164 -60
  62. ccxt/alpaca.py +727 -63
  63. ccxt/ascendex.py +395 -249
  64. ccxt/async_support/__init__.py +36 -14
  65. ccxt/async_support/ace.py +164 -60
  66. ccxt/async_support/alpaca.py +727 -63
  67. ccxt/async_support/ascendex.py +396 -249
  68. ccxt/async_support/base/exchange.py +531 -155
  69. ccxt/async_support/base/ws/aiohttp_client.py +28 -5
  70. ccxt/async_support/base/ws/cache.py +3 -2
  71. ccxt/async_support/base/ws/client.py +26 -5
  72. ccxt/async_support/base/ws/fast_client.py +4 -3
  73. ccxt/async_support/base/ws/functions.py +1 -1
  74. ccxt/async_support/base/ws/future.py +40 -31
  75. ccxt/async_support/base/ws/order_book_side.py +3 -0
  76. ccxt/async_support/bequant.py +1 -1
  77. ccxt/async_support/bigone.py +329 -202
  78. ccxt/async_support/binance.py +3030 -1087
  79. ccxt/async_support/binancecoinm.py +2 -1
  80. ccxt/async_support/binanceus.py +12 -1
  81. ccxt/async_support/binanceusdm.py +3 -1
  82. ccxt/async_support/bingx.py +3104 -880
  83. ccxt/async_support/bit2c.py +119 -38
  84. ccxt/async_support/bitbank.py +215 -76
  85. ccxt/async_support/bitbns.py +124 -53
  86. ccxt/async_support/bitfinex.py +3236 -1078
  87. ccxt/async_support/bitfinex1.py +1711 -0
  88. ccxt/async_support/bitflyer.py +238 -49
  89. ccxt/async_support/bitget.py +1513 -563
  90. ccxt/async_support/bithumb.py +199 -65
  91. ccxt/async_support/bitmart.py +1320 -435
  92. ccxt/async_support/bitmex.py +308 -111
  93. ccxt/async_support/bitopro.py +256 -96
  94. ccxt/async_support/bitrue.py +365 -233
  95. ccxt/async_support/bitso.py +201 -89
  96. ccxt/async_support/bitstamp.py +438 -269
  97. ccxt/async_support/bitteam.py +179 -73
  98. ccxt/async_support/bitvavo.py +180 -70
  99. ccxt/async_support/bl3p.py +92 -25
  100. ccxt/async_support/blockchaincom.py +193 -79
  101. ccxt/async_support/blofin.py +392 -148
  102. ccxt/async_support/btcalpha.py +161 -55
  103. ccxt/async_support/btcbox.py +250 -34
  104. ccxt/async_support/btcmarkets.py +232 -85
  105. ccxt/async_support/btcturk.py +159 -60
  106. ccxt/async_support/bybit.py +2231 -1193
  107. ccxt/async_support/cex.py +1409 -1329
  108. ccxt/async_support/coinbase.py +1454 -287
  109. ccxt/async_support/coinbaseadvanced.py +17 -0
  110. ccxt/async_support/{coinbasepro.py → coinbaseexchange.py} +233 -99
  111. ccxt/async_support/coinbaseinternational.py +428 -88
  112. ccxt/async_support/coincatch.py +5152 -0
  113. ccxt/async_support/coincheck.py +121 -38
  114. ccxt/async_support/coinex.py +4020 -3339
  115. ccxt/async_support/coinlist.py +273 -116
  116. ccxt/async_support/coinmate.py +204 -97
  117. ccxt/async_support/coinmetro.py +203 -110
  118. ccxt/async_support/coinone.py +142 -68
  119. ccxt/async_support/coinsph.py +206 -89
  120. ccxt/async_support/coinspot.py +137 -62
  121. ccxt/async_support/cryptocom.py +515 -185
  122. ccxt/async_support/currencycom.py +203 -85
  123. ccxt/async_support/defx.py +2066 -0
  124. ccxt/async_support/delta.py +404 -109
  125. ccxt/async_support/deribit.py +557 -323
  126. ccxt/async_support/digifinex.py +340 -223
  127. ccxt/async_support/ellipx.py +1826 -0
  128. ccxt/async_support/exmo.py +259 -128
  129. ccxt/async_support/gate.py +1472 -463
  130. ccxt/async_support/gemini.py +206 -84
  131. ccxt/async_support/hashkey.py +4164 -0
  132. ccxt/async_support/hitbtc.py +334 -178
  133. ccxt/async_support/hollaex.py +134 -83
  134. ccxt/async_support/htx.py +1095 -563
  135. ccxt/async_support/huobijp.py +105 -56
  136. ccxt/async_support/hyperliquid.py +1633 -268
  137. ccxt/async_support/idex.py +148 -95
  138. ccxt/async_support/independentreserve.py +236 -31
  139. ccxt/async_support/indodax.py +165 -62
  140. ccxt/async_support/kraken.py +871 -354
  141. ccxt/async_support/krakenfutures.py +324 -100
  142. ccxt/async_support/kucoin.py +917 -357
  143. ccxt/async_support/kucoinfutures.py +1004 -149
  144. ccxt/async_support/kuna.py +138 -106
  145. ccxt/async_support/latoken.py +135 -79
  146. ccxt/async_support/lbank.py +290 -113
  147. ccxt/async_support/luno.py +112 -62
  148. ccxt/async_support/lykke.py +104 -55
  149. ccxt/async_support/mercado.py +36 -29
  150. ccxt/async_support/mexc.py +995 -429
  151. ccxt/async_support/myokx.py +43 -0
  152. ccxt/async_support/ndax.py +163 -82
  153. ccxt/async_support/novadax.py +121 -75
  154. ccxt/async_support/oceanex.py +175 -59
  155. ccxt/async_support/okcoin.py +222 -163
  156. ccxt/async_support/okx.py +1776 -454
  157. ccxt/async_support/onetrading.py +132 -414
  158. ccxt/async_support/oxfun.py +2832 -0
  159. ccxt/async_support/p2b.py +79 -51
  160. ccxt/async_support/paradex.py +2017 -0
  161. ccxt/async_support/paymium.py +56 -32
  162. ccxt/async_support/phemex.py +572 -196
  163. ccxt/async_support/poloniex.py +218 -95
  164. ccxt/async_support/poloniexfutures.py +260 -92
  165. ccxt/async_support/probit.py +143 -110
  166. ccxt/async_support/timex.py +123 -70
  167. ccxt/async_support/tokocrypto.py +129 -93
  168. ccxt/async_support/tradeogre.py +39 -25
  169. ccxt/async_support/upbit.py +322 -113
  170. ccxt/async_support/vertex.py +2983 -0
  171. ccxt/async_support/wavesexchange.py +227 -173
  172. ccxt/async_support/wazirx.py +145 -65
  173. ccxt/async_support/whitebit.py +533 -138
  174. ccxt/async_support/woo.py +1137 -296
  175. ccxt/async_support/woofipro.py +2716 -0
  176. ccxt/async_support/xt.py +4628 -0
  177. ccxt/async_support/yobit.py +160 -92
  178. ccxt/async_support/zaif.py +80 -33
  179. ccxt/async_support/zonda.py +140 -69
  180. ccxt/base/errors.py +51 -20
  181. ccxt/base/exchange.py +1722 -480
  182. ccxt/base/precise.py +10 -0
  183. ccxt/base/types.py +223 -4
  184. ccxt/bequant.py +1 -1
  185. ccxt/bigone.py +329 -202
  186. ccxt/binance.py +3030 -1087
  187. ccxt/binancecoinm.py +2 -1
  188. ccxt/binanceus.py +12 -1
  189. ccxt/binanceusdm.py +3 -1
  190. ccxt/bingx.py +3104 -880
  191. ccxt/bit2c.py +119 -38
  192. ccxt/bitbank.py +215 -76
  193. ccxt/bitbns.py +124 -53
  194. ccxt/bitfinex.py +3235 -1078
  195. ccxt/bitfinex1.py +1710 -0
  196. ccxt/bitflyer.py +238 -49
  197. ccxt/bitget.py +1513 -563
  198. ccxt/bithumb.py +198 -65
  199. ccxt/bitmart.py +1320 -435
  200. ccxt/bitmex.py +308 -111
  201. ccxt/bitopro.py +256 -96
  202. ccxt/bitrue.py +365 -233
  203. ccxt/bitso.py +201 -89
  204. ccxt/bitstamp.py +438 -269
  205. ccxt/bitteam.py +179 -73
  206. ccxt/bitvavo.py +180 -70
  207. ccxt/bl3p.py +92 -25
  208. ccxt/blockchaincom.py +193 -79
  209. ccxt/blofin.py +392 -148
  210. ccxt/btcalpha.py +161 -55
  211. ccxt/btcbox.py +250 -34
  212. ccxt/btcmarkets.py +232 -85
  213. ccxt/btcturk.py +159 -60
  214. ccxt/bybit.py +2231 -1193
  215. ccxt/cex.py +1408 -1329
  216. ccxt/coinbase.py +1454 -287
  217. ccxt/coinbaseadvanced.py +17 -0
  218. ccxt/{coinbasepro.py → coinbaseexchange.py} +233 -99
  219. ccxt/coinbaseinternational.py +428 -88
  220. ccxt/coincatch.py +5152 -0
  221. ccxt/coincheck.py +121 -38
  222. ccxt/coinex.py +4020 -3339
  223. ccxt/coinlist.py +273 -116
  224. ccxt/coinmate.py +204 -97
  225. ccxt/coinmetro.py +203 -110
  226. ccxt/coinone.py +142 -68
  227. ccxt/coinsph.py +206 -89
  228. ccxt/coinspot.py +137 -62
  229. ccxt/cryptocom.py +515 -185
  230. ccxt/currencycom.py +203 -85
  231. ccxt/defx.py +2065 -0
  232. ccxt/delta.py +404 -109
  233. ccxt/deribit.py +557 -323
  234. ccxt/digifinex.py +340 -223
  235. ccxt/ellipx.py +1826 -0
  236. ccxt/exmo.py +259 -128
  237. ccxt/gate.py +1472 -463
  238. ccxt/gemini.py +206 -84
  239. ccxt/hashkey.py +4164 -0
  240. ccxt/hitbtc.py +334 -178
  241. ccxt/hollaex.py +134 -83
  242. ccxt/htx.py +1095 -563
  243. ccxt/huobijp.py +105 -56
  244. ccxt/hyperliquid.py +1632 -268
  245. ccxt/idex.py +148 -95
  246. ccxt/independentreserve.py +235 -31
  247. ccxt/indodax.py +165 -62
  248. ccxt/kraken.py +871 -354
  249. ccxt/krakenfutures.py +324 -100
  250. ccxt/kucoin.py +917 -357
  251. ccxt/kucoinfutures.py +1004 -149
  252. ccxt/kuna.py +138 -106
  253. ccxt/latoken.py +135 -79
  254. ccxt/lbank.py +290 -113
  255. ccxt/luno.py +112 -62
  256. ccxt/lykke.py +104 -55
  257. ccxt/mercado.py +36 -29
  258. ccxt/mexc.py +994 -429
  259. ccxt/myokx.py +43 -0
  260. ccxt/ndax.py +163 -82
  261. ccxt/novadax.py +121 -75
  262. ccxt/oceanex.py +175 -59
  263. ccxt/okcoin.py +222 -163
  264. ccxt/okx.py +1776 -454
  265. ccxt/onetrading.py +132 -414
  266. ccxt/oxfun.py +2831 -0
  267. ccxt/p2b.py +79 -51
  268. ccxt/paradex.py +2017 -0
  269. ccxt/paymium.py +56 -32
  270. ccxt/phemex.py +572 -196
  271. ccxt/poloniex.py +218 -95
  272. ccxt/poloniexfutures.py +260 -92
  273. ccxt/pro/__init__.py +29 -5
  274. ccxt/pro/alpaca.py +32 -17
  275. ccxt/pro/ascendex.py +62 -14
  276. ccxt/pro/bequant.py +4 -0
  277. ccxt/pro/binance.py +1596 -329
  278. ccxt/pro/binancecoinm.py +1 -0
  279. ccxt/pro/binanceus.py +2 -9
  280. ccxt/pro/binanceusdm.py +2 -0
  281. ccxt/pro/bingx.py +527 -134
  282. ccxt/pro/bitcoincom.py +4 -1
  283. ccxt/pro/bitfinex.py +731 -266
  284. ccxt/pro/bitfinex1.py +635 -0
  285. ccxt/pro/bitget.py +726 -357
  286. ccxt/pro/bithumb.py +380 -0
  287. ccxt/pro/bitmart.py +138 -39
  288. ccxt/pro/bitmex.py +199 -40
  289. ccxt/pro/bitopro.py +25 -13
  290. ccxt/pro/bitrue.py +31 -32
  291. ccxt/pro/bitstamp.py +7 -6
  292. ccxt/pro/bitvavo.py +203 -81
  293. ccxt/pro/blockchaincom.py +30 -17
  294. ccxt/pro/blofin.py +692 -0
  295. ccxt/pro/bybit.py +791 -82
  296. ccxt/pro/cex.py +99 -51
  297. ccxt/pro/coinbase.py +220 -30
  298. ccxt/{async_support/hitbtc3.py → pro/coinbaseadvanced.py} +5 -5
  299. ccxt/pro/{coinbasepro.py → coinbaseexchange.py} +19 -19
  300. ccxt/pro/coinbaseinternational.py +193 -30
  301. ccxt/pro/coincatch.py +1464 -0
  302. ccxt/pro/coincheck.py +11 -6
  303. ccxt/pro/coinex.py +965 -665
  304. ccxt/pro/coinone.py +17 -10
  305. ccxt/pro/cryptocom.py +446 -66
  306. ccxt/pro/currencycom.py +11 -10
  307. ccxt/pro/defx.py +832 -0
  308. ccxt/pro/deribit.py +167 -31
  309. ccxt/pro/exmo.py +252 -20
  310. ccxt/pro/gate.py +729 -64
  311. ccxt/pro/gemini.py +44 -26
  312. ccxt/pro/hashkey.py +802 -0
  313. ccxt/pro/hitbtc.py +208 -103
  314. ccxt/pro/hollaex.py +25 -9
  315. ccxt/pro/htx.py +83 -39
  316. ccxt/pro/huobijp.py +17 -16
  317. ccxt/pro/hyperliquid.py +502 -31
  318. ccxt/pro/idex.py +28 -13
  319. ccxt/pro/independentreserve.py +21 -16
  320. ccxt/pro/kraken.py +298 -51
  321. ccxt/pro/krakenfutures.py +166 -75
  322. ccxt/pro/kucoin.py +395 -77
  323. ccxt/pro/kucoinfutures.py +400 -99
  324. ccxt/pro/lbank.py +52 -31
  325. ccxt/pro/luno.py +12 -10
  326. ccxt/pro/mexc.py +400 -50
  327. ccxt/pro/myokx.py +28 -0
  328. ccxt/pro/ndax.py +25 -12
  329. ccxt/pro/okcoin.py +28 -9
  330. ccxt/pro/okx.py +935 -124
  331. ccxt/pro/onetrading.py +41 -24
  332. ccxt/pro/oxfun.py +1054 -0
  333. ccxt/pro/p2b.py +100 -24
  334. ccxt/pro/paradex.py +352 -0
  335. ccxt/pro/phemex.py +92 -33
  336. ccxt/pro/poloniex.py +128 -49
  337. ccxt/pro/poloniexfutures.py +53 -32
  338. ccxt/pro/probit.py +92 -85
  339. ccxt/pro/upbit.py +401 -8
  340. ccxt/pro/vertex.py +943 -0
  341. ccxt/pro/wazirx.py +46 -28
  342. ccxt/pro/whitebit.py +65 -12
  343. ccxt/pro/woo.py +437 -65
  344. ccxt/pro/woofipro.py +1271 -0
  345. ccxt/pro/xt.py +1067 -0
  346. ccxt/probit.py +143 -110
  347. ccxt/static_dependencies/__init__.py +1 -1
  348. ccxt/static_dependencies/lark/__init__.py +38 -0
  349. ccxt/static_dependencies/lark/__pyinstaller/__init__.py +6 -0
  350. ccxt/static_dependencies/lark/__pyinstaller/hook-lark.py +14 -0
  351. ccxt/static_dependencies/lark/ast_utils.py +59 -0
  352. ccxt/static_dependencies/lark/common.py +86 -0
  353. ccxt/static_dependencies/lark/exceptions.py +292 -0
  354. ccxt/static_dependencies/lark/grammar.py +130 -0
  355. ccxt/static_dependencies/lark/grammars/__init__.py +0 -0
  356. ccxt/static_dependencies/lark/indenter.py +143 -0
  357. ccxt/static_dependencies/lark/lark.py +658 -0
  358. ccxt/static_dependencies/lark/lexer.py +678 -0
  359. ccxt/static_dependencies/lark/load_grammar.py +1428 -0
  360. ccxt/static_dependencies/lark/parse_tree_builder.py +391 -0
  361. ccxt/static_dependencies/lark/parser_frontends.py +257 -0
  362. ccxt/static_dependencies/lark/parsers/__init__.py +0 -0
  363. ccxt/static_dependencies/lark/parsers/cyk.py +340 -0
  364. ccxt/static_dependencies/lark/parsers/earley.py +314 -0
  365. ccxt/static_dependencies/lark/parsers/earley_common.py +42 -0
  366. ccxt/static_dependencies/lark/parsers/earley_forest.py +801 -0
  367. ccxt/static_dependencies/lark/parsers/grammar_analysis.py +203 -0
  368. ccxt/static_dependencies/lark/parsers/lalr_analysis.py +332 -0
  369. ccxt/static_dependencies/lark/parsers/lalr_interactive_parser.py +158 -0
  370. ccxt/static_dependencies/lark/parsers/lalr_parser.py +122 -0
  371. ccxt/static_dependencies/lark/parsers/lalr_parser_state.py +110 -0
  372. ccxt/static_dependencies/lark/parsers/xearley.py +165 -0
  373. ccxt/static_dependencies/lark/py.typed +0 -0
  374. ccxt/static_dependencies/lark/reconstruct.py +107 -0
  375. ccxt/static_dependencies/lark/tools/__init__.py +70 -0
  376. ccxt/static_dependencies/lark/tools/nearley.py +202 -0
  377. ccxt/static_dependencies/lark/tools/serialize.py +32 -0
  378. ccxt/static_dependencies/lark/tools/standalone.py +196 -0
  379. ccxt/static_dependencies/lark/tree.py +267 -0
  380. ccxt/static_dependencies/lark/tree_matcher.py +186 -0
  381. ccxt/static_dependencies/lark/tree_templates.py +180 -0
  382. ccxt/static_dependencies/lark/utils.py +343 -0
  383. ccxt/static_dependencies/lark/visitors.py +596 -0
  384. ccxt/static_dependencies/marshmallow/__init__.py +81 -0
  385. ccxt/static_dependencies/marshmallow/base.py +65 -0
  386. ccxt/static_dependencies/marshmallow/class_registry.py +94 -0
  387. ccxt/static_dependencies/marshmallow/decorators.py +231 -0
  388. ccxt/static_dependencies/marshmallow/error_store.py +60 -0
  389. ccxt/static_dependencies/marshmallow/exceptions.py +71 -0
  390. ccxt/static_dependencies/marshmallow/fields.py +2114 -0
  391. ccxt/static_dependencies/marshmallow/orderedset.py +89 -0
  392. ccxt/static_dependencies/marshmallow/py.typed +0 -0
  393. ccxt/static_dependencies/marshmallow/schema.py +1228 -0
  394. ccxt/static_dependencies/marshmallow/types.py +12 -0
  395. ccxt/static_dependencies/marshmallow/utils.py +378 -0
  396. ccxt/static_dependencies/marshmallow/validate.py +678 -0
  397. ccxt/static_dependencies/marshmallow/warnings.py +2 -0
  398. ccxt/static_dependencies/marshmallow_dataclass/__init__.py +1047 -0
  399. ccxt/static_dependencies/marshmallow_dataclass/collection_field.py +51 -0
  400. ccxt/static_dependencies/marshmallow_dataclass/lazy_class_attribute.py +45 -0
  401. ccxt/static_dependencies/marshmallow_dataclass/mypy.py +71 -0
  402. ccxt/static_dependencies/marshmallow_dataclass/py.typed +0 -0
  403. ccxt/static_dependencies/marshmallow_dataclass/typing.py +14 -0
  404. ccxt/static_dependencies/marshmallow_dataclass/union_field.py +82 -0
  405. ccxt/static_dependencies/marshmallow_oneofschema/__init__.py +1 -0
  406. ccxt/static_dependencies/marshmallow_oneofschema/one_of_schema.py +193 -0
  407. ccxt/static_dependencies/marshmallow_oneofschema/py.typed +0 -0
  408. ccxt/static_dependencies/starknet/__init__.py +0 -0
  409. ccxt/static_dependencies/starknet/cairo/__init__.py +0 -0
  410. ccxt/static_dependencies/starknet/cairo/data_types.py +123 -0
  411. ccxt/static_dependencies/starknet/cairo/deprecated_parse/__init__.py +0 -0
  412. ccxt/static_dependencies/starknet/cairo/deprecated_parse/cairo_types.py +77 -0
  413. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser.py +46 -0
  414. ccxt/static_dependencies/starknet/cairo/deprecated_parse/parser_transformer.py +138 -0
  415. ccxt/static_dependencies/starknet/cairo/felt.py +64 -0
  416. ccxt/static_dependencies/starknet/cairo/type_parser.py +121 -0
  417. ccxt/static_dependencies/starknet/cairo/v1/__init__.py +0 -0
  418. ccxt/static_dependencies/starknet/cairo/v1/type_parser.py +59 -0
  419. ccxt/static_dependencies/starknet/cairo/v2/__init__.py +0 -0
  420. ccxt/static_dependencies/starknet/cairo/v2/type_parser.py +77 -0
  421. ccxt/static_dependencies/starknet/ccxt_utils.py +7 -0
  422. ccxt/static_dependencies/starknet/common.py +15 -0
  423. ccxt/static_dependencies/starknet/constants.py +39 -0
  424. ccxt/static_dependencies/starknet/hash/__init__.py +0 -0
  425. ccxt/static_dependencies/starknet/hash/address.py +79 -0
  426. ccxt/static_dependencies/starknet/hash/compiled_class_hash_objects.py +111 -0
  427. ccxt/static_dependencies/starknet/hash/selector.py +16 -0
  428. ccxt/static_dependencies/starknet/hash/storage.py +12 -0
  429. ccxt/static_dependencies/starknet/hash/utils.py +78 -0
  430. ccxt/static_dependencies/starknet/models/__init__.py +0 -0
  431. ccxt/static_dependencies/starknet/models/typed_data.py +45 -0
  432. ccxt/static_dependencies/starknet/serialization/__init__.py +24 -0
  433. ccxt/static_dependencies/starknet/serialization/_calldata_reader.py +40 -0
  434. ccxt/static_dependencies/starknet/serialization/_context.py +142 -0
  435. ccxt/static_dependencies/starknet/serialization/data_serializers/__init__.py +10 -0
  436. ccxt/static_dependencies/starknet/serialization/data_serializers/_common.py +82 -0
  437. ccxt/static_dependencies/starknet/serialization/data_serializers/array_serializer.py +43 -0
  438. ccxt/static_dependencies/starknet/serialization/data_serializers/bool_serializer.py +37 -0
  439. ccxt/static_dependencies/starknet/serialization/data_serializers/byte_array_serializer.py +66 -0
  440. ccxt/static_dependencies/starknet/serialization/data_serializers/cairo_data_serializer.py +71 -0
  441. ccxt/static_dependencies/starknet/serialization/data_serializers/enum_serializer.py +71 -0
  442. ccxt/static_dependencies/starknet/serialization/data_serializers/felt_serializer.py +50 -0
  443. ccxt/static_dependencies/starknet/serialization/data_serializers/named_tuple_serializer.py +58 -0
  444. ccxt/static_dependencies/starknet/serialization/data_serializers/option_serializer.py +43 -0
  445. ccxt/static_dependencies/starknet/serialization/data_serializers/output_serializer.py +40 -0
  446. ccxt/static_dependencies/starknet/serialization/data_serializers/payload_serializer.py +72 -0
  447. ccxt/static_dependencies/starknet/serialization/data_serializers/struct_serializer.py +36 -0
  448. ccxt/static_dependencies/starknet/serialization/data_serializers/tuple_serializer.py +36 -0
  449. ccxt/static_dependencies/starknet/serialization/data_serializers/uint256_serializer.py +76 -0
  450. ccxt/static_dependencies/starknet/serialization/data_serializers/uint_serializer.py +100 -0
  451. ccxt/static_dependencies/starknet/serialization/data_serializers/unit_serializer.py +32 -0
  452. ccxt/static_dependencies/starknet/serialization/errors.py +10 -0
  453. ccxt/static_dependencies/starknet/serialization/factory.py +229 -0
  454. ccxt/static_dependencies/starknet/serialization/function_serialization_adapter.py +110 -0
  455. ccxt/static_dependencies/starknet/serialization/tuple_dataclass.py +59 -0
  456. ccxt/static_dependencies/starknet/utils/__init__.py +0 -0
  457. ccxt/static_dependencies/starknet/utils/constructor_args_translator.py +86 -0
  458. ccxt/static_dependencies/starknet/utils/iterable.py +13 -0
  459. ccxt/static_dependencies/starknet/utils/schema.py +13 -0
  460. ccxt/static_dependencies/starknet/utils/typed_data.py +182 -0
  461. ccxt/static_dependencies/starkware/__init__.py +0 -0
  462. ccxt/static_dependencies/starkware/crypto/__init__.py +0 -0
  463. ccxt/static_dependencies/starkware/crypto/fast_pedersen_hash.py +50 -0
  464. ccxt/static_dependencies/starkware/crypto/math_utils.py +78 -0
  465. ccxt/static_dependencies/starkware/crypto/signature.py +2344 -0
  466. ccxt/static_dependencies/starkware/crypto/utils.py +63 -0
  467. ccxt/static_dependencies/sympy/__init__.py +0 -0
  468. ccxt/static_dependencies/sympy/core/__init__.py +0 -0
  469. ccxt/static_dependencies/sympy/core/intfunc.py +35 -0
  470. ccxt/static_dependencies/sympy/external/__init__.py +0 -0
  471. ccxt/static_dependencies/sympy/external/gmpy.py +345 -0
  472. ccxt/static_dependencies/sympy/external/importtools.py +187 -0
  473. ccxt/static_dependencies/sympy/external/ntheory.py +637 -0
  474. ccxt/static_dependencies/sympy/external/pythonmpq.py +341 -0
  475. ccxt/static_dependencies/typing_inspect/__init__.py +0 -0
  476. ccxt/static_dependencies/typing_inspect/typing_inspect.py +851 -0
  477. ccxt/test/{test_async.py → tests_async.py} +456 -391
  478. ccxt/test/tests_helpers.py +285 -0
  479. ccxt/test/tests_init.py +39 -0
  480. ccxt/test/{test_sync.py → tests_sync.py} +456 -393
  481. ccxt/timex.py +123 -70
  482. ccxt/tokocrypto.py +129 -93
  483. ccxt/tradeogre.py +39 -25
  484. ccxt/upbit.py +322 -113
  485. ccxt/vertex.py +2983 -0
  486. ccxt/wavesexchange.py +227 -173
  487. ccxt/wazirx.py +145 -65
  488. ccxt/whitebit.py +533 -138
  489. ccxt/woo.py +1137 -296
  490. ccxt/woofipro.py +2716 -0
  491. ccxt/xt.py +4627 -0
  492. ccxt/yobit.py +159 -92
  493. ccxt/zaif.py +80 -33
  494. ccxt/zonda.py +140 -69
  495. ccxt-4.4.48.dist-info/LICENSE.txt +21 -0
  496. ccxt-4.4.48.dist-info/METADATA +646 -0
  497. ccxt-4.4.48.dist-info/RECORD +669 -0
  498. {ccxt-4.2.77.dist-info → ccxt-4.4.48.dist-info}/WHEEL +1 -1
  499. ccxt/abstract/bitbay.py +0 -47
  500. ccxt/abstract/bitfinex2.py +0 -139
  501. ccxt/abstract/hitbtc3.py +0 -115
  502. ccxt/async_support/bitbay.py +0 -17
  503. ccxt/async_support/bitfinex2.py +0 -3496
  504. ccxt/async_support/flowbtc.py +0 -34
  505. ccxt/bitbay.py +0 -17
  506. ccxt/bitfinex2.py +0 -3496
  507. ccxt/flowbtc.py +0 -34
  508. ccxt/hitbtc3.py +0 -16
  509. ccxt/pro/bitfinex2.py +0 -1081
  510. ccxt/test/base/__init__.py +0 -28
  511. ccxt/test/base/test_account.py +0 -26
  512. ccxt/test/base/test_balance.py +0 -56
  513. ccxt/test/base/test_borrow_interest.py +0 -35
  514. ccxt/test/base/test_borrow_rate.py +0 -32
  515. ccxt/test/base/test_calculate_fee.py +0 -51
  516. ccxt/test/base/test_crypto.py +0 -127
  517. ccxt/test/base/test_currency.py +0 -76
  518. ccxt/test/base/test_datetime.py +0 -103
  519. ccxt/test/base/test_decimal_to_precision.py +0 -392
  520. ccxt/test/base/test_deep_extend.py +0 -68
  521. ccxt/test/base/test_deposit_withdrawal.py +0 -50
  522. ccxt/test/base/test_exchange_datetime_functions.py +0 -76
  523. ccxt/test/base/test_funding_rate_history.py +0 -29
  524. ccxt/test/base/test_last_price.py +0 -32
  525. ccxt/test/base/test_ledger_entry.py +0 -45
  526. ccxt/test/base/test_ledger_item.py +0 -48
  527. ccxt/test/base/test_leverage_tier.py +0 -33
  528. ccxt/test/base/test_margin_mode.py +0 -24
  529. ccxt/test/base/test_margin_modification.py +0 -35
  530. ccxt/test/base/test_market.py +0 -190
  531. ccxt/test/base/test_number.py +0 -411
  532. ccxt/test/base/test_ohlcv.py +0 -32
  533. ccxt/test/base/test_open_interest.py +0 -32
  534. ccxt/test/base/test_order.py +0 -64
  535. ccxt/test/base/test_order_book.py +0 -63
  536. ccxt/test/base/test_position.py +0 -60
  537. ccxt/test/base/test_shared_methods.py +0 -345
  538. ccxt/test/base/test_status.py +0 -24
  539. ccxt/test/base/test_throttle.py +0 -126
  540. ccxt/test/base/test_ticker.py +0 -86
  541. ccxt/test/base/test_trade.py +0 -47
  542. ccxt/test/base/test_trading_fee.py +0 -26
  543. ccxt/test/base/test_transaction.py +0 -39
  544. ccxt-4.2.77.dist-info/METADATA +0 -626
  545. ccxt-4.2.77.dist-info/RECORD +0 -534
  546. {ccxt-4.2.77.dist-info → ccxt-4.4.48.dist-info}/top_level.txt +0 -0
ccxt/defx.py ADDED
@@ -0,0 +1,2065 @@
1
+ # -*- coding: utf-8 -*-
2
+
3
+ # PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
4
+ # https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
5
+
6
+ from ccxt.base.exchange import Exchange
7
+ from ccxt.abstract.defx import ImplicitAPI
8
+ import hashlib
9
+ from ccxt.base.types import Balances, Currency, Int, LedgerEntry, Leverage, Market, Num, Order, OrderBook, OrderSide, OrderType, Position, Str, Strings, Ticker, Tickers, FundingRate, Trade, Transaction
10
+ from typing import List
11
+ from ccxt.base.errors import ExchangeError
12
+ from ccxt.base.errors import AuthenticationError
13
+ from ccxt.base.errors import ArgumentsRequired
14
+ from ccxt.base.errors import BadRequest
15
+ from ccxt.base.errors import InvalidOrder
16
+ from ccxt.base.errors import NotSupported
17
+ from ccxt.base.decimal_to_precision import TICK_SIZE
18
+ from ccxt.base.precise import Precise
19
+
20
+
21
+ class defx(Exchange, ImplicitAPI):
22
+
23
+ def describe(self):
24
+ return self.deep_extend(super(defx, self).describe(), {
25
+ 'id': 'defx',
26
+ 'name': 'Defx X',
27
+ # 'countries': [''],
28
+ 'rateLimit': 100,
29
+ 'version': 'v1',
30
+ 'certified': False,
31
+ 'pro': False,
32
+ 'hostname': 'defx.com',
33
+ 'dex': True,
34
+ 'has': {
35
+ 'CORS': None,
36
+ 'spot': False,
37
+ 'margin': False,
38
+ 'swap': True,
39
+ 'future': False,
40
+ 'option': False,
41
+ 'addMargin': True,
42
+ 'cancelAllOrders': True,
43
+ 'cancelAllOrdersAfter': False,
44
+ 'cancelOrder': True,
45
+ 'cancelWithdraw': False,
46
+ 'closeAllPositions': True,
47
+ 'closePosition': True,
48
+ 'createConvertTrade': False,
49
+ 'createDepositAddress': False,
50
+ 'createMarketBuyOrderWithCost': False,
51
+ 'createMarketOrder': False,
52
+ 'createMarketOrderWithCost': False,
53
+ 'createMarketSellOrderWithCost': False,
54
+ 'createOrder': True,
55
+ 'createOrderWithTakeProfitAndStopLoss': True,
56
+ 'createReduceOnlyOrder': True,
57
+ 'createStopLimitOrder': False,
58
+ 'createStopLossOrder': False,
59
+ 'createStopMarketOrder': False,
60
+ 'createStopOrder': False,
61
+ 'createTakeProfitOrder': True,
62
+ 'createTrailingAmountOrder': False,
63
+ 'createTrailingPercentOrder': False,
64
+ 'createTriggerOrder': True,
65
+ 'fetchAccounts': False,
66
+ 'fetchBalance': True,
67
+ 'fetchCanceledOrders': True,
68
+ 'fetchClosedOrder': False,
69
+ 'fetchClosedOrders': True,
70
+ 'fetchConvertCurrencies': False,
71
+ 'fetchConvertQuote': False,
72
+ 'fetchConvertTrade': False,
73
+ 'fetchConvertTradeHistory': False,
74
+ 'fetchCurrencies': False,
75
+ 'fetchDepositAddress': False,
76
+ 'fetchDepositAddresses': False,
77
+ 'fetchDepositAddressesByNetwork': False,
78
+ 'fetchDeposits': False,
79
+ 'fetchDepositsWithdrawals': False,
80
+ 'fetchFundingHistory': False,
81
+ 'fetchFundingInterval': False,
82
+ 'fetchFundingIntervals': False,
83
+ 'fetchFundingRate': True,
84
+ 'fetchFundingRateHistory': False,
85
+ 'fetchFundingRates': False,
86
+ 'fetchIndexOHLCV': False,
87
+ 'fetchLedger': True,
88
+ 'fetchLeverage': False,
89
+ 'fetchMarginAdjustmentHistory': False,
90
+ 'fetchMarginMode': False,
91
+ 'fetchMarkets': True,
92
+ 'fetchMarkOHLCV': False,
93
+ 'fetchMarkPrice': False,
94
+ 'fetchMarkPrices': False,
95
+ 'fetchMyTrades': True,
96
+ 'fetchOHLCV': True,
97
+ 'fetchOpenInterestHistory': False,
98
+ 'fetchOpenOrder': False,
99
+ 'fetchOpenOrders': True,
100
+ 'fetchOrder': True,
101
+ 'fetchOrderBook': True,
102
+ 'fetchOrders': True,
103
+ 'fetchOrderTrades': False,
104
+ 'fetchPosition': True,
105
+ 'fetchPositionHistory': False,
106
+ 'fetchPositionMode': False,
107
+ 'fetchPositions': True,
108
+ 'fetchPositionsHistory': False,
109
+ 'fetchPremiumIndexOHLCV': False,
110
+ 'fetchStatus': True,
111
+ 'fetchTicker': True,
112
+ 'fetchTickers': True,
113
+ 'fetchTime': True,
114
+ 'fetchTrades': True,
115
+ 'fetchTradingFee': False,
116
+ 'fetchTradingFees': False,
117
+ 'fetchTransactions': False,
118
+ 'fetchTransfers': False,
119
+ 'fetchWithdrawals': False,
120
+ 'reduceMargin': False,
121
+ 'sandbox': True,
122
+ 'setLeverage': True,
123
+ 'setMargin': False,
124
+ 'setPositionMode': False,
125
+ 'transfer': False,
126
+ 'withdraw': True,
127
+ },
128
+ 'timeframes': {
129
+ '1m': '1m',
130
+ '3m': '3m',
131
+ '5m': '5m',
132
+ '15m': '15m',
133
+ '30m': '30m',
134
+ '1h': '1h',
135
+ '2h': '2h',
136
+ '4h': '4h',
137
+ '12h': '12h',
138
+ '1d': '1d',
139
+ '1w': '1w',
140
+ '1M': '1M',
141
+ },
142
+ 'urls': {
143
+ 'logo': 'https://github.com/user-attachments/assets/4e92bace-d7a9-45ea-92be-122168dc87e4',
144
+ 'api': {
145
+ 'public': 'https://api.{hostname}',
146
+ 'private': 'https://api.{hostname}',
147
+ },
148
+ 'test': {
149
+ 'public': 'https://api.testnet.{hostname}',
150
+ 'private': 'https://api.testnet.{hostname}',
151
+ },
152
+ 'www': 'https://defx.com/home',
153
+ 'doc': [
154
+ 'https://docs.defx.com/docs',
155
+ 'https://api-docs.defx.com/',
156
+ ],
157
+ 'fees': [
158
+ '',
159
+ ],
160
+ 'referral': {
161
+ 'url': 'https://app.defx.com/join/6I2CZ7',
162
+ },
163
+ },
164
+ 'api': {
165
+ 'v1': {
166
+ 'public': {
167
+ 'get': {
168
+ 'healthcheck/ping': 1,
169
+ 'symbols/{symbol}/ohlc': 1,
170
+ 'symbols/{symbol}/trades': 1,
171
+ 'symbols/{symbol}/prices': 1,
172
+ 'symbols/{symbol}/ticker/24hr': 1,
173
+ 'symbols/{symbol}/depth/{level}/{slab}': 1,
174
+ 'ticker/24HrAgg': 1,
175
+ 'c/markets': 1,
176
+ 'c/markets/metadata': 1,
177
+ 'analytics/market/stats/newUsers': 1,
178
+ 'analytics/market/stats/tvl': 1,
179
+ 'analytics/market/stats/volumeByInstrument': 1,
180
+ 'analytics/market/stats/liquidation': 1,
181
+ 'analytics/market/stats/totalVolume': 1,
182
+ 'analytics/market/stats/openInterest': 1,
183
+ 'analytics/market/stats/totalTrades': 1,
184
+ 'analytics/market/stats/basis': 1,
185
+ 'analytics/market/stats/insuranceFund': 1,
186
+ 'analytics/market/stats/longAndShortRatio': 1,
187
+ 'analytics/market/stats/fundingRate': 1,
188
+ 'analytics/market/overview': 1,
189
+ 'explorer/search': 1,
190
+ 'explorer/transactions': 1,
191
+ 'explorer/blocks': 1,
192
+ },
193
+ },
194
+ 'private': {
195
+ 'get': {
196
+ 'api/order/{orderId}': 1,
197
+ 'api/orders': 1,
198
+ 'api/orders/oco/{parentOrderId}': 1,
199
+ 'api/trades': 1,
200
+ 'api/position/active': 1,
201
+ 'api/users/metadata/leverage': 1,
202
+ 'api/users/metadata/feeMultiplier': 1,
203
+ 'api/users/metadata/slippage': 1,
204
+ 'api/users/referral': 1,
205
+ 'api/users/apikeys': 1,
206
+ 'connection-signature-message/evm': 1,
207
+ 'api/users/profile/wallets': 1,
208
+ 'api/notifications': 1,
209
+ 'api/wallet/balance': 1,
210
+ 'api/wallet/transactions': 1,
211
+ 'api/analytics/user/overview': 1,
212
+ 'api/analytics/user/pnl': 1,
213
+ 'api/analytics/points/overview': 1,
214
+ 'api/analytics/points/history': 1,
215
+ },
216
+ 'post': {
217
+ 'api/order': 1,
218
+ 'api/position/oco': 1,
219
+ 'api/users/socket/listenKeys': 1,
220
+ 'api/users/metadata/leverage': 1,
221
+ 'api/users/metadata/feeMultiplier': 1,
222
+ 'api/users/metadata/slippage': 1,
223
+ 'api/users/referral/recordReferralSignup': 1,
224
+ 'api/users/apikeys': 1,
225
+ 'api/users/profile/wallets': 1,
226
+ 'api/transfers/withdrawal': 1,
227
+ 'api/transfers/bridge/withdrawal': 1,
228
+ },
229
+ 'put': {
230
+ 'api/position/updatePositionMargin': 1,
231
+ 'api/users/socket/listenKeys/{listenKey}': 1,
232
+ 'api/users/apikeys/{accessKey}/status': 1,
233
+ 'api/users/referral': 1,
234
+ },
235
+ 'patch': {
236
+ 'api/users/apikeys/{accessKey}': 1,
237
+ },
238
+ 'delete': {
239
+ 'api/orders/allOpen': 1,
240
+ 'api/order/{orderId}': 1,
241
+ 'api/position/{positionId}': 1,
242
+ 'api/position/all': 1,
243
+ 'api/users/socket/listenKeys/{listenKey}': 1,
244
+ 'api/users/apikeys/{accessKey}': 1,
245
+ },
246
+ },
247
+ },
248
+ },
249
+ 'fees': {
250
+ 'trading': {
251
+ 'tierBased': True,
252
+ 'percentage': True,
253
+ 'maker': self.parse_number('0.0002'),
254
+ 'taker': self.parse_number('0.0005'),
255
+ },
256
+ },
257
+ 'options': {
258
+ 'sandboxMode': False,
259
+ },
260
+ 'features': {
261
+ 'spot': None,
262
+ 'forDerivatives': {
263
+ 'sandbox': True,
264
+ 'createOrder': {
265
+ 'marginMode': False,
266
+ 'triggerPrice': True,
267
+ # todo implement
268
+ 'triggerPriceType': {
269
+ 'last': True,
270
+ 'mark': True,
271
+ 'index': False,
272
+ },
273
+ 'triggerDirection': False,
274
+ 'stopLossPrice': False, # todo
275
+ 'takeProfitPrice': False, # todo
276
+ 'attachedStopLossTakeProfit': None,
277
+ 'timeInForce': {
278
+ 'IOC': True,
279
+ 'FOK': True,
280
+ 'PO': True,
281
+ 'GTD': False,
282
+ },
283
+ 'hedged': False,
284
+ 'selfTradePrevention': False,
285
+ 'trailing': False,
286
+ 'iceberg': False,
287
+ 'leverage': False,
288
+ 'marketBuyByCost': False,
289
+ 'marketBuyRequiresPrice': False,
290
+ },
291
+ 'createOrders': None,
292
+ 'fetchMyTrades': {
293
+ 'marginMode': False,
294
+ 'limit': 1000,
295
+ 'daysBack': None,
296
+ 'untilDays': None,
297
+ },
298
+ 'fetchOrder': {
299
+ 'marginMode': False,
300
+ 'trigger': False,
301
+ 'trailing': False,
302
+ },
303
+ 'fetchOpenOrders': {
304
+ 'marginMode': True,
305
+ 'limit': 100,
306
+ 'trigger': False,
307
+ 'trailing': False,
308
+ },
309
+ 'fetchOrders': {
310
+ 'marginMode': False,
311
+ 'limit': 500,
312
+ 'daysBack': 100000,
313
+ 'untilDays': 100000,
314
+ 'trigger': False,
315
+ 'trailing': False,
316
+ },
317
+ 'fetchClosedOrders': {
318
+ 'marginMode': False,
319
+ 'limit': 500,
320
+ 'daysBack': 100000,
321
+ 'daysBackCanceled': 1,
322
+ 'untilDays': 100000,
323
+ 'trigger': False,
324
+ 'trailing': False,
325
+ },
326
+ 'fetchOHLCV': {
327
+ 'limit': 1000,
328
+ },
329
+ },
330
+ 'swap': {
331
+ 'linear': {
332
+ 'extends': 'forDerivatives',
333
+ },
334
+ 'inverse': None,
335
+ },
336
+ 'future': {
337
+ 'linear': None,
338
+ 'inverse': None,
339
+ },
340
+ },
341
+ 'commonCurrencies': {},
342
+ 'exceptions': {
343
+ 'exact': {
344
+ '404': BadRequest, # {"errorCode":404,"errorMessage":"Not Found"}
345
+ 'missing_auth_signature': AuthenticationError, # {"msg":"Missing auth signature","code":"missing_auth_signature"}
346
+ 'order_rejected': InvalidOrder, # {"success":false,"err":{"msg":"Order has already been rejected","code":"order_rejected"}}
347
+ 'invalid_order_id': InvalidOrder, # {"success":false,"err":{"msg":"Invalid order id","code":"invalid_order_id"}}
348
+ 'filter_lotsize_maxqty': InvalidOrder, # {"errorCode":"filter_lotsize_maxqty","errorMessage":"LOT_SIZE filter failed, quantity more than maxQty","errorData":{"maxQty":"5000.00"}}
349
+ 'filter_notional_min': InvalidOrder, # {"errorCode":"filter_notional_min","errorMessage":"NOTIONAL filter failed, Notional value of quote asset less than minNotional","errorData":{"minNotional":"100.00000000"}}
350
+ 'failed_index_price_up_multiplier_filter': InvalidOrder, # {"errorCode":"failed_index_price_up_multiplier_filter","errorMessage":"failed_index_price_up_multiplier_filter","errorData":{"maxPrice":"307.81241042"}}
351
+ 'no_open_orders': InvalidOrder, # {"errorMessage":"No open orders found","errorCode":"no_open_orders"}
352
+ 'active_position_not_found': InvalidOrder, # {"errorCode":"active_position_not_found","errorMessage":"Active position not found"}
353
+ 'position_inactive': InvalidOrder, # {"errorCode":"position_inactive","errorMessage":"Position is already inactive"}
354
+ 'invalid_position_id': InvalidOrder, # {"errorCode":"invalid_position_id","errorMessage":"Position id is invalid"}
355
+ 'Internal server error': ExchangeError, # {"msg":"Internal server error","code":"internal_server_error"}
356
+ },
357
+ 'broad': {
358
+ 'Bad Request': BadRequest, # {"errorMessage":"Bad Request","data":[{"param":"symbol","message":"\"symbol\" must be one of [ETH_USDC, BTC_USDC, BNB_USDC, SOL_USDC, DOGE_USDC, TON_USDC, AVAX_USDC, WIF_USDC, KPEPE_USDC, KSHIB_USDC, KBONK_USDC, MOODENG_USDC, POPCAT_USDC, MOTHER_USDC]"}]}
359
+ },
360
+ },
361
+ 'precisionMode': TICK_SIZE,
362
+ })
363
+
364
+ def fetch_status(self, params={}):
365
+ """
366
+ the latest known information on the availability of the exchange API
367
+
368
+ https://api-docs.defx.com/#4b03bb3b-a0fa-4dfb-b96c-237bde0ce9e6
369
+
370
+ :param dict [params]: extra parameters specific to the exchange API endpoint
371
+ :returns dict: a `status structure <https://docs.ccxt.com/#/?id=exchange-status-structure>`
372
+ """
373
+ response = self.v1PublicGetHealthcheckPing(params)
374
+ #
375
+ # {
376
+ # "success": True,
377
+ # "t": 1709705048323,
378
+ # "v": "0.0.7",
379
+ # "msg": "A programmer’s wife tells him, “While you’re at the grocery store, buy some eggs.” He never comes back."
380
+ # }
381
+ #
382
+ status = None
383
+ success = self.safe_bool(response, 'success')
384
+ if success:
385
+ status = 'ok'
386
+ else:
387
+ status = 'error'
388
+ return {
389
+ 'status': status,
390
+ 'updated': None,
391
+ 'eta': None,
392
+ 'url': None,
393
+ 'info': response,
394
+ }
395
+
396
+ def fetch_time(self, params={}):
397
+ """
398
+ fetches the current integer timestamp in milliseconds from the exchange server
399
+
400
+ https://api-docs.defx.com/#4b03bb3b-a0fa-4dfb-b96c-237bde0ce9e6
401
+
402
+ :param dict [params]: extra parameters specific to the exchange API endpoint
403
+ :returns int: the current integer timestamp in milliseconds from the exchange server
404
+ """
405
+ response = self.v1PublicGetHealthcheckPing(params)
406
+ #
407
+ # {
408
+ # "success": True,
409
+ # "t": 1709705048323,
410
+ # "v": "0.0.7",
411
+ # "msg": "A programmer’s wife tells him, “While you’re at the grocery store, buy some eggs.” He never comes back."
412
+ # }
413
+ #
414
+ return self.safe_integer(response, 't')
415
+
416
+ def fetch_markets(self, params={}) -> List[Market]:
417
+ """
418
+ retrieves data on all markets for defx
419
+
420
+ https://api-docs.defx.com/#73cce0c8-f842-4891-9145-01bb6d61324d
421
+ https://api-docs.defx.com/#24fd4e5b-840e-451e-99e0-7fea47c7f371
422
+
423
+ :param dict [params]: extra parameters specific to the exchange API endpoint
424
+ :returns dict[]: an array of objects representing market data
425
+ """
426
+ request = {
427
+ 'type': 'perps',
428
+ }
429
+ promises = [
430
+ self.v1PublicGetCMarkets(self.extend(request, params)),
431
+ self.v1PublicGetCMarketsMetadata(self.extend(request, params)),
432
+ ]
433
+ responses = promises
434
+ #
435
+ # {
436
+ # "data": [
437
+ # {
438
+ # "market": "DOGE_USDC",
439
+ # "candleWindows": [
440
+ # "1m",
441
+ # "3m",
442
+ # "5m",
443
+ # "15m",
444
+ # "30m",
445
+ # "1h",
446
+ # "2h",
447
+ # "4h",
448
+ # "12h",
449
+ # "1d",
450
+ # "1w",
451
+ # "1M"
452
+ # ],
453
+ # "depthSlabs": [
454
+ # "0.00001",
455
+ # "0.00005",
456
+ # "0.0001",
457
+ # "0.001",
458
+ # "0.01"
459
+ # ],
460
+ # "filters": [
461
+ # {
462
+ # "filterType": "LOT_SIZE",
463
+ # "minQty": "1.00000",
464
+ # "maxQty": "1500000.00000",
465
+ # "stepSize": "1.00000"
466
+ # },
467
+ # {
468
+ # "filterType": "MARKET_LOT_SIZE",
469
+ # "minQty": "1.00000",
470
+ # "maxQty": "750000.00000",
471
+ # "stepSize": "1.00000"
472
+ # },
473
+ # {
474
+ # "filterType": "PRICE_FILTER",
475
+ # "minPrice": "0.00244000",
476
+ # "maxPrice": "30.00000000",
477
+ # "tickSize": "0.00001"
478
+ # },
479
+ # {
480
+ # "filterType": "NOTIONAL",
481
+ # "minNotional": "100.00000000"
482
+ # },
483
+ # {
484
+ # "filterType": "PERCENT_PRICE_BY_SIDE",
485
+ # "bidMultiplierUp": "1.5",
486
+ # "bidMultiplierDown": "0.5",
487
+ # "askMultiplierUp": "1.5",
488
+ # "askMultiplierDown": "0.5"
489
+ # },
490
+ # {
491
+ # "filterType": "INDEX_PRICE_FILTER",
492
+ # "multiplierUp": "1.3",
493
+ # "multiplierDown": "0.7"
494
+ # }
495
+ # ],
496
+ # "cappedLeverage": "25",
497
+ # "maintenanceMarginTiers": [
498
+ # {
499
+ # "tier": "1",
500
+ # "minMaintenanceMargin": "0",
501
+ # "maxMaintenanceMargin": "2500",
502
+ # "leverage": "25"
503
+ # },
504
+ # {
505
+ # "tier": "2",
506
+ # "minMaintenanceMargin": "2500",
507
+ # "maxMaintenanceMargin": "12500",
508
+ # "leverage": "20"
509
+ # },
510
+ # {
511
+ # "tier": "3",
512
+ # "minMaintenanceMargin": "12500",
513
+ # "maxMaintenanceMargin": "25000",
514
+ # "leverage": "15"
515
+ # },
516
+ # {
517
+ # "tier": "4",
518
+ # "minMaintenanceMargin": "25000",
519
+ # "maxMaintenanceMargin": "50000",
520
+ # "leverage": "10"
521
+ # },
522
+ # {
523
+ # "tier": "5",
524
+ # "minMaintenanceMargin": "50000",
525
+ # "maxMaintenanceMargin": "75000",
526
+ # "leverage": "8"
527
+ # },
528
+ # {
529
+ # "tier": "6",
530
+ # "minMaintenanceMargin": "75000",
531
+ # "maxMaintenanceMargin": "125000",
532
+ # "leverage": "7"
533
+ # },
534
+ # {
535
+ # "tier": "7",
536
+ # "minMaintenanceMargin": "125000",
537
+ # "maxMaintenanceMargin": "187500",
538
+ # "leverage": "5"
539
+ # },
540
+ # {
541
+ # "tier": "8",
542
+ # "minMaintenanceMargin": "187500",
543
+ # "maxMaintenanceMargin": "250000",
544
+ # "leverage": "3"
545
+ # },
546
+ # {
547
+ # "tier": "9",
548
+ # "minMaintenanceMargin": "250000",
549
+ # "maxMaintenanceMargin": "375000",
550
+ # "leverage": "2"
551
+ # },
552
+ # {
553
+ # "tier": "10",
554
+ # "minMaintenanceMargin": "375000",
555
+ # "maxMaintenanceMargin": "500000",
556
+ # "leverage": "1"
557
+ # }
558
+ # ],
559
+ # "fees": {
560
+ # "maker": "0.08",
561
+ # "taker": "0.1"
562
+ # }
563
+ # },
564
+ # ]
565
+ # }
566
+ #
567
+ activeMarkets = self.safe_list(responses[0], 'data')
568
+ activeMarketsByType = self.index_by(activeMarkets, 'market')
569
+ marketMetadatas = self.safe_list(responses[1], 'data')
570
+ for i in range(0, len(marketMetadatas)):
571
+ marketId = marketMetadatas[i]['market']
572
+ status = None
573
+ if marketId in activeMarketsByType:
574
+ status = activeMarketsByType[marketId]['status']
575
+ marketMetadatas[i]['status'] = status
576
+ return self.parse_markets(marketMetadatas)
577
+
578
+ def parse_market(self, market: dict) -> Market:
579
+ marketId = self.safe_string(market, 'market')
580
+ parts = marketId.split('_')
581
+ baseId = self.safe_string(parts, 0)
582
+ quoteId = self.safe_string(parts, 1)
583
+ base = self.safe_currency_code(baseId)
584
+ quote = self.safe_currency_code(quoteId)
585
+ symbol = base + '/' + quote + ':' + quote
586
+ filters = self.safe_list(market, 'filters', [])
587
+ fees = self.safe_dict(market, 'fees', {})
588
+ filtersByType = self.index_by(filters, 'filterType')
589
+ priceFilter = self.safe_dict(filtersByType, 'PRICE_FILTER', {})
590
+ lotFilter = self.safe_dict(filtersByType, 'LOT_SIZE', {})
591
+ marketLotFilter = self.safe_dict(filtersByType, 'MARKET_LOT_SIZE', {})
592
+ notionalFilter = self.safe_dict(filtersByType, 'NOTIONAL', {})
593
+ return {
594
+ 'id': marketId,
595
+ 'symbol': symbol,
596
+ 'base': base,
597
+ 'quote': quote,
598
+ 'settle': quote,
599
+ 'baseId': baseId,
600
+ 'quoteId': quoteId,
601
+ 'settleId': quoteId,
602
+ 'type': 'swap',
603
+ 'spot': False,
604
+ 'margin': False,
605
+ 'swap': True,
606
+ 'future': False,
607
+ 'option': False,
608
+ 'active': self.safe_string(market, 'status', '') == 'active',
609
+ 'contract': True,
610
+ 'linear': True,
611
+ 'inverse': None,
612
+ 'taker': self.safe_number(fees, 'taker'),
613
+ 'maker': self.safe_number(fees, 'maker'),
614
+ 'contractSize': self.parse_number('1'),
615
+ 'expiry': None,
616
+ 'expiryDatetime': None,
617
+ 'strike': None,
618
+ 'optionType': None,
619
+ 'precision': {
620
+ 'amount': self.safe_number(lotFilter, 'stepSize'),
621
+ 'price': self.safe_number(priceFilter, 'tickSize'),
622
+ },
623
+ 'limits': {
624
+ 'leverage': {
625
+ 'min': None,
626
+ 'max': self.safe_number(market, 'cappedLeverage'),
627
+ },
628
+ 'amount': {
629
+ 'min': self.safe_number(lotFilter, 'minQty'),
630
+ 'max': self.safe_number(lotFilter, 'maxQty'),
631
+ },
632
+ 'price': {
633
+ 'min': self.safe_number(priceFilter, 'minPrice'),
634
+ 'max': self.safe_number(priceFilter, 'maxPrice'),
635
+ },
636
+ 'cost': {
637
+ 'min': self.safe_number(notionalFilter, 'minNotional'),
638
+ 'max': None,
639
+ },
640
+ 'market': {
641
+ 'min': self.safe_number(marketLotFilter, 'minQty'),
642
+ 'max': self.safe_number(marketLotFilter, 'maxQty'),
643
+ },
644
+ },
645
+ 'created': None,
646
+ 'info': market,
647
+ }
648
+
649
+ def fetch_ticker(self, symbol: str, params={}) -> Ticker:
650
+ """
651
+ fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
652
+
653
+ https://api-docs.defx.com/#fe6f81d0-2f3a-4eee-976f-c8fc8f4c5d56
654
+
655
+ :param str symbol: unified symbol of the market to fetch the ticker for
656
+ :param dict [params]: extra parameters specific to the exchange API endpoint
657
+ :returns dict: a `ticker structure <https://docs.ccxt.com/#/?id=ticker-structure>`
658
+ """
659
+ self.load_markets()
660
+ market = self.market(symbol)
661
+ request: dict = {
662
+ 'symbol': market['id'],
663
+ }
664
+ response = self.v1PublicGetSymbolsSymbolTicker24hr(self.extend(request, params))
665
+ #
666
+ # {
667
+ # "symbol": "BTC_USDC",
668
+ # "priceChange": "0",
669
+ # "priceChangePercent": "0",
670
+ # "weightedAvgPrice": "0",
671
+ # "lastPrice": "2.00",
672
+ # "lastQty": "10.000",
673
+ # "bestBidPrice": "1646.00",
674
+ # "bestBidQty": "10.000",
675
+ # "bestAskPrice": "1646.00",
676
+ # "bestAskQty": "10.000",
677
+ # "openPrice": "0.00",
678
+ # "highPrice": "0.00",
679
+ # "lowPrice": "0.00",
680
+ # "volume": "0.000",
681
+ # "quoteVolume": "0.00",
682
+ # "openTime": 1700142658697,
683
+ # "closeTime": 1700142658697,
684
+ # "openInterestBase": "1.000",
685
+ # "openInterestQuote": "0.43112300"
686
+ # }
687
+ #
688
+ return self.parse_ticker(response, market)
689
+
690
+ def fetch_tickers(self, symbols: Strings = None, params={}) -> Tickers:
691
+ """
692
+ fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
693
+
694
+ https://api-docs.defx.com/#8c61cfbd-40d9-410e-b014-f5b36eba51d1
695
+
696
+ :param str[]|None symbols: unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned
697
+ :param dict [params]: extra parameters specific to the exchange API endpoint
698
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
699
+ """
700
+ self.load_markets()
701
+ market = None
702
+ if symbols is not None:
703
+ symbols = self.market_symbols(symbols)
704
+ firstSymbol = self.safe_string(symbols, 0)
705
+ if firstSymbol is not None:
706
+ market = self.market(firstSymbol)
707
+ type = None
708
+ type, params = self.handle_market_type_and_params('fetchTickers', market, params)
709
+ if type == 'spot':
710
+ raise NotSupported(self.id + ' fetchTickers() is not supported for ' + type + ' markets')
711
+ response = self.v1PublicGetTicker24HrAgg(params)
712
+ #
713
+ # {
714
+ # "ETH_USDC": {
715
+ # "priceChange": "0",
716
+ # "priceChangePercent": "0",
717
+ # "openPrice": "1646.15",
718
+ # "highPrice": "1646.15",
719
+ # "lowPrice": "1646.15",
720
+ # "lastPrice": "1646.15",
721
+ # "quoteVolume": "13.17",
722
+ # "volume": "0.008",
723
+ # "markPrice": "1645.15"
724
+ # }
725
+ # }
726
+ #
727
+ return self.parse_tickers(response, symbols)
728
+
729
+ def parse_ticker(self, ticker: dict, market: Market = None) -> Ticker:
730
+ #
731
+ # fetchTicker
732
+ #
733
+ # {
734
+ # "symbol": "BTC_USDC",
735
+ # "priceChange": "0",
736
+ # "priceChangePercent": "0",
737
+ # "weightedAvgPrice": "0",
738
+ # "lastPrice": "2.00",
739
+ # "lastQty": "10.000",
740
+ # "bestBidPrice": "1646.00",
741
+ # "bestBidQty": "10.000",
742
+ # "bestAskPrice": "1646.00",
743
+ # "bestAskQty": "10.000",
744
+ # "openPrice": "0.00",
745
+ # "highPrice": "0.00",
746
+ # "lowPrice": "0.00",
747
+ # "volume": "0.000",
748
+ # "quoteVolume": "0.00",
749
+ # "openTime": 1700142658697,
750
+ # "closeTime": 1700142658697,
751
+ # "openInterestBase": "1.000",
752
+ # "openInterestQuote": "0.43112300"
753
+ # }
754
+ #
755
+ # fetchTickers
756
+ #
757
+ # "ETH_USDC": {
758
+ # "priceChange": "0",
759
+ # "priceChangePercent": "0",
760
+ # "openPrice": "1646.15",
761
+ # "highPrice": "1646.15",
762
+ # "lowPrice": "1646.15",
763
+ # "lastPrice": "1646.15",
764
+ # "quoteVolume": "13.17",
765
+ # "volume": "0.008",
766
+ # "markPrice": "1645.15"
767
+ # }
768
+ #
769
+ # fetchMarkPrice
770
+ #
771
+ # {
772
+ # "markPrice": "100.00",
773
+ # "indexPrice": "100.00",
774
+ # "ltp": "101.34",
775
+ # "movingFundingRate": "0.08",
776
+ # "payoutFundingRate": "-0.03",
777
+ # "nextFundingPayout": 1711555532146
778
+ # }
779
+ #
780
+ marketId = self.safe_string(ticker, 'symbol')
781
+ if marketId is not None:
782
+ market = self.market(marketId)
783
+ symbol = market['symbol']
784
+ open = self.safe_string(ticker, 'openPrice')
785
+ high = self.safe_string(ticker, 'highPrice')
786
+ low = self.safe_string(ticker, 'lowPrice')
787
+ close = self.safe_string(ticker, 'lastPrice')
788
+ quoteVolume = self.safe_string(ticker, 'quoteVolume')
789
+ baseVolume = self.safe_string(ticker, 'volume')
790
+ percentage = self.safe_string(ticker, 'priceChangePercent')
791
+ change = self.safe_string(ticker, 'priceChange')
792
+ ts = self.safe_integer(ticker, 'closeTime')
793
+ if ts == 0:
794
+ ts = None
795
+ datetime = self.iso8601(ts)
796
+ bid = self.safe_string(ticker, 'bestBidPrice')
797
+ bidVolume = self.safe_string(ticker, 'bestBidQty')
798
+ ask = self.safe_string(ticker, 'bestAskPrice')
799
+ askVolume = self.safe_string(ticker, 'bestAskQty')
800
+ return self.safe_ticker({
801
+ 'symbol': symbol,
802
+ 'timestamp': ts,
803
+ 'datetime': datetime,
804
+ 'high': high,
805
+ 'low': low,
806
+ 'bid': bid,
807
+ 'bidVolume': bidVolume,
808
+ 'ask': ask,
809
+ 'askVolume': askVolume,
810
+ 'vwap': None,
811
+ 'open': open,
812
+ 'close': close,
813
+ 'last': None,
814
+ 'previousClose': None,
815
+ 'change': change,
816
+ 'percentage': percentage,
817
+ 'average': None,
818
+ 'baseVolume': baseVolume,
819
+ 'quoteVolume': quoteVolume,
820
+ 'markPrice': self.safe_string(ticker, 'markPrice'),
821
+ 'indexPrice': self.safe_string(ticker, 'indexPrice'),
822
+ 'info': ticker,
823
+ }, market)
824
+
825
+ def fetch_ohlcv(self, symbol: str, timeframe='1m', since: Int = None, limit: Int = None, params={}) -> List[list]:
826
+ """
827
+
828
+ https://api-docs.defx.com/#54b71951-1472-4670-b5af-4c2dc41e73d0
829
+
830
+ fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
831
+ :param str symbol: unified symbol of the market to fetch OHLCV data for
832
+ :param str timeframe: the length of time each candle represents
833
+ :param int [since]: timestamp in ms of the earliest candle to fetch
834
+ :param int [limit]: max=1000, max=100 when since is defined and is less than(now - (999 * (timeframe in ms)))
835
+ :param dict [params]: extra parameters specific to the exchange API endpoint
836
+ :param int [params.until]: the latest time in ms to fetch orders for
837
+ :returns int[][]: A list of candles ordered, open, high, low, close, volume
838
+ """
839
+ self.load_markets()
840
+ market = self.market(symbol)
841
+ maxLimit = 1000
842
+ if limit is None:
843
+ limit = maxLimit
844
+ limit = min(maxLimit, limit)
845
+ request: dict = {
846
+ 'symbol': market['id'],
847
+ 'interval': self.safe_string(self.timeframes, timeframe, timeframe),
848
+ 'limit': limit,
849
+ }
850
+ until = self.safe_integer_2(params, 'until', 'till')
851
+ params = self.omit(params, ['until', 'till'])
852
+ request['endTime'] = self.milliseconds() if (until is None) else until
853
+ if since is None:
854
+ request['startTime'] = 0
855
+ else:
856
+ request['startTime'] = since
857
+ if until is None:
858
+ timeframeInSeconds = self.parse_timeframe(timeframe)
859
+ timeframeInMilliseconds = timeframeInSeconds * 1000
860
+ totalTimeframeInMilliseconds = limit * timeframeInMilliseconds
861
+ request['endTime'] = self.sum(since, totalTimeframeInMilliseconds)
862
+ response = self.v1PublicGetSymbolsSymbolOhlc(self.extend(request, params))
863
+ #
864
+ # [
865
+ # {
866
+ # "symbol": "BTC_USDC",
867
+ # "open": "0.00",
868
+ # "high": "0.00",
869
+ # "low": "0.00",
870
+ # "close": "0.00",
871
+ # "volume": "0.000",
872
+ # "quoteAssetVolume": "0.00",
873
+ # "takerBuyAssetVolume": "0.000",
874
+ # "takerBuyQuoteAssetVolume": "0.00",
875
+ # "numberOfTrades": 0,
876
+ # "start": 1702453663894,
877
+ # "end": 1702453663894,
878
+ # "isClosed": True
879
+ # }
880
+ # ]
881
+ #
882
+ return self.parse_ohlcvs(response, market, timeframe, since, limit)
883
+
884
+ def parse_ohlcv(self, ohlcv, market: Market = None) -> list:
885
+ # example response in fetchOHLCV
886
+ return [
887
+ self.safe_integer(ohlcv, 'start'),
888
+ self.safe_number(ohlcv, 'open'),
889
+ self.safe_number(ohlcv, 'high'),
890
+ self.safe_number(ohlcv, 'low'),
891
+ self.safe_number(ohlcv, 'close'),
892
+ self.safe_number(ohlcv, 'volume'),
893
+ ]
894
+
895
+ def fetch_trades(self, symbol: str, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
896
+ """
897
+ get the list of most recent trades for a particular symbol
898
+
899
+ https://api-docs.defx.com/#5865452f-ea32-4f13-bfbc-03af5f5574fd
900
+
901
+ :param str symbol: unified symbol of the market to fetch trades for
902
+ :param int [since]: timestamp in ms of the earliest trade to fetch
903
+ :param int [limit]: the maximum amount of trades to fetch
904
+ :param dict [params]: extra parameters specific to the exchange API endpoint
905
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
906
+ """
907
+ self.load_markets()
908
+ market = self.market(symbol)
909
+ maxLimit = 50
910
+ if limit is None:
911
+ limit = maxLimit
912
+ limit = min(maxLimit, limit)
913
+ request: dict = {
914
+ 'symbol': market['id'],
915
+ 'limit': limit,
916
+ }
917
+ response = self.v1PublicGetSymbolsSymbolTrades(self.extend(request, params))
918
+ #
919
+ # [
920
+ # {
921
+ # "buyerMaker": "false",
922
+ # "price": "2.0000",
923
+ # "qty": "10.0000",
924
+ # "symbol": "BTC_USDC",
925
+ # "timestamp": "1702453663894"
926
+ # }
927
+ # ]
928
+ #
929
+ return self.parse_trades(response, market, since, limit)
930
+
931
+ def fetch_my_trades(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Trade]:
932
+ """
933
+ fetch all trades made by the user
934
+
935
+ https://api-docs.defx.com/#06b5b33c-2fc6-48de-896c-fc316f5871a7
936
+
937
+ :param str symbol: unified symbol of the market to fetch trades for
938
+ :param int [since]: timestamp in ms of the earliest trade to fetch
939
+ :param int [limit]: the maximum amount of trades to fetch
940
+ :param dict [params]: extra parameters specific to the exchange API endpoint
941
+ :returns Trade[]: a list of `trade structures <https://docs.ccxt.com/#/?id=public-trades>`
942
+ """
943
+ self.load_markets()
944
+ request: dict = {}
945
+ if symbol is not None:
946
+ market = self.market(symbol)
947
+ request['symbols'] = market['id']
948
+ if limit is not None:
949
+ maxLimit = 100
950
+ limit = min(maxLimit, limit)
951
+ request['pageSize'] = limit
952
+ response = self.v1PrivateGetApiTrades(self.extend(request, params))
953
+ #
954
+ # {
955
+ # "data": [
956
+ # {
957
+ # "id": "0192f665-c05b-7ba0-a080-8b6c99083489",
958
+ # "orderId": "757730811259651728",
959
+ # "time": "2024-11-04T08:58:36.474Z",
960
+ # "symbol": "SOL_USDC",
961
+ # "side": "SELL",
962
+ # "price": "160.43600000",
963
+ # "qty": "1.00",
964
+ # "fee": "0.08823980",
965
+ # "role": "TAKER",
966
+ # "pnl": "0.00000000"
967
+ # }
968
+ # ]
969
+ # }
970
+ #
971
+ data = self.safe_list(response, 'data', [])
972
+ return self.parse_trades(data, None, since, limit)
973
+
974
+ def parse_trade(self, trade: dict, market: Market = None) -> Trade:
975
+ #
976
+ # fetchTrades
977
+ # {
978
+ # "buyerMaker": "false",
979
+ # "price": "2.0000",
980
+ # "qty": "10.0000",
981
+ # "symbol": "BTC_USDC",
982
+ # "timestamp": "1702453663894"
983
+ # }
984
+ #
985
+ # fetchMyTrades
986
+ # {
987
+ # "id": "0192f665-c05b-7ba0-a080-8b6c99083489",
988
+ # "orderId": "757730811259651728",
989
+ # "time": "2024-11-04T08:58:36.474Z",
990
+ # "symbol": "SOL_USDC",
991
+ # "side": "SELL",
992
+ # "price": "160.43600000",
993
+ # "qty": "1.00",
994
+ # "fee": "0.08823980",
995
+ # "role": "TAKER",
996
+ # "pnl": "0.00000000"
997
+ # }
998
+ #
999
+ time = self.safe_string(trade, 'time')
1000
+ timestamp = self.safe_integer(trade, 'timestamp', self.parse8601(time))
1001
+ marketId = self.safe_string(trade, 'symbol')
1002
+ market = self.safe_market(marketId, market)
1003
+ symbol = market['symbol']
1004
+ price = self.safe_string(trade, 'price')
1005
+ amount = self.safe_string(trade, 'qty')
1006
+ id = self.safe_string(trade, 'id')
1007
+ oid = self.safe_string(trade, 'orderId')
1008
+ takerOrMaker = self.safe_string_lower(trade, 'role')
1009
+ buyerMaker = self.safe_bool(trade, 'buyerMaker')
1010
+ side = self.safe_string_lower(trade, 'side')
1011
+ if buyerMaker is not None:
1012
+ if buyerMaker:
1013
+ side = 'sell'
1014
+ else:
1015
+ side = 'buy'
1016
+ return self.safe_trade({
1017
+ 'id': id,
1018
+ 'timestamp': timestamp,
1019
+ 'datetime': self.iso8601(timestamp),
1020
+ 'symbol': symbol,
1021
+ 'side': side,
1022
+ 'price': price,
1023
+ 'amount': amount,
1024
+ 'cost': None,
1025
+ 'order': oid,
1026
+ 'takerOrMaker': takerOrMaker,
1027
+ 'type': None,
1028
+ 'fee': {
1029
+ 'cost': self.safe_string(trade, 'fee'),
1030
+ 'currency': 'USDC',
1031
+ },
1032
+ 'info': trade,
1033
+ }, market)
1034
+
1035
+ def fetch_order_book(self, symbol: str, limit: Int = None, params={}) -> OrderBook:
1036
+ """
1037
+ fetches information on open orders with bid(buy) and ask(sell) prices, volumes and other data
1038
+
1039
+ https://api-docs.defx.com/#6c1a2971-8325-4e7d-9962-e0bfcaacf9c4
1040
+
1041
+ :param str symbol: unified symbol of the market to fetch the order book for
1042
+ :param int [limit]: the maximum amount of order book entries to return
1043
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1044
+ :param str [params.slab]: slab from market.info.depthSlabs
1045
+ :returns dict: A dictionary of `order book structures <https://docs.ccxt.com/#/?id=order-book-structure>` indexed by market symbols
1046
+ """
1047
+ self.load_markets()
1048
+ market = self.market(symbol)
1049
+ if limit is None:
1050
+ limit = 10 # limit must be one of [5, 10, 20]
1051
+ marketInfo = self.safe_dict(market, 'info', {})
1052
+ slab = self.safe_list(marketInfo, 'depthSlabs', [])
1053
+ request: dict = {
1054
+ 'symbol': market['id'],
1055
+ 'level': limit,
1056
+ 'slab': self.safe_string(slab, 0),
1057
+ }
1058
+ response = self.v1PublicGetSymbolsSymbolDepthLevelSlab(self.extend(request, params))
1059
+ #
1060
+ # {
1061
+ # "symbol": "ETH_USDC",
1062
+ # "level": "5",
1063
+ # "slab": "1",
1064
+ # "lastTradeTimestamp": "1708313446812",
1065
+ # "timestamp": "1708313446812",
1066
+ # "bids": [
1067
+ # {
1068
+ # "price": "1646.16",
1069
+ # "qty": "0.001"
1070
+ # }
1071
+ # ],
1072
+ # "asks": [
1073
+ # {
1074
+ # "price": "1646.16",
1075
+ # "qty": "0.001"
1076
+ # }
1077
+ # ]
1078
+ # }
1079
+ #
1080
+ timestamp = self.safe_integer(response, 'timestamp')
1081
+ return self.parse_order_book(response, symbol, timestamp, 'bids', 'asks', 'price', 'qty')
1082
+
1083
+ def fetch_mark_price(self, symbol: str, params={}) -> Ticker:
1084
+ """
1085
+ fetches mark price for the market
1086
+
1087
+ https://api-docs.defx.com/#12168192-4e7b-4458-a001-e8b80961f0b7
1088
+
1089
+ :param str symbol: unified symbol of the market to fetch the ticker for
1090
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1091
+ :param str [params.subType]: "linear" or "inverse"
1092
+ :returns dict: a dictionary of `ticker structures <https://docs.ccxt.com/#/?id=ticker-structure>`
1093
+ """
1094
+ self.load_markets()
1095
+ market = self.market(symbol)
1096
+ request = {
1097
+ 'symbol': market['id'],
1098
+ }
1099
+ response = self.v1PublicGetSymbolsSymbolPrices(self.extend(request, params))
1100
+ #
1101
+ # {
1102
+ # "markPrice": "100.00",
1103
+ # "indexPrice": "100.00",
1104
+ # "ltp": "101.34",
1105
+ # "movingFundingRate": "0.08",
1106
+ # "payoutFundingRate": "-0.03",
1107
+ # "nextFundingPayout": 1711555532146
1108
+ # }
1109
+ #
1110
+ return self.parse_ticker(response, market)
1111
+
1112
+ def fetch_funding_rate(self, symbol: str, params={}) -> FundingRate:
1113
+ """
1114
+ fetch the current funding rate
1115
+
1116
+ https://api-docs.defx.com/#12168192-4e7b-4458-a001-e8b80961f0b7
1117
+
1118
+ :param str symbol: unified market symbol
1119
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1120
+ :returns dict: a `funding rate structure <https://docs.ccxt.com/#/?id=funding-rate-structure>`
1121
+ """
1122
+ self.load_markets()
1123
+ market = self.market(symbol)
1124
+ request = {
1125
+ 'symbol': market['id'],
1126
+ }
1127
+ response = self.v1PublicGetSymbolsSymbolPrices(self.extend(request, params))
1128
+ #
1129
+ # {
1130
+ # "markPrice": "100.00",
1131
+ # "indexPrice": "100.00",
1132
+ # "ltp": "101.34",
1133
+ # "movingFundingRate": "0.08",
1134
+ # "payoutFundingRate": "-0.03",
1135
+ # "nextFundingPayout": 1711555532146
1136
+ # }
1137
+ #
1138
+ return self.parse_funding_rate(response, market)
1139
+
1140
+ def parse_funding_rate(self, contract, market: Market = None) -> FundingRate:
1141
+ #
1142
+ # {
1143
+ # "markPrice": "100.00",
1144
+ # "indexPrice": "100.00",
1145
+ # "ltp": "101.34",
1146
+ # "movingFundingRate": "0.08",
1147
+ # "payoutFundingRate": "-0.03",
1148
+ # "nextFundingPayout": 1711555532146
1149
+ # }
1150
+ #
1151
+ markPrice = self.safe_number(contract, 'markPrice')
1152
+ indexPrice = self.safe_number(contract, 'indexPrice')
1153
+ fundingRate = self.safe_number(contract, 'payoutFundingRate')
1154
+ fundingTime = self.safe_integer(contract, 'nextFundingPayout')
1155
+ return {
1156
+ 'info': contract,
1157
+ 'symbol': market['symbol'],
1158
+ 'markPrice': markPrice,
1159
+ 'indexPrice': indexPrice,
1160
+ 'interestRate': None,
1161
+ 'estimatedSettlePrice': None,
1162
+ 'timestamp': None,
1163
+ 'datetime': None,
1164
+ 'fundingRate': fundingRate,
1165
+ 'fundingTimestamp': fundingTime,
1166
+ 'fundingDatetime': self.iso8601(fundingTime),
1167
+ 'nextFundingRate': None,
1168
+ 'nextFundingTimestamp': None,
1169
+ 'nextFundingDatetime': None,
1170
+ 'previousFundingRate': None,
1171
+ 'previousFundingTimestamp': None,
1172
+ 'previousFundingDatetime': None,
1173
+ 'interval': None,
1174
+ }
1175
+
1176
+ def fetch_balance(self, params={}) -> Balances:
1177
+ """
1178
+ query for balance and get the amount of funds available for trading or funds locked in orders
1179
+
1180
+ https://api-docs.defx.com/#26414338-14f7-40a1-b246-f8ea8571493f
1181
+
1182
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1183
+ :returns dict: a `balance structure <https://docs.ccxt.com/#/?id=balance-structure>`
1184
+ """
1185
+ self.load_markets()
1186
+ response = self.v1PrivateGetApiWalletBalance(params)
1187
+ #
1188
+ # {
1189
+ # "assets": [
1190
+ # {
1191
+ # "asset": "USDC",
1192
+ # "balance": "0.000"
1193
+ # }
1194
+ # ]
1195
+ # }
1196
+ #
1197
+ data = self.safe_list(response, 'assets')
1198
+ return self.parse_balance(data)
1199
+
1200
+ def parse_balance(self, balances) -> Balances:
1201
+ result: dict = {
1202
+ 'info': balances,
1203
+ }
1204
+ for i in range(0, len(balances)):
1205
+ balance = balances[i]
1206
+ code = self.safe_currency_code(self.safe_string(balance, 'asset'))
1207
+ account = self.account()
1208
+ account['total'] = self.safe_string(balance, 'balance')
1209
+ result[code] = account
1210
+ return self.safe_balance(result)
1211
+
1212
+ def create_order(self, symbol: str, type: OrderType, side: OrderSide, amount: float, price: Num = None, params={}):
1213
+ """
1214
+ create a trade order
1215
+
1216
+ https://api-docs.defx.com/#ba222d88-8856-4d3c-87a9-7cec07bb2622
1217
+
1218
+ :param str symbol: unified symbol of the market to create an order in
1219
+ :param str type: 'market' or 'limit'
1220
+ :param str side: 'buy' or 'sell'
1221
+ :param float amount: how much of currency you want to trade in units of base currency
1222
+ :param float [price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1223
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1224
+ :param float [params.triggerPrice]: The price a trigger order is triggered at
1225
+ :param str [params.reduceOnly]: for swap and future reduceOnly is a string 'true' or 'false' that cant be sent with close position set to True or in hedge mode. For spot margin and option reduceOnly is a boolean.
1226
+ :returns dict: an `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1227
+ """
1228
+ self.load_markets()
1229
+ market = self.market(symbol)
1230
+ reduceOnly = self.safe_bool_2(params, 'reduceOnly', 'reduce_only')
1231
+ params = self.omit(params, ['reduceOnly', 'reduce_only'])
1232
+ orderType = type.upper()
1233
+ orderSide = side.upper()
1234
+ request: dict = {
1235
+ 'symbol': market['id'],
1236
+ 'side': orderSide,
1237
+ 'type': orderType,
1238
+ }
1239
+ takeProfitPrice = self.safe_string(params, 'takeProfitPrice')
1240
+ triggerPrice = self.safe_string_2(params, 'stopPrice', 'triggerPrice')
1241
+ isMarket = orderType == 'MARKET'
1242
+ isLimit = orderType == 'LIMIT'
1243
+ timeInForce = self.safe_string_upper(params, 'timeInForce')
1244
+ if timeInForce is not None:
1245
+ # GTC, IOC, FOK, AON
1246
+ request['timeInForce'] = timeInForce
1247
+ else:
1248
+ if isLimit:
1249
+ request['timeInForce'] = 'GTC'
1250
+ if reduceOnly:
1251
+ request['reduceOnly'] = reduceOnly
1252
+ clientOrderId = self.safe_string(params, 'clientOrderId')
1253
+ if clientOrderId is not None:
1254
+ request['newClientOrderId'] = clientOrderId
1255
+ if triggerPrice is not None or takeProfitPrice is not None:
1256
+ request['workingType'] = 'MARK_PRICE'
1257
+ if takeProfitPrice is not None:
1258
+ request['stopPrice'] = self.price_to_precision(symbol, takeProfitPrice)
1259
+ if isMarket:
1260
+ request['type'] = 'TAKE_PROFIT_MARKET'
1261
+ else:
1262
+ request['type'] = 'TAKE_PROFIT_LIMIT'
1263
+ else:
1264
+ request['stopPrice'] = self.price_to_precision(symbol, triggerPrice)
1265
+ if isMarket:
1266
+ request['type'] = 'STOP_MARKET'
1267
+ else:
1268
+ request['type'] = 'STOP_LIMIT'
1269
+ if isLimit and price is not None:
1270
+ request['price'] = self.price_to_precision(symbol, price)
1271
+ request['quantity'] = self.amount_to_precision(symbol, amount)
1272
+ params = self.omit(params, ['clOrdID', 'clientOrderId', 'client_order_id', 'postOnly', 'timeInForce', 'stopPrice', 'triggerPrice', 'takeProfitPrice'])
1273
+ response = self.v1PrivatePostApiOrder(self.extend(request, params))
1274
+ #
1275
+ # {
1276
+ # "success": True,
1277
+ # "data": {
1278
+ # "orderId": "",
1279
+ # "clientOrderId": "",
1280
+ # "cumulativeQty": "",
1281
+ # "cumulativeQuote": "",
1282
+ # "executedQty": "",
1283
+ # "avgPrice": "",
1284
+ # "origQty": "",
1285
+ # "price": "",
1286
+ # "reduceOnly": True,
1287
+ # "side": "",
1288
+ # "status": "",
1289
+ # "symbol": "",
1290
+ # "timeInForce": "",
1291
+ # "type": "",
1292
+ # "workingType": ""
1293
+ # }
1294
+ # }
1295
+ #
1296
+ data = self.safe_dict(response, 'data')
1297
+ return self.parse_order(data, market)
1298
+
1299
+ def parse_order_status(self, status: Str):
1300
+ if status is not None:
1301
+ statuses: dict = {
1302
+ 'NEW': 'open',
1303
+ 'OPEN': 'open',
1304
+ 'CANCELLED': 'canceled',
1305
+ 'REJECTED': 'rejected',
1306
+ 'FILLED': 'closed',
1307
+ }
1308
+ return self.safe_string(statuses, status, status)
1309
+ return status
1310
+
1311
+ def parse_order(self, order: dict, market: Market = None) -> Order:
1312
+ #
1313
+ # {
1314
+ # "orderId": "746472647227344528",
1315
+ # "createdAt": "2024-10-25T16:49:31.077Z",
1316
+ # "updatedAt": "2024-10-25T16:49:31.378Z",
1317
+ # "clientOrderId": "0192c495-49c3-71ee-b3d3-7442a2090807",
1318
+ # "reduceOnly": False,
1319
+ # "side": "SELL",
1320
+ # "status": "FILLED",
1321
+ # "symbol": "SOL_USDC",
1322
+ # "timeInForce": "GTC",
1323
+ # "type": "MARKET",
1324
+ # "origQty": "0.80",
1325
+ # "executedQty": "0.80",
1326
+ # "cumulativeQuote": "137.87440000",
1327
+ # "avgPrice": "172.34300000",
1328
+ # "totalPnL": "0.00000000",
1329
+ # "totalFee": "0.07583092",
1330
+ # "workingType": null,
1331
+ # "postOnly": False,
1332
+ # "linkedOrderParentType": null,
1333
+ # "isTriggered": False,
1334
+ # "slippagePercentage": "5"
1335
+ # }
1336
+ #
1337
+ orderId = self.safe_string(order, 'orderId')
1338
+ clientOrderId = self.safe_string(order, 'clientOrderId')
1339
+ marketId = self.safe_string(order, 'symbol')
1340
+ market = self.safe_market(marketId, market)
1341
+ symbol = market['symbol']
1342
+ price = self.safe_string(order, 'price')
1343
+ amount = self.safe_string(order, 'origQty')
1344
+ orderType = self.safe_string_lower(order, 'type')
1345
+ status = self.safe_string(order, 'status')
1346
+ side = self.safe_string_lower(order, 'side')
1347
+ filled = self.omit_zero(self.safe_string(order, 'executedQty'))
1348
+ average = self.omit_zero(self.safe_string(order, 'avgPrice'))
1349
+ timeInForce = self.safe_string_lower(order, 'timeInForce')
1350
+ takeProfitPrice: Str = None
1351
+ triggerPrice: Str = None
1352
+ if orderType is not None:
1353
+ if orderType.find('take_profit') >= 0:
1354
+ takeProfitPrice = self.safe_string(order, 'stopPrice')
1355
+ else:
1356
+ triggerPrice = self.safe_string(order, 'stopPrice')
1357
+ timestamp = self.parse8601(self.safe_string(order, 'createdAt'))
1358
+ lastTradeTimestamp = self.parse8601(self.safe_string(order, 'updatedAt'))
1359
+ return self.safe_order({
1360
+ 'id': orderId,
1361
+ 'clientOrderId': clientOrderId,
1362
+ 'timestamp': timestamp,
1363
+ 'datetime': self.iso8601(timestamp),
1364
+ 'lastTradeTimestamp': lastTradeTimestamp,
1365
+ 'lastUpdateTimestamp': lastTradeTimestamp,
1366
+ 'status': self.parse_order_status(status),
1367
+ 'symbol': symbol,
1368
+ 'type': orderType,
1369
+ 'timeInForce': timeInForce,
1370
+ 'postOnly': self.safe_bool(order, 'postOnly'),
1371
+ 'reduceOnly': self.safe_bool(order, 'reduceOnly'),
1372
+ 'side': side,
1373
+ 'price': price,
1374
+ 'triggerPrice': triggerPrice,
1375
+ 'takeProfitPrice': takeProfitPrice,
1376
+ 'stopLossPrice': None,
1377
+ 'average': average,
1378
+ 'amount': amount,
1379
+ 'filled': filled,
1380
+ 'remaining': None,
1381
+ 'cost': None,
1382
+ 'trades': None,
1383
+ 'fee': {
1384
+ 'cost': self.safe_string(order, 'totalFee'),
1385
+ 'currency': 'USDC',
1386
+ },
1387
+ 'info': order,
1388
+ }, market)
1389
+
1390
+ def cancel_order(self, id: str, symbol: Str = None, params={}):
1391
+ """
1392
+
1393
+ https://api-docs.defx.com/#09186f23-f8d1-4993-acf4-9974d8a6ddb0
1394
+
1395
+ cancels an open order
1396
+ :param str id: order id
1397
+ :param str symbol: unified symbol of the market the order was made in
1398
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1399
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1400
+ """
1401
+ self.load_markets()
1402
+ request: dict = {
1403
+ 'orderId': id,
1404
+ 'idType': 'orderId',
1405
+ }
1406
+ clientOrderId = self.safe_string_n(params, ['clOrdID', 'clientOrderId', 'client_order_id'])
1407
+ isByClientOrder = clientOrderId is not None
1408
+ if isByClientOrder:
1409
+ if symbol is None:
1410
+ raise ArgumentsRequired(self.id + ' cancelOrder() requires a symbol argument')
1411
+ market = self.market(symbol)
1412
+ request['orderId'] = clientOrderId
1413
+ request['idType'] = 'clientOrderId'
1414
+ request['symbol'] = market['id']
1415
+ params = self.omit(params, ['clOrdID', 'clientOrderId', 'client_order_id'])
1416
+ response = self.v1PrivateDeleteApiOrderOrderId(self.extend(request, params))
1417
+ #
1418
+ # {
1419
+ # "success": True
1420
+ # }
1421
+ #
1422
+ extendParams: dict = {'symbol': symbol}
1423
+ if isByClientOrder:
1424
+ extendParams['clientOrderId'] = clientOrderId
1425
+ else:
1426
+ extendParams['id'] = id
1427
+ return self.extend(self.parse_order(response), extendParams)
1428
+
1429
+ def cancel_all_orders(self, symbol: Str = None, params={}):
1430
+ """
1431
+ cancel all open orders
1432
+
1433
+ https://api-docs.defx.com/#db5531da-3692-4a53-841f-6ad6495f823a
1434
+
1435
+ :param str symbol: unified market symbol, only orders in the market of self symbol are cancelled when symbol is not None
1436
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1437
+ :returns dict[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1438
+ """
1439
+ self.load_markets()
1440
+ market = self.market(symbol)
1441
+ request: dict = {
1442
+ 'symbols': [market['id']],
1443
+ }
1444
+ response = self.v1PrivateDeleteApiOrdersAllOpen(self.extend(request, params))
1445
+ #
1446
+ # {
1447
+ # "data": {
1448
+ # "msg": "The operation of cancel all open order is done."
1449
+ # }
1450
+ # }
1451
+ #
1452
+ return response
1453
+
1454
+ def fetch_position(self, symbol: str, params={}):
1455
+ """
1456
+ fetch data on a single open contract trade position
1457
+
1458
+ https://api-docs.defx.com/#d89dbb86-9aba-4f59-ac5d-a97ff25ea80e
1459
+
1460
+ :param str symbol: unified market symbol of the market the position is held in, default is None
1461
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1462
+ :returns dict: a `position structure <https://docs.ccxt.com/#/?id=position-structure>`
1463
+ """
1464
+ if symbol is None:
1465
+ raise ArgumentsRequired(self.id + ' fetchPosition() requires a symbol argument')
1466
+ self.load_markets()
1467
+ market = self.market(symbol)
1468
+ request: dict = {
1469
+ 'symbol': market['id'],
1470
+ }
1471
+ response = self.v1PrivateGetApiPositionActive(self.extend(request, params))
1472
+ #
1473
+ # {
1474
+ # "data": [
1475
+ # {
1476
+ # "positionId": "0192c495-4a68-70ee-9081-9d368bd16dfc",
1477
+ # "symbol": "SOL_USDC",
1478
+ # "positionSide": "SHORT",
1479
+ # "entryPrice": "172.34300000",
1480
+ # "quantity": "0.80",
1481
+ # "marginAmount": "20.11561173",
1482
+ # "marginAsset": "USDC",
1483
+ # "pnl": "0.00000000"
1484
+ # }
1485
+ # ]
1486
+ # }
1487
+ #
1488
+ data = self.safe_list(response, 'data', [])
1489
+ first = self.safe_dict(data, 0, {})
1490
+ return self.parse_position(first, market)
1491
+
1492
+ def fetch_positions(self, symbols: Strings = None, params={}):
1493
+ """
1494
+ fetch all open positions
1495
+
1496
+ https://api-docs.defx.com/#d89dbb86-9aba-4f59-ac5d-a97ff25ea80e
1497
+
1498
+ :param str[] [symbols]: list of unified market symbols
1499
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1500
+ :returns dict[]: a list of `position structure <https://docs.ccxt.com/#/?id=position-structure>`
1501
+ """
1502
+ self.load_markets()
1503
+ response = self.v1PrivateGetApiPositionActive(params)
1504
+ #
1505
+ # {
1506
+ # "data": [
1507
+ # {
1508
+ # "positionId": "0192c495-4a68-70ee-9081-9d368bd16dfc",
1509
+ # "symbol": "SOL_USDC",
1510
+ # "positionSide": "SHORT",
1511
+ # "entryPrice": "172.34300000",
1512
+ # "quantity": "0.80",
1513
+ # "marginAmount": "20.11561173",
1514
+ # "marginAsset": "USDC",
1515
+ # "pnl": "0.00000000"
1516
+ # }
1517
+ # ]
1518
+ # }
1519
+ #
1520
+ positions = self.safe_list(response, 'data', [])
1521
+ return self.parse_positions(positions, symbols)
1522
+
1523
+ def parse_position(self, position: dict, market: Market = None):
1524
+ #
1525
+ # {
1526
+ # "positionId": "0192c495-4a68-70ee-9081-9d368bd16dfc",
1527
+ # "symbol": "SOL_USDC",
1528
+ # "positionSide": "SHORT",
1529
+ # "entryPrice": "172.34300000",
1530
+ # "quantity": "0.80",
1531
+ # "marginAmount": "20.11561173",
1532
+ # "marginAsset": "USDC",
1533
+ # "pnl": "0.00000000"
1534
+ # }
1535
+ #
1536
+ marketId = self.safe_string(position, 'symbol')
1537
+ market = self.safe_market(marketId, market)
1538
+ size = Precise.string_abs(self.safe_string(position, 'quantity'))
1539
+ side = self.safe_string_lower(position, 'positionSide')
1540
+ unrealisedPnl = self.omit_zero(self.safe_string(position, 'pnl'))
1541
+ entryPrice = self.omit_zero(self.safe_string(position, 'entryPrice'))
1542
+ initialMargin = self.safe_string(position, 'marginAmount')
1543
+ return self.safe_position({
1544
+ 'info': position,
1545
+ 'id': self.safe_string(position, 'positionId'),
1546
+ 'symbol': market['symbol'],
1547
+ 'timestamp': None,
1548
+ 'datetime': None,
1549
+ 'lastUpdateTimestamp': None,
1550
+ 'initialMargin': self.parse_number(initialMargin),
1551
+ 'initialMarginPercentage': None,
1552
+ 'maintenanceMargin': None,
1553
+ 'maintenanceMarginPercentage': None,
1554
+ 'entryPrice': self.parse_number(entryPrice),
1555
+ 'notional': None,
1556
+ 'leverage': None,
1557
+ 'unrealizedPnl': self.parse_number(unrealisedPnl),
1558
+ 'realizedPnl': None,
1559
+ 'contracts': self.parse_number(size),
1560
+ 'contractSize': self.safe_number(market, 'contractSize'),
1561
+ 'marginRatio': None,
1562
+ 'liquidationPrice': None,
1563
+ 'markPrice': None,
1564
+ 'lastPrice': None,
1565
+ 'collateral': None,
1566
+ 'marginMode': None,
1567
+ 'side': side,
1568
+ 'percentage': None,
1569
+ 'stopLossPrice': None,
1570
+ 'takeProfitPrice': None,
1571
+ 'hedged': None,
1572
+ })
1573
+
1574
+ def fetch_order(self, id: str, symbol: Str = None, params={}):
1575
+ """
1576
+ fetches information on an order made by the user
1577
+
1578
+ https://api-docs.defx.com/#44f82dd5-26b3-4e1f-b4aa-88ceddd65237
1579
+
1580
+ :param str id: the order id
1581
+ :param str symbol: unified symbol of the market the order was made in
1582
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1583
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1584
+ """
1585
+ self.load_markets()
1586
+ request: dict = {
1587
+ 'orderId': id,
1588
+ 'idType': 'orderId',
1589
+ }
1590
+ clientOrderId = self.safe_string_n(params, ['clOrdID', 'clientOrderId', 'client_order_id'])
1591
+ params = self.omit(params, ['clOrdID', 'clientOrderId', 'client_order_id'])
1592
+ if clientOrderId is not None:
1593
+ if symbol is None:
1594
+ raise ArgumentsRequired(self.id + ' fetchOrder() requires a symbol argument')
1595
+ market = self.market(symbol)
1596
+ request['orderId'] = clientOrderId
1597
+ request['idType'] = 'clientOrderId'
1598
+ request['symbol'] = market['id']
1599
+ response = self.v1PrivateGetApiOrderOrderId(self.extend(request, params))
1600
+ #
1601
+ # {
1602
+ # "success": True,
1603
+ # "data": {
1604
+ # "orderId": "555068654076559792",
1605
+ # "createdAt": "2024-05-08T05:45:42.148Z",
1606
+ # "updatedAt": "2024-05-08T05:45:42.166Z",
1607
+ # "clientOrderId": "dummyClientOrderId",
1608
+ # "reduceOnly": False,
1609
+ # "side": "SELL",
1610
+ # "status": "REJECTED",
1611
+ # "symbol": "BTC_USDC",
1612
+ # "timeInForce": "GTC",
1613
+ # "type": "TAKE_PROFIT_MARKET",
1614
+ # "origQty": "1.000",
1615
+ # "executedQty": "0.000",
1616
+ # "cumulativeQuote": "0.00",
1617
+ # "avgPrice": "0.00",
1618
+ # "stopPrice": "65000.00",
1619
+ # "totalPnL": "0.00",
1620
+ # "workingType": "MARK_PRICE",
1621
+ # "postOnly": False
1622
+ # }
1623
+ # }
1624
+ #
1625
+ data = self.safe_dict(response, 'data')
1626
+ return self.parse_order(data)
1627
+
1628
+ def fetch_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1629
+ """
1630
+ fetches information on multiple orders made by the user
1631
+
1632
+ https://api-docs.defx.com/#ab200038-8acb-4170-b05e-4fcb4cc13751
1633
+
1634
+ :param str symbol: unified market symbol
1635
+ :param int [since]: the earliest time in ms to fetch open orders for
1636
+ :param int [limit]: the maximum number of open order structures to retrieve
1637
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1638
+ :param int [params.until]: the latest time in ms to fetch orders for
1639
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1640
+ """
1641
+ self.load_markets()
1642
+ request: dict = {}
1643
+ if symbol is not None:
1644
+ market = self.market(symbol)
1645
+ request['symbols'] = market['id']
1646
+ until = self.safe_integer(params, 'until')
1647
+ if until is not None:
1648
+ params = self.omit(params, 'until')
1649
+ request['end'] = self.iso8601(until)
1650
+ if since is not None:
1651
+ request['start'] = self.iso8601(since)
1652
+ if limit is not None:
1653
+ maxLimit = 100
1654
+ limit = min(maxLimit, limit)
1655
+ request['pageSize'] = limit
1656
+ response = self.v1PrivateGetApiOrders(self.extend(request, params))
1657
+ #
1658
+ # {
1659
+ # "data": [
1660
+ # {
1661
+ # "orderId": "746472647227344528",
1662
+ # "createdAt": "2024-10-25T16:49:31.077Z",
1663
+ # "updatedAt": "2024-10-25T16:49:31.378Z",
1664
+ # "clientOrderId": "0192c495-49c3-71ee-b3d3-7442a2090807",
1665
+ # "reduceOnly": False,
1666
+ # "side": "SELL",
1667
+ # "status": "FILLED",
1668
+ # "symbol": "SOL_USDC",
1669
+ # "timeInForce": "GTC",
1670
+ # "type": "MARKET",
1671
+ # "origQty": "0.80",
1672
+ # "executedQty": "0.80",
1673
+ # "cumulativeQuote": "137.87440000",
1674
+ # "avgPrice": "172.34300000",
1675
+ # "totalPnL": "0.00000000",
1676
+ # "totalFee": "0.07583092",
1677
+ # "workingType": null,
1678
+ # "postOnly": False,
1679
+ # "linkedOrderParentType": null,
1680
+ # "isTriggered": False,
1681
+ # "slippagePercentage": 5
1682
+ # }
1683
+ # ]
1684
+ # }
1685
+ #
1686
+ data = self.safe_list(response, 'data', [])
1687
+ return self.parse_orders(data, None, since, limit)
1688
+
1689
+ def fetch_open_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1690
+ """
1691
+ fetch all unfilled currently open orders
1692
+
1693
+ https://api-docs.defx.com/#ab200038-8acb-4170-b05e-4fcb4cc13751
1694
+
1695
+ :param str symbol: unified market symbol
1696
+ :param int [since]: the earliest time in ms to fetch open orders for
1697
+ :param int [limit]: the maximum number of open order structures to retrieve
1698
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1699
+ :param int [params.until]: the latest time in ms to fetch orders for
1700
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1701
+ """
1702
+ req = {
1703
+ 'statuses': 'OPEN',
1704
+ }
1705
+ return self.fetch_orders(symbol, since, limit, self.extend(req, params))
1706
+
1707
+ def fetch_closed_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1708
+ """
1709
+ fetches information on multiple closed orders made by the user
1710
+
1711
+ https://api-docs.defx.com/#ab200038-8acb-4170-b05e-4fcb4cc13751
1712
+
1713
+ :param str symbol: unified market symbol
1714
+ :param int [since]: the earliest time in ms to fetch open orders for
1715
+ :param int [limit]: the maximum number of open order structures to retrieve
1716
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1717
+ :param int [params.until]: the latest time in ms to fetch orders for
1718
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1719
+ """
1720
+ req = {
1721
+ 'statuses': 'FILLED',
1722
+ }
1723
+ return self.fetch_orders(symbol, since, limit, self.extend(req, params))
1724
+
1725
+ def fetch_canceled_orders(self, symbol: Str = None, since: Int = None, limit: Int = None, params={}) -> List[Order]:
1726
+ """
1727
+ fetches information on multiple canceled orders made by the user
1728
+
1729
+ https://api-docs.defx.com/#ab200038-8acb-4170-b05e-4fcb4cc13751
1730
+
1731
+ :param str symbol: unified market symbol
1732
+ :param int [since]: the earliest time in ms to fetch open orders for
1733
+ :param int [limit]: the maximum number of open order structures to retrieve
1734
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1735
+ :param int [params.until]: the latest time in ms to fetch orders for
1736
+ :returns Order[]: a list of `order structures <https://docs.ccxt.com/#/?id=order-structure>`
1737
+ """
1738
+ req = {
1739
+ 'statuses': 'CANCELED',
1740
+ }
1741
+ return self.fetch_orders(symbol, since, limit, self.extend(req, params))
1742
+
1743
+ def close_position(self, symbol: str, side: OrderSide = None, params={}) -> Order:
1744
+ """
1745
+ closes an open position for a market
1746
+
1747
+ https://api-docs.defx.com/#b2c08074-c4d9-4e50-b637-0d6c498fa29e
1748
+
1749
+ :param str symbol: unified CCXT market symbol
1750
+ :param str [side]: one-way mode: 'buy' or 'sell', hedge-mode: 'long' or 'short'
1751
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1752
+ :param str [params.positionId]: the position id you want to close
1753
+ :param str [params.type]: 'MARKET' or 'LIMIT'
1754
+ :param str [params.quantity]: how much of currency you want to trade in units of base currency
1755
+ :param str [params.price]: the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
1756
+ :returns dict: An `order structure <https://docs.ccxt.com/#/?id=order-structure>`
1757
+ """
1758
+ self.load_markets()
1759
+ positionId = self.safe_string(params, 'positionId')
1760
+ if positionId is None:
1761
+ raise ArgumentsRequired(self.id + ' closePosition() requires a positionId')
1762
+ type = self.safe_string_upper(params, 'type')
1763
+ if type is None:
1764
+ raise ArgumentsRequired(self.id + ' closePosition() requires a type')
1765
+ quantity = self.safe_string(params, 'quantity')
1766
+ if quantity is None:
1767
+ raise ArgumentsRequired(self.id + ' closePosition() requires a quantity')
1768
+ request: dict = {
1769
+ 'positionId': positionId,
1770
+ 'type': type,
1771
+ 'quantity': quantity,
1772
+ }
1773
+ if type != 'MARKET':
1774
+ price = self.safe_string(params, 'price')
1775
+ if price is None:
1776
+ raise ArgumentsRequired(self.id + ' closePosition() requires a price')
1777
+ request['price'] = price
1778
+ params = self.omit(params, ['positionId', 'type', 'quantity', 'price'])
1779
+ response = self.v1PrivateDeleteApiPositionPositionId(self.extend(request, params))
1780
+ #
1781
+ # {}
1782
+ #
1783
+ return response
1784
+
1785
+ def close_all_positions(self, params={}) -> List[Position]:
1786
+ """
1787
+ closes all open positions for a market type
1788
+
1789
+ https://api-docs.defx.com/#d6f63b43-100e-47a9-998c-8b6c0c72d204
1790
+
1791
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1792
+ :returns dict[]: A list of `position structures <https://docs.ccxt.com/#/?id=position-structure>`
1793
+ """
1794
+ self.load_markets()
1795
+ response = self.v1PrivateDeleteApiPositionAll(params)
1796
+ #
1797
+ # {
1798
+ # "data": [
1799
+ # {
1800
+ # "positionId": "d6ca1a27-28ad-47ae-b244-0bda5ac37b2b",
1801
+ # "success": True
1802
+ # }
1803
+ # ]
1804
+ # }
1805
+ #
1806
+ data = self.safe_list(response, 'data', [])
1807
+ return self.parse_positions(data, None, params)
1808
+
1809
+ def fetch_ledger(self, code: Str = None, since: Int = None, limit: Int = None, params={}) -> List[LedgerEntry]:
1810
+ """
1811
+ fetch the history of changes, actions done by the user or operations that altered the balance of the user
1812
+
1813
+ https://api-docs.defx.com/#38cc8974-794f-48c0-b959-db045a0ee565
1814
+
1815
+ :param str [code]: unified currency code
1816
+ :param int [since]: timestamp in ms of the earliest ledger entry
1817
+ :param int [limit]: max number of ledger entries to return
1818
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1819
+ :param int [params.until]: timestamp in ms of the latest ledger entry
1820
+ :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)
1821
+ :returns dict: a `ledger structure <https://docs.ccxt.com/#/?id=ledger>`
1822
+ """
1823
+ self.load_markets()
1824
+ paginate = False
1825
+ paginate, params = self.handle_option_and_params(params, 'fetchLedger', 'paginate')
1826
+ if paginate:
1827
+ return self.fetch_paginated_call_dynamic('fetchLedger', code, since, limit, params)
1828
+ request: dict = {}
1829
+ if since is not None:
1830
+ request['start'] = since
1831
+ else:
1832
+ request['start'] = 0
1833
+ until = self.safe_integer(params, 'until')
1834
+ if until is not None:
1835
+ params = self.omit(params, 'until')
1836
+ request['end'] = until
1837
+ else:
1838
+ request['end'] = self.milliseconds()
1839
+ response = self.v1PrivateGetApiWalletTransactions(self.extend(request, params))
1840
+ data = self.safe_list(response, 'transactions', [])
1841
+ return self.parse_ledger(data, None, since, limit)
1842
+
1843
+ def parse_ledger_entry(self, item: dict, currency: Currency = None) -> LedgerEntry:
1844
+ #
1845
+ # {
1846
+ # "id": "01JCSZS6H5VQND3GF5P98SJ29C",
1847
+ # "timestamp": 1731744012054,
1848
+ # "type": "FundingFee",
1849
+ # "amount": "0.02189287",
1850
+ # "asset": "USDC",
1851
+ # "operation": "CREDIT"
1852
+ # }
1853
+ #
1854
+ amount = self.safe_string(item, 'amount')
1855
+ currencyId = self.safe_string(item, 'asset')
1856
+ code = self.safe_currency_code(currencyId, currency)
1857
+ currency = self.safe_currency(currencyId, currency)
1858
+ timestamp = self.safe_integer(item, 'timestamp')
1859
+ type = self.safe_string(item, 'type')
1860
+ return self.safe_ledger_entry({
1861
+ 'info': item,
1862
+ 'id': self.safe_string(item, 'id'),
1863
+ 'direction': None,
1864
+ 'account': None,
1865
+ 'referenceAccount': None,
1866
+ 'referenceId': None,
1867
+ 'type': self.parse_ledger_entry_type(type),
1868
+ 'currency': code,
1869
+ 'amount': self.parse_number(amount),
1870
+ 'timestamp': timestamp,
1871
+ 'datetime': self.iso8601(timestamp),
1872
+ 'before': None,
1873
+ 'after': None,
1874
+ 'status': None,
1875
+ 'fee': None,
1876
+ }, currency)
1877
+
1878
+ def parse_ledger_entry_type(self, type):
1879
+ ledgerType: dict = {
1880
+ 'FundingFee': 'fee',
1881
+ 'FeeRebate': 'fee',
1882
+ 'FeeKickback': 'fee',
1883
+ 'RealizedPnl': 'trade',
1884
+ 'LiquidationClearance': 'trade',
1885
+ 'Transfer': 'transfer',
1886
+ 'ReferralPayout': 'referral',
1887
+ 'Commission': 'commission',
1888
+ }
1889
+ return self.safe_string(ledgerType, type, type)
1890
+
1891
+ def withdraw(self, code: str, amount: float, address: str, tag=None, params={}):
1892
+ """
1893
+ make a withdrawal
1894
+
1895
+ https://api-docs.defx.com/#2600f503-63ed-4672-b8f6-69ea5f03203b
1896
+
1897
+ :param str code: unified currency code
1898
+ :param float amount: the amount to withdraw
1899
+ :param str address: the address to withdraw to
1900
+ :param str tag:
1901
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1902
+ :returns dict: a `transaction structure <https://docs.ccxt.com/#/?id=transaction-structure>`
1903
+ """
1904
+ self.load_markets()
1905
+ currency = self.currency(code)
1906
+ request: dict = {
1907
+ 'amount': self.currency_to_precision(code, amount),
1908
+ 'asset': currency['id'],
1909
+ # 'network': 'ARB_SEPOLIA',
1910
+ # 'chainId': '421614',
1911
+ }
1912
+ response = self.v1PrivatePostApiTransfersBridgeWithdrawal(self.extend(request, params))
1913
+ #
1914
+ # {
1915
+ # "transactionId": "0x301e5851e5aefa733abfbc8b30817ca3b61601e0ddf1df8c59656fb888b0bc9c"
1916
+ # }
1917
+ #
1918
+ return self.parse_transaction(response, currency)
1919
+
1920
+ def parse_transaction(self, transaction: dict, currency: Currency = None) -> Transaction:
1921
+ #
1922
+ # withdraw
1923
+ #
1924
+ # {
1925
+ # "transactionId": "0x301e5851e5aefa733abfbc8b30817ca3b61601e0ddf1df8c59656fb888b0bc9c"
1926
+ # }
1927
+ #
1928
+ txid = self.safe_string(transaction, 'transactionId')
1929
+ return {
1930
+ 'info': transaction,
1931
+ 'id': None,
1932
+ 'txid': txid,
1933
+ 'timestamp': None,
1934
+ 'datetime': None,
1935
+ 'network': None,
1936
+ 'address': None,
1937
+ 'addressTo': None,
1938
+ 'addressFrom': None,
1939
+ 'tag': None,
1940
+ 'tagTo': None,
1941
+ 'tagFrom': None,
1942
+ 'type': None,
1943
+ 'amount': None,
1944
+ 'currency': self.safe_currency_code(None, currency),
1945
+ 'status': None,
1946
+ 'updated': None,
1947
+ 'internal': None,
1948
+ 'comment': None,
1949
+ 'fee': None,
1950
+ }
1951
+
1952
+ def set_leverage(self, leverage: Int, symbol: Str = None, params={}):
1953
+ """
1954
+ set the level of leverage for a market
1955
+
1956
+ https://api-docs.defx.com/#4cb4ecc4-6c61-4194-8353-be67faaf7ca7
1957
+
1958
+ :param float leverage: the rate of leverage
1959
+ :param str symbol: unified market symbol
1960
+ :param dict [params]: extra parameters specific to the exchange API endpoint
1961
+ :returns dict: response from the exchange
1962
+ """
1963
+ if symbol is None:
1964
+ raise ArgumentsRequired(self.id + ' setLeverage() requires a symbol argument')
1965
+ self.load_markets()
1966
+ request: dict = {
1967
+ 'leverage': self.number_to_string(leverage),
1968
+ }
1969
+ market = self.market(symbol)
1970
+ request['symbol'] = market['id']
1971
+ response = self.v1PrivatePostApiUsersMetadataLeverage(self.extend(request, params))
1972
+ #
1973
+ # {
1974
+ # "success": True,
1975
+ # "data": {
1976
+ # "leverage": "11",
1977
+ # "symbol": "BTC_USDC"
1978
+ # }
1979
+ # }
1980
+ #
1981
+ data = self.safe_dict(response, 'data', {})
1982
+ return self.parse_leverage(data, market)
1983
+
1984
+ def parse_leverage(self, leverage: dict, market: Market = None) -> Leverage:
1985
+ #
1986
+ # "data": {
1987
+ # "leverage": "11",
1988
+ # "symbol": "BTC_USDC"
1989
+ # }
1990
+ #
1991
+ marketId = self.safe_string(leverage, 'symbol')
1992
+ leverageValue = self.safe_integer(leverage, 'leverage')
1993
+ return {
1994
+ 'info': leverage,
1995
+ 'symbol': self.safe_symbol(marketId, market),
1996
+ 'marginMode': None,
1997
+ 'longLeverage': leverageValue,
1998
+ 'shortLeverage': leverageValue,
1999
+ }
2000
+
2001
+ def nonce(self):
2002
+ return self.milliseconds()
2003
+
2004
+ def sign(self, path, section='public', method='GET', params={}, headers=None, body=None):
2005
+ version = section[0]
2006
+ access = section[1]
2007
+ pathWithParams = self.implode_params(path, params)
2008
+ url = self.implode_hostname(self.urls['api'][access])
2009
+ url += '/' + version + '/'
2010
+ params = self.omit(params, self.extract_params(path))
2011
+ params = self.keysort(params)
2012
+ if access == 'public':
2013
+ url += 'open/' + pathWithParams
2014
+ if params:
2015
+ url += '?' + self.rawencode(params)
2016
+ else:
2017
+ self.check_required_credentials()
2018
+ headers = {'X-DEFX-SOURCE': 'ccxt'}
2019
+ url += 'auth/' + pathWithParams
2020
+ nonce = str(self.milliseconds())
2021
+ payload = nonce
2022
+ if method == 'GET' or path == 'api/order/{orderId}':
2023
+ payload += self.rawencode(params)
2024
+ if params:
2025
+ url += '?' + self.rawencode(params)
2026
+ else:
2027
+ if params is not None:
2028
+ body = self.json(params)
2029
+ payload += body
2030
+ headers['Content-Type'] = 'application/json'
2031
+ signature = self.hmac(self.encode(payload), self.encode(self.secret), hashlib.sha256)
2032
+ headers['X-DEFX-APIKEY'] = self.apiKey
2033
+ headers['X-DEFX-TIMESTAMP'] = nonce
2034
+ headers['X-DEFX-SIGNATURE'] = signature
2035
+ return {'url': url, 'method': method, 'body': body, 'headers': headers}
2036
+
2037
+ def handle_errors(self, httpCode: int, reason: str, url: str, method: str, headers: dict, body: str, response, requestHeaders, requestBody):
2038
+ if not response:
2039
+ return None # fallback to default error handler
2040
+ # {"errorCode":404,"errorMessage":"Not Found"}
2041
+ # {"msg":"Missing auth signature","code":"missing_auth_signature"}
2042
+ # {"success":false,"err":{"msg":"Invalid order id","code":"invalid_order_id"}}
2043
+ success = self.safe_bool(response, 'success')
2044
+ err = self.safe_dict(response, 'err', response)
2045
+ errorCode = self.safe_string_2(err, 'errorCode', 'code')
2046
+ if not success:
2047
+ feedback = self.id + ' ' + self.json(response)
2048
+ self.throw_broadly_matched_exception(self.exceptions['broad'], body, feedback)
2049
+ self.throw_exactly_matched_exception(self.exceptions['exact'], errorCode, feedback)
2050
+ return None
2051
+
2052
+ def default_network_code_for_currency(self, code):
2053
+ currencyItem = self.currency(code)
2054
+ networks = currencyItem['networks']
2055
+ networkKeys = list(networks.keys())
2056
+ for i in range(0, len(networkKeys)):
2057
+ network = networkKeys[i]
2058
+ if network == 'ETH':
2059
+ return network
2060
+ # if it was not returned according to above options, then return the first network of currency
2061
+ return self.safe_value(networkKeys, 0)
2062
+
2063
+ def set_sandbox_mode(self, enable: bool):
2064
+ super(defx, self).set_sandbox_mode(enable)
2065
+ self.options['sandboxMode'] = enable