ccxt-look 1.81.50

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 (264) hide show
  1. package/.cache/eslintcache +1 -0
  2. package/.dockerignore +6 -0
  3. package/.eslintignore +1 -0
  4. package/.gitattributes +5 -0
  5. package/.readthedocs.yaml +16 -0
  6. package/CONTRIBUTING.md +1049 -0
  7. package/LICENSE.txt +21 -0
  8. package/README.md +537 -0
  9. package/SECURITY.md +5 -0
  10. package/build/cleanup-old-tags.js +94 -0
  11. package/build/countries.js +256 -0
  12. package/build/export-exchanges.js +520 -0
  13. package/build/fs.js +51 -0
  14. package/build/transpile.js +1772 -0
  15. package/build/vss.js +78 -0
  16. package/ccxt.browser.js +7 -0
  17. package/ccxt.d.ts +692 -0
  18. package/ccxt.js +171 -0
  19. package/cleanup.sh +2 -0
  20. package/composer-install.sh +20 -0
  21. package/dist/ccxt.browser.js +208383 -0
  22. package/gource.sh +3 -0
  23. package/index.html +7 -0
  24. package/js/.eslintrc +87 -0
  25. package/js/aax.js +2686 -0
  26. package/js/ascendex.js +2584 -0
  27. package/js/base/.eslintrc.js +43 -0
  28. package/js/base/Exchange.js +2371 -0
  29. package/js/base/Precise.js +283 -0
  30. package/js/base/errorHierarchy.js +47 -0
  31. package/js/base/errors.js +55 -0
  32. package/js/base/functions/crypto.js +158 -0
  33. package/js/base/functions/encode.js +118 -0
  34. package/js/base/functions/generic.js +270 -0
  35. package/js/base/functions/misc.js +138 -0
  36. package/js/base/functions/number.js +329 -0
  37. package/js/base/functions/platform.js +38 -0
  38. package/js/base/functions/string.js +21 -0
  39. package/js/base/functions/throttle.js +79 -0
  40. package/js/base/functions/time.js +210 -0
  41. package/js/base/functions/type.js +66 -0
  42. package/js/base/functions.js +28 -0
  43. package/js/bequant.js +32 -0
  44. package/js/bibox.js +1407 -0
  45. package/js/bigone.js +1366 -0
  46. package/js/binance.js +5652 -0
  47. package/js/binancecoinm.js +46 -0
  48. package/js/binanceus.js +46 -0
  49. package/js/binanceusdm.js +49 -0
  50. package/js/bit2c.js +535 -0
  51. package/js/bitbank.js +842 -0
  52. package/js/bitbay.js +16 -0
  53. package/js/bitbns.js +1073 -0
  54. package/js/bitcoincom.js +15 -0
  55. package/js/bitfinex.js +1433 -0
  56. package/js/bitfinex2.js +2025 -0
  57. package/js/bitflyer.js +840 -0
  58. package/js/bitforex.js +614 -0
  59. package/js/bitget.js +2397 -0
  60. package/js/bithumb.js +980 -0
  61. package/js/bitmart.js +2516 -0
  62. package/js/bitmex.js +1809 -0
  63. package/js/bitopro.js +1443 -0
  64. package/js/bitpanda.js +1782 -0
  65. package/js/bitrue.js +1747 -0
  66. package/js/bitso.js +1062 -0
  67. package/js/bitstamp.js +1757 -0
  68. package/js/bitstamp1.js +343 -0
  69. package/js/bittrex.js +1876 -0
  70. package/js/bitvavo.js +1579 -0
  71. package/js/bkex.js +1233 -0
  72. package/js/bl3p.js +346 -0
  73. package/js/blockchaincom.js +969 -0
  74. package/js/btcalpha.js +680 -0
  75. package/js/btcbox.js +477 -0
  76. package/js/btcmarkets.js +1022 -0
  77. package/js/btctradeua.js +466 -0
  78. package/js/btcturk.js +734 -0
  79. package/js/buda.js +946 -0
  80. package/js/bw.js +1265 -0
  81. package/js/bybit.js +3372 -0
  82. package/js/bytetrade.js +1336 -0
  83. package/js/cdax.js +1646 -0
  84. package/js/cex.js +1410 -0
  85. package/js/coinbase.js +1342 -0
  86. package/js/coinbaseprime.js +31 -0
  87. package/js/coinbasepro.js +1466 -0
  88. package/js/coincheck.js +755 -0
  89. package/js/coinex.js +3400 -0
  90. package/js/coinfalcon.js +880 -0
  91. package/js/coinmate.js +794 -0
  92. package/js/coinone.js +816 -0
  93. package/js/coinspot.js +345 -0
  94. package/js/crex24.js +1636 -0
  95. package/js/cryptocom.js +1832 -0
  96. package/js/currencycom.js +1748 -0
  97. package/js/delta.js +1547 -0
  98. package/js/deribit.js +2148 -0
  99. package/js/digifinex.js +1585 -0
  100. package/js/eqonex.js +1660 -0
  101. package/js/exmo.js +1670 -0
  102. package/js/fairdesk.js +1231 -0
  103. package/js/flowbtc.js +35 -0
  104. package/js/fmfwio.js +34 -0
  105. package/js/ftx.js +2751 -0
  106. package/js/ftxus.js +38 -0
  107. package/js/gateio.js +4174 -0
  108. package/js/gemini.js +1397 -0
  109. package/js/hitbtc.js +1343 -0
  110. package/js/hitbtc3.js +2329 -0
  111. package/js/hollaex.js +1486 -0
  112. package/js/huobi.js +5706 -0
  113. package/js/huobijp.js +1710 -0
  114. package/js/huobipro.js +18 -0
  115. package/js/idex.js +1439 -0
  116. package/js/independentreserve.js +649 -0
  117. package/js/indodax.js +742 -0
  118. package/js/itbit.js +722 -0
  119. package/js/kraken.js +2179 -0
  120. package/js/kucoin.js +2571 -0
  121. package/js/kucoinfutures.js +1771 -0
  122. package/js/kuna.js +809 -0
  123. package/js/latoken.js +1445 -0
  124. package/js/lbank.js +760 -0
  125. package/js/liquid.js +1432 -0
  126. package/js/luno.js +873 -0
  127. package/js/lykke.js +1147 -0
  128. package/js/mercado.js +771 -0
  129. package/js/mexc.js +3151 -0
  130. package/js/ndax.js +2233 -0
  131. package/js/novadax.js +1318 -0
  132. package/js/oceanex.js +816 -0
  133. package/js/okcoin.js +3841 -0
  134. package/js/okex.js +16 -0
  135. package/js/okex5.js +16 -0
  136. package/js/okx.js +4795 -0
  137. package/js/paymium.js +498 -0
  138. package/js/phemex.js +2957 -0
  139. package/js/poloniex.js +1674 -0
  140. package/js/probit.js +1346 -0
  141. package/js/qtrade.js +1588 -0
  142. package/js/ripio.js +1061 -0
  143. package/js/static_dependencies/BN/bn.js +3526 -0
  144. package/js/static_dependencies/README.md +1 -0
  145. package/js/static_dependencies/crypto-js/crypto-js.js +5988 -0
  146. package/js/static_dependencies/elliptic/lib/elliptic/curve/base.js +375 -0
  147. package/js/static_dependencies/elliptic/lib/elliptic/curve/edwards.js +433 -0
  148. package/js/static_dependencies/elliptic/lib/elliptic/curve/index.js +8 -0
  149. package/js/static_dependencies/elliptic/lib/elliptic/curve/mont.js +180 -0
  150. package/js/static_dependencies/elliptic/lib/elliptic/curve/short.js +938 -0
  151. package/js/static_dependencies/elliptic/lib/elliptic/curves.js +204 -0
  152. package/js/static_dependencies/elliptic/lib/elliptic/ec/index.js +240 -0
  153. package/js/static_dependencies/elliptic/lib/elliptic/ec/key.js +119 -0
  154. package/js/static_dependencies/elliptic/lib/elliptic/ec/signature.js +24 -0
  155. package/js/static_dependencies/elliptic/lib/elliptic/eddsa/index.js +145 -0
  156. package/js/static_dependencies/elliptic/lib/elliptic/eddsa/key.js +100 -0
  157. package/js/static_dependencies/elliptic/lib/elliptic/eddsa/signature.js +65 -0
  158. package/js/static_dependencies/elliptic/lib/elliptic/precomputed/secp256k1.js +780 -0
  159. package/js/static_dependencies/elliptic/lib/elliptic/utils.js +214 -0
  160. package/js/static_dependencies/elliptic/lib/elliptic.js +22 -0
  161. package/js/static_dependencies/elliptic/lib/hmac-drbg/hmac-drbg.js +114 -0
  162. package/js/static_dependencies/fetch-ponyfill/fetch-node.js +39 -0
  163. package/js/static_dependencies/node-fetch/index.js +1564 -0
  164. package/js/static_dependencies/node-rsa/NodeRSA.js +223 -0
  165. package/js/static_dependencies/node-rsa/asn1/ber/errors.js +13 -0
  166. package/js/static_dependencies/node-rsa/asn1/ber/index.js +21 -0
  167. package/js/static_dependencies/node-rsa/asn1/ber/reader.js +262 -0
  168. package/js/static_dependencies/node-rsa/asn1/ber/types.js +36 -0
  169. package/js/static_dependencies/node-rsa/asn1/index.js +17 -0
  170. package/js/static_dependencies/node-rsa/encryptEngines/js.js +34 -0
  171. package/js/static_dependencies/node-rsa/formats/components.js +71 -0
  172. package/js/static_dependencies/node-rsa/formats/formats.js +31 -0
  173. package/js/static_dependencies/node-rsa/formats/pkcs1.js +148 -0
  174. package/js/static_dependencies/node-rsa/formats/pkcs8.js +187 -0
  175. package/js/static_dependencies/node-rsa/libs/jsbn.js +1252 -0
  176. package/js/static_dependencies/node-rsa/libs/rsa.js +147 -0
  177. package/js/static_dependencies/node-rsa/schemes/pkcs1.js +176 -0
  178. package/js/static_dependencies/node-rsa/schemes/schemes.js +21 -0
  179. package/js/static_dependencies/node-rsa/utils.js +98 -0
  180. package/js/static_dependencies/qs/formats.js +18 -0
  181. package/js/static_dependencies/qs/index.js +11 -0
  182. package/js/static_dependencies/qs/parse.js +242 -0
  183. package/js/static_dependencies/qs/stringify.js +269 -0
  184. package/js/static_dependencies/qs/utils.js +230 -0
  185. package/js/stex.js +1925 -0
  186. package/js/test/.eslintrc.js +42 -0
  187. package/js/test/Exchange/test.balance.js +61 -0
  188. package/js/test/Exchange/test.borrowRate.js +32 -0
  189. package/js/test/Exchange/test.currency.js +52 -0
  190. package/js/test/Exchange/test.fetchBalance.js +23 -0
  191. package/js/test/Exchange/test.fetchBorrowInterest.js +59 -0
  192. package/js/test/Exchange/test.fetchBorrowRate.js +32 -0
  193. package/js/test/Exchange/test.fetchBorrowRates.js +28 -0
  194. package/js/test/Exchange/test.fetchClosedOrders.js +32 -0
  195. package/js/test/Exchange/test.fetchCurrencies.js +35 -0
  196. package/js/test/Exchange/test.fetchDeposits.js +31 -0
  197. package/js/test/Exchange/test.fetchFundingFees.js +19 -0
  198. package/js/test/Exchange/test.fetchFundingRateHistory.js +40 -0
  199. package/js/test/Exchange/test.fetchL2OrderBook.js +23 -0
  200. package/js/test/Exchange/test.fetchLedger.js +42 -0
  201. package/js/test/Exchange/test.fetchLeverageTiers.js +33 -0
  202. package/js/test/Exchange/test.fetchMarketLeverageTiers.js +22 -0
  203. package/js/test/Exchange/test.fetchMarkets.js +33 -0
  204. package/js/test/Exchange/test.fetchMyTrades.js +42 -0
  205. package/js/test/Exchange/test.fetchOHLCV.js +46 -0
  206. package/js/test/Exchange/test.fetchOpenOrders.js +36 -0
  207. package/js/test/Exchange/test.fetchOrderBook.js +25 -0
  208. package/js/test/Exchange/test.fetchOrderBooks.js +35 -0
  209. package/js/test/Exchange/test.fetchOrders.js +41 -0
  210. package/js/test/Exchange/test.fetchPositions.js +47 -0
  211. package/js/test/Exchange/test.fetchStatus.js +35 -0
  212. package/js/test/Exchange/test.fetchTicker.js +38 -0
  213. package/js/test/Exchange/test.fetchTickers.js +49 -0
  214. package/js/test/Exchange/test.fetchTrades.js +39 -0
  215. package/js/test/Exchange/test.fetchTradingFee.js +18 -0
  216. package/js/test/Exchange/test.fetchTradingFees.js +22 -0
  217. package/js/test/Exchange/test.fetchTransactions.js +31 -0
  218. package/js/test/Exchange/test.fetchWithdrawals.js +31 -0
  219. package/js/test/Exchange/test.ledgerItem.js +46 -0
  220. package/js/test/Exchange/test.leverageTier.js +33 -0
  221. package/js/test/Exchange/test.loadMarkets.js +35 -0
  222. package/js/test/Exchange/test.market.js +129 -0
  223. package/js/test/Exchange/test.ohlcv.js +33 -0
  224. package/js/test/Exchange/test.order.js +62 -0
  225. package/js/test/Exchange/test.orderbook.js +61 -0
  226. package/js/test/Exchange/test.position.js +21 -0
  227. package/js/test/Exchange/test.throttle.js +94 -0
  228. package/js/test/Exchange/test.ticker.js +95 -0
  229. package/js/test/Exchange/test.trade.js +68 -0
  230. package/js/test/Exchange/test.tradingFee.js +34 -0
  231. package/js/test/Exchange/test.transaction.js +35 -0
  232. package/js/test/base/.eslintrc +38 -0
  233. package/js/test/base/functions/test.crypto.js +110 -0
  234. package/js/test/base/functions/test.datetime.js +62 -0
  235. package/js/test/base/functions/test.generic.js +152 -0
  236. package/js/test/base/functions/test.number.js +362 -0
  237. package/js/test/base/functions/test.time.js +56 -0
  238. package/js/test/base/functions/test.type.js +53 -0
  239. package/js/test/base/test.base.js +193 -0
  240. package/js/test/errors/test.InsufficientFunds.js +86 -0
  241. package/js/test/errors/test.InvalidNonce.js +64 -0
  242. package/js/test/errors/test.InvalidOrder.js +35 -0
  243. package/js/test/errors/test.OrderNotFound.js +39 -0
  244. package/js/test/test.js +426 -0
  245. package/js/test/test.timeout_hang.js +12 -0
  246. package/js/therock.js +1431 -0
  247. package/js/tidebit.js +632 -0
  248. package/js/tidex.js +939 -0
  249. package/js/timex.js +1283 -0
  250. package/js/upbit.js +1622 -0
  251. package/js/vcc.js +1353 -0
  252. package/js/wavesexchange.js +2185 -0
  253. package/js/wazirx.js +732 -0
  254. package/js/whitebit.js +1352 -0
  255. package/js/woo.js +1577 -0
  256. package/js/xena.js +1948 -0
  257. package/js/yobit.js +1129 -0
  258. package/js/zaif.js +647 -0
  259. package/js/zb.js +4088 -0
  260. package/js/zipmex.js +40 -0
  261. package/js/zonda.js +1497 -0
  262. package/multilang.sh +159 -0
  263. package/package.json +591 -0
  264. package/postinstall.js +103 -0
