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
@@ -0,0 +1,129 @@
1
+ 'use strict'
2
+
3
+ const assert = require ('assert')
4
+
5
+ function testMarket (exchange, market, method) {
6
+ const format = {
7
+ 'id': 'btcusd', // string literal for referencing within an exchange
8
+ 'symbol': 'BTC/USD', // uppercase string literal of a pair of currencies
9
+ 'base': 'BTC', // unified uppercase string, base currency, 3 or more letters
10
+ 'quote': 'USD', // unified uppercase string, quote currency, 3 or more letters
11
+ 'taker': 0.0011, // taker fee, for example, 0.0011 = 0.11%
12
+ 'maker': 0.0009, // maker fee, for example, 0.0009 = 0.09%
13
+ 'baseId': 'btc', // exchange-specific base currency id
14
+ 'quoteId': 'usd', // exchange-specific quote currency id
15
+ 'active': true, // boolean, market status
16
+ 'type': 'spot',
17
+ 'linear': undefined,
18
+ 'inverse': undefined,
19
+ 'spot': true,
20
+ 'swap': false,
21
+ 'future': false,
22
+ 'option': false,
23
+ 'margin': false,
24
+ 'contract': false,
25
+ 'contractSize': 0.001,
26
+ 'expiry': 1656057600000,
27
+ 'expiryDatetime': '2022-06-24T08:00:00.000Z',
28
+ 'optionType': 'put',
29
+ 'strike': 56000,
30
+ 'settle': undefined,
31
+ 'settleId': undefined,
32
+ 'precision': {
33
+ 'price': 8, // integer or fraction
34
+ 'amount': 8, // integer or fraction
35
+ 'cost': 8, // integer or fraction
36
+ },
37
+ // value limits when placing orders on this market
38
+ 'limits': {
39
+ 'amount': {
40
+ 'min': 0.01, // order amount should be > min
41
+ 'max': 1000, // order amount should be < max
42
+ },
43
+ 'price': {
44
+ 'min': 0.01, // order price should be > min
45
+ 'max': 1000, // order price should be < max
46
+ },
47
+ // order cost = price * amount
48
+ 'cost': {
49
+ 'min': 0.01, // order cost should be > min
50
+ 'max': 1000, // order cost should be < max
51
+ },
52
+ },
53
+ 'info': {}, // the original unparsed market info from the exchange
54
+ };
55
+ let keys = Object.keys (format);
56
+ for (let i = 0; i < keys.length; i++) {
57
+ const key = keys[i];
58
+ const keyPresent = (key in market);
59
+ assert (keyPresent, key + ' missing ' + exchange.json (market));
60
+ }
61
+ keys = [
62
+ 'id',
63
+ 'symbol',
64
+ 'baseId',
65
+ 'quoteId',
66
+ 'base',
67
+ 'quote',
68
+ 'precision',
69
+ 'limits',
70
+ ];
71
+ for (let i = 0; i < keys.length; i++) {
72
+ const key = keys[i];
73
+ assert (market[key] !== undefined, key + ' undefined ' + exchange.json (market));
74
+ }
75
+ assert ((market['taker'] === undefined) || (typeof market['taker'] === 'number'));
76
+ assert ((market['maker'] === undefined) || (typeof market['maker'] === 'number'));
77
+ if (market['contract']) {
78
+ assert (market['linear'] !== market['inverse']);
79
+ } else {
80
+ assert ((market['linear'] === undefined) && (market['inverse'] === undefined));
81
+ }
82
+ if (market['option']) {
83
+ assert (market['strike'] !== undefined);
84
+ assert (market['optionType'] !== undefined);
85
+ }
86
+ const validTypes = {
87
+ 'spot': true,
88
+ 'margin': true,
89
+ 'swap': true,
90
+ 'future': true,
91
+ 'option': true,
92
+ };
93
+ const type = market['type'];
94
+ //
95
+ // binance has type = 'delivery'
96
+ // https://github.com/ccxt/ccxt/issues/11121
97
+ //
98
+ // assert (type in validTypes);
99
+ //
100
+ const types = Object.keys (validTypes);
101
+ for (let i = 0; i < types.length; i++) {
102
+ const entry = types[i];
103
+ if (entry in market) {
104
+ const value = market[entry];
105
+ assert ((value === undefined) || value || !value);
106
+ }
107
+ }
108
+ //
109
+ // todo fix binance
110
+ //
111
+ // if (market['future']) {
112
+ // assert ((market['swap'] === false) && (market['option'] === false));
113
+ // } else if (market['swap']) {
114
+ // assert ((market['future'] === false) && (market['option'] === false));
115
+ // } else if (market['option']) {
116
+ // assert ((market['future'] === false) && (market['swap'] === false));
117
+ // }
118
+ // if (market['linear']) {
119
+ // assert (market['inverse'] === false);
120
+ // } else if (market['inverse']) {
121
+ // assert (market['linear'] === false);
122
+ // }
123
+ // if (market['future']) {
124
+ // assert (market['expiry'] !== undefined);
125
+ // assert (market['expiryDatetime'] !== undefined);
126
+ // }
127
+ }
128
+
129
+ module.exports = testMarket;
@@ -0,0 +1,33 @@
1
+ 'use strict';
2
+
3
+ const assert = require ('assert');
4
+
5
+ function testOHLCV (exchange, ohlcv, symbol, now) {
6
+
7
+ const json = exchange.json (ohlcv);
8
+ assert (ohlcv);
9
+ assert (Array.isArray (ohlcv), json);
10
+ const length = ohlcv.length;
11
+ assert (length >= 6);
12
+ for (let i = 0; i < ohlcv.length; i++) {
13
+ assert ((ohlcv[i] === undefined) || (typeof ohlcv[i] === 'number'), json);
14
+ }
15
+
16
+ assert (ohlcv[0] > 1230940800000, json); // 03 Jan 2009 - first block
17
+ assert (ohlcv[0] < 2147483648000, json); // 19 Jan 2038 - int32 overflows
18
+
19
+ const skippedExchanges = [
20
+ 'bitmex', // BitMEX API docs: also note the open price is equal to the close price of the previous timeframe bucket.
21
+ 'vcc', // same as BitMEX, the open price is equal to the close price of the previous timeframe bucket.
22
+ 'delta',
23
+ 'cryptocom',
24
+ ];
25
+
26
+ if (!exchange.inArray (exchange.id, skippedExchanges)) {
27
+ assert ((ohlcv[1] === undefined) || (ohlcv[2] === undefined) || (ohlcv[1] <= ohlcv[2]), 'open > high, ' + exchange.safeString (ohlcv, 1, 'undefined') + ' > ' + exchange.safeString (ohlcv, 2, 'undefined')); // open <= high
28
+ assert ((ohlcv[3] === undefined) || (ohlcv[2] === undefined) || (ohlcv[3] <= ohlcv[2]), 'low > high, ' + exchange.safeString (ohlcv, 2, 'undefined') + ' > ' + exchange.safeString (ohlcv, 3, 'undefined')); // low <= high
29
+ assert ((ohlcv[3] === undefined) || (ohlcv[4] === undefined) || (ohlcv[3] <= ohlcv[4]), 'low > close, ' + exchange.safeString (ohlcv, 3, 'undefined') + ' > ' + exchange.safeString (ohlcv, 4, 'undefined')); // low <= close
30
+ }
31
+ }
32
+
33
+ module.exports = testOHLCV;
@@ -0,0 +1,62 @@
1
+ 'use strict';
2
+
3
+ const assert = require ('assert');
4
+
5
+ function testOrder (exchange, order, symbol, now) {
6
+ assert (order);
7
+ assert ('id' in order);
8
+ assert (typeof order['id'] === 'string');
9
+ assert ('clientOrderId' in order);
10
+ assert ((order['clientOrderId'] === undefined) || (typeof order['clientOrderId'] === 'string'));
11
+ assert ('timestamp' in order);
12
+ assert (typeof order['timestamp'] === 'number');
13
+ assert (order['timestamp'] > 1230940800000); // 03 Jan 2009 - first block
14
+ assert (order['timestamp'] < now);
15
+ assert ('lastTradeTimestamp' in order);
16
+ assert ('datetime' in order);
17
+ assert (order['datetime'] === exchange.iso8601 (order['timestamp']));
18
+ assert ('status' in order);
19
+ assert ((order['status'] === 'open') || (order['status'] === 'closed') || (order['status'] === 'canceled'));
20
+ assert ('symbol' in order);
21
+ assert (order['symbol'] === symbol);
22
+ assert ('type' in order);
23
+ assert ((order['type'] === undefined) || (typeof order['type'] === 'string'));
24
+ assert ('timeInForce' in order);
25
+ assert ((order['timeInForce'] === undefined) || (typeof order['timeInForce'] === 'string'));
26
+ assert ('side' in order);
27
+ assert ((order['side'] === 'buy') || (order['side'] === 'sell'));
28
+ assert ('price' in order);
29
+ assert ((order['price'] === undefined) || (typeof order['price'] === 'number'));
30
+ if (order['price'] !== undefined) {
31
+ assert (order['price'] > 0);
32
+ }
33
+ assert ('amount' in order);
34
+ assert (typeof order['amount'] === 'number');
35
+ assert (order['amount'] >= 0);
36
+ assert ('filled' in order);
37
+ if (order['filled'] !== undefined) {
38
+ assert (typeof order['filled'] === 'number');
39
+ assert ((order['filled'] >= 0) && (order['filled'] <= order['amount']));
40
+ }
41
+ assert ('remaining' in order);
42
+ if (order['remaining'] !== undefined) {
43
+ assert (typeof order['remaining'] === 'number');
44
+ assert ((order['remaining'] >= 0) && (order['remaining'] <= order['amount']));
45
+ }
46
+ assert ('trades' in order);
47
+ if (order['trades']) {
48
+ assert (Array.isArray (order['trades']));
49
+ }
50
+ assert ('fee' in order);
51
+ const fee = order['fee'];
52
+ if (fee) {
53
+ assert (typeof fee['cost'] === 'number');
54
+ if (fee['cost'] !== 0) {
55
+ assert (typeof fee['currency'] === 'string');
56
+ }
57
+ }
58
+ assert ('info' in order);
59
+ assert (order['info']);
60
+ }
61
+
62
+ module.exports = testOrder;
@@ -0,0 +1,61 @@
1
+ 'use strict'
2
+
3
+ // ----------------------------------------------------------------------------
4
+
5
+ const assert = require ('assert')
6
+
7
+ // ----------------------------------------------------------------------------
8
+
9
+ module.exports = (exchange, orderbook, method, symbol) => {
10
+
11
+ const format = {
12
+ // 'symbol': 'ETH/BTC', // reserved
13
+ 'bids': [],
14
+ 'asks': [],
15
+ 'timestamp': 1234567890,
16
+ 'datetime': '2017-09-01T00:00:00',
17
+ 'nonce': 134234234,
18
+ // 'info': {},
19
+ }
20
+
21
+ const keys = Object.keys (format)
22
+ for (let i = 0; i < keys.length; i++) {
23
+ assert (keys[i] in orderbook)
24
+ }
25
+
26
+ const bids = orderbook['bids']
27
+ const asks = orderbook['asks']
28
+
29
+ for (let i = 0; i < bids.length; i++) {
30
+ if (bids.length > (i + 1)) {
31
+ assert (bids[i][0] >= bids[i + 1][0])
32
+ }
33
+ assert (typeof bids[i][0] === 'number')
34
+ assert (typeof bids[i][1] === 'number')
35
+ }
36
+
37
+ for (let i = 0; i < asks.length; i++) {
38
+ if (asks.length > (i + 1)) {
39
+ assert (asks[i][0] <= asks[i + 1][0])
40
+ }
41
+ assert (typeof asks[i][0] === 'number')
42
+ assert (typeof asks[i][1] === 'number')
43
+ }
44
+
45
+ if (![
46
+
47
+ 'bitrue',
48
+ 'ftxus',
49
+ 'mexc',
50
+ 'xbtce',
51
+ 'upbit', // an orderbook might have a 0-price ask occasionally
52
+
53
+ ].includes (exchange.id)) {
54
+
55
+ if (bids.length && asks.length) {
56
+ assert (bids[0][0] <= asks[0][0], 'bids[0][0]:', bids[0][0], 'of', bids.length, 'asks[0][0]:', asks[0][0], 'of', asks.length)
57
+ }
58
+ }
59
+
60
+ console.log (symbol, method, orderbook['nonce'] || orderbook['datetime'], bids.length, 'bids:', bids[0], asks.length, 'asks:', asks[0])
61
+ }
@@ -0,0 +1,21 @@
1
+ 'use strict';
2
+
3
+ const assert = require ('assert');
4
+
5
+ function testPosition (exchange, position, symbol, now) {
6
+ assert (position);
7
+ assert ('id' in position);
8
+ assert (position['id'] === undefined || typeof position['id'] === 'string');
9
+ assert ('timestamp' in position);
10
+ assert (position['timestamp'] === undefined || typeof position['timestamp'] === 'number');
11
+ assert (position['timestamp'] === undefined || position['timestamp'] > 1230940800000); // 03 Jan 2009 - first cryptocurrency block creation time
12
+ assert (position['timestamp'] === undefined || position['timestamp'] < now);
13
+ assert ('datetime' in position);
14
+ assert (position['datetime'] === exchange.iso8601 (position['timestamp']));
15
+ assert ('symbol' in position);
16
+ assert (symbol === undefined || position['symbol'] === symbol);
17
+ assert ('info' in position);
18
+ assert (position['info']);
19
+ }
20
+
21
+ module.exports = testPosition;
@@ -0,0 +1,94 @@
1
+ const { throttle } = require ('../../base/functions/throttle')
2
+
3
+ const delta = 10
4
+ const testCases = [
5
+ {
6
+ 'tokens': 0,
7
+ 'refillRate': 1 / 50,
8
+ 'cost': 1,
9
+ 'runs': 100,
10
+ },
11
+ {
12
+ 'tokens': 20,
13
+ 'refillRate': 1 / 50,
14
+ 'cost': 1,
15
+ 'runs': 100,
16
+ },
17
+ {
18
+ 'tokens': 40,
19
+ 'refillRate': 1 / 50,
20
+ 'cost': 1,
21
+ 'runs': 100,
22
+ },
23
+ {
24
+ 'tokens': 0,
25
+ 'refillRate': 1 / 20,
26
+ 'cost': 1,
27
+ 'runs': 100,
28
+ },
29
+ {
30
+ 'tokens': 100,
31
+ 'refillRate': 1 / 20,
32
+ 'cost': 5,
33
+ 'runs': 50,
34
+ },
35
+ {
36
+ 'tokens': 0,
37
+ 'refillRate': 1 / 40,
38
+ 'cost': 2,
39
+ 'runs': 50,
40
+ },
41
+ {
42
+ 'tokens': 1,
43
+ 'refillRate': 1 / 100,
44
+ 'cost': 1,
45
+ 'runs': 10,
46
+ },
47
+ {
48
+ 'tokens': 5,
49
+ 'refillRate': 1 / 100,
50
+ 'cost': 1,
51
+ 'runs': 10,
52
+ },
53
+ {
54
+ 'tokens': 0,
55
+ 'refillRate': 1 / 500,
56
+ 'cost': 1,
57
+ 'runs': 10,
58
+ },
59
+ {
60
+ 'tokens': 0,
61
+ 'refillRate': 1 / 10,
62
+ 'cost': 1,
63
+ 'runs': 500,
64
+ },
65
+ ]
66
+
67
+
68
+ let number = 0
69
+ for (const test of testCases) {
70
+ test['number'] = number++
71
+ const instantlyComplete = test['tokens'] / test['cost']
72
+ // after that each run will take cost and the total time will be runs * cost / refillRate
73
+ const remaining = test['runs'] - instantlyComplete - 1
74
+ test['expected'] = remaining * test['cost'] / test['refillRate']
75
+ }
76
+
77
+ async function runner (test) {
78
+ const throttler = throttle ({
79
+ 'refillRate': test['refillRate'],
80
+ 'tokens': test['tokens'],
81
+ })
82
+ const start = performance.now ()
83
+ for (let i = 0; i < test['runs']; i++) {
84
+ await throttler (test['cost'])
85
+ }
86
+ const end = performance.now ()
87
+ const elapsed = end - start
88
+ const result = Math.abs (elapsed - test['expected']) < delta
89
+ console.log (`case ${test['number']} ${result ? 'suceeded' : 'failed'} in ${elapsed}ms expected ${test['expected']}ms`)
90
+ }
91
+
92
+ for (const test of testCases) {
93
+ runner (test)
94
+ }
@@ -0,0 +1,95 @@
1
+ 'use strict'
2
+
3
+ // ----------------------------------------------------------------------------
4
+
5
+ const assert = require ('assert')
6
+
7
+ // ----------------------------------------------------------------------------
8
+
9
+ module.exports = (exchange, ticker, method, symbol) => {
10
+
11
+ const format = {
12
+ 'symbol': 'ETH/BTC',
13
+ 'info': {},
14
+ 'timestamp': 1234567890,
15
+ 'datetime': '2017-09-01T00:00:00',
16
+ 'high': 1.234, // highest price
17
+ 'low': 1.234, // lowest price
18
+ 'bid': 1.234, // current best bid (buy) price
19
+ 'bidVolume': 1.234, // current best bid (buy) amount (may be missing or undefined)
20
+ 'ask': 1.234, // current best ask (sell) price
21
+ 'askVolume': 1.234, // current best ask (sell) amount (may be missing or undefined)
22
+ 'vwap': 1.234, // volume weighed average price
23
+ 'open': 1.234, // opening price
24
+ 'close': 1.234, // price of last trade (closing price for current period)
25
+ 'last': 1.234, // same as `close`, duplicated for convenience
26
+ 'previousClose': 1.234, // closing price for the previous period
27
+ 'change': 1.234, // absolute change, `last - open`
28
+ 'percentage': 1.234, // relative change, `(change/open) * 100`
29
+ 'average': 1.234, // average price, `(last + open) / 2`
30
+ 'baseVolume': 1.234, // volume of base currency
31
+ 'quoteVolume': 1.234, // volume of quote currency
32
+ }
33
+
34
+ const keys = Object.keys (format)
35
+ for (let i = 0; i < keys.length; i++) {
36
+ const key = keys[i]
37
+ assert (key in ticker)
38
+ }
39
+
40
+ assert (!('first' in ticker), '`first` field leftover in ' + exchange.id)
41
+ assert (ticker['last'] === ticker['close'], '`last` != `close` in ' + exchange.id)
42
+
43
+ if (method !== undefined) {
44
+ console.log (ticker['datetime'], exchange.id, method, ticker['symbol'], ticker['last'])
45
+ }
46
+
47
+ // const { high, low, vwap, baseVolume, quoteVolume } = ticker
48
+ // this assert breaks QuadrigaCX sometimes... still investigating
49
+ // if (vwap) {
50
+ // assert (vwap >= low && vwap <= high)
51
+ // }
52
+ // if (baseVolume && quoteVolume && high && low) {
53
+ // assert (quoteVolume >= baseVolume * low) // this assertion breaks therock
54
+ // assert (quoteVolume <= baseVolume * high)
55
+ // }
56
+ // if (baseVolume && vwap) {
57
+ // assert (quoteVolume)
58
+ // }
59
+ // if (quoteVolume && vwap) {
60
+ // assert (baseVolume)
61
+ // }
62
+
63
+ if (![
64
+
65
+ 'bigone',
66
+ 'bitmart',
67
+ 'bitrue',
68
+ 'btcturk',
69
+ 'bybit',
70
+ 'coss',
71
+ 'ftx',
72
+ 'ftxus',
73
+ 'gateio', // some ticker bids are greaters than asks
74
+ 'idex',
75
+ 'mercado',
76
+ 'mexc',
77
+ 'okex',
78
+ 'poloniex',
79
+ 'qtrade',
80
+ 'southxchange', // https://user-images.githubusercontent.com/1294454/59953532-314bea80-9489-11e9-85b3-2a711ca49aa7.png
81
+ 'timex',
82
+ 'xbtce',
83
+
84
+ ].includes (exchange.id)) {
85
+
86
+ if (ticker['baseVolume'] || ticker['quoteVolume']) {
87
+ if (ticker['bid'] && ticker['ask']) {
88
+ assert (ticker['bid'] <= ticker['ask'], (ticker['symbol'] ? (ticker['symbol'] + ' ') : '') + 'ticker bid is greater than ticker ask!')
89
+ }
90
+ }
91
+
92
+ }
93
+
94
+ return ticker
95
+ }
@@ -0,0 +1,68 @@
1
+ 'use strict';
2
+
3
+ const assert = require ('assert');
4
+
5
+ function testTrade (exchange, trade, symbol, now) {
6
+ assert (trade);
7
+ const sampleTrade = {
8
+ 'info': { 'a': 1, 'b': 2, 'c': 3 }, // the original decoded JSON as is
9
+ 'id': '12345-67890:09876/54321', // string trade id
10
+ 'timestamp': 1502962946216, // Unix timestamp in milliseconds
11
+ 'datetime': '2017-08-17 12:42:48.000', // ISO8601 datetime with milliseconds
12
+ 'symbol': 'ETH/BTC', // symbol
13
+ 'order': '12345-67890:09876/54321', // string order id or undefined/None/null
14
+ 'type': 'limit', // order type, 'market', 'limit' or undefined/None/null
15
+ 'side': 'buy', // direction of the trade, 'buy' or 'sell'
16
+ 'takerOrMaker': 'taker', // string, 'taker' or 'maker'
17
+ 'price': 0.06917684, // float price in quote currency
18
+ 'amount': 1.5, // amount of base currency
19
+ 'cost': 0.10376526, // total cost (including fees), `price * amount`
20
+ };
21
+ const keys = Object.keys (sampleTrade);
22
+ for (let i = 0; i < keys.length; i++) {
23
+ const key = keys[i];
24
+ assert (key in trade);
25
+ }
26
+ const fee = ('fee' in trade) ? trade['fee'] : undefined;
27
+ const fees = ('fees' in trade) ? trade['fees'] : undefined;
28
+ // logical XOR
29
+ // doesn't work when both fee is defined and fees is defined
30
+ // if (fee || fees) {
31
+ // assert (!(fee && fees));
32
+ // }
33
+ if (fee) {
34
+ assert (('cost' in fee) && ('currency' in fee));
35
+ }
36
+ if (fees) {
37
+ assert (Array.isArray (fees));
38
+ for (let i = 0; i < fees.length; i++) {
39
+ const fee = fees[i];
40
+ assert (('cost' in fee) && ('currency' in fee));
41
+ }
42
+ }
43
+ const id = trade['id'];
44
+ assert ((id === undefined) || (typeof id === 'string'));
45
+ const timestamp = trade['timestamp'];
46
+ assert (typeof timestamp === 'number' || timestamp === undefined);
47
+ if (timestamp) {
48
+ assert (timestamp > 1230940800000); // 03 Jan 2009 - first block
49
+ assert (timestamp < 2147483648000); // 19 Jan 2038 - int32 overflows
50
+ const adjustedNow = now + 60000;
51
+ assert (timestamp < adjustedNow, 'trade.timestamp is greater than or equal to current time: trade: ' + exchange.iso8601 (timestamp) + ' now: ' + exchange.iso8601 (now));
52
+ }
53
+ assert (trade['datetime'] === exchange.iso8601 (timestamp));
54
+ assert (trade['symbol'] === symbol, 'trade symbol is not equal to requested symbol: trade: ' + trade['symbol'] + ' requested: ' + symbol);
55
+ assert (trade['type'] === undefined || typeof trade['type'] === 'string');
56
+ assert (trade['side'] === undefined || trade['side'] === 'buy' || trade['side'] === 'sell', 'unexpected trade side ' + trade['side']);
57
+ assert (trade['order'] === undefined || typeof trade['order'] === 'string');
58
+ assert (typeof trade['price'] === 'number', 'trade.price is not a number');
59
+ assert (trade['price'] > 0);
60
+ assert (typeof trade['amount'] === 'number', 'trade.amount is not a number');
61
+ assert (trade['amount'] >= 0);
62
+ assert (trade['cost'] === undefined || typeof trade['cost'] === 'number', 'trade.cost is not a number');
63
+ assert (trade['cost'] === undefined || trade['cost'] >= 0);
64
+ const takerOrMaker = trade['takerOrMaker'];
65
+ assert (takerOrMaker === undefined || takerOrMaker === 'taker' || takerOrMaker === 'maker');
66
+ }
67
+
68
+ module.exports = testTrade;
@@ -0,0 +1,34 @@
1
+ 'use strict'
2
+
3
+ // ----------------------------------------------------------------------------
4
+
5
+ const assert = require ('assert')
6
+
7
+ // ---------------------------------------------------------------------------
8
+
9
+ function testTradingFee (exchange = undefined, symbol, fee) {
10
+ assert (fee, 'fee is undefined')
11
+ const sampleFee = {
12
+ 'info': { 'a': 1, 'b': 2, 'c': 3 },
13
+ 'symbol': 'ETH/BTC',
14
+ 'maker': 0.002,
15
+ 'taker': 0.003,
16
+ }
17
+ const keys = Object.keys (sampleFee)
18
+ for (let i = 0; i < keys.length; i++) {
19
+ const key = keys[i]
20
+ assert (key in fee, 'fee key ' + key + ' not found')
21
+ }
22
+ assert (fee['symbol'] === symbol, 'trade symbol is not equal to requested symbol: trade: ' + fee['symbol'] + ' requested: ' + symbol)
23
+ assert (typeof fee['maker'] === 'number', 'maker fee is not a number')
24
+ assert (typeof fee['taker'] === 'number', 'taker fee is not a number')
25
+ if ('percentage' in fee) {
26
+ assert (typeof fee['percentage'] === 'boolean', 'percentage is not a boolean')
27
+ }
28
+ if ('tierBased' in fee) {
29
+ assert (typeof fee['tierBased'] === 'boolean', 'percentage is not a boolean')
30
+ }
31
+ return fee
32
+ }
33
+
34
+ module.exports = testTradingFee
@@ -0,0 +1,35 @@
1
+ 'use strict';
2
+
3
+ // ----------------------------------------------------------------------------
4
+
5
+ const assert = require ('assert');
6
+
7
+ // ---------------------------------------------------------------------------
8
+
9
+ function testTransaction (exchange, transaction, code, now) {
10
+ assert (transaction);
11
+ assert ((transaction['id'] === undefined) || (typeof transaction['id'] === 'string'));
12
+ assert (typeof transaction['timestamp'] === 'number');
13
+ assert (transaction['timestamp'] > 1230940800000); // 03 Jan 2009 - first block
14
+ assert (transaction['timestamp'] < now);
15
+ assert ('updated' in transaction);
16
+ assert ('address' in transaction);
17
+ assert ('tag' in transaction);
18
+ assert ('txid' in transaction);
19
+ assert (transaction['datetime'] === exchange.iso8601 (transaction['timestamp']));
20
+ assert ((transaction['status'] === 'ok') || (transaction['status'] === 'pending') || (transaction['status'] === 'canceled'));
21
+ assert (transaction['currency'] === code);
22
+ assert (typeof transaction['type'] === 'string');
23
+ assert (transaction['type'] === 'deposit' || transaction['type'] === 'withdrawal');
24
+ assert (typeof transaction['amount'] === 'number');
25
+ assert (transaction['amount'] >= 0);
26
+ if (transaction['fee']) {
27
+ assert (typeof transaction['fee']['cost'] === 'number');
28
+ if (transaction['fee']['cost'] !== 0) {
29
+ assert (typeof transaction['fee']['currency'] === 'string');
30
+ }
31
+ }
32
+ assert (transaction.info);
33
+ }
34
+
35
+ module.exports = testTransaction;