package/js/ripio.js ADDED
@@ -0,0 +1,1061 @@
1
+ 'use strict';
2
+
3
+ // ---------------------------------------------------------------------------
4
+
5
+ const Exchange = require ('./base/Exchange');
6
+ const { AuthenticationError, ExchangeError, BadSymbol, BadRequest, InvalidOrder, ArgumentsRequired, OrderNotFound, InsufficientFunds, DDoSProtection } = require ('./base/errors');
7
+ const { TICK_SIZE } = require ('./base/functions/number');
8
+
9
+ // ---------------------------------------------------------------------------
10
+
11
+ module.exports = class ripio extends Exchange {
12
+ describe () {
13
+ return this.deepExtend (super.describe (), {
14
+ 'id': 'ripio',
15
+ 'name': 'Ripio',
16
+ 'countries': [ 'AR', 'BR' ], // Argentina
17
+ 'rateLimit': 50,
18
+ 'version': 'v1',
19
+ 'pro': true,
20
+ // new metainfo interface
21
+ 'has': {
22
+ 'CORS': undefined,
23
+ 'spot': true,
24
+ 'margin': false,
25
+ 'swap': false,
26
+ 'future': false,
27
+ 'option': false,
28
+ 'addMargin': false,
29
+ 'cancelOrder': true,
30
+ 'createOrder': true,
31
+ 'createReduceOnlyOrder': false,
32
+ 'fetchBalance': true,
33
+ 'fetchBorrowRate': false,
34
+ 'fetchBorrowRateHistories': false,
35
+ 'fetchBorrowRateHistory': false,
36
+ 'fetchBorrowRates': false,
37
+ 'fetchBorrowRatesPerSymbol': false,
38
+ 'fetchClosedOrders': true,
39
+ 'fetchCurrencies': true,
40
+ 'fetchFundingHistory': false,
41
+ 'fetchFundingRate': false,
42
+ 'fetchFundingRateHistory': false,
43
+ 'fetchFundingRates': false,
44
+ 'fetchIndexOHLCV': false,
45
+ 'fetchLeverage': false,
46
+ 'fetchLeverageTiers': false,
47
+ 'fetchMarkOHLCV': false,
48
+ 'fetchMyTrades': true,
49
+ 'fetchOpenOrders': true,
50
+ 'fetchOrder': true,
51
+ 'fetchOrderBook': true,
52
+ 'fetchOrders': true,
53
+ 'fetchPosition': false,
54
+ 'fetchPositions': false,
55
+ 'fetchPositionsRisk': false,
56
+ 'fetchPremiumIndexOHLCV': false,
57
+ 'fetchTicker': true,
58
+ 'fetchTickers': true,
59
+ 'fetchTrades': true,
60
+ 'fetchTradingFee': false,
61
+ 'fetchTradingFees': true,
62
+ 'reduceMargin': false,
63
+ 'setLeverage': false,
64
+ 'setMarginMode': false,
65
+ 'setPositionMode': false,
66
+ },
67
+ 'urls': {
68
+ 'logo': 'https://user-images.githubusercontent.com/1294454/94507548-a83d6a80-0218-11eb-9998-28b9cec54165.jpg',
69
+ 'api': {
70
+ 'public': 'https://api.exchange.ripio.com/api',
71
+ 'private': 'https://api.exchange.ripio.com/api',
72
+ },
73
+ 'www': 'https://exchange.ripio.com',
74
+ 'doc': [
75
+ 'https://exchange.ripio.com/en/api/',
76
+ ],
77
+ 'fees': 'https://exchange.ripio.com/en/fee',
78
+ },
79
+ 'api': {
80
+ 'public': {
81
+ 'get': [
82
+ 'rate/all/',
83
+ 'rate/{pair}/',
84
+ 'orderbook/{pair}/',
85
+ 'tradehistory/{pair}/',
86
+ 'pair/',
87
+ 'currency/',
88
+ 'orderbook/{pair}/depth/',
89
+ ],
90
+ },
91
+ 'private': {
92
+ 'get': [
93
+ 'balances/exchange_balances/',
94
+ 'order/{pair}/{order_id}/',
95
+ 'order/{pair}/',
96
+ 'trade/{pair}/',
97
+ ],
98
+ 'post': [
99
+ 'order/{pair}/',
100
+ 'order/{pair}/{order_id}/cancel/',
101
+ ],
102
+ },
103
+ },
104
+ 'fees': {
105
+ 'trading': {
106
+ 'tierBased': true,
107
+ 'percentage': true,
108
+ 'taker': 0.0 / 100,
109
+ 'maker': 0.0 / 100,
110
+ },
111
+ },
112
+ 'precisionMode': TICK_SIZE,
113
+ 'requiredCredentials': {
114
+ 'apiKey': true,
115
+ 'secret': false,
116
+ },
117
+ 'exceptions': {
118
+ 'exact': {
119
+ },
120
+ 'broad': {
121
+ 'Authentication credentials were not provided': AuthenticationError, // {"detail":"Authentication credentials were not provided."}
122
+ 'Disabled pair': BadSymbol, // {"status_code":400,"errors":{"pair":["Invalid/Disabled pair BTC_ARS"]},"message":"An error has occurred, please check the form."}
123
+ 'Invalid order type': InvalidOrder, // {"status_code":400,"errors":{"order_type":["Invalid order type. Valid options: ['MARKET', 'LIMIT']"]},"message":"An error has occurred, please check the form."}
124
+ 'Your balance is not enough': InsufficientFunds, // {"status_code":400,"errors":{"non_field_errors":["Your balance is not enough for this order: You have 0 BTC but you need 1 BTC"]},"message":"An error has occurred, please check the form."}
125
+ "Order couldn't be created": ExchangeError, // {'status_code': 400,'errors': {'non_field_errors': _("Order couldn't be created")}, 'message': _('Seems like an unexpected error occurred. Please try again later or write us to support@ripio.com if the problem persists.') }
126
+ // {"status_code":404,"errors":{"order":["Order 286e560e-b8a2-464b-8b84-15a7e2a67eab not found."]},"message":"An error has occurred, please check the form."}
127
+ // {"status_code":404,"errors":{"trade":["Trade <trade_id> not found."]},"message":"An error has occurred, please check the form."}
128
+ 'not found': OrderNotFound,
129
+ 'Invalid pair': BadSymbol, // {"status_code":400,"errors":{"pair":["Invalid pair FOOBAR"]},"message":"An error has occurred, please check the form."}
130
+ 'amount must be a number': BadRequest, // {"status_code":400,"errors":{"amount":["amount must be a number"]},"message":"An error has occurred, please check the form."}
131
+ 'Total must be at least': InvalidOrder, // {"status_code":400,"errors":{"non_field_errors":["Total must be at least 10."]},"message":"An error has occurred, please check the form."}
132
+ 'Account not found': BadRequest, // {"error_description": "Account not found."}, "status": 404
133
+ 'Wrong password provided': AuthenticationError, // {'error': "Wrong password provided."}, “status_code”: 400
134
+ 'User tokens limit': DDoSProtection, // {'error': "User tokens limit. Can't create more than 10 tokens."}, “status_code”: 400
135
+ 'Something unexpected ocurred': ExchangeError, // {'status_code': 400, 'errors': {'non_field_errors': 'Something unexpected ocurred!'}, 'message': 'Seems like an unexpected error occurred. Please try again later or write us to support@ripio.com if the problem persists.'}
136
+ // {'status_code': 404, 'errors': {'account_balance': ['Exchange balance <currency>not found.']},'message': 'An error has occurred, please check the form.'}
137
+ // {'status_code': 404, 'errors': {'account_balance': ['Account balance <id> not found.']},'message': 'An error has occurred, please check the form.'}
138
+ 'account_balance': BadRequest,
139
+ },
140
+ },
141
+ });
142
+ }
143
+
144
+ async fetchMarkets (params = {}) {
145
+ const response = await this.publicGetPair (params);
146
+ //
147
+ // {
148
+ // "next":null,
149
+ // "previous":null,
150
+ // "results":[
151
+ // {
152
+ // "base":"BTC",
153
+ // "base_name":"Bitcoin",
154
+ // "quote":"USDC",
155
+ // "quote_name":"USD Coin",
156
+ // "symbol":"BTC_USDC",
157
+ // "fees":[
158
+ // {
159
+ // "traded_volume": 0.0,
160
+ // "maker_fee": 0.0,
161
+ // "taker_fee": 0.0,
162
+ // "cancellation_fee": 0.0
163
+ // }
164
+ // ],
165
+ // "country":"ZZ",
166
+ // "enabled":true,
167
+ // "priority":10,
168
+ // "min_amount":"0.00001",
169
+ // "price_tick":"0.000001",
170
+ // "min_value":"10",
171
+ // "limit_price_threshold":"25.00"
172
+ // },
173
+ // ]
174
+ // }
175
+ //
176
+ const result = [];
177
+ const results = this.safeValue (response, 'results', []);
178
+ for (let i = 0; i < results.length; i++) {
179
+ const market = results[i];
180
+ const baseId = this.safeString (market, 'base');
181
+ const quoteId = this.safeString (market, 'quote');
182
+ const id = this.safeString (market, 'symbol');
183
+ const base = this.safeCurrencyCode (baseId);
184
+ const quote = this.safeCurrencyCode (quoteId);
185
+ const fees = this.safeValue (market, 'fees', []);
186
+ const firstFee = this.safeValue (fees, 0, {});
187
+ result.push ({
188
+ 'id': id,
189
+ 'symbol': base + '/' + quote,
190
+ 'base': base,
191
+ 'quote': quote,
192
+ 'settle': undefined,
193
+ 'baseId': baseId,
194
+ 'quoteId': quoteId,
195
+ 'settleId': undefined,
196
+ 'type': 'spot',
197
+ 'spot': true,
198
+ 'margin': false,
199
+ 'swap': false,
200
+ 'future': false,
201
+ 'option': false,
202
+ 'active': this.safeValue (market, 'enabled', true),
203
+ 'contract': false,
204
+ 'linear': undefined,
205
+ 'inverse': undefined,
206
+ 'taker': this.safeNumber (firstFee, 'taker_fee', 0.0),
207
+ 'maker': this.safeNumber (firstFee, 'maker_fee', 0.0),
208
+ 'contractSize': undefined,
209
+ 'expiry': undefined,
210
+ 'expiryDatetime': undefined,
211
+ 'strike': undefined,
212
+ 'optionType': undefined,
213
+ 'precision': {
214
+ 'amount': this.safeNumber (market, 'min_amount'),
215
+ 'price': this.safeNumber (market, 'price_tick'),
216
+ },
217
+ 'limits': {
218
+ 'leverage': {
219
+ 'min': undefined,
220
+ 'max': undefined,
221
+ },
222
+ 'amount': {
223
+ 'min': this.safeNumber (market, 'min_amount'),
224
+ 'max': undefined,
225
+ },
226
+ 'price': {
227
+ 'min': undefined,
228
+ 'max': undefined,
229
+ },
230
+ 'cost': {
231
+ 'min': this.safeNumber (market, 'min_value'),
232
+ 'max': undefined,
233
+ },
234
+ },
235
+ 'info': market,
236
+ });
237
+ }
238
+ return result;
239
+ }
240
+
241
+ async fetchCurrencies (params = {}) {
242
+ const response = await this.publicGetCurrency (params);
243
+ //
244
+ // {
245
+ // "next":null,
246
+ // "previous":null,
247
+ // "results":[
248
+ // {
249
+ // "name":"Argentine Peso",
250
+ // "symbol":"$",
251
+ // "currency":"ARS",
252
+ // "country":"AR",
253
+ // "decimal_places":"2",
254
+ // "enabled":true
255
+ // },
256
+ // {
257
+ // "name":"Bitcoin Cash",
258
+ // "symbol":"BCH",
259
+ // "currency":"BCH",
260
+ // "country":"AR",
261
+ // "decimal_places":"8",
262
+ // "enabled":true
263
+ // },
264
+ // {
265
+ // "name":"Bitcoin",
266
+ // "symbol":"BTC",
267
+ // "currency":"BTC",
268
+ // "country":"AR",
269
+ // "decimal_places":"8",
270
+ // "enabled":true
271
+ // }
272
+ // ]
273
+ // }
274
+ //
275
+ const results = this.safeValue (response, 'results', []);
276
+ const result = {};
277
+ for (let i = 0; i < results.length; i++) {
278
+ const currency = results[i];
279
+ const id = this.safeString (currency, 'currency');
280
+ const code = this.safeCurrencyCode (id);
281
+ const name = this.safeString (currency, 'name');
282
+ const active = this.safeValue (currency, 'enabled', true);
283
+ const precision = this.safeInteger (currency, 'decimal_places');
284
+ result[code] = {
285
+ 'id': id,
286
+ 'code': code,
287
+ 'name': name,
288
+ 'info': currency, // the original payload
289
+ 'active': active,
290
+ 'deposit': undefined,
291
+ 'withdraw': undefined,
292
+ 'fee': undefined,
293
+ 'precision': precision,
294
+ 'limits': {
295
+ 'amount': { 'min': undefined, 'max': undefined },
296
+ 'withdraw': { 'min': undefined, 'max': undefined },
297
+ },
298
+ };
299
+ }
300
+ return result;
301
+ }
302
+
303
+ parseTicker (ticker, market = undefined) {
304
+ //
305
+ // fetchTicker, fetchTickers
306
+ //
307
+ // {
308
+ // "pair":"BTC_USDC",
309
+ // "last_price":"10850.02",
310
+ // "low":"10720.03",
311
+ // "high":"10909.99",
312
+ // "variation":"1.21",
313
+ // "volume":"0.83868",
314
+ // "base":"BTC",
315
+ // "base_name":"Bitcoin",
316
+ // "quote":"USDC",
317
+ // "quote_name":"USD Coin",
318
+ // "bid":"10811.00",
319
+ // "ask":"10720.03",
320
+ // "avg":"10851.47",
321
+ // "ask_volume":"0.00140",
322
+ // "bid_volume":"0.00185",
323
+ // "created_at":"2020-09-28 21:44:51.228920+00:00"
324
+ // }
325
+ //
326
+ const timestamp = this.parse8601 (this.safeString (ticker, 'created_at'));
327
+ const marketId = this.safeString (ticker, 'pair');
328
+ market = this.safeMarket (marketId, market, '_');
329
+ const symbol = market['symbol'];
330
+ const last = this.safeString (ticker, 'last_price');
331
+ const average = this.safeString (ticker, 'avg');
332
+ return this.safeTicker ({
333
+ 'symbol': symbol,
334
+ 'timestamp': timestamp,
335
+ 'datetime': this.iso8601 (timestamp),
336
+ 'high': this.safeString (ticker, 'high'),
337
+ 'low': this.safeString (ticker, 'low'),
338
+ 'bid': this.safeString (ticker, 'bid'),
339
+ 'bidVolume': this.safeString (ticker, 'bid_volume'),
340
+ 'ask': this.safeString (ticker, 'ask'),
341
+ 'askVolume': this.safeString (ticker, 'ask_volume'),
342
+ 'vwap': undefined,
343
+ 'open': undefined,
344
+ 'close': last,
345
+ 'last': last,
346
+ 'previousClose': undefined,
347
+ 'change': undefined,
348
+ 'percentage': undefined,
349
+ 'average': average,
350
+ 'baseVolume': undefined,
351
+ 'quoteVolume': undefined,
352
+ 'info': ticker,
353
+ }, market, false);
354
+ }
355
+
356
+ async fetchTicker (symbol, params = {}) {
357
+ await this.loadMarkets ();
358
+ const market = this.market (symbol);
359
+ const request = {
360
+ 'pair': market['id'],
361
+ };
362
+ const response = await this.publicGetRatePair (this.extend (request, params));
363
+ //
364
+ // {
365
+ // "pair":"BTC_USDC",
366
+ // "last_price":"10850.02",
367
+ // "low":"10720.03",
368
+ // "high":"10909.99",
369
+ // "variation":"1.21",
370
+ // "volume":"0.83868",
371
+ // "base":"BTC",
372
+ // "base_name":"Bitcoin",
373
+ // "quote":"USDC",
374
+ // "quote_name":"USD Coin",
375
+ // "bid":"10811.00",
376
+ // "ask":"10720.03",
377
+ // "avg":"10851.47",
378
+ // "ask_volume":"0.00140",
379
+ // "bid_volume":"0.00185",
380
+ // "created_at":"2020-09-28 21:44:51.228920+00:00"
381
+ // }
382
+ //
383
+ return this.parseTicker (response, market);
384
+ }
385
+
386
+ async fetchTickers (symbols = undefined, params = {}) {
387
+ await this.loadMarkets ();
388
+ const response = await this.publicGetRateAll (params);
389
+ //
390
+ // [
391
+ // {
392
+ // "pair":"BTC_USDC",
393
+ // "last_price":"10850.02",
394
+ // "low":"10720.03",
395
+ // "high":"10909.99",
396
+ // "variation":"1.21",
397
+ // "volume":"0.83868",
398
+ // "base":"BTC",
399
+ // "base_name":"Bitcoin",
400
+ // "quote":"USDC",
401
+ // "quote_name":"USD Coin",
402
+ // "bid":"10811.00",
403
+ // "ask":"10720.03",
404
+ // "avg":"10851.47",
405
+ // "ask_volume":"0.00140",
406
+ // "bid_volume":"0.00185",
407
+ // "created_at":"2020-09-28 21:44:51.228920+00:00"
408
+ // }
409
+ // ]
410
+ //
411
+ const result = {};
412
+ for (let i = 0; i < response.length; i++) {
413
+ const ticker = this.parseTicker (response[i]);
414
+ const symbol = ticker['symbol'];
415
+ result[symbol] = ticker;
416
+ }
417
+ return this.filterByArray (result, 'symbol', symbols);
418
+ }
419
+
420
+ async fetchOrderBook (symbol, limit = undefined, params = {}) {
421
+ await this.loadMarkets ();
422
+ const request = {
423
+ 'pair': this.marketId (symbol),
424
+ };
425
+ const response = await this.publicGetOrderbookPair (this.extend (request, params));
426
+ //
427
+ // {
428
+ // "buy":[
429
+ // {"amount":"0.00230","total":"24.95","price":"10850.02"},
430
+ // {"amount":"0.07920","total":"858.52","price":"10840.00"},
431
+ // {"amount":"0.00277","total":"30.00","price":"10833.03"},
432
+ // ],
433
+ // "sell":[
434
+ // {"amount":"0.03193","total":"348.16","price":"10904.00"},
435
+ // {"amount":"0.00210","total":"22.90","price":"10905.70"},
436
+ // {"amount":"0.00300","total":"32.72","price":"10907.98"},
437
+ // ],
438
+ // "updated_id":47225
439
+ // }
440
+ //
441
+ const orderbook = this.parseOrderBook (response, symbol, undefined, 'buy', 'sell', 'price', 'amount');
442
+ orderbook['nonce'] = this.safeInteger (response, 'updated_id');
443
+ return orderbook;
444
+ }
445
+
446
+ parseTrade (trade, market = undefined) {
447
+ //
448
+ //
449
+ // fetchTrades (public)
450
+ //
451
+ // {
452
+ // "created_at":1649899167,
453
+ // "amount":"0.00852",
454
+ // "price":"3106.000000",
455
+ // "side":"SELL",
456
+ // "pair":"ETH_USDC",
457
+ // "taker_fee":"0",
458
+ // "taker_side":"SELL",
459
+ // "maker_fee":"0"
460
+ // }
461
+ //
462
+ //
463
+ // fetchMyTrades (private)
464
+ //
465
+ // {
466
+ // "created_at":1601322501,
467
+ // "amount":"0.00276",
468
+ // "price":"10850.020000",
469
+ // "side":"SELL",
470
+ // "pair":"BTC_USDC",
471
+ // "taker_fee":"0",
472
+ // "taker_side":"SELL",
473
+ // "maker_fee":"0",
474
+ // "taker":2577953,
475
+ // "maker":2577937
476
+ // }
477
+ //
478
+ // createOrder fills
479
+ //
480
+ // {
481
+ // "pair":"BTC_USDC",
482
+ // "exchanged":0.002,
483
+ // "match_price":10593.99,
484
+ // "maker_fee":0.0,
485
+ // "taker_fee":0.0,
486
+ // "timestamp":1601730306942
487
+ // }
488
+ //
489
+ const id = this.safeString (trade, 'id');
490
+ let timestamp = this.safeInteger (trade, 'timestamp');
491
+ timestamp = this.safeTimestamp (trade, 'created_at', timestamp);
492
+ let side = this.safeString (trade, 'side');
493
+ const takerSide = this.safeString (trade, 'taker_side');
494
+ const takerOrMaker = (takerSide === side) ? 'taker' : 'maker';
495
+ if (side !== undefined) {
496
+ side = side.toLowerCase ();
497
+ }
498
+ const priceString = this.safeString2 (trade, 'price', 'match_price');
499
+ const amountString = this.safeString2 (trade, 'amount', 'exchanged');
500
+ const marketId = this.safeString (trade, 'pair');
501
+ market = this.safeMarket (marketId, market);
502
+ const feeCostString = this.safeString (trade, takerOrMaker + '_fee');
503
+ const orderId = this.safeString (trade, takerOrMaker);
504
+ let fee = undefined;
505
+ if (feeCostString !== undefined) {
506
+ fee = {
507
+ 'cost': feeCostString,
508
+ 'currency': (side === 'buy') ? market['base'] : market['quote'],
509
+ };
510
+ }
511
+ return this.safeTrade ({
512
+ 'id': id,
513
+ 'order': orderId,
514
+ 'timestamp': timestamp,
515
+ 'datetime': this.iso8601 (timestamp),
516
+ 'symbol': market['symbol'],
517
+ 'type': undefined,
518
+ 'side': side,
519
+ 'price': priceString,
520
+ 'amount': amountString,
521
+ 'cost': undefined,
522
+ 'takerOrMaker': takerOrMaker,
523
+ 'fee': fee,
524
+ 'info': trade,
525
+ }, market);
526
+ }
527
+
528
+ async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
529
+ await this.loadMarkets ();
530
+ const market = this.market (symbol);
531
+ const request = {
532
+ 'pair': market['id'],
533
+ };
534
+ const response = await this.publicGetTradehistoryPair (this.extend (request, params));
535
+ //
536
+ // [
537
+ // {
538
+ // "created_at":1649899167,
539
+ // "amount":"0.00852",
540
+ // "price":"3106.000000",
541
+ // "side":"SELL",
542
+ // "pair":"ETH_USDC",
543
+ // "taker_fee":"0",
544
+ // "taker_side":"SELL",
545
+ // "maker_fee":"0"
546
+ // }
547
+ // ]
548
+ //
549
+ return this.parseTrades (response, market, since, limit);
550
+ }
551
+
552
+ async fetchTradingFees (params = {}) {
553
+ await this.loadMarkets ();
554
+ const response = await this.publicGetPair (params);
555
+ //
556
+ // {
557
+ // next: null,
558
+ // previous: null,
559
+ // results: [
560
+ // {
561
+ // base: 'BTC',
562
+ // base_name: 'Bitcoin',
563
+ // quote: 'USDC',
564
+ // quote_name: 'USD Coin',
565
+ // symbol: 'BTC_USDC',
566
+ // fees: [
567
+ // {
568
+ // traded_volume: '0.0',
569
+ // maker_fee: '0.0',
570
+ // taker_fee: '0.0',
571
+ // cancellation_fee: '0.0'
572
+ // }
573
+ // ],
574
+ // country: 'ZZ',
575
+ // enabled: true,
576
+ // priority: '10',
577
+ // min_amount: '0.0000100000',
578
+ // price_tick: '0.000001',
579
+ // min_value: '10',
580
+ // limit_price_threshold: '25.00'
581
+ // },
582
+ // ]
583
+ // }
584
+ //
585
+ const results = this.safeValue (response, 'results', []);
586
+ const result = {};
587
+ for (let i = 0; i < results.length; i++) {
588
+ const pair = results[i];
589
+ const marketId = this.safeString (pair, 'symbol');
590
+ const symbol = this.safeSymbol (marketId, undefined, '_');
591
+ const fees = this.safeValue (pair, 'fees', []);
592
+ const fee = this.safeValue (fees, 0, {});
593
+ result[symbol] = {
594
+ 'info': pair,
595
+ 'symbol': symbol,
596
+ 'maker': this.safeNumber (fee, 'maker_fee'),
597
+ 'taker': this.safeNumber (fee, 'taker_fee'),
598
+ 'tierBased': false,
599
+ };
600
+ }
601
+ return result;
602
+ }
603
+
604
+ parseBalance (response) {
605
+ const result = { 'info': response };
606
+ for (let i = 0; i < response.length; i++) {
607
+ const balance = response[i];
608
+ const currencyId = this.safeString (balance, 'symbol');
609
+ const code = this.safeCurrencyCode (currencyId);
610
+ const account = this.account ();
611
+ account['free'] = this.safeString (balance, 'available');
612
+ account['used'] = this.safeString (balance, 'locked');
613
+ result[code] = account;
614
+ }
615
+ return this.safeBalance (result);
616
+ }
617
+
618
+ async fetchBalance (params = {}) {
619
+ await this.loadMarkets ();
620
+ const response = await this.privateGetBalancesExchangeBalances (params);
621
+ //
622
+ // [
623
+ // {
624
+ // "id":603794,
625
+ // "currency":"USD Coin",
626
+ // "symbol":"USDC",
627
+ // "available":"0",
628
+ // "locked":"0",
629
+ // "code":"exchange",
630
+ // "balance_type":"crypto"
631
+ // },
632
+ // ]
633
+ //
634
+ return this.parseBalance (response);
635
+ }
636
+
637
+ async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
638
+ await this.loadMarkets ();
639
+ const market = this.market (symbol);
640
+ const uppercaseType = type.toUpperCase ();
641
+ const uppercaseSide = side.toUpperCase ();
642
+ const request = {
643
+ 'pair': market['id'],
644
+ 'order_type': uppercaseType, // LIMIT, MARKET
645
+ 'side': uppercaseSide, // BUY or SELL
646
+ 'amount': this.amountToPrecision (symbol, amount),
647
+ };
648
+ if (uppercaseType === 'LIMIT') {
649
+ request['limit_price'] = this.priceToPrecision (symbol, price);
650
+ }
651
+ const response = await this.privatePostOrderPair (this.extend (request, params));
652
+ //
653
+ // {
654
+ // "order_id": "160f523c-f6ef-4cd1-a7c9-1a8ede1468d8",
655
+ // "pair": "BTC_ARS",
656
+ // "side": "BUY",
657
+ // "amount": "0.00400",
658
+ // "notional": null,
659
+ // "fill_or_kill": false,
660
+ // "all_or_none": false,
661
+ // "order_type": "LIMIT",
662
+ // "status": "OPEN",
663
+ // "created_at": 1578413945,
664
+ // "filled": "0.00000",
665
+ // "limit_price": "10.00",
666
+ // "stop_price": null,
667
+ // "distance": null
668
+ // }
669
+ //
670
+ // createOrder market type
671
+ //
672
+ // {
673
+ // "order_id":"d6b60c01-8624-44f2-9e6c-9e8cd677ea5c",
674
+ // "pair":"BTC_USDC",
675
+ // "side":"BUY",
676
+ // "amount":"0.00200",
677
+ // "notional":"50",
678
+ // "fill_or_kill":false,
679
+ // "all_or_none":false,
680
+ // "order_type":"MARKET",
681
+ // "status":"OPEN",
682
+ // "created_at":1601730306,
683
+ // "filled":"0.00000",
684
+ // "fill_price":10593.99,
685
+ // "fee":0.0,
686
+ // "fills":[
687
+ // {
688
+ // "pair":"BTC_USDC",
689
+ // "exchanged":0.002,
690
+ // "match_price":10593.99,
691
+ // "maker_fee":0.0,
692
+ // "taker_fee":0.0,
693
+ // "timestamp":1601730306942
694
+ // }
695
+ // ],
696
+ // "filled_at":"2020-10-03T13:05:06.942186Z",
697
+ // "limit_price":"0.000000",
698
+ // "stop_price":null,
699
+ // "distance":null
700
+ // }
701
+ //
702
+ return this.parseOrder (response, market);
703
+ }
704
+
705
+ async cancelOrder (id, symbol = undefined, params = {}) {
706
+ if (symbol === undefined) {
707
+ throw new ArgumentsRequired (this.id + ' cancelOrder() requires a symbol argument');
708
+ }
709
+ await this.loadMarkets ();
710
+ const market = this.market (symbol);
711
+ const request = {
712
+ 'pair': market['id'],
713
+ 'order_id': id,
714
+ };
715
+ const response = await this.privatePostOrderPairOrderIdCancel (this.extend (request, params));
716
+ //
717
+ // {
718
+ // "order_id": "286e560e-b8a2-464b-8b84-15a7e2a67eab",
719
+ // "pair": "BTC_ARS",
720
+ // "side": "SELL",
721
+ // "amount": "0.00100",
722
+ // "notional": null,
723
+ // "fill_or_kill": false,
724
+ // "all_or_none": false,
725
+ // "order_type": "LIMIT",
726
+ // "status": "CANC",
727
+ // "created_at": 1575472707,
728
+ // "filled": "0.00000",
729
+ // "limit_price": "681000.00",
730
+ // "stop_price": null,
731
+ // "distance": null
732
+ // }
733
+ //
734
+ return this.parseOrder (response, market);
735
+ }
736
+
737
+ async fetchOrder (id, symbol = undefined, params = {}) {
738
+ if (symbol === undefined) {
739
+ throw new ArgumentsRequired (this.id + ' fetchOrder() requires a symbol argument');
740
+ }
741
+ await this.loadMarkets ();
742
+ const market = this.market (symbol);
743
+ const request = {
744
+ 'pair': market['id'],
745
+ 'order_id': id,
746
+ };
747
+ const response = await this.privateGetOrderPairOrderId (this.extend (request, params));
748
+ //
749
+ // {
750
+ // "order_id": "0b4ff48e-cfd6-42db-8d8c-3b536da447af",
751
+ // "pair": "BTC_ARS",
752
+ // "side": "BUY",
753
+ // "amount": "0.00100",
754
+ // "notional": null,
755
+ // "fill_or_kill": false,
756
+ // "all_or_none": false,
757
+ // "order_type": "LIMIT",
758
+ // "status": "OPEN",
759
+ // "created_at": 1575472944,
760
+ // "filled": "0.00000",
761
+ // "limit_price": "661000.00",
762
+ // "stop_price": null,
763
+ // "distance": null
764
+ // }
765
+ //
766
+ return this.parseOrder (response, market);
767
+ }
768
+
769
+ async fetchOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
770
+ if (symbol === undefined) {
771
+ throw new ArgumentsRequired (this.id + ' fetchOrders() requires a symbol argument');
772
+ }
773
+ await this.loadMarkets ();
774
+ const market = this.market (symbol);
775
+ const request = {
776
+ 'pair': market['id'],
777
+ // 'status': 'OPEN,PART,CLOS,CANC,COMP',
778
+ // 'offset': 0,
779
+ // 'limit': limit,
780
+ };
781
+ if (limit !== undefined) {
782
+ request['offset'] = limit;
783
+ }
784
+ const response = await this.privateGetOrderPair (this.extend (request, params));
785
+ //
786
+ // {
787
+ // "next": "https://api.exchange.ripio.com/api/v1/order/BTC_ARS/?limit=20&offset=20&page=1&page_size=25&status=OPEN%2CPART",
788
+ // "previous": null,
789
+ // "results": {
790
+ // "data": [
791
+ // {
792
+ // "order_id": "ca74280b-6966-4b73-a720-68709078922b",
793
+ // "pair": "BTC_ARS",
794
+ // "side": "SELL",
795
+ // "amount": "0.00100",
796
+ // "notional": null,
797
+ // "fill_or_kill": false,
798
+ // "all_or_none": false,
799
+ // "order_type": "LIMIT",
800
+ // "status": "OPEN",
801
+ // "created_at": 1578340134,
802
+ // "filled": "0.00000",
803
+ // "limit_price": "665000.00",
804
+ // "stop_price": null,
805
+ // "distance": null
806
+ // },
807
+ // ]
808
+ // }
809
+ // }
810
+ //
811
+ const results = this.safeValue (response, 'results', {});
812
+ const data = this.safeValue (results, 'data', []);
813
+ return this.parseOrders (data, market, since, limit);
814
+ }
815
+
816
+ async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
817
+ const request = {
818
+ 'status': 'OPEN,PART',
819
+ };
820
+ return await this.fetchOrders (symbol, since, limit, this.extend (request, params));
821
+ }
822
+
823
+ async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
824
+ const request = {
825
+ 'status': 'CLOS,CANC,COMP',
826
+ };
827
+ return await this.fetchOrders (symbol, since, limit, this.extend (request, params));
828
+ }
829
+
830
+ parseOrderStatus (status) {
831
+ const statuses = {
832
+ 'OPEN': 'open',
833
+ 'PART': 'open',
834
+ 'CLOS': 'canceled',
835
+ 'CANC': 'canceled',
836
+ 'COMP': 'closed',
837
+ };
838
+ return this.safeString (statuses, status, status);
839
+ }
840
+
841
+ parseOrder (order, market = undefined) {
842
+ //
843
+ // createOrder, cancelOrder, fetchOpenOrders, fetchClosedOrders, fetchOrders, fetchOrder
844
+ //
845
+ // {
846
+ // "order_id": "286e560e-b8a2-464b-8b84-15a7e2a67eab",
847
+ // "pair": "BTC_ARS",
848
+ // "side": "SELL",
849
+ // "amount": "0.00100",
850
+ // "notional": null,
851
+ // "fill_or_kill": false,
852
+ // "all_or_none": false,
853
+ // "order_type": "LIMIT",
854
+ // "status": "CANC",
855
+ // "created_at": 1575472707,
856
+ // "filled": "0.00000",
857
+ // "limit_price": "681000.00",
858
+ // "stop_price": null,
859
+ // "distance": null
860
+ // }
861
+ //
862
+ // {
863
+ // "order_id":"d6b60c01-8624-44f2-9e6c-9e8cd677ea5c",
864
+ // "pair":"BTC_USDC",
865
+ // "side":"BUY",
866
+ // "amount":"0.00200",
867
+ // "notional":"50",
868
+ // "fill_or_kill":false,
869
+ // "all_or_none":false,
870
+ // "order_type":"MARKET",
871
+ // "status":"OPEN",
872
+ // "created_at":1601730306,
873
+ // "filled":"0.00000",
874
+ // "fill_price":10593.99,
875
+ // "fee":0.0,
876
+ // "fills":[
877
+ // {
878
+ // "pair":"BTC_USDC",
879
+ // "exchanged":0.002,
880
+ // "match_price":10593.99,
881
+ // "maker_fee":0.0,
882
+ // "taker_fee":0.0,
883
+ // "timestamp":1601730306942
884
+ // }
885
+ // ],
886
+ // "filled_at":"2020-10-03T13:05:06.942186Z",
887
+ // "limit_price":"0.000000",
888
+ // "stop_price":null,
889
+ // "distance":null
890
+ // }
891
+ //
892
+ const id = this.safeString (order, 'order_id');
893
+ const amount = this.safeNumber (order, 'amount');
894
+ let cost = this.safeNumber (order, 'notional');
895
+ const type = this.safeStringLower (order, 'order_type');
896
+ const priceField = (type === 'market') ? 'fill_price' : 'limit_price';
897
+ const price = this.safeNumber (order, priceField);
898
+ const side = this.safeStringLower (order, 'side');
899
+ const status = this.parseOrderStatus (this.safeString (order, 'status'));
900
+ const timestamp = this.safeTimestamp (order, 'created_at');
901
+ let average = this.safeValue (order, 'fill_price');
902
+ let filled = this.safeNumber (order, 'filled');
903
+ let remaining = undefined;
904
+ const fills = this.safeValue (order, 'fills');
905
+ let trades = undefined;
906
+ let lastTradeTimestamp = undefined;
907
+ if (fills !== undefined) {
908
+ const numFills = fills.length;
909
+ if (numFills > 0) {
910
+ filled = 0;
911
+ cost = 0;
912
+ trades = this.parseTrades (fills, market, undefined, undefined, {
913
+ 'order': id,
914
+ 'side': side,
915
+ });
916
+ for (let i = 0; i < trades.length; i++) {
917
+ const trade = trades[i];
918
+ filled = this.sum (trade['amount'], filled);
919
+ cost = this.sum (trade['cost'], cost);
920
+ lastTradeTimestamp = trade['timestamp'];
921
+ }
922
+ if ((average === undefined) && (filled > 0)) {
923
+ average = cost / filled;
924
+ }
925
+ }
926
+ }
927
+ if (filled !== undefined) {
928
+ if ((cost === undefined) && (price !== undefined)) {
929
+ cost = price * filled;
930
+ }
931
+ if (amount !== undefined) {
932
+ remaining = Math.max (0, amount - filled);
933
+ }
934
+ }
935
+ const marketId = this.safeString (order, 'pair');
936
+ const symbol = this.safeSymbol (marketId, market, '_');
937
+ const stopPrice = this.safeNumber (order, 'stop_price');
938
+ return {
939
+ 'id': id,
940
+ 'clientOrderId': undefined,
941
+ 'info': order,
942
+ 'timestamp': timestamp,
943
+ 'datetime': this.iso8601 (timestamp),
944
+ 'lastTradeTimestamp': lastTradeTimestamp,
945
+ 'symbol': symbol,
946
+ 'type': type,
947
+ 'timeInForce': undefined,
948
+ 'postOnly': undefined,
949
+ 'side': side,
950
+ 'price': price,
951
+ 'stopPrice': stopPrice,
952
+ 'amount': amount,
953
+ 'cost': cost,
954
+ 'average': average,
955
+ 'filled': filled,
956
+ 'remaining': remaining,
957
+ 'status': status,
958
+ 'fee': undefined,
959
+ 'trades': trades,
960
+ };
961
+ }
962
+
963
+ async fetchMyTrades (symbol = undefined, since = undefined, limit = undefined, params = {}) {
964
+ if (symbol === undefined) {
965
+ throw new ArgumentsRequired (this.id + ' fetchMyTrades() requires a symbol argument');
966
+ }
967
+ await this.loadMarkets ();
968
+ const market = this.market (symbol);
969
+ const request = {
970
+ 'pair': market['id'],
971
+ // 'offset': 0,
972
+ // 'limit': limit,
973
+ };
974
+ if (limit !== undefined) {
975
+ request['limit'] = limit;
976
+ }
977
+ const response = await this.privateGetTradePair (this.extend (request, params));
978
+ //
979
+ // {
980
+ // "next": "https://api.exchange.ripio.com/api/v1/trade/<pair>/?limit=20&offset=20",
981
+ // "previous": null,
982
+ // "results": {
983
+ // "data": [
984
+ // {
985
+ // "created_at": 1578414028,
986
+ // "amount": "0.00100",
987
+ // "price": "665000.00",
988
+ // "side": "BUY",
989
+ // "taker_fee": "0",
990
+ // "taker_side": "BUY",
991
+ // "match_price": "66500000",
992
+ // "maker_fee": "0",
993
+ // "taker": 4892,
994
+ // "maker": 4889
995
+ // },
996
+ // ]
997
+ // }
998
+ // }
999
+ //
1000
+ const results = this.safeValue (response, 'results', {});
1001
+ const data = this.safeValue (results, 'data', []);
1002
+ return this.parseTrades (data, market, since, limit);
1003
+ }
1004
+
1005
+ sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
1006
+ const request = '/' + this.version + '/' + this.implodeParams (path, params);
1007
+ let url = this.urls['api'][api] + request;
1008
+ const query = this.omit (params, this.extractParams (path));
1009
+ if (api === 'public') {
1010
+ if (Object.keys (query).length) {
1011
+ url += '?' + this.urlencode (query);
1012
+ }
1013
+ } else if (api === 'private') {
1014
+ this.checkRequiredCredentials ();
1015
+ if (method === 'POST') {
1016
+ body = this.json (query);
1017
+ } else {
1018
+ if (Object.keys (query).length) {
1019
+ url += '?' + this.urlencode (query);
1020
+ }
1021
+ }
1022
+ headers = {
1023
+ 'Content-Type': 'application/json',
1024
+ 'Authorization': 'Bearer ' + this.apiKey,
1025
+ };
1026
+ }
1027
+ return { 'url': url, 'method': method, 'body': body, 'headers': headers };
1028
+ }
1029
+
1030
+ handleErrors (code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
1031
+ if (response === undefined) {
1032
+ return;
1033
+ }
1034
+ //
1035
+ // {"detail":"Authentication credentials were not provided."}
1036
+ // {"status_code":400,"errors":{"pair":["Invalid pair FOOBAR"]},"message":"An error has occurred, please check the form."}
1037
+ // {"status_code":400,"errors":{"order_type":["Invalid order type. Valid options: ['MARKET', 'LIMIT']"]},"message":"An error has occurred, please check the form."}
1038
+ // {"status_code":400,"errors":{"non_field_errors":"Something unexpected ocurred!"},"message":"Seems like an unexpected error occurred. Please try again later or write us to support@ripio.com if the problem persists."}
1039
+ // {"status_code":400,"errors":{"pair":["Invalid/Disabled pair BTC_ARS"]},"message":"An error has occurred, please check the form."}
1040
+ //
1041
+ const detail = this.safeString (response, 'detail');
1042
+ if (detail !== undefined) {
1043
+ const feedback = this.id + ' ' + body;
1044
+ // this.throwExactlyMatchedException (this.exceptions['exact'], message, feedback);
1045
+ this.throwBroadlyMatchedException (this.exceptions['broad'], detail, feedback);
1046
+ }
1047
+ const errors = this.safeValue (response, 'errors');
1048
+ if (errors !== undefined) {
1049
+ const feedback = this.id + ' ' + body;
1050
+ const keys = Object.keys (errors);
1051
+ for (let i = 0; i < keys.length; i++) {
1052
+ const key = keys[i];
1053
+ const error = this.safeValue (errors, key, []);
1054
+ const message = this.safeString (error, 0);
1055
+ // this.throwExactlyMatchedException (this.exceptions['exact'], message, feedback);
1056
+ this.throwBroadlyMatchedException (this.exceptions['broad'], message, feedback);
1057
+ }
1058
+ throw new ExchangeError (feedback); // unknown message
1059
+ }
1060
+ }
1061
+ };