Snapshots
This commit is contained in:
1 parent
e91125801d
commit
6368221937
75 files changed
+8943
-4332
No files matched your search
+23
-1
@@ -333,9 +333,21 @@ function exportKeywordsToPackageJson (exchanges) {
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
function exportEverything () {
|
||||
function flatten (nested, result = []) {
|
||||
for (const key in nested) {
|
||||
result.push (key)
|
||||
if (Object.keys (nested[key]).length)
|
||||
flatten (nested[key], result)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
|
||||
function exportEverything () {
|
||||
const ids = getIncludedExchangeIds ()
|
||||
const errorHierarchy = require ('../js/base/errorHierarchy.js')
|
||||
const flat = flatten (errorHierarchy)
|
||||
flat.push ('error_hierarchy')
|
||||
|
||||
const replacements = [
|
||||
{
|
||||
@@ -353,6 +365,16 @@ function exportEverything () {
|
||||
regex: /(?:from ccxt\.[^\.]+ import [^\s]+\s+\# noqa\: F401[\r]?[\n])+[\r]?[\n]exchanges/,
|
||||
replacement: ids.map (id => ('from ccxt.' + id + ' import ' + id).padEnd (60) + '# noqa: F401').join ("\n") + "\n\nexchanges",
|
||||
},
|
||||
{
|
||||
file: './python/ccxt/__init__.py',
|
||||
regex: /(?:from ccxt\.base\.errors import [^\s]+\s+\# noqa\: F401[\r]?[\n])+[\r]?[\n]/,
|
||||
replacement: flat.map (error => ('from ccxt.base.errors' + ' import ' + error).padEnd (60) + '# noqa: F401').join ("\n") + "\n\n",
|
||||
},
|
||||
{
|
||||
file: './python/ccxt/async_support/__init__.py',
|
||||
regex: /(?:from ccxt\.base\.errors import [^\s]+\s+\# noqa\: F401[\r]?[\n])+[\r]?[\n]/,
|
||||
replacement: flat.map (error => ('from ccxt.base.errors' + ' import ' + error).padEnd (60) + '# noqa: F401').join ("\n") + "\n\n",
|
||||
},
|
||||
{
|
||||
file: './python/ccxt/async_support/__init__.py',
|
||||
regex: /(?:from ccxt\.async_support\.[^\.]+ import [^\s]+\s+\# noqa\: F401[\r]?[\n])+[\r]?[\n]exchanges/,
|
||||
|
||||
+2
@@ -199,6 +199,7 @@ class Transpiler {
|
||||
[ /(^|[^a-zA-Z0-9_])(?:let|const|var)\s/g, '$1' ],
|
||||
[ /Object\.keys\s*\((.*)\)\.length/g, '$1' ],
|
||||
[ /Object\.keys\s*\((.*)\)/g, 'list($1.keys())' ],
|
||||
[ /Object\.values\s*\((.*)\)/g, 'list($1.values())' ],
|
||||
[ /\[([^\]]+)\]\.join\s*\(([^\)]+)\)/g, "$2.join([$1])" ],
|
||||
[ /hash \(([^,]+)\, \'(sha[0-9])\'/g, "hash($1, '$2'" ],
|
||||
[ /hmac \(([^,]+)\, ([^,]+)\, \'(md5)\'/g, 'hmac($1, $2, hashlib.$3' ],
|
||||
@@ -330,6 +331,7 @@ class Transpiler {
|
||||
[ /(^|[^a-zA-Z0-9_])(?:let|const|var)\s/g, '$1' ],
|
||||
[ /Object\.keys\s*\((.*)\)\.length/g, '$1' ],
|
||||
[ /Object\.keys\s*\((.*)\)/g, 'is_array($1) ? array_keys($1) : array()' ],
|
||||
[ /Object\.values\s*\((.*)\)/g, 'is_array($1) ? array_values($1) : array()' ],
|
||||
[ /([^\s]+\s*\(\))\.toString \(\)/g, '(string) $1' ],
|
||||
[ /([^\s]+)\.toString \(\)/g, '(string) $1' ],
|
||||
[ /throw new Error \((.*)\)/g, 'throw new \\Exception($1)' ],
|
||||
|
||||
+2
-3
@@ -35,7 +35,7 @@ const Exchange = require ('./js/base/Exchange')
|
||||
//-----------------------------------------------------------------------------
|
||||
// this is updated by vss.js when building
|
||||
|
||||
const version = '1.25.80'
|
||||
const version = '1.27.45'
|
||||
|
||||
Exchange.ccxtVersion = version
|
||||
|
||||
@@ -44,7 +44,6 @@ Exchange.ccxtVersion = version
|
||||
const exchanges = {
|
||||
'_1btcxe': require ('./js/_1btcxe.js'),
|
||||
'acx': require ('./js/acx.js'),
|
||||
'adara': require ('./js/adara.js'),
|
||||
'anxpro': require ('./js/anxpro.js'),
|
||||
'aofex': require ('./js/aofex.js'),
|
||||
'bcex': require ('./js/bcex.js'),
|
||||
@@ -115,8 +114,8 @@ const exchanges = {
|
||||
'fybse': require ('./js/fybse.js'),
|
||||
'gateio': require ('./js/gateio.js'),
|
||||
'gemini': require ('./js/gemini.js'),
|
||||
'hbtc': require ('./js/hbtc.js'),
|
||||
'hitbtc': require ('./js/hitbtc.js'),
|
||||
'hitbtc2': require ('./js/hitbtc2.js'),
|
||||
'hollaex': require ('./js/hollaex.js'),
|
||||
'huobipro': require ('./js/huobipro.js'),
|
||||
'huobiru': require ('./js/huobiru.js'),
|
||||
|
||||
+4395
-2136
File diff suppressed because it is too large.
Load diff
-1255
File diff suppressed because it is too large.
Load diff
+9
-3
@@ -30,6 +30,7 @@ module.exports = class aofex extends Exchange {
|
||||
'fetchOpenOrders': true,
|
||||
'fetchClosedOrders': true,
|
||||
'fetchClosedOrder': true,
|
||||
'fetchOrderTrades': true,
|
||||
'fetchTradingFee': true,
|
||||
},
|
||||
'timeframes': {
|
||||
@@ -559,7 +560,7 @@ module.exports = class aofex extends Exchange {
|
||||
//
|
||||
const id = this.safeString (trade, 'id');
|
||||
const ctime = this.parse8601 (this.safeString (trade, 'ctime'));
|
||||
const timestamp = this.safeTimestamp (trade, 'ts', ctime);
|
||||
const timestamp = this.safeTimestamp (trade, 'ts', ctime) - 28800000; // 8 hours, adjust to UTC;
|
||||
let symbol = undefined;
|
||||
if ((symbol === undefined) && (market !== undefined)) {
|
||||
symbol = market['symbol'];
|
||||
@@ -725,7 +726,7 @@ module.exports = class aofex extends Exchange {
|
||||
base = market['base'];
|
||||
quote = market['quote'];
|
||||
}
|
||||
const timestamp = this.parse8601 (this.safeString (order, 'ctime'));
|
||||
const timestamp = this.parse8601 (this.safeString (order, 'ctime')) - 28800000; // 8 hours, adjust to UTC
|
||||
const orderType = this.safeString (order, 'type');
|
||||
const type = (orderType === '2') ? 'limit' : 'market';
|
||||
const side = this.safeString (order, 'side');
|
||||
@@ -883,11 +884,16 @@ module.exports = class aofex extends Exchange {
|
||||
return this.parseOrder (order);
|
||||
}
|
||||
|
||||
async fetchOrderTrades (id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
||||
const response = await this.fetchClosedOrder (id, symbol, params);
|
||||
return this.safeValue (response, 'trades', []);
|
||||
}
|
||||
|
||||
async fetchOrdersWithMethod (method, symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
||||
await this.loadMarkets ();
|
||||
const request = {
|
||||
// 'from': 'BM7442641584965237751ZMAKJ5', // query start order_sn
|
||||
// 'direct': 'prev', // next
|
||||
'direct': 'prev', // next
|
||||
};
|
||||
let market = undefined;
|
||||
if (symbol !== undefined) {
|
||||
|
||||
+43
-15
@@ -288,8 +288,9 @@ module.exports = class Exchange {
|
||||
const config = deepExtend (this.describe (), userConfig)
|
||||
|
||||
// merge to this
|
||||
for (const [property, value] of Object.entries (config))
|
||||
for (const [property, value] of Object.entries (config)) {
|
||||
this[property] = deepExtend (this[property], value)
|
||||
}
|
||||
|
||||
if (!this.httpAgent) {
|
||||
this.httpAgent = defaultFetch.http ? new defaultFetch.http.Agent ({ 'keepAlive': true }) : undefined
|
||||
@@ -304,13 +305,15 @@ module.exports = class Exchange {
|
||||
this['has' + capitalize (k)] = !!this.has[k] // converts 'emulated' to true
|
||||
}
|
||||
|
||||
if (this.api)
|
||||
if (this.api) {
|
||||
this.defineRestApi (this.api, 'request')
|
||||
}
|
||||
|
||||
this.initRestRateLimiter ()
|
||||
|
||||
if (this.markets)
|
||||
if (this.markets) {
|
||||
this.setMarkets (this.markets)
|
||||
}
|
||||
}
|
||||
|
||||
defaults () {
|
||||
@@ -342,20 +345,23 @@ module.exports = class Exchange {
|
||||
|
||||
checkAddress (address) {
|
||||
|
||||
if (address === undefined)
|
||||
if (address === undefined) {
|
||||
throw new InvalidAddress (this.id + ' address is undefined')
|
||||
}
|
||||
|
||||
// check the address is not the same letter like 'aaaaa' nor too short nor has a space
|
||||
if ((unique (address).length === 1) || address.length < this.minFundingAddressLength || address.includes (' '))
|
||||
if ((unique (address).length === 1) || address.length < this.minFundingAddressLength || address.includes (' ')) {
|
||||
throw new InvalidAddress (this.id + ' address is invalid or has less than ' + this.minFundingAddressLength.toString () + ' characters: "' + this.json (address) + '"')
|
||||
}
|
||||
|
||||
return address
|
||||
}
|
||||
|
||||
initRestRateLimiter () {
|
||||
|
||||
if (this.rateLimit === undefined)
|
||||
if (this.rateLimit === undefined) {
|
||||
throw new Error (this.id + '.rateLimit property is not configured')
|
||||
}
|
||||
|
||||
this.tokenBucket = this.extend ({
|
||||
delay: 1,
|
||||
@@ -386,15 +392,17 @@ module.exports = class Exchange {
|
||||
const promise =
|
||||
fetchImplementation (url, this.extend (params, this.fetchOptions))
|
||||
.catch ((e) => {
|
||||
if (isNode)
|
||||
if (isNode) {
|
||||
throw new ExchangeNotAvailable ([ this.id, method, url, e.type, e.message ].join (' '))
|
||||
}
|
||||
throw e // rethrow all unknown errors
|
||||
})
|
||||
.then (response => this.handleRestResponse (response, url, method, headers, body))
|
||||
.then ((response) => this.handleRestResponse (response, url, method, headers, body))
|
||||
|
||||
return timeout (this.timeout, promise).catch ((e) => {
|
||||
if (e instanceof TimedOut)
|
||||
if (e instanceof TimedOut) {
|
||||
throw new RequestTimeout (this.id + ' ' + method + ' ' + url + ' request timed out (' + this.timeout + ' ms)')
|
||||
}
|
||||
throw e
|
||||
})
|
||||
}
|
||||
@@ -442,16 +450,20 @@ module.exports = class Exchange {
|
||||
let underscore = type + '_' + lowercaseMethod + '_' + underscoreSuffix
|
||||
|
||||
if ('suffixes' in options) {
|
||||
if ('camelcase' in options['suffixes'])
|
||||
if ('camelcase' in options['suffixes']) {
|
||||
camelcase += options['suffixes']['camelcase']
|
||||
if ('underscore' in options.suffixes)
|
||||
}
|
||||
if ('underscore' in options.suffixes) {
|
||||
underscore += options['suffixes']['underscore']
|
||||
}
|
||||
}
|
||||
|
||||
if ('underscore_suffix' in options)
|
||||
if ('underscore_suffix' in options) {
|
||||
underscore += options.underscoreSuffix;
|
||||
if ('camelcase_suffix' in options)
|
||||
}
|
||||
if ('camelcase_suffix' in options) {
|
||||
camelcase += options.camelcaseSuffix;
|
||||
}
|
||||
|
||||
let partial = async params => this[methodName] (path, type, uppercaseMethod, params || {})
|
||||
|
||||
@@ -594,7 +606,7 @@ module.exports = class Exchange {
|
||||
getResponseHeaders (response) {
|
||||
const result = {}
|
||||
response.headers.forEach ((value, key) => {
|
||||
key = key.split ('-').map (word => capitalize (word)).join ('-')
|
||||
key = key.split ('-').map ((word) => capitalize (word)).join ('-')
|
||||
result[key] = value
|
||||
})
|
||||
return result
|
||||
@@ -632,7 +644,7 @@ module.exports = class Exchange {
|
||||
}
|
||||
|
||||
setMarkets (markets, currencies = undefined) {
|
||||
const values = Object.values (markets).map (market => deepExtend ({
|
||||
const values = Object.values (markets).map ((market) => deepExtend ({
|
||||
'limits': this.limits,
|
||||
'precision': this.precision,
|
||||
}, this.fees['trading'], market))
|
||||
@@ -803,6 +815,22 @@ module.exports = class Exchange {
|
||||
throw new NotSupported (this.id + ' fetchOrder not supported yet');
|
||||
}
|
||||
|
||||
fetchUnifiedOrder (order, params = {}) {
|
||||
return this.fetchOrder (this.safeValue (order, 'id'), this.safeValue (order, 'symbol'), params);
|
||||
}
|
||||
|
||||
createOrder (symbol, type, side, amount, price = undefined, params = {}) {
|
||||
throw new NotSupported (this.id + ' createOrder not supported yet');
|
||||
}
|
||||
|
||||
cancelOrder (id, symbol = undefined, params = {}) {
|
||||
throw new NotSupported (this.id + ' cancelOrder not supported yet');
|
||||
}
|
||||
|
||||
cancelUnifiedOrder (order, params = {}) {
|
||||
return this.cancelOrder (this.safeValue (order, 'id'), this.safeValue (order, 'symbol'), params);
|
||||
}
|
||||
|
||||
fetchOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
||||
throw new NotSupported (this.id + ' fetchOrders not supported yet');
|
||||
}
|
||||
|
||||
+11
-7
@@ -45,23 +45,27 @@ function numberToString (x) { // avoids scientific notation for too large and to
|
||||
|
||||
if (typeof x === 'string') return x
|
||||
|
||||
const s = x.toString ()
|
||||
if (Math.abs (x) < 1.0) {
|
||||
const s = x.toString ()
|
||||
const e = parseInt (s.split ('e-')[1])
|
||||
const neg = (s[0] === '-')
|
||||
if (e) {
|
||||
x *= Math.pow (10, e - 1)
|
||||
x = (neg ? '-' : '') + '0.' + (new Array (e)).join ('0') + x.toString ().substring (neg ? 3 : 2)
|
||||
return x
|
||||
}
|
||||
} else {
|
||||
let e = parseInt (x.toString ().split ('+')[1])
|
||||
if (e > 20) {
|
||||
e -= 20
|
||||
x /= Math.pow (10, e)
|
||||
x += (new Array (e + 1)).join ('0')
|
||||
const parts = s.split ('e')
|
||||
if (parts[1]) {
|
||||
let e = parseInt (parts[1])
|
||||
const m = parts[0].split ('.')
|
||||
if (m[1]) {
|
||||
e -= m[1].length
|
||||
}
|
||||
return m[0] + m[1] + (new Array (e + 1)).join ('0')
|
||||
}
|
||||
}
|
||||
return x.toString ()
|
||||
return s;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
+106
-34
@@ -3,7 +3,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const Exchange = require ('./base/Exchange');
|
||||
const { ExchangeError, ArgumentsRequired, ExchangeNotAvailable, InsufficientFunds, OrderNotFound, InvalidOrder, DDoSProtection, InvalidNonce, AuthenticationError, InvalidAddress, RateLimitExceeded, PermissionDenied } = require ('./base/errors');
|
||||
const { ExchangeError, ArgumentsRequired, ExchangeNotAvailable, InsufficientFunds, OrderNotFound, InvalidOrder, DDoSProtection, InvalidNonce, AuthenticationError, InvalidAddress, RateLimitExceeded, PermissionDenied, NotSupported } = require ('./base/errors');
|
||||
const { ROUND, TRUNCATE } = require ('./base/functions/number');
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -37,6 +37,7 @@ module.exports = class binance extends Exchange {
|
||||
'fetchTransactions': false,
|
||||
'fetchTradingFee': true,
|
||||
'fetchTradingFees': true,
|
||||
'cancelAllOrders': true,
|
||||
},
|
||||
'timeframes': {
|
||||
'1m': '1m',
|
||||
@@ -57,6 +58,10 @@ module.exports = class binance extends Exchange {
|
||||
},
|
||||
'urls': {
|
||||
'logo': 'https://user-images.githubusercontent.com/1294454/29604020-d5483cdc-87ee-11e7-94c7-d1a8d9169293.jpg',
|
||||
'test': {
|
||||
'fapiPublic': 'https://testnet.binancefuture.com/fapi/v1',
|
||||
'fapiPrivate': 'https://testnet.binancefuture.com/fapi/v1',
|
||||
},
|
||||
'api': {
|
||||
'web': 'https://www.binance.com',
|
||||
'wapi': 'https://api.binance.com/wapi/v3',
|
||||
@@ -130,6 +135,8 @@ module.exports = class binance extends Exchange {
|
||||
'lending/union/purchaseRecord',
|
||||
'lending/union/redemptionRecord',
|
||||
'lending/union/interestHistory',
|
||||
'lending/project/list',
|
||||
'lending/project/position/list',
|
||||
],
|
||||
'post': [
|
||||
'asset/dust',
|
||||
@@ -146,6 +153,7 @@ module.exports = class binance extends Exchange {
|
||||
'userDataStream',
|
||||
'futures/transfer',
|
||||
// lending
|
||||
'lending/customizedFixed/purchase',
|
||||
'lending/daily/purchase',
|
||||
'lending/daily/redeem',
|
||||
],
|
||||
@@ -211,6 +219,8 @@ module.exports = class binance extends Exchange {
|
||||
'income',
|
||||
],
|
||||
'post': [
|
||||
'batchOrders',
|
||||
'positionSide/dual',
|
||||
'positionMargin',
|
||||
'marginType',
|
||||
'order',
|
||||
@@ -221,6 +231,7 @@ module.exports = class binance extends Exchange {
|
||||
'listenKey',
|
||||
],
|
||||
'delete': [
|
||||
'batchOrders',
|
||||
'order',
|
||||
'allOpenOrders',
|
||||
'listenKey',
|
||||
@@ -267,6 +278,7 @@ module.exports = class binance extends Exchange {
|
||||
'order/test',
|
||||
],
|
||||
'delete': [
|
||||
'openOrders', // added on 2020-04-25 for canceling all open orders per symbol
|
||||
'orderList', // oco
|
||||
'order',
|
||||
],
|
||||
@@ -289,7 +301,6 @@ module.exports = class binance extends Exchange {
|
||||
'fetchTradesMethod': 'publicGetAggTrades', // publicGetTrades, publicGetHistoricalTrades
|
||||
'fetchTickersMethod': 'publicGetTicker24hr',
|
||||
'defaultTimeInForce': 'GTC', // 'GTC' = Good To Cancel (default), 'IOC' = Immediate Or Cancel
|
||||
'defaultLimitOrderType': 'limit', // or 'limit_maker'
|
||||
'defaultType': 'spot', // 'spot', 'future'
|
||||
'hasAlreadyAuthenticatedSuccessfully': false,
|
||||
'warnOnFetchOpenOrdersWithoutSymbol': true,
|
||||
@@ -326,6 +337,32 @@ module.exports = class binance extends Exchange {
|
||||
});
|
||||
}
|
||||
|
||||
setSandboxMode (enabled) {
|
||||
if (enabled) { // eslint-disable-line no-extra-boolean-cast
|
||||
if ('test' in this.urls) {
|
||||
const type = this.safeString (this.options, 'defaultType', 'spot');
|
||||
if (type !== 'future') {
|
||||
throw new NotSupported (this.id + ' does not have a sandbox URL for ' + type + " markets, set exchange.options['defaultType'] = 'future' or don't use the sandbox for " + this.id);
|
||||
}
|
||||
if (typeof this.urls['api'] === 'string') {
|
||||
this.urls['api_backup'] = this.urls['api'];
|
||||
this.urls['api'] = this.urls['test'];
|
||||
} else {
|
||||
this.urls['api_backup'] = this.extend ({}, this.urls['api']);
|
||||
this.urls['api'] = this.extend ({}, this.urls['test']);
|
||||
}
|
||||
} else {
|
||||
throw new NotSupported (this.id + ' does not have a sandbox URL');
|
||||
}
|
||||
} else if ('api_backup' in this.urls) {
|
||||
if (typeof this.urls['api'] === 'string') {
|
||||
this.urls['api'] = this.urls['api_backup'];
|
||||
} else {
|
||||
this.urls['api'] = this.extend ({}, this.urls['api_backup']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nonce () {
|
||||
return this.milliseconds () - this.options['timeDifference'];
|
||||
}
|
||||
@@ -476,7 +513,7 @@ module.exports = class binance extends Exchange {
|
||||
'max': undefined,
|
||||
},
|
||||
'cost': {
|
||||
'min': -1 * Math.log10 (precision['amount']),
|
||||
'min': undefined,
|
||||
'max': undefined,
|
||||
},
|
||||
},
|
||||
@@ -720,7 +757,7 @@ module.exports = class binance extends Exchange {
|
||||
|
||||
async fetchBidsAsks (symbols = undefined, params = {}) {
|
||||
await this.loadMarkets ();
|
||||
const defaultType = this.safeString2 (this.options, 'fetchOpenOrders', 'defaultType', 'spot');
|
||||
const defaultType = this.safeString2 (this.options, 'fetchBidsAsks', 'defaultType', 'spot');
|
||||
const type = this.safeString (params, 'type', defaultType);
|
||||
const query = this.omit (params, 'type');
|
||||
const method = (type === 'spot') ? 'publicGetTickerBookTicker' : 'fapiPublicGetTickerBookTicker';
|
||||
@@ -737,12 +774,12 @@ module.exports = class binance extends Exchange {
|
||||
|
||||
parseOHLCV (ohlcv, market = undefined, timeframe = '1m', since = undefined, limit = undefined) {
|
||||
return [
|
||||
ohlcv[0],
|
||||
parseFloat (ohlcv[1]),
|
||||
parseFloat (ohlcv[2]),
|
||||
parseFloat (ohlcv[3]),
|
||||
parseFloat (ohlcv[4]),
|
||||
parseFloat (ohlcv[5]),
|
||||
this.safeInteger (ohlcv, 0),
|
||||
this.safeFloat (ohlcv, 1),
|
||||
this.safeFloat (ohlcv, 2),
|
||||
this.safeFloat (ohlcv, 3),
|
||||
this.safeFloat (ohlcv, 4),
|
||||
this.safeFloat (ohlcv, 5),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -870,6 +907,10 @@ module.exports = class binance extends Exchange {
|
||||
if (market !== undefined) {
|
||||
symbol = market['symbol'];
|
||||
}
|
||||
let cost = undefined;
|
||||
if ((price !== undefined) && (amount !== undefined)) {
|
||||
cost = price * amount;
|
||||
}
|
||||
return {
|
||||
'info': trade,
|
||||
'timestamp': timestamp,
|
||||
@@ -878,11 +919,11 @@ module.exports = class binance extends Exchange {
|
||||
'id': id,
|
||||
'order': orderId,
|
||||
'type': undefined,
|
||||
'takerOrMaker': takerOrMaker,
|
||||
'side': side,
|
||||
'takerOrMaker': takerOrMaker,
|
||||
'price': price,
|
||||
'amount': amount,
|
||||
'cost': price * amount,
|
||||
'cost': cost,
|
||||
'fee': fee,
|
||||
};
|
||||
}
|
||||
@@ -1180,6 +1221,8 @@ module.exports = class binance extends Exchange {
|
||||
} else if (uppercaseType === 'STOP') {
|
||||
stopPriceIsRequired = true;
|
||||
priceIsRequired = true;
|
||||
} else if (uppercaseType === 'STOP_MARKET') {
|
||||
stopPriceIsRequired = true;
|
||||
}
|
||||
if (priceIsRequired) {
|
||||
if (price === undefined) {
|
||||
@@ -1339,6 +1382,27 @@ module.exports = class binance extends Exchange {
|
||||
return this.parseOrder (response);
|
||||
}
|
||||
|
||||
async cancelAllOrders (symbol = undefined, params = {}) {
|
||||
if (symbol === undefined) {
|
||||
throw new ArgumentsRequired (this.id + ' cancelAllOrders requires a symbol argument');
|
||||
}
|
||||
await this.loadMarkets ();
|
||||
const market = this.market (symbol);
|
||||
const request = {
|
||||
'symbol': market['id'],
|
||||
};
|
||||
const defaultType = this.safeString2 (this.options, 'cancelAllOrders', 'defaultType', 'spot');
|
||||
const type = this.safeString (params, 'type', defaultType);
|
||||
const query = this.omit (params, 'type');
|
||||
const method = (type === 'spot') ? 'privateDeleteOpenOrders' : 'fapiPrivateDeleteAllOpenOrders';
|
||||
const response = await this[method] (this.extend (request, query));
|
||||
if (Array.isArray (response)) {
|
||||
return this.parseOrders (response, market);
|
||||
} else {
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
async fetchMyTrades (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
||||
if (symbol === undefined) {
|
||||
throw new ArgumentsRequired (this.id + ' fetchMyTrades requires a symbol argument');
|
||||
@@ -1571,10 +1635,7 @@ module.exports = class binance extends Exchange {
|
||||
}
|
||||
|
||||
parseTransactionStatusByType (status, type = undefined) {
|
||||
if (type === undefined) {
|
||||
return status;
|
||||
}
|
||||
const statuses = {
|
||||
const statusesByType = {
|
||||
'deposit': {
|
||||
'0': 'pending',
|
||||
'1': 'ok',
|
||||
@@ -1589,32 +1650,38 @@ module.exports = class binance extends Exchange {
|
||||
'6': 'ok', // Completed
|
||||
},
|
||||
};
|
||||
return (status in statuses[type]) ? statuses[type][status] : status;
|
||||
const statuses = this.safeValue (statusesByType, type, {});
|
||||
return this.safeString (statuses, status, status);
|
||||
}
|
||||
|
||||
parseTransaction (transaction, currency = undefined) {
|
||||
//
|
||||
// fetchDeposits
|
||||
// { insertTime: 1517425007000,
|
||||
// amount: 0.3,
|
||||
// address: "0x0123456789abcdef",
|
||||
// addressTag: "",
|
||||
// txId: "0x0123456789abcdef",
|
||||
// asset: "ETH",
|
||||
// status: 1 }
|
||||
//
|
||||
// {
|
||||
// insertTime: 1517425007000,
|
||||
// amount: 0.3,
|
||||
// address: "0x0123456789abcdef",
|
||||
// addressTag: "",
|
||||
// txId: "0x0123456789abcdef",
|
||||
// asset: "ETH",
|
||||
// status: 1
|
||||
// }
|
||||
//
|
||||
// fetchWithdrawals
|
||||
//
|
||||
// { amount: 14,
|
||||
// address: "0x0123456789abcdef...",
|
||||
// {
|
||||
// amount: 14,
|
||||
// address: "0x0123456789abcdef...",
|
||||
// successTime: 1514489710000,
|
||||
// transactionFee: 0.01,
|
||||
// addressTag: "",
|
||||
// txId: "0x0123456789abcdef...",
|
||||
// id: "0123456789abcdef...",
|
||||
// asset: "ETH",
|
||||
// applyTime: 1514488724000,
|
||||
// status: 6 }
|
||||
// transactionFee: 0.01,
|
||||
// addressTag: "",
|
||||
// txId: "0x0123456789abcdef...",
|
||||
// id: "0123456789abcdef...",
|
||||
// asset: "ETH",
|
||||
// applyTime: 1514488724000,
|
||||
// status: 6
|
||||
// }
|
||||
//
|
||||
const id = this.safeString (transaction, 'id');
|
||||
const address = this.safeString (transaction, 'address');
|
||||
@@ -1624,7 +1691,7 @@ module.exports = class binance extends Exchange {
|
||||
tag = undefined;
|
||||
}
|
||||
}
|
||||
const txid = this.safeValue (transaction, 'txId');
|
||||
const txid = this.safeString (transaction, 'txId');
|
||||
const currencyId = this.safeString (transaction, 'asset');
|
||||
const code = this.safeCurrencyCode (currencyId, currency);
|
||||
let timestamp = undefined;
|
||||
@@ -1854,6 +1921,11 @@ module.exports = class binance extends Exchange {
|
||||
'timestamp': this.nonce (),
|
||||
'recvWindow': this.options['recvWindow'],
|
||||
}, params));
|
||||
} else if (path === 'batchOrders') {
|
||||
query = this.rawencode (this.extend ({
|
||||
'timestamp': this.nonce (),
|
||||
'recvWindow': this.options['recvWindow'],
|
||||
}, params));
|
||||
} else {
|
||||
query = this.urlencode (this.extend ({
|
||||
'timestamp': this.nonce (),
|
||||
|
||||
+3
-3
@@ -31,10 +31,10 @@ module.exports = class binanceus extends binance {
|
||||
},
|
||||
'fees': {
|
||||
'trading': {
|
||||
'tierBased': false,
|
||||
'tierBased': true,
|
||||
'percentage': true,
|
||||
'taker': 0.0, // 0.1% trading fee, zero fees for all trading pairs before November 1
|
||||
'maker': 0.0, // 0.1% trading fee, zero fees for all trading pairs before November 1
|
||||
'taker': 0.001, // 0.1% trading fee, zero fees for all trading pairs before November 1
|
||||
'maker': 0.001, // 0.1% trading fee, zero fees for all trading pairs before November 1
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
+67
-2
@@ -3,7 +3,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const Exchange = require ('./base/Exchange');
|
||||
const { InvalidNonce, InsufficientFunds, AuthenticationError, InvalidOrder, ExchangeError, OrderNotFound, AccountSuspended, BadSymbol, OrderImmediatelyFillable, RateLimitExceeded } = require ('./base/errors');
|
||||
const { InvalidNonce, InsufficientFunds, AuthenticationError, InvalidOrder, ExchangeError, OrderNotFound, AccountSuspended, BadSymbol, OrderImmediatelyFillable, RateLimitExceeded, OnMaintenance } = require ('./base/errors');
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -53,6 +53,7 @@ module.exports = class bitbay extends Exchange {
|
||||
'https://github.com/BitBayNet/API',
|
||||
'https://docs.bitbay.net/v1.0.1-en/reference',
|
||||
],
|
||||
'support': 'https://support.bitbay.net',
|
||||
'fees': 'https://bitbay.net/en/fees',
|
||||
},
|
||||
'api': {
|
||||
@@ -117,8 +118,60 @@ module.exports = class bitbay extends Exchange {
|
||||
},
|
||||
'fees': {
|
||||
'trading': {
|
||||
'maker': 0.0,
|
||||
'taker': 0.1 / 100,
|
||||
'percentage': true,
|
||||
'tierBased': false,
|
||||
},
|
||||
'fiat': {
|
||||
'maker': 0.30 / 100,
|
||||
'taker': 0.43 / 100,
|
||||
'percentage': true,
|
||||
'tierBased': true,
|
||||
'tiers': {
|
||||
'taker': [
|
||||
[ 0.0043, 0 ],
|
||||
[ 0.0042, 1250 ],
|
||||
[ 0.0041, 3750 ],
|
||||
[ 0.0040, 7500 ],
|
||||
[ 0.0039, 10000 ],
|
||||
[ 0.0038, 15000 ],
|
||||
[ 0.0037, 20000 ],
|
||||
[ 0.0036, 25000 ],
|
||||
[ 0.0035, 37500 ],
|
||||
[ 0.0034, 50000 ],
|
||||
[ 0.0033, 75000 ],
|
||||
[ 0.0032, 100000 ],
|
||||
[ 0.0031, 150000 ],
|
||||
[ 0.0030, 200000 ],
|
||||
[ 0.0029, 250000 ],
|
||||
[ 0.0028, 375000 ],
|
||||
[ 0.0027, 500000 ],
|
||||
[ 0.0026, 625000 ],
|
||||
[ 0.0025, 875000 ],
|
||||
],
|
||||
'maker': [
|
||||
[ 0.0030, 0 ],
|
||||
[ 0.0029, 1250 ],
|
||||
[ 0.0028, 3750 ],
|
||||
[ 0.0028, 7500 ],
|
||||
[ 0.0027, 10000 ],
|
||||
[ 0.0026, 15000 ],
|
||||
[ 0.0025, 20000 ],
|
||||
[ 0.0025, 25000 ],
|
||||
[ 0.0024, 37500 ],
|
||||
[ 0.0023, 50000 ],
|
||||
[ 0.0023, 75000 ],
|
||||
[ 0.0022, 100000 ],
|
||||
[ 0.0021, 150000 ],
|
||||
[ 0.0021, 200000 ],
|
||||
[ 0.0020, 250000 ],
|
||||
[ 0.0019, 375000 ],
|
||||
[ 0.0018, 500000 ],
|
||||
[ 0.0018, 625000 ],
|
||||
[ 0.0017, 875000 ],
|
||||
],
|
||||
},
|
||||
},
|
||||
'funding': {
|
||||
'withdraw': {
|
||||
@@ -135,6 +188,9 @@ module.exports = class bitbay extends Exchange {
|
||||
},
|
||||
},
|
||||
},
|
||||
'options': {
|
||||
'fiatCurrencies': [ 'EUR', 'USD', 'GBP', 'PLN' ],
|
||||
},
|
||||
'exceptions': {
|
||||
'400': ExchangeError, // At least one parameter wasn't set
|
||||
'401': InvalidOrder, // Invalid order type
|
||||
@@ -159,12 +215,14 @@ module.exports = class bitbay extends Exchange {
|
||||
'OFFER_NOT_FOUND': OrderNotFound,
|
||||
'OFFER_WOULD_HAVE_BEEN_PARTIALLY_FILLED': OrderImmediatelyFillable,
|
||||
'ACTION_LIMIT_EXCEEDED': RateLimitExceeded,
|
||||
'UNDER_MAINTENANCE': OnMaintenance,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async fetchMarkets (params = {}) {
|
||||
const response = await this.v1_01PublicGetTradingTicker (params);
|
||||
const fiatCurrencies = this.safeValue (this.options, 'fiatCurrencies', []);
|
||||
//
|
||||
// {
|
||||
// status: 'Ok',
|
||||
@@ -203,6 +261,12 @@ module.exports = class bitbay extends Exchange {
|
||||
'amount': this.safeInteger (first, 'scale'),
|
||||
'price': this.safeInteger (second, 'scale'),
|
||||
};
|
||||
let fees = this.safeValue (this.fees, 'trading', {});
|
||||
if (this.inArray (base, fiatCurrencies) || this.inArray (quote, fiatCurrencies)) {
|
||||
fees = this.safeValue (this.fees, 'fiat', {});
|
||||
}
|
||||
const maker = this.safeFloat (fees, 'maker');
|
||||
const taker = this.safeFloat (fees, 'taker');
|
||||
// todo: check that the limits have ben interpreted correctly
|
||||
// todo: parse the fees page
|
||||
result.push ({
|
||||
@@ -214,7 +278,8 @@ module.exports = class bitbay extends Exchange {
|
||||
'quoteId': quoteId,
|
||||
'precision': precision,
|
||||
'active': undefined,
|
||||
'fee': undefined,
|
||||
'maker': maker,
|
||||
'taker': taker,
|
||||
'limits': {
|
||||
'amount': {
|
||||
'min': this.safeFloat (first, 'minOffer'),
|
||||
|
||||
+6
-6
@@ -905,12 +905,12 @@ module.exports = class bitfinex extends Exchange {
|
||||
|
||||
parseOHLCV (ohlcv, market = undefined, timeframe = '1m', since = undefined, limit = undefined) {
|
||||
return [
|
||||
ohlcv[0],
|
||||
ohlcv[1],
|
||||
ohlcv[3],
|
||||
ohlcv[4],
|
||||
ohlcv[2],
|
||||
ohlcv[5],
|
||||
this.safeInteger (ohlcv, 0),
|
||||
this.safeFloat (ohlcv, 1),
|
||||
this.safeFloat (ohlcv, 3),
|
||||
this.safeFloat (ohlcv, 4),
|
||||
this.safeFloat (ohlcv, 2),
|
||||
this.safeFloat (ohlcv, 5),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -699,6 +699,7 @@ module.exports = class bitfinex2 extends bitfinex {
|
||||
'PARTIALLY FILLED': 'open',
|
||||
'EXECUTED': 'closed',
|
||||
'CANCELED': 'canceled',
|
||||
'CANCELED was: PARTIALLY FILLED': 'canceled',
|
||||
'INSUFFICIENT MARGIN': 'canceled',
|
||||
'INSUFFICIENT BALANCE (G1) was: PARTIALLY FILLED': 'canceled',
|
||||
'RSN_DUST': 'rejected',
|
||||
|
||||
+393
-44
@@ -3,7 +3,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const Exchange = require ('./base/Exchange');
|
||||
const { ExchangeError, ExchangeNotAvailable, AuthenticationError, BadRequest, PermissionDenied, InvalidAddress } = require ('./base/errors');
|
||||
const { ExchangeError, ExchangeNotAvailable, AuthenticationError, BadRequest, PermissionDenied, InvalidAddress, ArgumentsRequired, InvalidOrder } = require ('./base/errors');
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -16,7 +16,12 @@ module.exports = class bithumb extends Exchange {
|
||||
'rateLimit': 500,
|
||||
'has': {
|
||||
'CORS': true,
|
||||
'createOrder': true,
|
||||
'cancelOrder': true,
|
||||
'createMarketOrder': true,
|
||||
'fetchTickers': true,
|
||||
'fetchOpenOrders': true,
|
||||
'fetchOrder': true,
|
||||
'withdraw': true,
|
||||
},
|
||||
'urls': {
|
||||
@@ -48,8 +53,8 @@ module.exports = class bithumb extends Exchange {
|
||||
'info/ticker',
|
||||
'info/orders',
|
||||
'info/user_transactions',
|
||||
'trade/place',
|
||||
'info/order_detail',
|
||||
'trade/place',
|
||||
'trade/cancel',
|
||||
'trade/btc_withdrawal',
|
||||
'trade/krw_deposit',
|
||||
@@ -165,15 +170,53 @@ module.exports = class bithumb extends Exchange {
|
||||
'currency': market['base'],
|
||||
};
|
||||
if (limit !== undefined) {
|
||||
request['count'] = limit; // max = 50
|
||||
request['count'] = limit; // default 30, max 30
|
||||
}
|
||||
const response = await this.publicGetOrderbookCurrency (this.extend (request, params));
|
||||
const orderbook = this.safeValue (response, 'data');
|
||||
const timestamp = this.safeInteger (orderbook, 'timestamp');
|
||||
return this.parseOrderBook (orderbook, timestamp, 'bids', 'asks', 'price', 'quantity');
|
||||
//
|
||||
// {
|
||||
// "status":"0000",
|
||||
// "data":{
|
||||
// "timestamp":"1587621553942",
|
||||
// "payment_currency":"KRW",
|
||||
// "order_currency":"BTC",
|
||||
// "bids":[
|
||||
// {"price":"8652000","quantity":"0.0043"},
|
||||
// {"price":"8651000","quantity":"0.0049"},
|
||||
// {"price":"8650000","quantity":"8.4791"},
|
||||
// ],
|
||||
// "asks":[
|
||||
// {"price":"8654000","quantity":"0.119"},
|
||||
// {"price":"8655000","quantity":"0.254"},
|
||||
// {"price":"8658000","quantity":"0.119"},
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
//
|
||||
const data = this.safeValue (response, 'data', {});
|
||||
const timestamp = this.safeInteger (data, 'timestamp');
|
||||
return this.parseOrderBook (data, timestamp, 'bids', 'asks', 'price', 'quantity');
|
||||
}
|
||||
|
||||
parseTicker (ticker, market = undefined) {
|
||||
//
|
||||
// fetchTicker, fetchTickers
|
||||
//
|
||||
// {
|
||||
// "opening_price":"227100",
|
||||
// "closing_price":"228400",
|
||||
// "min_price":"222300",
|
||||
// "max_price":"230000",
|
||||
// "units_traded":"82618.56075337",
|
||||
// "acc_trade_value":"18767376138.6031",
|
||||
// "prev_closing_price":"227100",
|
||||
// "units_traded_24H":"151871.13484676",
|
||||
// "acc_trade_value_24H":"34247610416.8974",
|
||||
// "fluctate_24H":"8700",
|
||||
// "fluctate_rate_24H":"3.96",
|
||||
// "date":"1587710327264", // fetchTickers inject this
|
||||
// }
|
||||
//
|
||||
const timestamp = this.safeInteger (ticker, 'date');
|
||||
let symbol = undefined;
|
||||
if (market !== undefined) {
|
||||
@@ -224,9 +267,31 @@ module.exports = class bithumb extends Exchange {
|
||||
async fetchTickers (symbols = undefined, params = {}) {
|
||||
await this.loadMarkets ();
|
||||
const response = await this.publicGetTickerAll (params);
|
||||
//
|
||||
// {
|
||||
// "status":"0000",
|
||||
// "data":{
|
||||
// "BTC":{
|
||||
// "opening_price":"9045000",
|
||||
// "closing_price":"9132000",
|
||||
// "min_price":"8938000",
|
||||
// "max_price":"9168000",
|
||||
// "units_traded":"4619.79967497",
|
||||
// "acc_trade_value":"42021363832.5187",
|
||||
// "prev_closing_price":"9041000",
|
||||
// "units_traded_24H":"8793.5045804",
|
||||
// "acc_trade_value_24H":"78933458515.4962",
|
||||
// "fluctate_24H":"530000",
|
||||
// "fluctate_rate_24H":"6.16"
|
||||
// },
|
||||
// "date":"1587710878669"
|
||||
// }
|
||||
// }
|
||||
//
|
||||
const result = {};
|
||||
const timestamp = this.safeInteger (response['data'], 'date');
|
||||
const tickers = this.omit (response['data'], 'date');
|
||||
const data = this.safeValue (response, 'data', {});
|
||||
const timestamp = this.safeInteger (data, 'date');
|
||||
const tickers = this.omit (data, 'date');
|
||||
const ids = Object.keys (tickers);
|
||||
for (let i = 0; i < ids.length; i++) {
|
||||
const id = ids[i];
|
||||
@@ -253,19 +318,72 @@ module.exports = class bithumb extends Exchange {
|
||||
'currency': market['base'],
|
||||
};
|
||||
const response = await this.publicGetTickerCurrency (this.extend (request, params));
|
||||
return this.parseTicker (response['data'], market);
|
||||
//
|
||||
// {
|
||||
// "status":"0000",
|
||||
// "data":{
|
||||
// "opening_price":"227100",
|
||||
// "closing_price":"228400",
|
||||
// "min_price":"222300",
|
||||
// "max_price":"230000",
|
||||
// "units_traded":"82618.56075337",
|
||||
// "acc_trade_value":"18767376138.6031",
|
||||
// "prev_closing_price":"227100",
|
||||
// "units_traded_24H":"151871.13484676",
|
||||
// "acc_trade_value_24H":"34247610416.8974",
|
||||
// "fluctate_24H":"8700",
|
||||
// "fluctate_rate_24H":"3.96",
|
||||
// "date":"1587710327264"
|
||||
// }
|
||||
// }
|
||||
//
|
||||
const data = this.safeValue (response, 'data', {});
|
||||
return this.parseTicker (data, market);
|
||||
}
|
||||
|
||||
parseTrade (trade, market = undefined) {
|
||||
//
|
||||
// fetchTrades (public)
|
||||
//
|
||||
// {
|
||||
// "transaction_date":"2020-04-23 22:21:46",
|
||||
// "type":"ask",
|
||||
// "units_traded":"0.0125",
|
||||
// "price":"8667000",
|
||||
// "total":"108337"
|
||||
// }
|
||||
//
|
||||
// fetchOrder (private)
|
||||
//
|
||||
// {
|
||||
// "transaction_date": "1572497603902030",
|
||||
// "price": "8601000",
|
||||
// "units": "0.005",
|
||||
// "fee_currency": "KRW",
|
||||
// "fee": "107.51",
|
||||
// "total": "43005"
|
||||
// }
|
||||
//
|
||||
// a workaround for their bug in date format, hours are not 0-padded
|
||||
const parts = trade['transaction_date'].split (' ');
|
||||
const transaction_date = parts[0];
|
||||
let transaction_time = parts[1];
|
||||
if (transaction_time.length < 8) {
|
||||
transaction_time = '0' + transaction_time;
|
||||
let timestamp = undefined;
|
||||
const transactionDatetime = this.safeString (trade, 'transaction_date');
|
||||
if (transactionDatetime !== undefined) {
|
||||
const parts = transactionDatetime.split (' ');
|
||||
const numParts = parts.length;
|
||||
if (numParts > 1) {
|
||||
const transactionDate = parts[0];
|
||||
let transactionTime = parts[1];
|
||||
if (transactionTime.length < 8) {
|
||||
transactionTime = '0' + transactionTime;
|
||||
}
|
||||
timestamp = this.parse8601 (transactionDate + ' ' + transactionTime);
|
||||
} else {
|
||||
timestamp = this.safeIntegerProduct (trade, 'transaction_date', 0.001);
|
||||
}
|
||||
}
|
||||
if (timestamp !== undefined) {
|
||||
timestamp -= 9 * 3600000; // they report UTC + 9 hours, server in Korean timezone
|
||||
}
|
||||
let timestamp = this.parse8601 (transaction_date + ' ' + transaction_time);
|
||||
timestamp -= 9 * 3600000; // they report UTC + 9 hours (server in Korean timezone)
|
||||
const type = undefined;
|
||||
let side = this.safeString (trade, 'type');
|
||||
side = (side === 'ask') ? 'sell' : 'buy';
|
||||
@@ -276,12 +394,24 @@ module.exports = class bithumb extends Exchange {
|
||||
}
|
||||
const price = this.safeFloat (trade, 'price');
|
||||
const amount = this.safeFloat (trade, 'units_traded');
|
||||
let cost = undefined;
|
||||
if (amount !== undefined) {
|
||||
if (price !== undefined) {
|
||||
cost = price * amount;
|
||||
let cost = this.safeFloat (trade, 'total');
|
||||
if (cost === undefined) {
|
||||
if (amount !== undefined) {
|
||||
if (price !== undefined) {
|
||||
cost = price * amount;
|
||||
}
|
||||
}
|
||||
}
|
||||
let fee = undefined;
|
||||
const feeCost = this.safeFloat (trade, 'fee');
|
||||
if (feeCost !== undefined) {
|
||||
const feeCurrencyId = this.safeString (trade, 'fee_currency');
|
||||
const feeCurrencyCode = this.commonCurrencyCode (feeCurrencyId);
|
||||
fee = {
|
||||
'cost': feeCost,
|
||||
'currency': feeCurrencyCode,
|
||||
};
|
||||
}
|
||||
return {
|
||||
'id': id,
|
||||
'info': trade,
|
||||
@@ -295,7 +425,7 @@ module.exports = class bithumb extends Exchange {
|
||||
'price': price,
|
||||
'amount': amount,
|
||||
'cost': cost,
|
||||
'fee': undefined,
|
||||
'fee': fee,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -309,57 +439,276 @@ module.exports = class bithumb extends Exchange {
|
||||
request['count'] = limit; // default 20, max 100
|
||||
}
|
||||
const response = await this.publicGetTransactionHistoryCurrency (this.extend (request, params));
|
||||
return this.parseTrades (response['data'], market, since, limit);
|
||||
//
|
||||
// {
|
||||
// "status":"0000",
|
||||
// "data":[
|
||||
// {
|
||||
// "transaction_date":"2020-04-23 22:21:46",
|
||||
// "type":"ask",
|
||||
// "units_traded":"0.0125",
|
||||
// "price":"8667000",
|
||||
// "total":"108337"
|
||||
// },
|
||||
// ]
|
||||
// }
|
||||
//
|
||||
const data = this.safeValue (response, 'data', []);
|
||||
return this.parseTrades (data, market, since, limit);
|
||||
}
|
||||
|
||||
async createOrder (symbol, type, side, amount, price = undefined, params = {}) {
|
||||
await this.loadMarkets ();
|
||||
const market = this.market (symbol);
|
||||
let request = undefined;
|
||||
let method = 'privatePostTrade';
|
||||
const request = {
|
||||
'order_currency': market['id'],
|
||||
'Payment_currency': market['quote'],
|
||||
'units': amount,
|
||||
};
|
||||
let method = 'privatePostTradePlace';
|
||||
if (type === 'limit') {
|
||||
request = {
|
||||
'order_currency': market['id'],
|
||||
'Payment_currency': market['quote'],
|
||||
'units': amount,
|
||||
'price': price,
|
||||
'type': (side === 'buy') ? 'bid' : 'ask',
|
||||
};
|
||||
method += 'Place';
|
||||
} else if (type === 'market') {
|
||||
request = {
|
||||
'currency': market['id'],
|
||||
'units': amount,
|
||||
};
|
||||
method += 'Market' + this.capitalize (side);
|
||||
request['price'] = price;
|
||||
request['type'] = (side === 'buy') ? 'bid' : 'ask';
|
||||
} else {
|
||||
method = 'privatePostTradeMarket' + this.capitalize (side);
|
||||
}
|
||||
const response = await this[method] (this.extend (request, params));
|
||||
const id = this.safeString (response, 'order_id');
|
||||
if (id === undefined) {
|
||||
throw new InvalidOrder (this.id + ' createOrder did not return an order id');
|
||||
}
|
||||
return {
|
||||
'info': response,
|
||||
'symbol': symbol,
|
||||
'type': type,
|
||||
'side': side,
|
||||
'id': id,
|
||||
};
|
||||
}
|
||||
|
||||
async fetchOrder (id, symbol = undefined, params = {}) {
|
||||
if (symbol === undefined) {
|
||||
throw new ArgumentsRequired (this.id + ' fetchOrder requires a symbol argument');
|
||||
}
|
||||
await this.loadMarkets ();
|
||||
const market = this.market (symbol);
|
||||
const request = {
|
||||
'order_id': id,
|
||||
'count': 1,
|
||||
'order_currency': market['base'],
|
||||
'payment_currency': market['quote'],
|
||||
};
|
||||
const response = await this.privatePostInfoOrderDetail (this.extend (request, params));
|
||||
//
|
||||
// {
|
||||
// "status": "0000",
|
||||
// "data": {
|
||||
// "transaction_date": "1572497603668315",
|
||||
// "type": "bid",
|
||||
// "order_status": "Completed",
|
||||
// "order_currency": "BTC",
|
||||
// "payment_currency": "KRW",
|
||||
// "order_price": "8601000",
|
||||
// "order_qty": "0.007",
|
||||
// "cancel_date": "",
|
||||
// "cancel_type": "",
|
||||
// "contract": [
|
||||
// {
|
||||
// "transaction_date": "1572497603902030",
|
||||
// "price": "8601000",
|
||||
// "units": "0.005",
|
||||
// "fee_currency": "KRW",
|
||||
// "fee": "107.51",
|
||||
// "total": "43005"
|
||||
// },
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
//
|
||||
const data = this.safeValue (response, 'data');
|
||||
return this.parseOrder (this.extend (data, { 'order_id': id }), market);
|
||||
}
|
||||
|
||||
parseOrderStatus (status) {
|
||||
const statuses = {
|
||||
'Pending': 'open',
|
||||
'Completed': 'closed',
|
||||
'Cancel': 'canceled',
|
||||
};
|
||||
return this.safeString (statuses, status, status);
|
||||
}
|
||||
|
||||
parseOrder (order, market = undefined) {
|
||||
//
|
||||
// fetchOrder
|
||||
//
|
||||
// {
|
||||
// "transaction_date": "1572497603668315",
|
||||
// "type": "bid",
|
||||
// "order_status": "Completed",
|
||||
// "order_currency": "BTC",
|
||||
// "payment_currency": "KRW",
|
||||
// "order_price": "8601000",
|
||||
// "order_qty": "0.007",
|
||||
// "cancel_date": "",
|
||||
// "cancel_type": "",
|
||||
// "contract": [
|
||||
// {
|
||||
// "transaction_date": "1572497603902030",
|
||||
// "price": "8601000",
|
||||
// "units": "0.005",
|
||||
// "fee_currency": "KRW",
|
||||
// "fee": "107.51",
|
||||
// "total": "43005"
|
||||
// },
|
||||
// ]
|
||||
// }
|
||||
//
|
||||
// fetchOpenOrders
|
||||
//
|
||||
// {
|
||||
// "order_currency": "BTC",
|
||||
// "payment_currency": "KRW",
|
||||
// "order_id": "C0101000007408440032",
|
||||
// "order_date": "1571728739360570",
|
||||
// "type": "bid",
|
||||
// "units": "5.0",
|
||||
// "units_remaining": "5.0",
|
||||
// "price": "501000",
|
||||
// }
|
||||
//
|
||||
const timestamp = this.safeIntegerProduct (order, 'order_date', 0.001);
|
||||
const sideProperty = this.safeValue2 (order, 'type', 'side');
|
||||
const side = (sideProperty === 'bid') ? 'buy' : 'sell';
|
||||
const status = this.parseOrderStatus (this.safeString (order, 'order_status'));
|
||||
let price = this.safeFloat2 (order, 'order_price', 'price');
|
||||
let type = 'limit';
|
||||
if (price === 0) {
|
||||
price = undefined;
|
||||
type = 'market';
|
||||
}
|
||||
const amount = this.safeFloat2 (order, 'order_qty', 'units');
|
||||
let remaining = this.safeFloat (order, 'units_remaining');
|
||||
if (remaining === undefined) {
|
||||
if (status === 'closed') {
|
||||
remaining = 0;
|
||||
} else {
|
||||
remaining = amount;
|
||||
}
|
||||
}
|
||||
let filled = undefined;
|
||||
if ((amount !== undefined) && (remaining !== undefined)) {
|
||||
filled = amount - remaining;
|
||||
}
|
||||
let symbol = undefined;
|
||||
const baseId = this.safeString (order, 'order_currency');
|
||||
const quoteId = this.safeString (order, 'payment_currency');
|
||||
const base = this.safeCurrencyCode (baseId);
|
||||
const quote = this.safeCurrencyCode (quoteId);
|
||||
if ((base !== undefined) && (quote !== undefined)) {
|
||||
symbol = base + '/' + quote;
|
||||
}
|
||||
if ((symbol === undefined) && (market !== undefined)) {
|
||||
symbol = market['symbol'];
|
||||
}
|
||||
const rawTrades = this.safeValue (order, 'contract');
|
||||
let trades = undefined;
|
||||
const id = this.safeString (order, 'order_id');
|
||||
if (rawTrades !== undefined) {
|
||||
trades = this.parseTrades (rawTrades, market, undefined, undefined, {
|
||||
'side': side,
|
||||
'symbol': symbol,
|
||||
'order': id,
|
||||
});
|
||||
}
|
||||
return {
|
||||
'info': order,
|
||||
'id': id,
|
||||
'timestamp': timestamp,
|
||||
'datetime': this.iso8601 (timestamp),
|
||||
'lastTradeTimestamp': undefined,
|
||||
'symbol': symbol,
|
||||
'type': type,
|
||||
'side': side,
|
||||
'price': price,
|
||||
'amount': amount,
|
||||
'cost': undefined,
|
||||
'average': undefined,
|
||||
'filled': filled,
|
||||
'remaining': remaining,
|
||||
'status': status,
|
||||
'fee': undefined,
|
||||
'trades': trades,
|
||||
};
|
||||
}
|
||||
|
||||
async fetchOpenOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
||||
if (symbol === undefined) {
|
||||
throw new ArgumentsRequired (this.id + ' fetchOpenOrders requires a symbol argument');
|
||||
}
|
||||
await this.loadMarkets ();
|
||||
const market = this.market (symbol);
|
||||
if (limit === undefined) {
|
||||
limit = 100;
|
||||
}
|
||||
const request = {
|
||||
'count': limit,
|
||||
'order_currency': market['base'],
|
||||
'payment_currency': market['quote'],
|
||||
};
|
||||
if (since !== undefined) {
|
||||
request['after'] = since;
|
||||
}
|
||||
const response = await this.privatePostInfoOrders (this.extend (request, params));
|
||||
//
|
||||
// {
|
||||
// "status": "0000",
|
||||
// "data": [
|
||||
// {
|
||||
// "order_currency": "BTC",
|
||||
// "payment_currency": "KRW",
|
||||
// "order_id": "C0101000007408440032",
|
||||
// "order_date": "1571728739360570",
|
||||
// "type": "bid",
|
||||
// "units": "5.0",
|
||||
// "units_remaining": "5.0",
|
||||
// "price": "501000",
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
//
|
||||
const data = this.safeValue (response, 'data', []);
|
||||
return this.parseOrders (data, market, since, limit);
|
||||
}
|
||||
|
||||
async cancelOrder (id, symbol = undefined, params = {}) {
|
||||
const side_in_params = ('side' in params);
|
||||
if (!side_in_params) {
|
||||
throw new ExchangeError (this.id + ' cancelOrder requires a `side` parameter (sell or buy) and a `currency` parameter');
|
||||
throw new ArgumentsRequired (this.id + ' cancelOrder requires a `symbol` argument and a `side` parameter (sell or buy)');
|
||||
}
|
||||
const currency = this.safeString (params, 'currency');
|
||||
if (currency === undefined) {
|
||||
throw new ExchangeError (this.id + ' cancelOrder requires a `currency` parameter (a currency id)');
|
||||
if (symbol === undefined) {
|
||||
throw new ArgumentsRequired (this.id + ' cancelOrder requires a `symbol` argument and a `side` parameter (sell or buy)');
|
||||
}
|
||||
const market = this.market (symbol);
|
||||
const side = (params['side'] === 'buy') ? 'bid' : 'ask';
|
||||
params = this.omit (params, [ 'side', 'currency' ]);
|
||||
// https://github.com/ccxt/ccxt/issues/6771
|
||||
const request = {
|
||||
'order_id': id,
|
||||
'type': side,
|
||||
'currency': currency,
|
||||
'order_currency': market['base'],
|
||||
'payment_currency': market['quote'],
|
||||
};
|
||||
return await this.privatePostTradeCancel (this.extend (request, params));
|
||||
}
|
||||
|
||||
cancelUnifiedOrder (order, params = {}) {
|
||||
const request = {
|
||||
'side': order['side'],
|
||||
};
|
||||
return this.cancelOrder (order['id'], order['symbol'], this.extend (request, params));
|
||||
}
|
||||
|
||||
async withdraw (code, amount, address, tag = undefined, params = {}) {
|
||||
this.checkAddress (address);
|
||||
await this.loadMarkets ();
|
||||
@@ -372,7 +721,7 @@ module.exports = class bithumb extends Exchange {
|
||||
if (currency === 'XRP' || currency === 'XMR') {
|
||||
const destination = this.safeString (params, 'destination');
|
||||
if ((tag === undefined) && (destination === undefined)) {
|
||||
throw new ExchangeError (this.id + ' ' + code + ' withdraw() requires a tag argument or an extra destination param');
|
||||
throw new ArgumentsRequired (this.id + ' ' + code + ' withdraw() requires a tag argument or an extra destination param');
|
||||
} else if (tag !== undefined) {
|
||||
request['destination'] = tag;
|
||||
}
|
||||
|
||||
+2
@@ -35,6 +35,7 @@ module.exports = class bitmart extends Exchange {
|
||||
'fetchClosedOrders': true,
|
||||
'fetchCanceledOrders': true,
|
||||
'fetchOrder': true,
|
||||
'signIn': true,
|
||||
},
|
||||
'urls': {
|
||||
'logo': 'https://user-images.githubusercontent.com/1294454/61835713-a2662f80-ae85-11e9-9d00-6442919701fd.jpg',
|
||||
@@ -42,6 +43,7 @@ module.exports = class bitmart extends Exchange {
|
||||
'www': 'https://www.bitmart.com/',
|
||||
'doc': 'https://github.com/bitmartexchange/bitmart-official-api-docs',
|
||||
'referral': 'http://www.bitmart.com/?r=rQCFLh',
|
||||
'fees': 'https://www.bitmart.com/fee/en',
|
||||
},
|
||||
'requiredCredentials': {
|
||||
'apiKey': true,
|
||||
|
||||
+9
-1
@@ -1134,11 +1134,19 @@ module.exports = class bitstamp extends Exchange {
|
||||
body = this.urlencode (query);
|
||||
contentType = 'application/x-www-form-urlencoded';
|
||||
headers['Content-Type'] = contentType;
|
||||
} else {
|
||||
// sending an empty POST request will trigger
|
||||
// an API0020 error returned by the exchange
|
||||
// therefore for empty requests we send a dummy object
|
||||
// https://github.com/ccxt/ccxt/issues/6846
|
||||
body = this.urlencode ({ 'foo': 'bar' });
|
||||
contentType = 'application/x-www-form-urlencoded';
|
||||
headers['Content-Type'] = contentType;
|
||||
}
|
||||
}
|
||||
const authBody = body ? body : '';
|
||||
const auth = xAuth + method + url.replace ('https://', '') + contentType + xAuthNonce + xAuthTimestamp + xAuthVersion + authBody;
|
||||
const signature = this.encode (this.hmac (this.encode (auth), this.encode (this.secret)));
|
||||
const signature = this.hmac (this.encode (auth), this.encode (this.secret));
|
||||
headers['X-Auth-Signature'] = signature;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -650,7 +650,7 @@ module.exports = class bitz extends Exchange {
|
||||
}
|
||||
} else {
|
||||
if (since !== undefined) {
|
||||
throw new ExchangeError (this.id + ' fetchOHLCV requires a limit argument if the since argument is specified');
|
||||
throw new ArgumentsRequired (this.id + ' fetchOHLCV requires a limit argument if the since argument is specified');
|
||||
}
|
||||
}
|
||||
const response = await this.marketGetKline (this.extend (request, params));
|
||||
|
||||
+5
-2
@@ -73,6 +73,9 @@ module.exports = class bleutrade extends Exchange {
|
||||
],
|
||||
},
|
||||
'v3Private': {
|
||||
'get': [
|
||||
'statement',
|
||||
],
|
||||
'post': [
|
||||
'getbalance',
|
||||
'getbalances',
|
||||
@@ -189,8 +192,8 @@ module.exports = class bleutrade extends Exchange {
|
||||
// MarketCurrencyLong: 'Litecoin',
|
||||
// BaseCurrencyLong: 'Tether' }
|
||||
const id = this.safeString (market, 'MarketName');
|
||||
const baseId = this.safeString (market, 'MarketCurrency');
|
||||
const quoteId = this.safeString (market, 'BaseCurrency');
|
||||
const baseId = this.safeString (market, 'MarketAsset');
|
||||
const quoteId = this.safeString (market, 'BaseAsset');
|
||||
const base = this.safeCurrencyCode (baseId);
|
||||
const quote = this.safeCurrencyCode (quoteId);
|
||||
const symbol = base + '/' + quote;
|
||||
|
||||
+1
@@ -18,6 +18,7 @@ module.exports = class btctradeua extends Exchange {
|
||||
'CORS': false,
|
||||
'createMarketOrder': false,
|
||||
'fetchOpenOrders': true,
|
||||
'signIn': true,
|
||||
},
|
||||
'urls': {
|
||||
'referral': 'https://btc-trade.com.ua/registration/22689',
|
||||
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const Exchange = require ('./base/Exchange');
|
||||
const { AddressPending, AuthenticationError, ExchangeError, NotSupported, PermissionDenied } = require ('./base/errors');
|
||||
const { AddressPending, AuthenticationError, ExchangeError, NotSupported, PermissionDenied, ArgumentsRequired } = require ('./base/errors');
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -692,7 +692,7 @@ module.exports = class buda extends Exchange {
|
||||
async fetchDeposits (code = undefined, since = undefined, limit = undefined, params = {}) {
|
||||
await this.loadMarkets ();
|
||||
if (code === undefined) {
|
||||
throw new ExchangeError (this.id + ': fetchDeposits() requires a currency code argument');
|
||||
throw new ArgumentsRequired (this.id + ': fetchDeposits() requires a currency code argument');
|
||||
}
|
||||
const currency = this.currency (code);
|
||||
const request = {
|
||||
@@ -707,7 +707,7 @@ module.exports = class buda extends Exchange {
|
||||
async fetchWithdrawals (code = undefined, since = undefined, limit = undefined, params = {}) {
|
||||
await this.loadMarkets ();
|
||||
if (code === undefined) {
|
||||
throw new ExchangeError (this.id + ': fetchDeposits() requires a currency code argument');
|
||||
throw new ArgumentsRequired (this.id + ': fetchDeposits() requires a currency code argument');
|
||||
}
|
||||
const currency = this.currency (code);
|
||||
const request = {
|
||||
|
||||
+220
-57
@@ -4,7 +4,7 @@
|
||||
|
||||
const Exchange = require ('./base/Exchange');
|
||||
const { TICK_SIZE } = require ('./base/functions/number');
|
||||
const { AuthenticationError, ExchangeError, ArgumentsRequired, PermissionDenied, InvalidOrder, OrderNotFound, InsufficientFunds, BadRequest, RateLimitExceeded, InvalidNonce } = require ('./base/errors');
|
||||
const { AuthenticationError, ExchangeError, ArgumentsRequired, PermissionDenied, InvalidOrder, OrderNotFound, InsufficientFunds, BadRequest, RateLimitExceeded, InvalidNonce, NotSupported } = require ('./base/errors');
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -48,7 +48,7 @@ module.exports = class bybit extends Exchange {
|
||||
'30m': '30',
|
||||
'1h': '60',
|
||||
'2h': '120',
|
||||
'3h': '180',
|
||||
'4h': '240',
|
||||
'6h': '360',
|
||||
'12h': '720',
|
||||
'1d': 'D',
|
||||
@@ -63,6 +63,7 @@ module.exports = class bybit extends Exchange {
|
||||
'www': 'https://www.bybit.com/',
|
||||
'doc': [
|
||||
'https://bybit-exchange.github.io/docs/inverse/',
|
||||
'https://bybit-exchange.github.io/docs/linear/',
|
||||
'https://github.com/bybit-exchange',
|
||||
],
|
||||
'fees': 'https://help.bybit.com/hc/en-us/articles/360039261154',
|
||||
@@ -116,6 +117,41 @@ module.exports = class bybit extends Exchange {
|
||||
'position/trading-stop',
|
||||
],
|
||||
},
|
||||
'publicLinear': {
|
||||
'get': [
|
||||
'kline',
|
||||
'recent-trading-records',
|
||||
'funding/prev-funding-rate',
|
||||
'mark-price-kline',
|
||||
],
|
||||
},
|
||||
'privateLinear': {
|
||||
'get': [
|
||||
'order/list',
|
||||
'order/search',
|
||||
'stop-order/list',
|
||||
'stop-order/search',
|
||||
'position/list',
|
||||
'position/set-auto-add-margin',
|
||||
'position/set-leverage',
|
||||
'position/switch-isolated',
|
||||
'position/trading-stop',
|
||||
'position/add-margin',
|
||||
'trade/execution/list',
|
||||
'trade/closed-pnl/list',
|
||||
'risk-limit',
|
||||
'funding/prev-funding',
|
||||
'funding/predicted-funding',
|
||||
],
|
||||
'post': [
|
||||
'order/create',
|
||||
'order/cancel',
|
||||
'order/cancelAll',
|
||||
'stop-order/create',
|
||||
'stop-order/cancel',
|
||||
'stop-order/cancelAll',
|
||||
],
|
||||
},
|
||||
'position': {
|
||||
'post': [
|
||||
'change-position-margin',
|
||||
@@ -227,6 +263,9 @@ module.exports = class bybit extends Exchange {
|
||||
},
|
||||
'precisionMode': TICK_SIZE,
|
||||
'options': {
|
||||
'marketTypes': {
|
||||
'BTC/USDT': 'linear',
|
||||
},
|
||||
'code': 'BTC',
|
||||
'fetchBalance': {
|
||||
'code': 'BTC',
|
||||
@@ -309,6 +348,8 @@ module.exports = class bybit extends Exchange {
|
||||
// }
|
||||
//
|
||||
const markets = this.safeValue (response, 'result', []);
|
||||
const options = this.safeValue (this.options, 'fetchMarkets', {});
|
||||
const linearQuoteCurrencies = this.safeValue (options, 'linear', { 'USDT': true });
|
||||
const result = [];
|
||||
for (let i = 0; i < markets.length; i++) {
|
||||
const market = markets[i];
|
||||
@@ -317,6 +358,8 @@ module.exports = class bybit extends Exchange {
|
||||
const quoteId = this.safeString (market, 'quote_currency');
|
||||
const base = this.safeCurrencyCode (baseId);
|
||||
const quote = this.safeCurrencyCode (quoteId);
|
||||
const linear = (quote in linearQuoteCurrencies);
|
||||
const inverse = !linear;
|
||||
const symbol = base + '/' + quote;
|
||||
const lotSizeFilter = this.safeValue (market, 'lot_size_filter', {});
|
||||
const priceFilter = this.safeValue (market, 'price_filter', {});
|
||||
@@ -333,6 +376,12 @@ module.exports = class bybit extends Exchange {
|
||||
'precision': precision,
|
||||
'taker': this.safeFloat (market, 'taker_fee'),
|
||||
'maker': this.safeFloat (market, 'maker_fee'),
|
||||
'type': 'future',
|
||||
'spot': false,
|
||||
'future': true,
|
||||
'option': false,
|
||||
'linear': linear,
|
||||
'inverse': inverse,
|
||||
'limits': {
|
||||
'amount': {
|
||||
'min': this.safeFloat (lotSizeFilter, 'min_trading_qty'),
|
||||
@@ -347,10 +396,6 @@ module.exports = class bybit extends Exchange {
|
||||
'max': undefined,
|
||||
},
|
||||
},
|
||||
'type': 'future',
|
||||
'spot': false,
|
||||
'future': true,
|
||||
'option': false,
|
||||
'info': market,
|
||||
});
|
||||
}
|
||||
@@ -610,13 +655,25 @@ module.exports = class bybit extends Exchange {
|
||||
// turnover: '162.32773718999994'
|
||||
// },
|
||||
//
|
||||
// {
|
||||
// "id":143536,
|
||||
// "symbol":"BTCUSDT",
|
||||
// "period":"15",
|
||||
// "start_at":1587883500,
|
||||
// "volume":1.035,
|
||||
// "open":7540.5,
|
||||
// "high":7541,
|
||||
// "low":7540.5,
|
||||
// "close":7541
|
||||
// }
|
||||
//
|
||||
return [
|
||||
this.safeTimestamp (ohlcv, 'open_time'),
|
||||
this.safeTimestamp2 (ohlcv, 'open_time', 'start_at'),
|
||||
this.safeFloat (ohlcv, 'open'),
|
||||
this.safeFloat (ohlcv, 'high'),
|
||||
this.safeFloat (ohlcv, 'low'),
|
||||
this.safeFloat (ohlcv, 'close'),
|
||||
this.safeFloat (ohlcv, 'turnover'),
|
||||
this.safeFloat2 (ohlcv, 'turnover', 'volume'),
|
||||
];
|
||||
}
|
||||
|
||||
@@ -641,7 +698,13 @@ module.exports = class bybit extends Exchange {
|
||||
if (limit !== undefined) {
|
||||
request['limit'] = limit; // max 200, default 200
|
||||
}
|
||||
const response = await this.publicGetKlineList (this.extend (request, params));
|
||||
const marketTypes = this.safeValue (this.options, 'marketTypes', {});
|
||||
const marketType = this.safeString (marketTypes, symbol);
|
||||
const method = (marketType === 'linear') ? 'publicLinearGetKline' : 'publicGetKlineList';
|
||||
const response = await this[method] (this.extend (request, params));
|
||||
//
|
||||
// inverse perpetual BTC/USD
|
||||
//
|
||||
// {
|
||||
// ret_code: 0,
|
||||
// ret_msg: 'OK',
|
||||
@@ -662,6 +725,30 @@ module.exports = class bybit extends Exchange {
|
||||
// ],
|
||||
// time_now: '1583953082.397330'
|
||||
// }
|
||||
//
|
||||
// linear perpetual BTC/USDT
|
||||
//
|
||||
// {
|
||||
// "ret_code":0,
|
||||
// "ret_msg":"OK",
|
||||
// "ext_code":"",
|
||||
// "ext_info":"",
|
||||
// "result":[
|
||||
// {
|
||||
// "id":143536,
|
||||
// "symbol":"BTCUSDT",
|
||||
// "period":"15",
|
||||
// "start_at":1587883500,
|
||||
// "volume":1.035,
|
||||
// "open":7540.5,
|
||||
// "high":7541,
|
||||
// "low":7540.5,
|
||||
// "close":7541
|
||||
// }
|
||||
// ],
|
||||
// "time_now":"1587884120.168077"
|
||||
// }
|
||||
//
|
||||
const result = this.safeValue (response, 'result', {});
|
||||
return this.parseOHLCVs (result, market, timeframe, since, limit);
|
||||
}
|
||||
@@ -688,6 +775,8 @@ module.exports = class bybit extends Exchange {
|
||||
// "exec_id": "256e5ef8-abfe-5772-971b-f944e15e0d68",
|
||||
// "exec_price": "8178.5",
|
||||
// "exec_qty": 1,
|
||||
// // the docs say the exec_time field is "abandoned" now
|
||||
// // the user should use "trade_time_ms"
|
||||
// "exec_time": "1571676941.70682",
|
||||
// "exec_type": "Trade", //Exec Type Enum
|
||||
// "exec_value": "0.00012227",
|
||||
@@ -702,30 +791,35 @@ module.exports = class bybit extends Exchange {
|
||||
// "order_type": "Market", //Order Type Enum
|
||||
// "side": "Buy", //Side Enum
|
||||
// "symbol": "BTCUSD", //Symbol Enum
|
||||
// "user_id": 1
|
||||
// "user_id": 1,
|
||||
// "trade_time_ms": 1577480599000
|
||||
// }
|
||||
//
|
||||
const id = this.safeString2 (trade, 'id', 'exec_id');
|
||||
let symbol = undefined;
|
||||
let base = undefined;
|
||||
const marketId = this.safeString (trade, 'symbol');
|
||||
let amount = this.safeFloat2 (trade, 'qty', 'exec_qty');
|
||||
let cost = this.safeFloat (trade, 'exec_value');
|
||||
const price = this.safeFloat2 (trade, 'price', 'exec_price');
|
||||
if (marketId in this.markets_by_id) {
|
||||
market = this.markets_by_id[marketId];
|
||||
symbol = market['symbol'];
|
||||
base = market['base'];
|
||||
}
|
||||
if ((symbol === undefined) && (market !== undefined)) {
|
||||
symbol = market['symbol'];
|
||||
base = market['base'];
|
||||
if (market !== undefined) {
|
||||
if (symbol === undefined) {
|
||||
symbol = market['symbol'];
|
||||
base = market['base'];
|
||||
}
|
||||
// if private trade
|
||||
if ('exec_fee' in trade) {
|
||||
if (market['inverse']) {
|
||||
amount = this.safeFloat (trade, 'exec_value');
|
||||
cost = this.safeFloat (trade, 'exec_qty');
|
||||
}
|
||||
}
|
||||
}
|
||||
let timestamp = this.parse8601 (this.safeString (trade, 'time'));
|
||||
if (timestamp === undefined) {
|
||||
timestamp = this.safeTimestamp (trade, 'exec_time');
|
||||
}
|
||||
const side = this.safeStringLower (trade, 'side');
|
||||
const price = this.safeFloat2 (trade, 'price', 'exec_price');
|
||||
const amount = this.safeFloat2 (trade, 'qty', 'exec_qty');
|
||||
let cost = this.safeFloat (trade, 'exec_value');
|
||||
if (cost === undefined) {
|
||||
if (amount !== undefined) {
|
||||
if (price !== undefined) {
|
||||
@@ -733,6 +827,11 @@ module.exports = class bybit extends Exchange {
|
||||
}
|
||||
}
|
||||
}
|
||||
let timestamp = this.parse8601 (this.safeString (trade, 'time'));
|
||||
if (timestamp === undefined) {
|
||||
timestamp = this.safeInteger (trade, 'trade_time_ms');
|
||||
}
|
||||
const side = this.safeStringLower (trade, 'side');
|
||||
const lastLiquidityInd = this.safeString (trade, 'last_liquidity_ind');
|
||||
const takerOrMaker = (lastLiquidityInd === 'AddedLiquidity') ? 'maker' : 'taker';
|
||||
const feeCost = this.safeFloat (trade, 'exec_fee');
|
||||
@@ -771,7 +870,10 @@ module.exports = class bybit extends Exchange {
|
||||
if (limit !== undefined) {
|
||||
request['count'] = limit; // default 500, max 1000
|
||||
}
|
||||
const response = await this.publicGetTradingRecords (this.extend (request, params));
|
||||
const marketTypes = this.safeValue (this.options, 'marketTypes', {});
|
||||
const marketType = this.safeString (marketTypes, symbol);
|
||||
const method = (marketType === 'linear') ? 'publicLinearGetRecentTradingRecords' : 'publicGetTradingRecords';
|
||||
const response = await this[method] (this.extend (request, params));
|
||||
//
|
||||
// {
|
||||
// ret_code: 0,
|
||||
@@ -885,8 +987,8 @@ module.exports = class bybit extends Exchange {
|
||||
// "last_exec_time": 0,
|
||||
// "last_exec_price": 0,
|
||||
// "leaves_qty": 1,
|
||||
// "cum_exec_qty": 0,
|
||||
// "cum_exec_value": 0,
|
||||
// "cum_exec_qty": 0, // in contracts, where 1 contract = 1 quote currency unit (USD for inverse contracts)
|
||||
// "cum_exec_value": 0, // in contract's underlying currency (BTC for inverse contracts)
|
||||
// "cum_exec_fee": 0,
|
||||
// "reject_reason": "",
|
||||
// "order_link_id": "",
|
||||
@@ -894,18 +996,69 @@ module.exports = class bybit extends Exchange {
|
||||
// "updated_at": "2019-11-30T11:03:43.455Z"
|
||||
// }
|
||||
//
|
||||
// fetchOrder
|
||||
//
|
||||
// {
|
||||
// "user_id" : 599946,
|
||||
// "symbol" : "BTCUSD",
|
||||
// "side" : "Buy",
|
||||
// "order_type" : "Limit",
|
||||
// "price" : "7948",
|
||||
// "qty" : 10,
|
||||
// "time_in_force" : "GoodTillCancel",
|
||||
// "order_status" : "Filled",
|
||||
// "ext_fields" : {
|
||||
// "o_req_num" : -1600687220498,
|
||||
// "xreq_type" : "x_create"
|
||||
// },
|
||||
// "last_exec_time" : "1588150113.968422",
|
||||
// "last_exec_price" : "7948",
|
||||
// "leaves_qty" : 0,
|
||||
// "leaves_value" : "0",
|
||||
// "cum_exec_qty" : 10,
|
||||
// "cum_exec_value" : "0.00125817",
|
||||
// "cum_exec_fee" : "-0.00000031",
|
||||
// "reject_reason" : "",
|
||||
// "cancel_type" : "",
|
||||
// "order_link_id" : "",
|
||||
// "created_at" : "2020-04-29T08:45:24.399146Z",
|
||||
// "updated_at" : "2020-04-29T08:48:33.968422Z",
|
||||
// "order_id" : "dd2504b9-0157-406a-99e1-efa522373944"
|
||||
// }
|
||||
//
|
||||
const marketId = this.safeString (order, 'symbol');
|
||||
let symbol = undefined;
|
||||
let base = undefined;
|
||||
if (marketId in this.markets_by_id) {
|
||||
market = this.markets_by_id[marketId];
|
||||
}
|
||||
const timestamp = this.parse8601 (this.safeString (order, 'created_at'));
|
||||
const id = this.safeString (order, 'order_id');
|
||||
const price = this.safeFloat (order, 'price');
|
||||
const average = this.safeFloat (order, 'average_price');
|
||||
const amount = this.safeFloat (order, 'qty');
|
||||
let filled = this.safeFloat (order, 'cum_exec_qty');
|
||||
let remaining = this.safeFloat (order, 'leaves_qty');
|
||||
let amount = undefined;
|
||||
let cost = undefined;
|
||||
let filled = undefined;
|
||||
let remaining = undefined;
|
||||
if (market !== undefined) {
|
||||
symbol = market['symbol'];
|
||||
base = market['base'];
|
||||
if (market['inverse']) {
|
||||
cost = this.safeFloat (order, 'cum_exec_qty');
|
||||
filled = this.safeFloat (order, 'cum_exec_value');
|
||||
remaining = this.safeFloat (order, 'leaves_value');
|
||||
amount = this.sum (filled, remaining);
|
||||
} else {
|
||||
amount = this.safeFloat (order, 'qty');
|
||||
cost = this.safeFloat (order, 'cum_exec_value');
|
||||
filled = this.safeFloat (order, 'cum_exec_qty');
|
||||
remaining = this.safeFloat (order, 'leaves_qty');
|
||||
}
|
||||
}
|
||||
let lastTradeTimestamp = this.safeTimestamp (order, 'last_exec_time');
|
||||
if (lastTradeTimestamp === 0) {
|
||||
lastTradeTimestamp = undefined;
|
||||
}
|
||||
let cost = this.safeFloat (order, 'cum_exec_value');
|
||||
if ((filled === undefined) && (amount !== undefined) && (remaining !== undefined)) {
|
||||
filled = amount - remaining;
|
||||
}
|
||||
@@ -920,22 +1073,6 @@ module.exports = class bybit extends Exchange {
|
||||
}
|
||||
}
|
||||
const status = this.parseOrderStatus (this.safeString (order, 'order_status'));
|
||||
const marketId = this.safeString (order, 'symbol');
|
||||
let symbol = undefined;
|
||||
let base = undefined;
|
||||
if (marketId in this.markets_by_id) {
|
||||
market = this.markets_by_id[marketId];
|
||||
symbol = market['symbol'];
|
||||
base = market['base'];
|
||||
}
|
||||
if (market !== undefined) {
|
||||
if (symbol === undefined) {
|
||||
symbol = market['symbol'];
|
||||
}
|
||||
if (base === undefined) {
|
||||
base = market['base'];
|
||||
}
|
||||
}
|
||||
const side = this.safeStringLower (order, 'side');
|
||||
let feeCost = this.safeFloat (order, 'cum_exec_fee');
|
||||
let fee = undefined;
|
||||
@@ -987,7 +1124,9 @@ module.exports = class bybit extends Exchange {
|
||||
// conditional orders ---------------------------------------------
|
||||
// 'stop_order_id': id, // one of stop_order_id or order_link_id is required for conditional orders
|
||||
};
|
||||
let method = 'privateGetOrder';
|
||||
const marketTypes = this.safeValue (this.options, 'marketTypes', {});
|
||||
const marketType = this.safeString (marketTypes, symbol);
|
||||
let method = (marketType === 'linear') ? 'privateLinearGetOrderSearch' : 'privateGetOrder';
|
||||
const stopOrderId = this.safeString (params, 'stop_order_id');
|
||||
if (stopOrderId === undefined) {
|
||||
const orderLinkId = this.safeString (params, 'order_link_id');
|
||||
@@ -995,7 +1134,7 @@ module.exports = class bybit extends Exchange {
|
||||
request['order_id'] = id;
|
||||
}
|
||||
} else {
|
||||
method = 'privateGetStopOrder';
|
||||
method = (marketType === 'linear') ? 'privateLinearGetStopOrderSearch' : 'privateGetStopOrder';
|
||||
}
|
||||
const response = await this[method] (this.extend (request, params));
|
||||
//
|
||||
@@ -1107,12 +1246,14 @@ module.exports = class bybit extends Exchange {
|
||||
}
|
||||
const stopPx = this.safeValue (params, 'stop_px');
|
||||
const basePrice = this.safeValue (params, 'base_price');
|
||||
let method = 'privatePostOrderCreate';
|
||||
const marketTypes = this.safeValue (this.options, 'marketTypes', {});
|
||||
const marketType = this.safeString (marketTypes, symbol);
|
||||
let method = (marketType === 'linear') ? 'privateLinearPostOrderCreate' : 'privatePostOrderCreate';
|
||||
if (stopPx !== undefined) {
|
||||
if (basePrice === undefined) {
|
||||
throw new ArgumentsRequired (this.id + ' createOrder requires both the stop_px and base_price params for a conditional ' + type + ' order');
|
||||
} else {
|
||||
method = 'openapiPostStopOrderCreate';
|
||||
method = (marketType === 'linear') ? 'privateLinearPostStopOrderCreate' : 'openapiPostStopOrderCreate';
|
||||
request['stop_px'] = this.priceToPrecision (symbol, stopPx);
|
||||
request['base_price'] = this.priceToPrecision (symbol, basePrice);
|
||||
params = this.omit (params, [ 'stop_px', 'base_price' ]);
|
||||
@@ -1206,6 +1347,11 @@ module.exports = class bybit extends Exchange {
|
||||
if (symbol === undefined) {
|
||||
throw new ArgumentsRequired (this.id + ' editOrder requires an symbol argument');
|
||||
}
|
||||
const marketTypes = this.safeValue (this.options, 'marketTypes', {});
|
||||
const marketType = this.safeString (marketTypes, symbol);
|
||||
if (marketType === 'linear') {
|
||||
throw new NotSupported (this.id + ' does not support editOrder for ' + marketType + ' ' + symbol + ' market type');
|
||||
}
|
||||
await this.loadMarkets ();
|
||||
const market = this.market (symbol);
|
||||
const request = {
|
||||
@@ -1283,7 +1429,9 @@ module.exports = class bybit extends Exchange {
|
||||
// conditional orders ---------------------------------------------
|
||||
// 'stop_order_id': id, // one of stop_order_id or order_link_id is required for conditional orders
|
||||
};
|
||||
let method = 'privatePostOrderCancel';
|
||||
const marketTypes = this.safeValue (this.options, 'marketTypes', {});
|
||||
const marketType = this.safeValue (marketTypes, symbol);
|
||||
let method = (marketType === 'linear') ? 'privateLinearPostOrderCancel' : 'privatePostOrderCancel';
|
||||
const stopOrderId = this.safeString (params, 'stop_order_id');
|
||||
if (stopOrderId === undefined) {
|
||||
const orderLinkId = this.safeString (params, 'order_link_id');
|
||||
@@ -1291,7 +1439,7 @@ module.exports = class bybit extends Exchange {
|
||||
request['order_id'] = id;
|
||||
}
|
||||
} else {
|
||||
method = 'openapiPostStopOrderCancel';
|
||||
method = (marketType === 'linear') ? 'privateLinearPostStopOrderCancel' : 'openapiPostStopOrderCancel';
|
||||
}
|
||||
const response = await this[method] (this.extend (request, params));
|
||||
const result = this.safeValue (response, 'result', {});
|
||||
@@ -1308,7 +1456,10 @@ module.exports = class bybit extends Exchange {
|
||||
'symbol': market['id'],
|
||||
};
|
||||
const options = this.safeValue (this.options, 'cancelAllOrders');
|
||||
const method = this.safeString (options, 'method', 'privatePostOrderCancelAll');
|
||||
const marketTypes = this.safeValue (this.options, 'marketTypes', {});
|
||||
const marketType = this.safeString (marketTypes, symbol);
|
||||
const defaultMethod = (marketType === 'linear') ? 'privateLinearPostOrderCancelAll' : 'privatePostOrderCancelAll';
|
||||
const method = this.safeString (options, 'method', defaultMethod);
|
||||
const response = await this[method] (this.extend (request, params));
|
||||
const result = this.safeValue (response, 'result', []);
|
||||
return this.parseOrders (result, market);
|
||||
@@ -1337,7 +1488,9 @@ module.exports = class bybit extends Exchange {
|
||||
request['limit'] = limit;
|
||||
}
|
||||
const options = this.safeValue (this.options, 'fetchOrders', {});
|
||||
let defaultMethod = 'openapiGetOrderList';
|
||||
const marketTypes = this.safeValue (this.options, 'marketTypes', {});
|
||||
const marketType = this.safeString (marketTypes, symbol);
|
||||
let defaultMethod = (marketType === 'linear') ? 'privateLinearGetOrderList' : 'openapiGetOrderList';
|
||||
let query = params;
|
||||
if (('stop_order_id' in params) || ('stop_order_status' in params)) {
|
||||
let stopOrderStatus = this.safeValue (params, 'stopOrderStatus');
|
||||
@@ -1348,7 +1501,7 @@ module.exports = class bybit extends Exchange {
|
||||
request['stop_order_status'] = stopOrderStatus;
|
||||
query = this.omit (params, 'stop_order_status');
|
||||
}
|
||||
defaultMethod = 'openapiGetStopOrderList';
|
||||
defaultMethod = (marketType === 'linear') ? 'privateLinearGetStopOrderList' : 'openapiGetStopOrderList';
|
||||
}
|
||||
const method = this.safeString (options, 'method', defaultMethod);
|
||||
const response = await this[method] (this.extend (request, query));
|
||||
@@ -1524,12 +1677,15 @@ module.exports = class bybit extends Exchange {
|
||||
request['symbol'] = market['id'];
|
||||
}
|
||||
if (since !== undefined) {
|
||||
request['start_time'] = parseInt (since / 1000);
|
||||
request['start_time'] = since;
|
||||
}
|
||||
if (limit !== undefined) {
|
||||
request['limit'] = limit; // default 20, max 50
|
||||
}
|
||||
const response = await this.privateGetExecutionList (this.extend (request, params));
|
||||
const marketTypes = this.safeValue (this.options, 'marketTypes', {});
|
||||
const marketType = this.safeString (marketTypes, symbol);
|
||||
const method = (marketType === 'linear') ? 'privateLinearGetTradeExecutionList' : 'privateGetExecutionList';
|
||||
const response = await this[method] (this.extend (request, params));
|
||||
//
|
||||
// {
|
||||
// "ret_code": 0,
|
||||
@@ -1864,6 +2020,11 @@ module.exports = class bybit extends Exchange {
|
||||
if (Object.keys (params).length) {
|
||||
request += '?' + this.rawencode (params);
|
||||
}
|
||||
} else if (api === 'publicLinear') {
|
||||
request = '/public/linear/' + request;
|
||||
if (Object.keys (params).length) {
|
||||
request += '?' + this.rawencode (params);
|
||||
}
|
||||
} else {
|
||||
this.checkRequiredCredentials ();
|
||||
if (api === 'openapi') {
|
||||
@@ -1871,14 +2032,16 @@ module.exports = class bybit extends Exchange {
|
||||
} else if (api === 'private') {
|
||||
// private v2
|
||||
request = '/' + this.version + '/' + api + '/' + request;
|
||||
} else if (api === 'privateLinear') {
|
||||
request = '/private/linear/' + request;
|
||||
} else {
|
||||
// position, user
|
||||
request += '/' + api + '/' + request;
|
||||
request = '/' + api + '/' + request;
|
||||
}
|
||||
const timestamp = this.nonce ();
|
||||
const query = this.extend (params, {
|
||||
'api_key': this.apiKey,
|
||||
'recvWindow': this.options['recvWindow'],
|
||||
'recv_window': this.options['recvWindow'],
|
||||
'timestamp': timestamp,
|
||||
});
|
||||
const auth = this.rawencode (this.keysort (query));
|
||||
|
||||
+11
-5
@@ -47,9 +47,15 @@ module.exports = class bytetrade extends Exchange {
|
||||
'1M': '1M',
|
||||
},
|
||||
'urls': {
|
||||
'test': 'https://api-v2-test.byte-trade.com',
|
||||
'test': {
|
||||
'market': 'https://api-v2-test.byte-trade.com',
|
||||
'public': 'https://api-v2-test.byte-trade.com',
|
||||
},
|
||||
'logo': 'https://user-images.githubusercontent.com/1294454/67288762-2f04a600-f4e6-11e9-9fd6-c60641919491.jpg',
|
||||
'api': 'https://api-v2.byte-trade.com',
|
||||
'api': {
|
||||
'market': 'https://api-v2.bytetrade.com',
|
||||
'public': 'https://api-v2.bytetrade.com',
|
||||
},
|
||||
'www': 'https://www.byte-trade.com',
|
||||
'doc': 'https://github.com/Bytetrade/bytetrade-official-api-docs/wiki',
|
||||
},
|
||||
@@ -1222,7 +1228,7 @@ module.exports = class bytetrade extends Exchange {
|
||||
this.numberToLE (address.length, 1),
|
||||
this.stringToBinary (this.encode (address)),
|
||||
this.numberToLE (parseInt (coinId), 4),
|
||||
this.numberToLE (Math.floor (parseInt (parseFloat (this.integerDivide (amountChain, eightBytes)))), 8),
|
||||
this.numberToLE (this.integerDivide (amountChain, eightBytes), 8),
|
||||
this.numberToLE (this.integerModulo (amountChain, eightBytes), 8),
|
||||
this.numberToLE (1, 1),
|
||||
this.numberToLE (this.integerDivide (assetFee, eightBytes), 8),
|
||||
@@ -1255,7 +1261,7 @@ module.exports = class bytetrade extends Exchange {
|
||||
this.numberToLE (middleAddress.length, 1),
|
||||
this.stringToBinary (this.encode (middleAddress)),
|
||||
this.numberToLE (parseInt (coinId), 4),
|
||||
this.numberToLE (Math.floor (parseInt (parseFloat (this.integerDivide (amountChain, eightBytes)))), 8),
|
||||
this.numberToLE (this.integerDivide (amountChain, eightBytes), 8),
|
||||
this.numberToLE (this.integerModulo (amountChain, eightBytes), 8),
|
||||
this.numberToLE (0, 1),
|
||||
this.numberToLE (1, 1),
|
||||
@@ -1358,7 +1364,7 @@ module.exports = class bytetrade extends Exchange {
|
||||
}
|
||||
|
||||
sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
||||
let url = this.urls['api'];
|
||||
let url = this.urls['api'][api];
|
||||
url += '/' + path;
|
||||
if (Object.keys (params).length) {
|
||||
url += '?' + this.urlencode (params);
|
||||
|
||||
+37
-1
@@ -564,9 +564,45 @@ module.exports = class cex extends Exchange {
|
||||
request['order_type'] = type;
|
||||
}
|
||||
const response = await this.privatePostPlaceOrderPair (this.extend (request, params));
|
||||
//
|
||||
// {
|
||||
// "id": "12978363524",
|
||||
// "time": 1586610022259,
|
||||
// "type": "buy",
|
||||
// "price": "0.033934",
|
||||
// "amount": "0.10722802",
|
||||
// "pending": "0.10722802",
|
||||
// "complete": false
|
||||
// }
|
||||
//
|
||||
const placedAmount = this.safeFloat (response, 'amount');
|
||||
const remaining = this.safeFloat (response, 'pending');
|
||||
const timestamp = this.safeValue (response, 'time');
|
||||
const complete = this.safeValue (response, 'complete');
|
||||
const status = complete ? 'closed' : 'open';
|
||||
let filled = undefined;
|
||||
if ((placedAmount !== undefined) && (remaining !== undefined)) {
|
||||
filled = Math.max (placedAmount - remaining, 0);
|
||||
}
|
||||
return {
|
||||
'id': this.safeString (response, 'id'),
|
||||
'info': response,
|
||||
'id': response['id'],
|
||||
'clientOrderId': undefined,
|
||||
'timestamp': timestamp,
|
||||
'datetime': this.iso8601 (timestamp),
|
||||
'lastTradeTimestamp': undefined,
|
||||
'type': type,
|
||||
'side': this.safeString (response, 'type'),
|
||||
'symbol': symbol,
|
||||
'status': status,
|
||||
'price': this.safeFloat (response, 'price'),
|
||||
'amount': placedAmount,
|
||||
'cost': undefined,
|
||||
'average': undefined,
|
||||
'remaining': remaining,
|
||||
'filled': filled,
|
||||
'fee': undefined,
|
||||
'trades': undefined,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+6
-2
@@ -561,6 +561,7 @@ module.exports = class coinmate extends Exchange {
|
||||
const statuses = {
|
||||
'FILLED': 'closed',
|
||||
'CANCELLED': 'canceled',
|
||||
'PARTIALLY_FILLED': 'open',
|
||||
'OPEN': 'open',
|
||||
};
|
||||
return this.safeString (statuses, status, status);
|
||||
@@ -623,12 +624,15 @@ module.exports = class coinmate extends Exchange {
|
||||
const price = this.safeFloat (order, 'price');
|
||||
const amount = this.safeFloat2 (order, 'originalAmount', 'amount');
|
||||
const remaining = this.safeFloat (order, 'remainingAmount', amount);
|
||||
const status = this.parseOrderStatus (this.safeString (order, 'status'));
|
||||
let status = this.parseOrderStatus (this.safeString (order, 'status'));
|
||||
const type = this.parseOrderType (this.safeString (order, 'orderTradeType'));
|
||||
let filled = undefined;
|
||||
let cost = undefined;
|
||||
if ((amount !== undefined) && (remaining !== undefined)) {
|
||||
filled = amount - remaining;
|
||||
filled = Math.min (amount - remaining, 0);
|
||||
if (remaining === 0) {
|
||||
status = 'closed';
|
||||
}
|
||||
if (price !== undefined) {
|
||||
cost = filled * price;
|
||||
}
|
||||
|
||||
-1
@@ -129,7 +129,6 @@ module.exports = class crex24 extends Exchange {
|
||||
'fetchClosedOrdersMethod': 'tradingGetOrderHistory', // or 'tradingGetActiveOrders'
|
||||
'fetchTickersMethod': 'publicGetTicker24hr',
|
||||
'defaultTimeInForce': 'GTC', // 'GTC' = Good To Cancel (default), 'IOC' = Immediate Or Cancel
|
||||
'defaultLimitOrderType': 'limit', // or 'limit_maker'
|
||||
'hasAlreadyAuthenticatedSuccessfully': false,
|
||||
'warnOnFetchOpenOrdersWithoutSymbol': true,
|
||||
'parseOrderToPrecision': false, // force amounts and costs in parseOrder to precision
|
||||
|
||||
+4
-2
@@ -525,11 +525,13 @@ module.exports = class deribit extends Exchange {
|
||||
'info': response,
|
||||
};
|
||||
const balance = this.safeValue (response, 'result', {});
|
||||
const currencyId = this.safeString (balance, 'currency');
|
||||
const currencyCode = this.safeCurrencyCode (currencyId);
|
||||
const account = this.account ();
|
||||
account['free'] = this.safeFloat (balance, 'availableFunds');
|
||||
account['used'] = this.safeFloat (balance, 'maintenanceMargin');
|
||||
account['total'] = this.safeFloat (balance, 'equity');
|
||||
result[code] = account;
|
||||
result[currencyCode] = account;
|
||||
return this.parseBalance (result);
|
||||
}
|
||||
|
||||
@@ -883,7 +885,7 @@ module.exports = class deribit extends Exchange {
|
||||
// M = maker, T = taker, MT = both
|
||||
takerOrMaker = (liquidity === 'M') ? 'maker' : 'taker';
|
||||
}
|
||||
const feeCost = this.safeFloat (trade, 'feeCost');
|
||||
const feeCost = this.safeFloat (trade, 'fee');
|
||||
let fee = undefined;
|
||||
if (feeCost !== undefined) {
|
||||
const feeCurrencyId = this.safeString (trade, 'fee_currency');
|
||||
|
||||
+363
-152
@@ -3,7 +3,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const Exchange = require ('./base/Exchange');
|
||||
const { ArgumentsRequired, ExchangeError, OrderNotFound, AuthenticationError, InsufficientFunds, InvalidOrder, InvalidNonce, NotSupported, OnMaintenance, RateLimitExceeded } = require ('./base/errors');
|
||||
const { ArgumentsRequired, ExchangeError, OrderNotFound, AuthenticationError, InsufficientFunds, InvalidOrder, InvalidNonce, NotSupported, OnMaintenance, RateLimitExceeded, BadRequest, PermissionDenied } = require ('./base/errors');
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -14,7 +14,7 @@ module.exports = class exmo extends Exchange {
|
||||
'name': 'EXMO',
|
||||
'countries': [ 'ES', 'RU' ], // Spain, Russia
|
||||
'rateLimit': 350, // once every 350 ms ≈ 180 requests per minute ≈ 3 requests per second
|
||||
'version': 'v1',
|
||||
'version': 'v1.1',
|
||||
'has': {
|
||||
'CORS': false,
|
||||
'fetchClosedOrders': 'emulated',
|
||||
@@ -32,6 +32,21 @@ module.exports = class exmo extends Exchange {
|
||||
'fetchFundingFees': true,
|
||||
'fetchCurrencies': true,
|
||||
'fetchTransactions': true,
|
||||
'fetchOHLCV': true,
|
||||
},
|
||||
'timeframes': {
|
||||
'1m': '1',
|
||||
'5m': '5',
|
||||
'15m': '15',
|
||||
'30m': '30',
|
||||
'45m': '45',
|
||||
'1h': '60',
|
||||
'2h': '120',
|
||||
'3h': '180',
|
||||
'4h': '240',
|
||||
'1d': 'D',
|
||||
'1w': 'W',
|
||||
'1M': 'M',
|
||||
},
|
||||
'urls': {
|
||||
'logo': 'https://user-images.githubusercontent.com/1294454/27766491-1b0ea956-5eda-11e7-9225-40d67b481b8d.jpg',
|
||||
@@ -62,6 +77,7 @@ module.exports = class exmo extends Exchange {
|
||||
'pair_settings',
|
||||
'ticker',
|
||||
'trades',
|
||||
'candles_history',
|
||||
],
|
||||
},
|
||||
'private': {
|
||||
@@ -69,6 +85,8 @@ module.exports = class exmo extends Exchange {
|
||||
'user_info',
|
||||
'order_create',
|
||||
'order_cancel',
|
||||
'stop_market_order_create',
|
||||
'stop_market_order_cancel',
|
||||
'user_open_orders',
|
||||
'user_trades',
|
||||
'user_cancelled_orders',
|
||||
@@ -103,86 +121,90 @@ module.exports = class exmo extends Exchange {
|
||||
'error': '',
|
||||
'data': {
|
||||
'limits': [
|
||||
{ 'pair': 'EXM/USDT', 'min_q': '1', 'max_q': '100000000', 'min_p': '0.00000001', 'max_p': '1000', 'min_a': '0.01', 'max_a': '100000' },
|
||||
{ 'pair': 'EXM/ETH', 'min_q': '1', 'max_q': '100000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.0001', 'max_a': '5000' },
|
||||
{ 'pair': 'ALGO/EXM', 'min_q': '1', 'max_q': '1000000', 'min_p': '0.001', 'max_p': '10000', 'min_a': '1', 'max_a': '50000000' },
|
||||
{ 'pair': 'ALGO/BTC', 'min_q': '1', 'max_q': '1000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.000001', 'max_a': '50' },
|
||||
{ 'pair': 'ATOM/EXM', 'min_q': '1', 'max_q': '500000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '200', 'max_a': '50000000' },
|
||||
{ 'pair': 'ATOM/BTC', 'min_q': '1', 'max_q': '500000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'BTC/USD', 'min_q': '0.0001', 'max_q': '1000', 'min_p': '1', 'max_p': '30000', 'min_a': '1', 'max_a': '500000' },
|
||||
{ 'pair': 'BTC/KZT', 'min_q': '0.0001', 'max_q': '1000', 'min_p': '1000', 'max_p': '12000000', 'min_a': '1000', 'max_a': '100000000' },
|
||||
{ 'pair': 'ETH/KZT', 'min_q': '0.001', 'max_q': '5000', 'min_p': '4', 'max_p': '40000000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'USDT/KZT', 'min_q': '1', 'max_q': '500000', 'min_p': '200', 'max_p': '4000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'ONT/EXM', 'min_q': '1', 'max_q': '1000000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '200', 'max_a': '15000000' },
|
||||
{ 'pair': 'ONT/BTC', 'min_q': '1', 'max_q': '1000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.00001', 'max_a': '10' },
|
||||
{ 'pair': 'ONT/RUB', 'min_q': '1', 'max_q': '1000000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '100', 'max_a': '6000000' },
|
||||
{ 'pair': 'ONT/UAH', 'min_q': '1', 'max_q': '1000000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '200', 'max_a': '250000' },
|
||||
{ 'pair': 'ONG/EXM', 'min_q': '1', 'max_q': '1000000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '100', 'max_a': '15000000' },
|
||||
{ 'pair': 'ONG/BTC', 'min_q': '1', 'max_q': '1000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.00001', 'max_a': '10' },
|
||||
{ 'pair': 'ONG/RUB', 'min_q': '1', 'max_q': '1000000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '100', 'max_a': '250000' },
|
||||
{ 'pair': 'ONG/UAH', 'min_q': '1', 'max_q': '1000000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '50', 'max_a': '6000000' },
|
||||
{ 'pair': 'CRON/BTC', 'min_q': '1', 'max_q': '100000', 'min_p': '0.0000001', 'max_p': '1', 'min_a': '0.00001', 'max_a': '100' },
|
||||
{ 'pair': 'CRON/ETH', 'min_q': '1', 'max_q': '100000', 'min_p': '0.0000001', 'max_p': '10', 'min_a': '0.00001', 'max_a': '5000' },
|
||||
{ 'pair': 'CRON/USDT', 'min_q': '1', 'max_q': '100000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '0.001', 'max_a': '500000' },
|
||||
{ 'pair': 'CRON/EXM', 'min_q': '1', 'max_q': '100000000', 'min_p': '0.00000001', 'max_p': '1000', 'min_a': '0.01', 'max_a': '100000' },
|
||||
{ 'pair': 'BTC/RUB', 'min_q': '0.0001', 'max_q': '1000', 'min_p': '1', 'max_p': '2000000', 'min_a': '10', 'max_a': '50000000' },
|
||||
{ 'pair': 'BTC/EUR', 'min_q': '0.0001', 'max_q': '1000', 'min_p': '1', 'max_p': '30000', 'min_a': '1', 'max_a': '500000' },
|
||||
{ 'pair': 'BTC/UAH', 'min_q': '0.0001', 'max_q': '1000', 'min_p': '1', 'max_p': '15000000', 'min_a': '10', 'max_a': '15000000' },
|
||||
{ 'pair': 'BTC/GBP', 'min_q': '0.0001', 'max_q': '1000', 'min_p': '1', 'max_p': '30000', 'min_a': '1', 'max_a': '500000' },
|
||||
{ 'pair': 'ETH/GBP', 'min_q': '0.001', 'max_q': '5000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'XRP/GBP', 'min_q': '1', 'max_q': '5000000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '0.001', 'max_a': '500000' },
|
||||
{ 'pair': 'USDT/GBP', 'min_q': '1', 'max_q': '500000', 'min_p': '0.5', 'max_p': '10', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'BTC/PLN', 'min_q': '0.0001', 'max_q': '1000', 'min_p': '1', 'max_p': '20000000', 'min_a': '50', 'max_a': '2000000' },
|
||||
{ 'pair': 'BTC/TRY', 'min_q': '0.0001', 'max_q': '1000', 'min_p': '1', 'max_p': '800000', 'min_a': '40', 'max_a': '6000000' },
|
||||
{ 'pair': 'BTC/KZT', 'min_q': '0.0001', 'max_q': '1000', 'min_p': '1000', 'max_p': '12000000', 'min_a': '1000', 'max_a': '100000000' },
|
||||
{ 'pair': 'BTC/USDT', 'min_q': '0.0001', 'max_q': '1000', 'min_p': '0.01', 'max_p': '30000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'ETH/BTC', 'min_q': '0.001', 'max_q': '5000', 'min_p': '0.00000001', 'max_p': '10', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'ETH/USD', 'min_q': '0.001', 'max_q': '5000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'ETH/RUB', 'min_q': '0.001', 'max_q': '5000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '150', 'max_a': '50000000' },
|
||||
{ 'pair': 'XRP/BTC', 'min_q': '1', 'max_q': '100000', 'min_p': '0.0000001', 'max_p': '1', 'min_a': '0.00001', 'max_a': '100' },
|
||||
{ 'pair': 'XRP/USD', 'min_q': '1', 'max_q': '100000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '0.001', 'max_a': '500000' },
|
||||
{ 'pair': 'XRP/RUB', 'min_q': '1', 'max_q': '100000', 'min_p': '0.000001', 'max_p': '1000', 'min_a': '0.01', 'max_a': '50000000' },
|
||||
{ 'pair': 'XRP/BTC', 'min_q': '1', 'max_q': '5000000', 'min_p': '0.0000001', 'max_p': '1', 'min_a': '0.00001', 'max_a': '100' },
|
||||
{ 'pair': 'XRP/USD', 'min_q': '1', 'max_q': '5000000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '0.001', 'max_a': '500000' },
|
||||
{ 'pair': 'XRP/RUB', 'min_q': '1', 'max_q': '5000000', 'min_p': '0.000001', 'max_p': '1000', 'min_a': '0.01', 'max_a': '50000000' },
|
||||
{ 'pair': 'ADA/BTC', 'min_q': '1', 'max_q': '10000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'ADA/ETH', 'min_q': '0.01', 'max_q': '10000000', 'min_p': '0.00000001', 'max_p': '10', 'min_a': '0.001', 'max_a': '5000' },
|
||||
{ 'pair': 'ADA/USD', 'min_q': '0.01', 'max_q': '10000000', 'min_p': '0.0001', 'max_p': '1000', 'min_a': '0.01', 'max_a': '500000' },
|
||||
{ 'pair': 'BCH/USD', 'min_q': '0.003', 'max_q': '10000', 'min_p': '0.00000001', 'max_p': '30000', 'min_a': '0.0001', 'max_a': '500000' },
|
||||
{ 'pair': 'BCH/RUB', 'min_q': '0.003', 'max_q': '10000', 'min_p': '0.00000001', 'max_p': '2000000', 'min_a': '0.0001', 'max_a': '50000000' },
|
||||
{ 'pair': 'BCH/EUR', 'min_q': '0.003', 'max_q': '100000', 'min_p': '0.01', 'max_p': '300000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'BCH/UAH', 'min_q': '0.003', 'max_q': '100000', 'min_p': '0.1', 'max_p': '30000', 'min_a': '10', 'max_a': '15000000' },
|
||||
{ 'pair': 'BCH/BTC', 'min_q': '0.003', 'max_q': '10000', 'min_p': '0.00000001', 'max_p': '5', 'min_a': '0.0001', 'max_a': '100' },
|
||||
{ 'pair': 'BCH/ETH', 'min_q': '0.003', 'max_q': '10000', 'min_p': '0.0000001', 'max_p': '200', 'min_a': '0.0001', 'max_a': '5000' },
|
||||
{ 'pair': 'BCH/USDT', 'min_q': '0.003', 'max_q': '100000', 'min_p': '0.01', 'max_p': '5000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'ALGO/USDT', 'min_q': '1', 'max_q': '1000000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '1', 'max_a': '500000' },
|
||||
{ 'pair': 'ALGO/RUB', 'min_q': '1', 'max_q': '1000000', 'min_p': '0.000001', 'max_p': '10000', 'min_a': '1', 'max_a': '50000000' },
|
||||
{ 'pair': 'ALGO/EUR', 'min_q': '1', 'max_q': '1000000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '1', 'max_a': '500000' },
|
||||
{ 'pair': 'ATOM/USD', 'min_q': '1', 'max_q': '500000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '0.5', 'max_a': '500000' },
|
||||
{ 'pair': 'ATOM/EUR', 'min_q': '1', 'max_q': '500000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '0.5', 'max_a': '500000' },
|
||||
{ 'pair': 'BCH/USD', 'min_q': '0.003', 'max_q': '5000', 'min_p': '0.00000001', 'max_p': '30000', 'min_a': '0.0001', 'max_a': '500000' },
|
||||
{ 'pair': 'BCH/RUB', 'min_q': '0.003', 'max_q': '5000', 'min_p': '0.00000001', 'max_p': '2000000', 'min_a': '0.0001', 'max_a': '50000000' },
|
||||
{ 'pair': 'BCH/EUR', 'min_q': '0.003', 'max_q': '5000', 'min_p': '0.01', 'max_p': '300000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'BCH/UAH', 'min_q': '0.003', 'max_q': '5000', 'min_p': '0.1', 'max_p': '30000', 'min_a': '10', 'max_a': '15000000' },
|
||||
{ 'pair': 'BCH/BTC', 'min_q': '0.003', 'max_q': '5000', 'min_p': '0.00000001', 'max_p': '5', 'min_a': '0.0001', 'max_a': '100' },
|
||||
{ 'pair': 'BCH/ETH', 'min_q': '0.003', 'max_q': '5000', 'min_p': '0.0000001', 'max_p': '200', 'min_a': '0.0001', 'max_a': '5000' },
|
||||
{ 'pair': 'BCH/USDT', 'min_q': '0.003', 'max_q': '5000', 'min_p': '0.01', 'max_p': '5000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'BTCZ/BTC', 'min_q': '100', 'max_q': '100000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'BTG/USD', 'min_q': '0.01', 'max_q': '200000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'BTG/BTC', 'min_q': '0.01', 'max_q': '200000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'BTG/ETH', 'min_q': '0.01', 'max_q': '200000', 'min_p': '0.0001', 'max_p': '100', 'min_a': '0.01', 'max_a': '5000' },
|
||||
{ 'pair': 'BTT/RUB', 'min_q': '1', 'max_q': '10000000', 'min_p': '0.000001', 'max_p': '1000', 'min_a': '0.000001', 'max_a': '100' },
|
||||
{ 'pair': 'BTT/UAH', 'min_q': '1', 'max_q': '10000000', 'min_p': '0.000001', 'max_p': '1000', 'min_a': '0.000001', 'max_a': '100' },
|
||||
{ 'pair': 'BTT/BTC', 'min_q': '1', 'max_q': '10000000', 'min_p': '0.00000001', 'max_p': '0.1', 'min_a': '0.00001', 'max_a': '100' },
|
||||
{ 'pair': 'BTG/USD', 'min_q': '0.01', 'max_q': '100000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'BTG/BTC', 'min_q': '0.01', 'max_q': '100000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'BTG/ETH', 'min_q': '0.01', 'max_q': '100000', 'min_p': '0.0001', 'max_p': '100', 'min_a': '0.01', 'max_a': '5000' },
|
||||
{ 'pair': 'BTT/RUB', 'min_q': '1', 'max_q': '500000000', 'min_p': '0.000001', 'max_p': '1000', 'min_a': '0.000001', 'max_a': '100' },
|
||||
{ 'pair': 'BTT/UAH', 'min_q': '1', 'max_q': '500000000', 'min_p': '0.000001', 'max_p': '1000', 'min_a': '0.000001', 'max_a': '100' },
|
||||
{ 'pair': 'BTT/BTC', 'min_q': '1', 'max_q': '500000000', 'min_p': '0.00000001', 'max_p': '0.1', 'min_a': '0.00001', 'max_a': '100' },
|
||||
{ 'pair': 'CRON/BTC', 'min_q': '1', 'max_q': '100000', 'min_p': '0.0000001', 'max_p': '1', 'min_a': '0.00001', 'max_a': '100' },
|
||||
{ 'pair': 'CRON/ETH', 'min_q': '1', 'max_q': '100000', 'min_p': '0.0000001', 'max_p': '10', 'min_a': '0.00001', 'max_a': '5000' },
|
||||
{ 'pair': 'CRON/USDT', 'min_q': '1', 'max_q': '100000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '0.001', 'max_a': '500000' },
|
||||
{ 'pair': 'CRON/EXM', 'min_q': '1', 'max_q': '100000000', 'min_p': '0.00000001', 'max_p': '1000', 'min_a': '0.01', 'max_a': '100000' },
|
||||
{ 'pair': 'DAI/USD', 'min_q': '1', 'max_q': '500000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'DAI/RUB', 'min_q': '1', 'max_q': '500000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '0.5', 'max_a': '30000000' },
|
||||
{ 'pair': 'DAI/BTC', 'min_q': '1', 'max_q': '500000', 'min_p': '0.0000001', 'max_p': '0.1', 'min_a': '0.00001', 'max_a': '100' },
|
||||
{ 'pair': 'DAI/ETH', 'min_q': '1', 'max_q': '500000', 'min_p': '0.000001', 'max_p': '10', 'min_a': '0.0001', 'max_a': '5000' },
|
||||
{ 'pair': 'DASH/USD', 'min_q': '0.01', 'max_q': '200000', 'min_p': '0.01', 'max_p': '10000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'DASH/RUB', 'min_q': '0.01', 'max_q': '200000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '150', 'max_a': '50000000' },
|
||||
{ 'pair': 'DASH/UAH', 'min_q': '0.01', 'max_q': '200000', 'min_p': '0.01', 'max_p': '200000', 'min_a': '10', 'max_a': '15000000' },
|
||||
{ 'pair': 'DASH/BTC', 'min_q': '0.01', 'max_q': '200000', 'min_p': '0.0001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'DASH/USDT', 'min_q': '0.01', 'max_q': '100000', 'min_p': '0.01', 'max_p': '5000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'DASH/USD', 'min_q': '0.01', 'max_q': '10000', 'min_p': '0.01', 'max_p': '10000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'DASH/RUB', 'min_q': '0.01', 'max_q': '10000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '150', 'max_a': '50000000' },
|
||||
{ 'pair': 'DASH/UAH', 'min_q': '0.01', 'max_q': '10000', 'min_p': '0.01', 'max_p': '200000', 'min_a': '10', 'max_a': '15000000' },
|
||||
{ 'pair': 'DASH/BTC', 'min_q': '0.01', 'max_q': '10000', 'min_p': '0.0001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'DASH/USDT', 'min_q': '0.01', 'max_q': '10000', 'min_p': '0.01', 'max_p': '5000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'DCR/RUB', 'min_q': '0.01', 'max_q': '50000', 'min_p': '0.00001', 'max_p': '100000', 'min_a': '0.5', 'max_a': '3000000' },
|
||||
{ 'pair': 'DCR/UAH', 'min_q': '0.01', 'max_q': '50000', 'min_p': '0.00001', 'max_p': '100000', 'min_a': '0.25', 'max_a': '1000000' },
|
||||
{ 'pair': 'DCR/BTC', 'min_q': '0.01', 'max_q': '50000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'DOGE/USD', 'min_q': '100', 'max_q': '1000000000', 'min_p': '0.0000001', 'max_p': '1000', 'min_a': '0.01', 'max_a': '500000' },
|
||||
{ 'pair': 'DOGE/BTC', 'min_q': '100', 'max_q': '100000000', 'min_p': '0.0000001', 'max_p': '1', 'min_a': '0.0001', 'max_a': '100' },
|
||||
{ 'pair': 'DXT/USD', 'min_q': '100', 'max_q': '10000000', 'min_p': '0.00001', 'max_p': '1000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'DXT/BTC', 'min_q': '100', 'max_q': '10000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.0001', 'max_a': '100' },
|
||||
{ 'pair': 'EOS/USD', 'min_q': '0.01', 'max_q': '100000', 'min_p': '0.01', 'max_p': '1000', 'min_a': '0.5', 'max_a': '500000' },
|
||||
{ 'pair': 'EOS/EUR', 'min_q': '0.01', 'max_q': '100000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '0.5', 'max_a': '500000' },
|
||||
{ 'pair': 'EOS/BTC', 'min_q': '0.01', 'max_q': '100000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'ETC/USD', 'min_q': '0.2', 'max_q': '1000', 'min_p': '0.01', 'max_p': '10000', 'min_a': '0.01', 'max_a': '500000' },
|
||||
{ 'pair': 'ETC/RUB', 'min_q': '0.2', 'max_q': '1000', 'min_p': '0.01', 'max_p': '10000', 'min_a': '0.01', 'max_a': '50000000' },
|
||||
{ 'pair': 'ETC/BTC', 'min_q': '0.2', 'max_q': '1000', 'min_p': '0.0001', 'max_p': '0.5', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'DOGE/USD', 'min_q': '100', 'max_q': '500000000', 'min_p': '0.0000001', 'max_p': '1000', 'min_a': '0.01', 'max_a': '500000' },
|
||||
{ 'pair': 'DOGE/BTC', 'min_q': '100', 'max_q': '500000000', 'min_p': '0.0000001', 'max_p': '1', 'min_a': '0.0001', 'max_a': '100' },
|
||||
{ 'pair': 'DXT/USD', 'min_q': '100', 'max_q': '50000000', 'min_p': '0.00001', 'max_p': '1000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'DXT/BTC', 'min_q': '100', 'max_q': '50000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.0001', 'max_a': '100' },
|
||||
{ 'pair': 'EOS/USD', 'min_q': '0.01', 'max_q': '500000', 'min_p': '0.01', 'max_p': '1000', 'min_a': '0.5', 'max_a': '500000' },
|
||||
{ 'pair': 'EOS/EUR', 'min_q': '0.01', 'max_q': '500000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '0.5', 'max_a': '500000' },
|
||||
{ 'pair': 'EOS/BTC', 'min_q': '0.01', 'max_q': '500000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'ETC/USD', 'min_q': '0.2', 'max_q': '100000', 'min_p': '0.01', 'max_p': '10000', 'min_a': '0.01', 'max_a': '500000' },
|
||||
{ 'pair': 'ETC/RUB', 'min_q': '0.2', 'max_q': '100000', 'min_p': '0.01', 'max_p': '10000', 'min_a': '0.01', 'max_a': '50000000' },
|
||||
{ 'pair': 'ETC/BTC', 'min_q': '0.2', 'max_q': '100000', 'min_p': '0.0001', 'max_p': '0.5', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'ETH/EUR', 'min_q': '0.001', 'max_q': '5000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'ETH/UAH', 'min_q': '0.001', 'max_q': '5000', 'min_p': '0.01', 'max_p': '1000000', 'min_a': '90', 'max_a': '15000000' },
|
||||
{ 'pair': 'ETH/PLN', 'min_q': '0.001', 'max_q': '5000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '50', 'max_a': '2000000' },
|
||||
{ 'pair': 'ETH/TRY', 'min_q': '0.001', 'max_q': '5000', 'min_p': '0.1', 'max_p': '80000', 'min_a': '10', 'max_a': '6000000' },
|
||||
{ 'pair': 'ETH/KZT', 'min_q': '0.001', 'max_q': '5000', 'min_p': '4', 'max_p': '40000000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'ETH/USDT', 'min_q': '0.001', 'max_q': '5000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'ETH/LTC', 'min_q': '0.001', 'max_q': '5000', 'min_p': '0.00000001', 'max_p': '100000', 'min_a': '0.05', 'max_a': '100000' },
|
||||
{ 'pair': 'ETZ/BTC', 'min_q': '1', 'max_q': '1000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.0001', 'max_a': '10' },
|
||||
{ 'pair': 'ETZ/ETH', 'min_q': '1', 'max_q': '1000000', 'min_p': '0.00000001', 'max_p': '100', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'ETZ/USDT', 'min_q': '1', 'max_q': '1000000', 'min_p': '0.000001', 'max_p': '1000', 'min_a': '0.01', 'max_a': '1000' },
|
||||
{ 'pair': 'GAS/USD', 'min_q': '0.01', 'max_q': '10000000', 'min_p': '0.01', 'max_p': '50000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'GAS/BTC', 'min_q': '0.01', 'max_q': '10000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'ETZ/BTC', 'min_q': '1', 'max_q': '50000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.0001', 'max_a': '10' },
|
||||
{ 'pair': 'ETZ/ETH', 'min_q': '1', 'max_q': '50000000', 'min_p': '0.00000001', 'max_p': '100', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'ETZ/USDT', 'min_q': '1', 'max_q': '50000000', 'min_p': '0.000001', 'max_p': '1000', 'min_a': '0.01', 'max_a': '1000' },
|
||||
{ 'pair': 'EXM/USDT', 'min_q': '1', 'max_q': '100000000', 'min_p': '0.00000001', 'max_p': '1000', 'min_a': '0.01', 'max_a': '100000' },
|
||||
{ 'pair': 'EXM/ETH', 'min_q': '1', 'max_q': '100000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.0001', 'max_a': '5000' },
|
||||
{ 'pair': 'GAS/USD', 'min_q': '0.01', 'max_q': '500000', 'min_p': '0.01', 'max_p': '50000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'GAS/BTC', 'min_q': '0.01', 'max_q': '500000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'GNT/BTC', 'min_q': '1', 'max_q': '10000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'GNT/ETH', 'min_q': '0.01', 'max_q': '10000000', 'min_p': '0.00000001', 'max_p': '10', 'min_a': '0.01', 'max_a': '5000' },
|
||||
{ 'pair': 'GUSD/USD', 'min_q': '1', 'max_q': '500000', 'min_p': '0.1', 'max_p': '10', 'min_a': '0.1', 'max_a': '500000' },
|
||||
@@ -197,84 +219,94 @@ module.exports = class exmo extends Exchange {
|
||||
{ 'pair': 'KICK/USDT', 'min_q': '1', 'max_q': '100000000', 'min_p': '0.00000001', 'max_p': '1000', 'min_a': '0.01', 'max_a': '100000' },
|
||||
{ 'pair': 'KICK/BTC', 'min_q': '1', 'max_q': '100000000', 'min_p': '0.00000001', 'max_p': '0.1', 'min_a': '0.00001', 'max_a': '100' },
|
||||
{ 'pair': 'KICK/ETH', 'min_q': '1', 'max_q': '100000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.0001', 'max_a': '5000' },
|
||||
{ 'pair': 'LSK/USD', 'min_q': '0.1', 'max_q': '200000', 'min_p': '0.1', 'max_p': '1000', 'min_a': '1', 'max_a': '500000' },
|
||||
{ 'pair': 'LSK/RUB', 'min_q': '0.1', 'max_q': '200000', 'min_p': '0.001', 'max_p': '100000', 'min_a': '0.5', 'max_a': '50000000' },
|
||||
{ 'pair': 'LSK/BTC', 'min_q': '1', 'max_q': '200000', 'min_p': '0.0000001', 'max_p': '1', 'min_a': '0.0015', 'max_a': '100' },
|
||||
{ 'pair': 'LTC/USD', 'min_q': '0.05', 'max_q': '1000000', 'min_p': '0.01', 'max_p': '10000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'LTC/RUB', 'min_q': '0.05', 'max_q': '1000000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '150', 'max_a': '50000000' },
|
||||
{ 'pair': 'LTC/EUR', 'min_q': '0.05', 'max_q': '1000000', 'min_p': '0.01', 'max_p': '10000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'LTC/UAH', 'min_q': '0.05', 'max_q': '1000000', 'min_p': '0.01', 'max_p': '300000', 'min_a': '5', 'max_a': '18000000' },
|
||||
{ 'pair': 'LTC/BTC', 'min_q': '0.05', 'max_q': '1000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'LSK/USD', 'min_q': '0.1', 'max_q': '500000', 'min_p': '0.1', 'max_p': '1000', 'min_a': '1', 'max_a': '500000' },
|
||||
{ 'pair': 'LSK/RUB', 'min_q': '0.1', 'max_q': '500000', 'min_p': '0.001', 'max_p': '100000', 'min_a': '0.5', 'max_a': '50000000' },
|
||||
{ 'pair': 'LSK/BTC', 'min_q': '1', 'max_q': '500000', 'min_p': '0.0000001', 'max_p': '1', 'min_a': '0.0015', 'max_a': '100' },
|
||||
{ 'pair': 'LTC/USD', 'min_q': '0.05', 'max_q': '10000', 'min_p': '0.01', 'max_p': '10000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'LTC/RUB', 'min_q': '0.05', 'max_q': '10000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '150', 'max_a': '50000000' },
|
||||
{ 'pair': 'LTC/EUR', 'min_q': '0.05', 'max_q': '10000', 'min_p': '0.01', 'max_p': '10000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'LTC/UAH', 'min_q': '0.05', 'max_q': '10000', 'min_p': '0.01', 'max_p': '300000', 'min_a': '5', 'max_a': '18000000' },
|
||||
{ 'pair': 'LTC/BTC', 'min_q': '0.05', 'max_q': '10000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'MKR/BTC', 'min_q': '0.0001', 'max_q': '1000', 'min_p': '0.0001', 'max_p': '100', 'min_a': '0.000001', 'max_a': '100' },
|
||||
{ 'pair': 'MKR/DAI', 'min_q': '0.0001', 'max_q': '1000', 'min_p': '0.5', 'max_p': '500000', 'min_a': '0.005', 'max_a': '500000' },
|
||||
{ 'pair': 'MNC/USD', 'min_q': '10', 'max_q': '100000000', 'min_p': '0.000001', 'max_p': '10000', 'min_a': '0.01', 'max_a': '100000' },
|
||||
{ 'pair': 'MNC/BTC', 'min_q': '10', 'max_q': '100000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.000001', 'max_a': '100' },
|
||||
{ 'pair': 'MNC/ETH', 'min_q': '10', 'max_q': '100000000', 'min_p': '0.0000001', 'max_p': '10', 'min_a': '0.00001', 'max_a': '1000' },
|
||||
{ 'pair': 'MNC/USD', 'min_q': '10', 'max_q': '500000000', 'min_p': '0.000001', 'max_p': '10000', 'min_a': '0.01', 'max_a': '100000' },
|
||||
{ 'pair': 'MNC/BTC', 'min_q': '10', 'max_q': '500000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.000001', 'max_a': '100' },
|
||||
{ 'pair': 'MNC/ETH', 'min_q': '10', 'max_q': '500000000', 'min_p': '0.0000001', 'max_p': '10', 'min_a': '0.00001', 'max_a': '1000' },
|
||||
{ 'pair': 'MNX/USD', 'min_q': '0.01', 'max_q': '10000000', 'min_p': '0.0001', 'max_p': '1000', 'min_a': '0.5', 'max_a': '500000' },
|
||||
{ 'pair': 'MNX/BTC', 'min_q': '1', 'max_q': '10000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'MNX/ETH', 'min_q': '0.01', 'max_q': '10000000', 'min_p': '0.00000001', 'max_p': '10', 'min_a': '0.01', 'max_a': '5000' },
|
||||
{ 'pair': 'NEO/USD', 'min_q': '0.01', 'max_q': '200000', 'min_p': '0.01', 'max_p': '50000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'NEO/RUB', 'min_q': '0.01', 'max_q': '200000', 'min_p': '0.001', 'max_p': '1500000', 'min_a': '50', 'max_a': '50000000' },
|
||||
{ 'pair': 'NEO/BTC', 'min_q': '0.1', 'max_q': '200000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'OMG/USD', 'min_q': '0.01', 'max_q': '100000', 'min_p': '0.01', 'max_p': '1000', 'min_a': '0.5', 'max_a': '500000' },
|
||||
{ 'pair': 'OMG/BTC', 'min_q': '1', 'max_q': '100000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'OMG/ETH', 'min_q': '0.01', 'max_q': '100000', 'min_p': '0.00000001', 'max_p': '10', 'min_a': '0.01', 'max_a': '5000' },
|
||||
{ 'pair': 'PTI/RUB', 'min_q': '1', 'max_q': '10000000', 'min_p': '0.00000001', 'max_p': '600000', 'min_a': '10', 'max_a': '600000' },
|
||||
{ 'pair': 'PTI/BTC', 'min_q': '1', 'max_q': '100000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.000001', 'max_a': '10' },
|
||||
{ 'pair': 'PTI/EOS', 'min_q': '1', 'max_q': '10000000', 'min_p': '0.0000001', 'max_p': '5000', 'min_a': '0.01', 'max_a': '20000' },
|
||||
{ 'pair': 'PTI/USDT', 'min_q': '1', 'max_q': '10000000', 'min_p': '0.000001', 'max_p': '10000', 'min_a': '0.01', 'max_a': '100000' },
|
||||
{ 'pair': 'QTUM/USD', 'min_q': '0.1', 'max_q': '200000', 'min_p': '0.00000001', 'max_p': '10000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'QTUM/BTC', 'min_q': '0.1', 'max_q': '200000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.0001', 'max_a': '100' },
|
||||
{ 'pair': 'QTUM/ETH', 'min_q': '0.1', 'max_q': '200000', 'min_p': '0.00000001', 'max_p': '100', 'min_a': '0.001', 'max_a': '5000' },
|
||||
{ 'pair': 'NEO/USD', 'min_q': '0.01', 'max_q': '100000', 'min_p': '0.01', 'max_p': '50000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'NEO/RUB', 'min_q': '0.01', 'max_q': '100000', 'min_p': '0.001', 'max_p': '1500000', 'min_a': '50', 'max_a': '50000000' },
|
||||
{ 'pair': 'NEO/BTC', 'min_q': '0.1', 'max_q': '100000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'OMG/USD', 'min_q': '0.01', 'max_q': '500000', 'min_p': '0.01', 'max_p': '1000', 'min_a': '0.5', 'max_a': '500000' },
|
||||
{ 'pair': 'OMG/BTC', 'min_q': '1', 'max_q': '500000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'OMG/ETH', 'min_q': '0.01', 'max_q': '500000', 'min_p': '0.00000001', 'max_p': '10', 'min_a': '0.01', 'max_a': '5000' },
|
||||
{ 'pair': 'ONG/EXM', 'min_q': '1', 'max_q': '1000000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '100', 'max_a': '15000000' },
|
||||
{ 'pair': 'ONG/BTC', 'min_q': '1', 'max_q': '1000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.00001', 'max_a': '10' },
|
||||
{ 'pair': 'ONG/RUB', 'min_q': '1', 'max_q': '1000000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '100', 'max_a': '250000' },
|
||||
{ 'pair': 'ONG/UAH', 'min_q': '1', 'max_q': '1000000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '50', 'max_a': '6000000' },
|
||||
{ 'pair': 'ONT/EXM', 'min_q': '1', 'max_q': '500000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '200', 'max_a': '15000000' },
|
||||
{ 'pair': 'ONT/BTC', 'min_q': '1', 'max_q': '500000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.00001', 'max_a': '10' },
|
||||
{ 'pair': 'ONT/RUB', 'min_q': '1', 'max_q': '500000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '100', 'max_a': '6000000' },
|
||||
{ 'pair': 'ONT/UAH', 'min_q': '1', 'max_q': '500000', 'min_p': '0.01', 'max_p': '100000', 'min_a': '200', 'max_a': '250000' },
|
||||
{ 'pair': 'PTI/RUB', 'min_q': '1', 'max_q': '50000000', 'min_p': '0.00000001', 'max_p': '600000', 'min_a': '10', 'max_a': '600000' },
|
||||
{ 'pair': 'PTI/BTC', 'min_q': '1', 'max_q': '50000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.000001', 'max_a': '10' },
|
||||
{ 'pair': 'PTI/EOS', 'min_q': '1', 'max_q': '50000000', 'min_p': '0.0000001', 'max_p': '5000', 'min_a': '0.01', 'max_a': '20000' },
|
||||
{ 'pair': 'PTI/USDT', 'min_q': '1', 'max_q': '50000000', 'min_p': '0.000001', 'max_p': '10000', 'min_a': '0.01', 'max_a': '100000' },
|
||||
{ 'pair': 'QTUM/USD', 'min_q': '0.1', 'max_q': '500000', 'min_p': '0.00000001', 'max_p': '10000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'QTUM/BTC', 'min_q': '0.1', 'max_q': '500000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.0001', 'max_a': '100' },
|
||||
{ 'pair': 'QTUM/ETH', 'min_q': '0.1', 'max_q': '500000', 'min_p': '0.00000001', 'max_p': '100', 'min_a': '0.001', 'max_a': '5000' },
|
||||
{ 'pair': 'ROOBEE/BTC', 'min_q': '1', 'max_q': '10000000', 'min_p': '0.00000001', 'max_p': '0.1', 'min_a': '0.00001', 'max_a': '100' },
|
||||
{ 'pair': 'SMART/USD', 'min_q': '10', 'max_q': '10000000', 'min_p': '0.000001', 'max_p': '1000', 'min_a': '1', 'max_a': '500000' },
|
||||
{ 'pair': 'SMART/RUB', 'min_q': '10', 'max_q': '10000000', 'min_p': '0.0001', 'max_p': '100000', 'min_a': '10', 'max_a': '50000000' },
|
||||
{ 'pair': 'SMART/EUR', 'min_q': '10', 'max_q': '10000000', 'min_p': '0.000001', 'max_p': '1000', 'min_a': '1', 'max_a': '500000' },
|
||||
{ 'pair': 'SMART/BTC', 'min_q': '10', 'max_q': '10000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.00001', 'max_a': '100' },
|
||||
{ 'pair': 'TRX/USD', 'min_q': '1', 'max_q': '10000000', 'min_p': '0.0001', 'max_p': '1000', 'min_a': '0.01', 'max_a': '500000' },
|
||||
{ 'pair': 'TRX/RUB', 'min_q': '1', 'max_q': '10000000', 'min_p': '0.000001', 'max_p': '100000', 'min_a': '0.1', 'max_a': '50000000' },
|
||||
{ 'pair': 'TRX/UAH', 'min_q': '1', 'max_q': '10000000', 'min_p': '0.000001', 'max_p': '100000', 'min_a': '0.1', 'max_a': '50000000' },
|
||||
{ 'pair': 'TRX/BTC', 'min_q': '1', 'max_q': '10000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'SMART/USD', 'min_q': '10', 'max_q': '100000000', 'min_p': '0.000001', 'max_p': '1000', 'min_a': '1', 'max_a': '500000' },
|
||||
{ 'pair': 'SMART/RUB', 'min_q': '10', 'max_q': '100000000', 'min_p': '0.0001', 'max_p': '100000', 'min_a': '10', 'max_a': '50000000' },
|
||||
{ 'pair': 'SMART/EUR', 'min_q': '10', 'max_q': '100000000', 'min_p': '0.000001', 'max_p': '1000', 'min_a': '1', 'max_a': '500000' },
|
||||
{ 'pair': 'SMART/BTC', 'min_q': '10', 'max_q': '100000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.00001', 'max_a': '100' },
|
||||
{ 'pair': 'TRX/USD', 'min_q': '1', 'max_q': '50000000', 'min_p': '0.0001', 'max_p': '1000', 'min_a': '0.01', 'max_a': '500000' },
|
||||
{ 'pair': 'TRX/EUR', 'min_q': '0.01', 'max_q': '50000000', 'min_p': '0.0001', 'max_p': '1000', 'min_a': '0.01', 'max_a': '500000' },
|
||||
{ 'pair': 'TRX/RUB', 'min_q': '1', 'max_q': '50000000', 'min_p': '0.000001', 'max_p': '100000', 'min_a': '0.1', 'max_a': '50000000' },
|
||||
{ 'pair': 'TRX/UAH', 'min_q': '1', 'max_q': '50000000', 'min_p': '0.000001', 'max_p': '100000', 'min_a': '0.1', 'max_a': '50000000' },
|
||||
{ 'pair': 'TRX/BTC', 'min_q': '1', 'max_q': '50000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'USDC/USD', 'min_q': '1', 'max_q': '500000', 'min_p': '0.0001', 'max_p': '1000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'USDC/BTC', 'min_q': '1', 'max_q': '500000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.0001', 'max_a': '100' },
|
||||
{ 'pair': 'USDC/ETH', 'min_q': '1', 'max_q': '500000', 'min_p': '0.0000001', 'max_p': '100', 'min_a': '0.001', 'max_a': '1000' },
|
||||
{ 'pair': 'USDC/USDT', 'min_q': '1', 'max_q': '500000', 'min_p': '0.0001', 'max_p': '1000', 'min_a': '3', 'max_a': '500000' },
|
||||
{ 'pair': 'USDT/USD', 'min_q': '1', 'max_q': '500000', 'min_p': '0.5', 'max_p': '10', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'USDT/RUB', 'min_q': '1', 'max_q': '500000', 'min_p': '0.01', 'max_p': '1000', 'min_a': '10', 'max_a': '50000000' },
|
||||
{ 'pair': 'USDT/EUR', 'min_q': '0.01', 'max_q': '100000', 'min_p': '0.1', 'max_p': '10', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'USDT/UAH', 'min_q': '0.01', 'max_q': '100000', 'min_p': '1', 'max_p': '3000', 'min_a': '2', 'max_a': '15000000' },
|
||||
{ 'pair': 'USDT/EUR', 'min_q': '0.01', 'max_q': '500000', 'min_p': '0.1', 'max_p': '10', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'USDT/UAH', 'min_q': '0.01', 'max_q': '500000', 'min_p': '1', 'max_p': '3000', 'min_a': '2', 'max_a': '15000000' },
|
||||
{ 'pair': 'USDT/KZT', 'min_q': '1', 'max_q': '500000', 'min_p': '200', 'max_p': '4000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'VLX/BTC', 'min_q': '1', 'max_q': '10000000', 'min_p': '0.00000001', 'max_p': '0.1', 'min_a': '0.00001', 'max_a': '100' },
|
||||
{ 'pair': 'WAVES/USD', 'min_q': '0.5', 'max_q': '10000', 'min_p': '0.001', 'max_p': '3500', 'min_a': '0.5', 'max_a': '500000' },
|
||||
{ 'pair': 'WAVES/RUB', 'min_q': '0.5', 'max_q': '10000', 'min_p': '0.01', 'max_p': '10000', 'min_a': '1', 'max_a': '50000000' },
|
||||
{ 'pair': 'WAVES/BTC', 'min_q': '0.5', 'max_q': '10000', 'min_p': '0.000001', 'max_p': '1', 'min_a': '0.0001', 'max_a': '100' },
|
||||
{ 'pair': 'WAVES/ETH', 'min_q': '0.5', 'max_q': '10000', 'min_p': '0.00001', 'max_p': '30', 'min_a': '0.0035', 'max_a': '3500' },
|
||||
{ 'pair': 'XEM/USD', 'min_q': '10', 'max_q': '5000000', 'min_p': '0.00001', 'max_p': '1000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'XEM/EUR', 'min_q': '10', 'max_q': '5000000', 'min_p': '0.00001', 'max_p': '1000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'XEM/UAH', 'min_q': '1', 'max_q': '5000000', 'min_p': '0.0001', 'max_p': '30000', 'min_a': '10', 'max_a': '15000000' },
|
||||
{ 'pair': 'XEM/BTC', 'min_q': '10', 'max_q': '5000000', 'min_p': '0.0000001', 'max_p': '1', 'min_a': '0.00015', 'max_a': '100' },
|
||||
{ 'pair': 'XLM/USD', 'min_q': '0.01', 'max_q': '200000', 'min_p': '0.0001', 'max_p': '1000', 'min_a': '0.01', 'max_a': '500000' },
|
||||
{ 'pair': 'XLM/RUB', 'min_q': '0.01', 'max_q': '200000', 'min_p': '0.00001', 'max_p': '100000', 'min_a': '0.1', 'max_a': '50000000' },
|
||||
{ 'pair': 'XLM/TRY', 'min_q': '0.01', 'max_q': '200000', 'min_p': '0.00001', 'max_p': '100000', 'min_a': '0.1', 'max_a': '6000000' },
|
||||
{ 'pair': 'XLM/BTC', 'min_q': '1', 'max_q': '200000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'XMR/USD', 'min_q': '0.01', 'max_q': '1000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'XMR/RUB', 'min_q': '0.01', 'max_q': '200000', 'min_p': '0.001', 'max_p': '600000', 'min_a': '10', 'max_a': '16000000' },
|
||||
{ 'pair': 'XMR/EUR', 'min_q': '0.01', 'max_q': '1000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'XMR/UAH', 'min_q': '0.01', 'max_q': '200000', 'min_p': '0.001', 'max_p': '300000', 'min_a': '5', 'max_a': '16000000' },
|
||||
{ 'pair': 'XMR/BTC', 'min_q': '0.01', 'max_q': '1000', 'min_p': '0.0001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'XMR/ETH', 'min_q': '0.01', 'max_q': '1000', 'min_p': '0.00000001', 'max_p': '100', 'min_a': '0.001', 'max_a': '5000' },
|
||||
{ 'pair': 'XRP/EUR', 'min_q': '1', 'max_q': '100000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '0.001', 'max_a': '500000' },
|
||||
{ 'pair': 'XRP/TRY', 'min_q': '1', 'max_q': '100000', 'min_p': '0.0001', 'max_p': '1000', 'min_a': '0.01', 'max_a': '6000000' },
|
||||
{ 'pair': 'XRP/UAH', 'min_q': '1', 'max_q': '100000', 'min_p': '0.0001', 'max_p': '1000', 'min_a': '0.01', 'max_a': '15000000' },
|
||||
{ 'pair': 'XRP/USDT', 'min_q': '1', 'max_q': '100000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '0.001', 'max_a': '500000' },
|
||||
{ 'pair': 'XRP/ETH', 'min_q': '1', 'max_q': '100000', 'min_p': '0.00000001', 'max_p': '10', 'min_a': '0.00001', 'max_a': '5000' },
|
||||
{ 'pair': 'WAVES/USD', 'min_q': '0.5', 'max_q': '500000', 'min_p': '0.001', 'max_p': '3500', 'min_a': '0.5', 'max_a': '500000' },
|
||||
{ 'pair': 'WAVES/RUB', 'min_q': '0.5', 'max_q': '500000', 'min_p': '0.01', 'max_p': '10000', 'min_a': '1', 'max_a': '50000000' },
|
||||
{ 'pair': 'WAVES/BTC', 'min_q': '0.5', 'max_q': '500000', 'min_p': '0.000001', 'max_p': '1', 'min_a': '0.0001', 'max_a': '100' },
|
||||
{ 'pair': 'WAVES/ETH', 'min_q': '0.5', 'max_q': '500000', 'min_p': '0.00001', 'max_p': '30', 'min_a': '0.0035', 'max_a': '3500' },
|
||||
{ 'pair': 'XEM/USD', 'min_q': '10', 'max_q': '10000000', 'min_p': '0.00001', 'max_p': '1000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'XEM/EUR', 'min_q': '10', 'max_q': '10000000', 'min_p': '0.00001', 'max_p': '1000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'XEM/UAH', 'min_q': '1', 'max_q': '10000000', 'min_p': '0.0001', 'max_p': '30000', 'min_a': '10', 'max_a': '15000000' },
|
||||
{ 'pair': 'XEM/BTC', 'min_q': '10', 'max_q': '10000000', 'min_p': '0.0000001', 'max_p': '1', 'min_a': '0.00015', 'max_a': '100' },
|
||||
{ 'pair': 'XLM/USD', 'min_q': '0.01', 'max_q': '5000000', 'min_p': '0.0001', 'max_p': '1000', 'min_a': '0.01', 'max_a': '500000' },
|
||||
{ 'pair': 'XLM/RUB', 'min_q': '0.01', 'max_q': '5000000', 'min_p': '0.00001', 'max_p': '100000', 'min_a': '0.1', 'max_a': '50000000' },
|
||||
{ 'pair': 'XLM/TRY', 'min_q': '0.01', 'max_q': '5000000', 'min_p': '0.00001', 'max_p': '100000', 'min_a': '0.1', 'max_a': '6000000' },
|
||||
{ 'pair': 'XLM/BTC', 'min_q': '1', 'max_q': '5000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'XMR/USD', 'min_q': '0.01', 'max_q': '10000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'XMR/RUB', 'min_q': '0.01', 'max_q': '10000', 'min_p': '0.001', 'max_p': '600000', 'min_a': '10', 'max_a': '16000000' },
|
||||
{ 'pair': 'XMR/EUR', 'min_q': '0.01', 'max_q': '10000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'XMR/UAH', 'min_q': '0.01', 'max_q': '10000', 'min_p': '0.001', 'max_p': '300000', 'min_a': '5', 'max_a': '16000000' },
|
||||
{ 'pair': 'XMR/BTC', 'min_q': '0.01', 'max_q': '10000', 'min_p': '0.0001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'XMR/ETH', 'min_q': '0.01', 'max_q': '10000', 'min_p': '0.00000001', 'max_p': '100', 'min_a': '0.001', 'max_a': '5000' },
|
||||
{ 'pair': 'XRP/EUR', 'min_q': '1', 'max_q': '5000000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '0.001', 'max_a': '500000' },
|
||||
{ 'pair': 'XRP/TRY', 'min_q': '1', 'max_q': '5000000', 'min_p': '0.0001', 'max_p': '1000', 'min_a': '0.01', 'max_a': '6000000' },
|
||||
{ 'pair': 'XRP/UAH', 'min_q': '1', 'max_q': '5000000', 'min_p': '0.0001', 'max_p': '1000', 'min_a': '0.01', 'max_a': '15000000' },
|
||||
{ 'pair': 'XRP/USDT', 'min_q': '1', 'max_q': '5000000', 'min_p': '0.001', 'max_p': '1000', 'min_a': '0.001', 'max_a': '500000' },
|
||||
{ 'pair': 'XRP/ETH', 'min_q': '1', 'max_q': '5000000', 'min_p': '0.00000001', 'max_p': '10', 'min_a': '0.00001', 'max_a': '5000' },
|
||||
{ 'pair': 'XTZ/USD', 'min_q': '0.1', 'max_q': '100000', 'min_p': '0.0001', 'max_p': '1000', 'min_a': '0.1', 'max_a': '100000' },
|
||||
{ 'pair': 'XTZ/RUB', 'min_q': '0.1', 'max_q': '100000', 'min_p': '0.00001', 'max_p': '100000', 'min_a': '0.5', 'max_a': '500000' },
|
||||
{ 'pair': 'XTZ/BTC', 'min_q': '0.1', 'max_q': '100000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.00001', 'max_a': '10' },
|
||||
{ 'pair': 'XTZ/ETH', 'min_q': '0.1', 'max_q': '100000', 'min_p': '0.0000001', 'max_p': '10', 'min_a': '0.0001', 'max_a': '1000' },
|
||||
{ 'pair': 'ZEC/USD', 'min_q': '0.01', 'max_q': '1000', 'min_p': '0.001', 'max_p': '5000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'ZEC/RUB', 'min_q': '0.01', 'max_q': '1000', 'min_p': '0.001', 'max_p': '100000', 'min_a': '0.1', 'max_a': '50000000' },
|
||||
{ 'pair': 'ZEC/EUR', 'min_q': '0.01', 'max_q': '1000', 'min_p': '0.001', 'max_p': '5000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'ZEC/BTC', 'min_q': '0.01', 'max_q': '1000', 'min_p': '0.00001', 'max_p': '10', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'ZEC/USD', 'min_q': '0.01', 'max_q': '10000', 'min_p': '0.001', 'max_p': '5000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'ZEC/RUB', 'min_q': '0.01', 'max_q': '10000', 'min_p': '0.001', 'max_p': '100000', 'min_a': '0.1', 'max_a': '50000000' },
|
||||
{ 'pair': 'ZEC/EUR', 'min_q': '0.01', 'max_q': '10000', 'min_p': '0.001', 'max_p': '5000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'ZEC/BTC', 'min_q': '0.01', 'max_q': '10000', 'min_p': '0.00001', 'max_p': '10', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'ZRX/USD', 'min_q': '0.01', 'max_q': '10000000', 'min_p': '0.00001', 'max_p': '1000', 'min_a': '0.1', 'max_a': '500000' },
|
||||
{ 'pair': 'ZRX/BTC', 'min_q': '1', 'max_q': '10000000', 'min_p': '0.00000001', 'max_p': '1', 'min_a': '0.001', 'max_a': '100' },
|
||||
{ 'pair': 'ZRX/ETH', 'min_q': '0.01', 'max_q': '10000000', 'min_p': '0.00000001', 'max_p': '10', 'min_a': '0.01', 'max_a': '5000' },
|
||||
@@ -337,6 +369,8 @@ module.exports = class exmo extends Exchange {
|
||||
{ 'prov': 'CRON', 'dep': '0%', 'wd': '5 CRON' },
|
||||
{ 'prov': 'ONT', 'dep': '0%', 'wd': '1 ONT' },
|
||||
{ 'prov': 'ONG', 'dep': '0%', 'wd': '5 ONG' },
|
||||
{ 'prov': 'ALGO', 'dep': '0%', 'wd': '0.01 ALGO' },
|
||||
{ 'prov': 'ATOM', 'dep': '0%', 'wd': '' },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -345,9 +379,10 @@ module.exports = class exmo extends Exchange {
|
||||
'items': [
|
||||
{ 'prov': 'EX-CODE', 'dep': '', 'wd': '0.2%' },
|
||||
{ 'prov': 'Payeer', 'dep': '3.95%', 'wd': '-' },
|
||||
{ 'prov': 'AdvCash', 'dep': '0%', 'wd': '3.99%' },
|
||||
{ 'prov': 'AdvCash', 'dep': '0%', 'wd': '3.49%' },
|
||||
{ 'prov': 'Visa/MasterCard (Simplex)', 'dep': '4.5% + 0.5 USD', 'wd': '-' },
|
||||
{ 'prov': 'Visa', 'dep': '3.45%', 'wd': '-' },
|
||||
{ 'prov': 'Frick Bank', 'dep': '0 USD', 'wd': '-' },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -355,22 +390,24 @@ module.exports = class exmo extends Exchange {
|
||||
'title': 'EUR',
|
||||
'items': [
|
||||
{ 'prov': 'EX-CODE', 'dep': '', 'wd': '0.2%' },
|
||||
{ 'prov': 'Visa/MasterCard (Simplex)', 'dep': '4.5% + 0.5 EUR', 'wd': '-' },
|
||||
{ 'prov': 'Visa/MasterCard', 'dep': '4.5% + 0.5 EUR', 'wd': '-' },
|
||||
{ 'prov': 'Visa', 'dep': '2.95%', 'wd': '-' },
|
||||
{ 'prov': 'SEPA', 'dep': '10 EUR', 'wd': '50 EUR' },
|
||||
{ 'prov': 'Frick Internal Transfer', 'dep': '0 EUR', 'wd': '-' },
|
||||
{ 'prov': 'SEPA Frick Bank', 'dep': '0 EUR', 'wd': '-' },
|
||||
{ 'prov': 'WIRE Frick Bank', 'dep': '0%', 'wd': '-' },
|
||||
{ 'prov': 'SEPA Weg Ag', 'dep': '-', 'wd': '1 EUR' },
|
||||
],
|
||||
},
|
||||
{
|
||||
'group': 'rub',
|
||||
'title': 'RUB',
|
||||
'items': [
|
||||
{ 'prov': 'Payeer', 'dep': '2.49%', 'wd': '-' },
|
||||
{ 'prov': 'Payeer', 'dep': '2.49%', 'wd': '3.99%' },
|
||||
{ 'prov': 'EX-CODE', 'dep': '', 'wd': '0.2%' },
|
||||
{ 'prov': 'Qiwi', 'dep': '0.99%', 'wd': '2%' },
|
||||
{ 'prov': 'Yandex Money', 'dep': '1.95%', 'wd': '-' },
|
||||
{ 'prov': 'Enfins', 'dep': '0%', 'wd': '1.49%' },
|
||||
{ 'prov': 'AdvCash', 'dep': '0%', 'wd': '2.49%' },
|
||||
{ 'prov': 'Visa/MasterCard', 'dep': '1.99%', 'wd': '4.49% + 60 RUB' },
|
||||
{ 'prov': 'Qiwi', 'dep': '1.49%', 'wd': '2.49%' },
|
||||
{ 'prov': 'Yandex Money', 'dep': '1.49%', 'wd': '-' },
|
||||
{ 'prov': 'AdvCash', 'dep': '0%', 'wd': '3.49%' },
|
||||
{ 'prov': 'Visa/MasterCard', 'dep': '2.99%', 'wd': '3.99% + 60 RUB' },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -378,7 +415,6 @@ module.exports = class exmo extends Exchange {
|
||||
'title': 'PLN',
|
||||
'items': [
|
||||
{ 'prov': 'EX-CODE', 'dep': '', 'wd': '0.2%' },
|
||||
{ 'prov': 'Visa/MasterCard (Simplex)', 'dep': '4.5% + 1 PLN', 'wd': '-' },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -388,6 +424,7 @@ module.exports = class exmo extends Exchange {
|
||||
{ 'prov': 'EX-CODE', 'dep': '', 'wd': '0.2%' },
|
||||
{ 'prov': 'Visa', 'dep': '3.05%', 'wd': '-' },
|
||||
{ 'prov': 'Visa/MasterCard (Simplex)', 'dep': '4.5% + 2 TRY', 'wd': '-' },
|
||||
{ 'prov': 'AdvCash', 'dep': '0%', 'wd': '-' },
|
||||
],
|
||||
},
|
||||
{
|
||||
@@ -396,17 +433,18 @@ module.exports = class exmo extends Exchange {
|
||||
'items': [
|
||||
{ 'prov': 'EX-CODE', 'dep': '', 'wd': '0.2%' },
|
||||
{ 'prov': 'Terminal', 'dep': '2.6%', 'wd': '-' },
|
||||
{ 'prov': 'Enfins', 'dep': '0%', 'wd': '1.95%' },
|
||||
{ 'prov': 'Visa/MasterCard', 'dep': '1% + 5 UAH', 'wd': '2.99%' },
|
||||
{ 'prov': 'Visa/MasterCard', 'dep': '1% + 5 UAH', 'wd': '-' },
|
||||
{ 'prov': 'Visa/MasterCard EasyTransfer', 'dep': '-', 'wd': '2.99%' },
|
||||
],
|
||||
},
|
||||
{
|
||||
'group': 'kzt',
|
||||
'title': 'KZT',
|
||||
'items': [
|
||||
{ 'prov': 'EX-CODE', 'dep': '', 'wd': '0.2%' },
|
||||
{ 'prov': 'Visa/MasterCard RoyalPay', 'dep': '-', 'wd': '2.99% + 450 KZT' },
|
||||
{ 'prov': 'Visa/MasterCard', 'dep': '3.5%', 'wd': '-' },
|
||||
{ 'prov': 'AdvCash', 'dep': '0%', 'wd': '1.49%' },
|
||||
{ 'prov': 'AdvCash', 'dep': '0%', 'wd': '-' },
|
||||
],
|
||||
},
|
||||
],
|
||||
@@ -420,6 +458,7 @@ module.exports = class exmo extends Exchange {
|
||||
'40015': ExchangeError, // API function do not exist
|
||||
'40016': OnMaintenance, // {"result":false,"error":"Error 40016: Maintenance work in progress"}
|
||||
'40017': AuthenticationError, // Wrong API Key
|
||||
'40032': PermissionDenied, // {"result":false,"error":"Error 40032: Access is denied for this API key"}
|
||||
'40034': RateLimitExceeded, // {"result":false,"error":"Error 40034: Access is denied, rate limit is exceeded"}
|
||||
'50052': InsufficientFunds,
|
||||
'50054': InsufficientFunds,
|
||||
@@ -429,6 +468,8 @@ module.exports = class exmo extends Exchange {
|
||||
'50321': InvalidOrder, // Price by order is more than permissible maximum for this pair
|
||||
},
|
||||
'broad': {
|
||||
'range period is too long': BadRequest,
|
||||
'invalid syntax': BadRequest,
|
||||
'API rate limit exceeded': RateLimitExceeded, // {"result":false,"error":"API rate limit exceeded for 99.33.55.224. Retry after 60 sec.","history":[],"begin":1579392000,"end":1579478400}
|
||||
},
|
||||
},
|
||||
@@ -590,8 +631,21 @@ module.exports = class exmo extends Exchange {
|
||||
}
|
||||
|
||||
async fetchMarkets (params = {}) {
|
||||
const fees = await this.fetchTradingFees ();
|
||||
const response = await this.publicGetPairSettings (params);
|
||||
//
|
||||
// {
|
||||
// "EXM_ETH": {
|
||||
// "min_quantity": "1",
|
||||
// "max_quantity": "1000",
|
||||
// "min_price": "1",
|
||||
// "max_price": "1000",
|
||||
// "max_amount": "1000",
|
||||
// "min_amount": "1",
|
||||
// "commission_taker_percent": "0.2",
|
||||
// "commission_maker_percent": "0.2"
|
||||
// },
|
||||
// }
|
||||
//
|
||||
const keys = Object.keys (response);
|
||||
const result = [];
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
@@ -601,6 +655,8 @@ module.exports = class exmo extends Exchange {
|
||||
const [ baseId, quoteId ] = symbol.split ('/');
|
||||
const base = this.safeCurrencyCode (baseId);
|
||||
const quote = this.safeCurrencyCode (quoteId);
|
||||
const taker = this.safeFloat (market, 'commission_taker_percent');
|
||||
const maker = this.safeFloat (market, 'commission_maker_percent');
|
||||
result.push ({
|
||||
'id': id,
|
||||
'symbol': symbol,
|
||||
@@ -609,8 +665,8 @@ module.exports = class exmo extends Exchange {
|
||||
'baseId': baseId,
|
||||
'quoteId': quoteId,
|
||||
'active': true,
|
||||
'taker': fees['taker'],
|
||||
'maker': fees['maker'],
|
||||
'taker': taker / 100,
|
||||
'maker': maker / 100,
|
||||
'limits': {
|
||||
'amount': {
|
||||
'min': this.safeFloat (market, 'min_quantity'),
|
||||
@@ -635,6 +691,74 @@ module.exports = class exmo extends Exchange {
|
||||
return result;
|
||||
}
|
||||
|
||||
async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
|
||||
await this.loadMarkets ();
|
||||
const market = this.market (symbol);
|
||||
const request = {
|
||||
'symbol': market['id'],
|
||||
'resolution': this.timeframes[timeframe],
|
||||
};
|
||||
const options = this.safeValue (this.options, 'fetchOHLCV');
|
||||
const maxLimit = this.safeInteger (options, 'maxLimit', 3000);
|
||||
const duration = this.parseTimeframe (timeframe);
|
||||
const now = this.milliseconds ();
|
||||
if (since === undefined) {
|
||||
if (limit === undefined) {
|
||||
throw new ArgumentsRequired (this.id + ' fetchOHLCV requires a since argument or a limit argument');
|
||||
} else {
|
||||
if (limit > maxLimit) {
|
||||
throw new BadRequest (this.id + ' fetchOHLCV will serve ' + maxLimit.toString () + ' candles at most');
|
||||
}
|
||||
request['from'] = parseInt (now / 1000) - limit * duration - 1;
|
||||
request['to'] = parseInt (now / 1000);
|
||||
}
|
||||
} else {
|
||||
request['from'] = parseInt (since / 1000) - 1;
|
||||
if (limit === undefined) {
|
||||
request['to'] = parseInt (now / 1000);
|
||||
} else {
|
||||
if (limit > maxLimit) {
|
||||
throw new BadRequest (this.id + ' fetchOHLCV will serve ' + maxLimit.toString () + ' candles at most');
|
||||
}
|
||||
const to = this.sum (since, limit * duration * 1000);
|
||||
request['to'] = parseInt (to / 1000);
|
||||
}
|
||||
}
|
||||
const response = await this.publicGetCandlesHistory (this.extend (request, params));
|
||||
//
|
||||
// {
|
||||
// "candles":[
|
||||
// {"t":1584057600000,"o":0.02235144,"c":0.02400233,"h":0.025171,"l":0.02221,"v":5988.34031761},
|
||||
// {"t":1584144000000,"o":0.0240373,"c":0.02367413,"h":0.024399,"l":0.0235,"v":2027.82522329},
|
||||
// {"t":1584230400000,"o":0.02363458,"c":0.02319242,"h":0.0237948,"l":0.02223196,"v":1707.96944997},
|
||||
// ]
|
||||
// }
|
||||
//
|
||||
const candles = this.safeValue (response, 'candles', []);
|
||||
return this.parseOHLCVs (candles, market, timeframe, since, limit);
|
||||
}
|
||||
|
||||
parseOHLCV (ohlcv, market = undefined, timeframe = '5m', since = undefined, limit = undefined) {
|
||||
//
|
||||
// {
|
||||
// "t":1584057600000,
|
||||
// "o":0.02235144,
|
||||
// "c":0.02400233,
|
||||
// "h":0.025171,
|
||||
// "l":0.02221,
|
||||
// "v":5988.34031761
|
||||
// }
|
||||
//
|
||||
return [
|
||||
this.safeInteger (ohlcv, 't'),
|
||||
this.safeFloat (ohlcv, 'o'),
|
||||
this.safeFloat (ohlcv, 'h'),
|
||||
this.safeFloat (ohlcv, 'l'),
|
||||
this.safeFloat (ohlcv, 'c'),
|
||||
this.safeFloat (ohlcv, 'v'),
|
||||
];
|
||||
}
|
||||
|
||||
async fetchBalance (params = {}) {
|
||||
await this.loadMarkets ();
|
||||
const response = await this.privatePostUserInfo (params);
|
||||
@@ -758,8 +882,36 @@ module.exports = class exmo extends Exchange {
|
||||
}
|
||||
|
||||
parseTrade (trade, market = undefined) {
|
||||
//
|
||||
// fetchTrades (public)
|
||||
//
|
||||
// {
|
||||
// "trade_id":165087520,
|
||||
// "date":1587470005,
|
||||
// "type":"buy",
|
||||
// "quantity":"1.004",
|
||||
// "price":"0.02491461",
|
||||
// "amount":"0.02501426"
|
||||
// },
|
||||
//
|
||||
// fetchMyTrades, fetchOrderTrades
|
||||
//
|
||||
// {
|
||||
// "trade_id": 3,
|
||||
// "date": 1435488248,
|
||||
// "type": "buy",
|
||||
// "pair": "BTC_USD",
|
||||
// "order_id": 12345,
|
||||
// "quantity": 1,
|
||||
// "price": 100,
|
||||
// "amount": 100,
|
||||
// "exec_type": "taker",
|
||||
// "commission_amount": "0.02",
|
||||
// "commission_currency": "BTC",
|
||||
// "commission_percent": "0.2"
|
||||
// }
|
||||
//
|
||||
const timestamp = this.safeTimestamp (trade, 'date');
|
||||
let fee = undefined;
|
||||
let symbol = undefined;
|
||||
const id = this.safeString (trade, 'trade_id');
|
||||
const orderId = this.safeString (trade, 'order_id');
|
||||
@@ -768,24 +920,35 @@ module.exports = class exmo extends Exchange {
|
||||
const cost = this.safeFloat (trade, 'amount');
|
||||
const side = this.safeString (trade, 'type');
|
||||
const type = undefined;
|
||||
if (market !== undefined) {
|
||||
const marketId = this.safeString (trade, 'pair');
|
||||
if (marketId !== undefined) {
|
||||
if (marketId in this.markets_by_id) {
|
||||
market = this.markets_by_id[marketId];
|
||||
} else {
|
||||
const [ baseId, quoteId ] = marketId.split ('_');
|
||||
const base = this.safeCurrencyCode (baseId);
|
||||
const quote = this.safeCurrencyCode (quoteId);
|
||||
symbol = base + '/' + quote;
|
||||
}
|
||||
}
|
||||
if ((symbol === undefined) && (market !== undefined)) {
|
||||
symbol = market['symbol'];
|
||||
if (market['taker'] !== market['maker']) {
|
||||
throw new ExchangeError (this.id + ' parseTrade can not deduce proper fee costs, taker and maker fees now differ');
|
||||
}
|
||||
if ((side === 'buy') && (amount !== undefined)) {
|
||||
fee = {
|
||||
'currency': market['base'],
|
||||
'cost': amount * market['taker'],
|
||||
'rate': market['taker'],
|
||||
};
|
||||
} else if ((side === 'sell') && (cost !== undefined)) {
|
||||
fee = {
|
||||
'currency': market['quote'],
|
||||
'cost': cost * market['taker'],
|
||||
'rate': market['taker'],
|
||||
};
|
||||
}
|
||||
const takerOrMaker = this.safeString (trade, 'exec_type');
|
||||
let fee = undefined;
|
||||
const feeCost = this.safeFloat (trade, 'commission_amount');
|
||||
if (feeCost !== undefined) {
|
||||
const feeCurrencyId = this.safeString (trade, 'commission_currency');
|
||||
const feeCurrencyCode = this.safeCurrencyCode (feeCurrencyId);
|
||||
let feeRate = this.safeFloat (trade, 'commission_percent');
|
||||
if (feeRate !== undefined) {
|
||||
feeRate /= 1000;
|
||||
}
|
||||
fee = {
|
||||
'cost': feeCost,
|
||||
'currency': feeCurrencyCode,
|
||||
'rate': feeRate,
|
||||
};
|
||||
}
|
||||
return {
|
||||
'id': id,
|
||||
@@ -796,7 +959,7 @@ module.exports = class exmo extends Exchange {
|
||||
'order': orderId,
|
||||
'type': type,
|
||||
'side': side,
|
||||
'takerOrMaker': undefined,
|
||||
'takerOrMaker': takerOrMaker,
|
||||
'price': price,
|
||||
'amount': amount,
|
||||
'cost': cost,
|
||||
@@ -811,6 +974,28 @@ module.exports = class exmo extends Exchange {
|
||||
'pair': market['id'],
|
||||
};
|
||||
const response = await this.publicGetTrades (this.extend (request, params));
|
||||
//
|
||||
// {
|
||||
// "ETH_BTC":[
|
||||
// {
|
||||
// "trade_id":165087520,
|
||||
// "date":1587470005,
|
||||
// "type":"buy",
|
||||
// "quantity":"1.004",
|
||||
// "price":"0.02491461",
|
||||
// "amount":"0.02501426"
|
||||
// },
|
||||
// {
|
||||
// "trade_id":165087369,
|
||||
// "date":1587469938,
|
||||
// "type":"buy",
|
||||
// "quantity":"0.94",
|
||||
// "price":"0.02492348",
|
||||
// "amount":"0.02342807"
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
//
|
||||
const data = this.safeValue (response, market['id'], []);
|
||||
return this.parseTrades (data, market, since, limit);
|
||||
}
|
||||
@@ -968,6 +1153,31 @@ module.exports = class exmo extends Exchange {
|
||||
'order_id': id.toString (),
|
||||
};
|
||||
const response = await this.privatePostOrderTrades (this.extend (request, params));
|
||||
//
|
||||
// {
|
||||
// "type": "buy",
|
||||
// "in_currency": "BTC",
|
||||
// "in_amount": "1",
|
||||
// "out_currency": "USD",
|
||||
// "out_amount": "100",
|
||||
// "trades": [
|
||||
// {
|
||||
// "trade_id": 3,
|
||||
// "date": 1435488248,
|
||||
// "type": "buy",
|
||||
// "pair": "BTC_USD",
|
||||
// "order_id": 12345,
|
||||
// "quantity": 1,
|
||||
// "price": 100,
|
||||
// "amount": 100,
|
||||
// "exec_type": "taker",
|
||||
// "commission_amount": "0.02",
|
||||
// "commission_currency": "BTC",
|
||||
// "commission_percent": "0.2"
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
//
|
||||
const trades = this.safeValue (response, 'trades');
|
||||
return this.parseTrades (trades, market, since, limit);
|
||||
}
|
||||
@@ -1415,9 +1625,10 @@ module.exports = class exmo extends Exchange {
|
||||
if (response === undefined) {
|
||||
return; // fallback to default error handler
|
||||
}
|
||||
if ('result' in response) {
|
||||
if (('result' in response) || ('errmsg' in response)) {
|
||||
//
|
||||
// {"result":false,"error":"Error 50052: Insufficient funds"}
|
||||
// {"s":"error","errmsg":"strconv.ParseInt: parsing \"\": invalid syntax"}
|
||||
//
|
||||
let success = this.safeValue (response, 'result', false);
|
||||
if (typeof success === 'string') {
|
||||
@@ -1429,7 +1640,7 @@ module.exports = class exmo extends Exchange {
|
||||
}
|
||||
if (!success) {
|
||||
let code = undefined;
|
||||
const message = this.safeString (response, 'error');
|
||||
const message = this.safeString2 (response, 'error', 'errmsg');
|
||||
const errorParts = message.split (':');
|
||||
const numParts = errorParts.length;
|
||||
if (numParts > 1) {
|
||||
|
||||
+4
@@ -580,6 +580,7 @@ module.exports = class ftx extends Exchange {
|
||||
// {
|
||||
// "fee": 20.1374935,
|
||||
// "feeRate": 0.0005,
|
||||
// "feeCurrency": "USD",
|
||||
// "future": "EOS-0329",
|
||||
// "id": 11215,
|
||||
// "liquidity": "taker",
|
||||
@@ -626,8 +627,11 @@ module.exports = class ftx extends Exchange {
|
||||
let fee = undefined;
|
||||
const feeCost = this.safeFloat (trade, 'fee');
|
||||
if (feeCost !== undefined) {
|
||||
const feeCurrencyId = this.safeString (trade, 'feeCurrency');
|
||||
const feeCurrencyCode = this.safeCurrencyCode (feeCurrencyId);
|
||||
fee = {
|
||||
'cost': feeCost,
|
||||
'currency': feeCurrencyCode,
|
||||
'rate': this.safeFloat (trade, 'feeRate'),
|
||||
};
|
||||
}
|
||||
|
||||
+94
-25
@@ -164,6 +164,26 @@ module.exports = class gateio extends Exchange {
|
||||
|
||||
async fetchMarkets (params = {}) {
|
||||
const response = await this.publicGetMarketinfo (params);
|
||||
//
|
||||
// {
|
||||
// "result":"true",
|
||||
// "pairs":[
|
||||
// {
|
||||
// "usdt_cnyx":{
|
||||
// "decimal_places":3,
|
||||
// "amount_decimal_places":3,
|
||||
// "min_amount":1,
|
||||
// "min_amount_a":1,
|
||||
// "min_amount_b":3,
|
||||
// "fee":0.02,
|
||||
// "trade_disabled":0,
|
||||
// "buy_disabled":0,
|
||||
// "sell_disabled":0
|
||||
// }
|
||||
// },
|
||||
// ]
|
||||
// }
|
||||
//
|
||||
const markets = this.safeValue (response, 'pairs');
|
||||
if (!markets) {
|
||||
throw new ExchangeError (this.id + ' fetchMarkets got an unrecognized response');
|
||||
@@ -190,14 +210,14 @@ module.exports = class gateio extends Exchange {
|
||||
const symbol = base + '/' + quote;
|
||||
const precision = {
|
||||
'amount': 8,
|
||||
'price': details['decimal_places'],
|
||||
'price': this.safeInteger (details, 'decimal_places'),
|
||||
};
|
||||
const amountLimits = {
|
||||
'min': details['min_amount'],
|
||||
'min': this.safeFloat (details, 'min_amount'),
|
||||
'max': undefined,
|
||||
};
|
||||
const priceLimits = {
|
||||
'min': Math.pow (10, -details['decimal_places']),
|
||||
'min': Math.pow (10, -precision['price']),
|
||||
'max': undefined,
|
||||
};
|
||||
const defaultCost = amountLimits['min'] * priceLimits['min'];
|
||||
@@ -211,9 +231,13 @@ module.exports = class gateio extends Exchange {
|
||||
'price': priceLimits,
|
||||
'cost': costLimits,
|
||||
};
|
||||
const active = true;
|
||||
const disabled = this.safeValue (details, 'trade_disabled');
|
||||
const active = !disabled;
|
||||
const uppercaseId = id.toUpperCase ();
|
||||
const fee = this.safeFloat (details, 'fee');
|
||||
result.push ({
|
||||
'id': id,
|
||||
'uppercaseId': uppercaseId,
|
||||
'symbol': symbol,
|
||||
'base': base,
|
||||
'quote': quote,
|
||||
@@ -221,8 +245,8 @@ module.exports = class gateio extends Exchange {
|
||||
'quoteId': quoteId,
|
||||
'info': market,
|
||||
'active': active,
|
||||
'maker': details['fee'] / 100,
|
||||
'taker': details['fee'] / 100,
|
||||
'maker': fee / 100,
|
||||
'taker': fee / 100,
|
||||
'precision': precision,
|
||||
'limits': limits,
|
||||
});
|
||||
@@ -484,22 +508,64 @@ module.exports = class gateio extends Exchange {
|
||||
|
||||
parseOrder (order, market = undefined) {
|
||||
//
|
||||
// {'amount': '0.00000000',
|
||||
// 'currencyPair': 'xlm_usdt',
|
||||
// 'fee': '0.0113766632239302 USDT',
|
||||
// 'feeCurrency': 'USDT',
|
||||
// 'feePercentage': 0.18,
|
||||
// 'feeValue': '0.0113766632239302',
|
||||
// 'filledAmount': '30.14004987',
|
||||
// 'filledRate': 0.2097,
|
||||
// 'initialAmount': '30.14004987',
|
||||
// 'initialRate': '0.2097',
|
||||
// 'left': 0,
|
||||
// 'orderNumber': '998307286',
|
||||
// 'rate': '0.2097',
|
||||
// 'status': 'closed',
|
||||
// 'timestamp': 1531158583,
|
||||
// 'type': 'sell'},
|
||||
// createOrder
|
||||
//
|
||||
// {
|
||||
// "fee": "0 ZEC",
|
||||
// "code": 0,
|
||||
// "rate": "0.0055",
|
||||
// "side": 2,
|
||||
// "type": "buy",
|
||||
// "ctime": 1586460839.138,
|
||||
// "market": "ZEC_BTC",
|
||||
// "result": "true",
|
||||
// "status": "open",
|
||||
// "iceberg": "0",
|
||||
// "message": "Success",
|
||||
// "feeValue": "0",
|
||||
// "filledRate": "0.005500000",
|
||||
// "leftAmount": "0.60607456",
|
||||
// "feeCurrency": "ZEC",
|
||||
// "orderNumber": 10755887009,
|
||||
// "filledAmount": "0",
|
||||
// "feePercentage": 0.002,
|
||||
// "initialAmount": "0.60607456"
|
||||
// }
|
||||
//
|
||||
// {
|
||||
// 'amount': '0.00000000',
|
||||
// 'currencyPair': 'xlm_usdt',
|
||||
// 'fee': '0.0113766632239302 USDT',
|
||||
// 'feeCurrency': 'USDT',
|
||||
// 'feePercentage': 0.18,
|
||||
// 'feeValue': '0.0113766632239302',
|
||||
// 'filledAmount': '30.14004987',
|
||||
// 'filledRate': 0.2097,
|
||||
// 'initialAmount': '30.14004987',
|
||||
// 'initialRate': '0.2097',
|
||||
// 'left': 0,
|
||||
// 'orderNumber': '998307286',
|
||||
// 'rate': '0.2097',
|
||||
// 'status': 'closed',
|
||||
// 'timestamp': 1531158583,
|
||||
// 'type': 'sell'
|
||||
// }
|
||||
//
|
||||
// {
|
||||
// "orderNumber": 10802237760,
|
||||
// "orderType": 1,
|
||||
// "type": "buy",
|
||||
// "rate": "0.54250000",
|
||||
// "amount": "45.55638518",
|
||||
// "total": "24.71433896",
|
||||
// "initialRate": "0.54250000",
|
||||
// "initialAmount": "45.55638518",
|
||||
// "filledRate": "0.54250000",
|
||||
// "filledAmount": "0",
|
||||
// "currencyPair": "nano_usdt",
|
||||
// "timestamp": 1586556143,
|
||||
// "status": "open"
|
||||
// }
|
||||
//
|
||||
const id = this.safeString2 (order, 'orderNumber', 'id');
|
||||
let symbol = undefined;
|
||||
@@ -520,12 +586,15 @@ module.exports = class gateio extends Exchange {
|
||||
} else if (side === '2') {
|
||||
side = 'buy';
|
||||
}
|
||||
const price = this.safeFloat2 (order, 'initialRate', 'price');
|
||||
const price = this.safeFloat2 (order, 'initialRate', 'rate');
|
||||
const average = this.safeFloat (order, 'filledRate');
|
||||
const amount = this.safeFloat2 (order, 'initialAmount', 'amount');
|
||||
const filled = this.safeFloat (order, 'filledAmount');
|
||||
// In the order status response, this field has a different name.
|
||||
const remaining = this.safeFloat2 (order, 'leftAmount', 'left');
|
||||
let remaining = this.safeFloat2 (order, 'leftAmount', 'left');
|
||||
if (remaining === undefined) {
|
||||
remaining = amount - filled;
|
||||
}
|
||||
const feeCost = this.safeFloat (order, 'feeValue');
|
||||
const feeCurrencyId = this.safeString (order, 'feeCurrency');
|
||||
const feeCurrencyCode = this.safeCurrencyCode (feeCurrencyId);
|
||||
@@ -651,7 +720,7 @@ module.exports = class gateio extends Exchange {
|
||||
|
||||
async fetchMyTrades (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
||||
if (symbol === undefined) {
|
||||
throw new ArgumentsRequired (this.id + ' fetchMyTrades requires symbol param');
|
||||
throw new ArgumentsRequired (this.id + ' fetchMyTrades requires symbol argument');
|
||||
}
|
||||
await this.loadMarkets ();
|
||||
const market = this.market (symbol);
|
||||
|
||||
+60
-54
@@ -180,8 +180,7 @@ module.exports = class gemini extends Exchange {
|
||||
if (numTables < 2) {
|
||||
throw new NotSupported (error);
|
||||
}
|
||||
// tables[1] = tables[1].replace ("\n", ''); // eslint-disable-line quotes
|
||||
const rows = tables[1].split ("<tr>\n"); // eslint-disable-line quotes
|
||||
const rows = tables[1].split ("\n<tr>\n"); // eslint-disable-line quotes
|
||||
const numRows = rows.length;
|
||||
if (numRows < 2) {
|
||||
throw new NotSupported (error);
|
||||
@@ -192,66 +191,73 @@ module.exports = class gemini extends Exchange {
|
||||
const row = rows[i];
|
||||
const cells = row.split ("</td>\n"); // eslint-disable-line quotes
|
||||
const numCells = cells.length;
|
||||
if (numCells < 7) {
|
||||
if (numCells < 9) {
|
||||
throw new NotSupported (error);
|
||||
}
|
||||
//
|
||||
// [
|
||||
// '<td><code class="prettyprint">btcusd</code>',
|
||||
// '<td>USD', // quote
|
||||
// '<td>BTC', // base
|
||||
// '<td>0.00001 BTC (1e-5)', // min amount
|
||||
// '<td>0.00000001 BTC (1e-8)', // amount min tick size
|
||||
// '<td>0.01 USD', // price min tick size
|
||||
// '</tr>\n'
|
||||
// '<td>BTC', // currency
|
||||
// '<td>0.00001 BTC (1e-5)', // min order size
|
||||
// '<td>0.00000001 BTC (1e-8)', // tick size
|
||||
// '<td>0.01 USD', // usd price increment
|
||||
// '<td>N/A', // btc price increment
|
||||
// '<td>0.0001 ETH (1e-4)', // eth price increment
|
||||
// '<td>0.0001 BCH (1e-4)', // bch price increment
|
||||
// '<td>0.001 LTC (1e-3)', // ltc price increment
|
||||
// '</tr>'
|
||||
// ]
|
||||
//
|
||||
let id = cells[0].replace ('<td>', '');
|
||||
id = id.replace ('<code class="prettyprint">', '');
|
||||
id = id.replace ('</code>', '');
|
||||
let baseId = cells[2].replace ('<td>', '');
|
||||
let quoteId = cells[1].replace ('<td>', '');
|
||||
const minAmountAsString = cells[3].replace ('<td>', '');
|
||||
const amountTickSizeAsString = cells[4].replace ('<td>', '');
|
||||
const priceTickSizeAsString = cells[5].replace ('<td>', '');
|
||||
const minAmount = minAmountAsString.split (' ');
|
||||
const amountPrecision = amountTickSizeAsString.split (' ');
|
||||
const pricePrecision = priceTickSizeAsString.split (' ');
|
||||
baseId = baseId.toLowerCase ();
|
||||
quoteId = quoteId.toLowerCase ();
|
||||
const uppercaseBaseId = cells[0].replace ('<td>', '');
|
||||
const baseId = uppercaseBaseId.toLowerCase ();
|
||||
const base = this.safeCurrencyCode (baseId);
|
||||
const quote = this.safeCurrencyCode (quoteId);
|
||||
const symbol = base + '/' + quote;
|
||||
const precision = {
|
||||
'amount': this.precisionFromString (amountPrecision[0]),
|
||||
'price': this.precisionFromString (pricePrecision[0]),
|
||||
};
|
||||
const active = undefined;
|
||||
result.push ({
|
||||
'id': id,
|
||||
'info': row,
|
||||
'symbol': symbol,
|
||||
'base': base,
|
||||
'quote': quote,
|
||||
'baseId': baseId,
|
||||
'quoteId': quoteId,
|
||||
'active': active,
|
||||
'precision': precision,
|
||||
'limits': {
|
||||
'amount': {
|
||||
'min': parseFloat (minAmount[0]),
|
||||
'max': undefined,
|
||||
const quoteIds = [ 'usd', 'btc', 'eth', 'bch', 'ltc' ];
|
||||
const minAmountString = cells[1].replace ('<td>', '');
|
||||
const minAmountParts = minAmountString.split (' ');
|
||||
const minAmount = this.safeFloat (minAmountParts, 0);
|
||||
const amountPrecisionString = cells[2].replace ('<td>', '');
|
||||
const amountPrecisionParts = amountPrecisionString.split (' ');
|
||||
const amountPrecision = this.precisionFromString (amountPrecisionParts[0]);
|
||||
for (let j = 0; j < quoteIds.length; j++) {
|
||||
const quoteId = quoteIds[j];
|
||||
const quote = this.safeCurrencyCode (quoteId);
|
||||
const pricePrecisionIndex = this.sum (3, j);
|
||||
const pricePrecisionString = cells[pricePrecisionIndex].replace ('<td>', '');
|
||||
if (pricePrecisionString === 'N/A') {
|
||||
continue;
|
||||
}
|
||||
const pricePrecisionParts = pricePrecisionString.split (' ');
|
||||
const pricePrecision = this.precisionFromString (pricePrecisionParts[0]);
|
||||
const symbol = base + '/' + quote;
|
||||
const id = baseId + quoteId;
|
||||
const active = undefined;
|
||||
result.push ({
|
||||
'id': id,
|
||||
'info': row,
|
||||
'symbol': symbol,
|
||||
'base': base,
|
||||
'quote': quote,
|
||||
'baseId': baseId,
|
||||
'quoteId': quoteId,
|
||||
'active': active,
|
||||
'precision': {
|
||||
'amount': amountPrecision,
|
||||
'price': pricePrecision,
|
||||
},
|
||||
'price': {
|
||||
'min': undefined,
|
||||
'max': undefined,
|
||||
'limits': {
|
||||
'amount': {
|
||||
'min': minAmount,
|
||||
'max': undefined,
|
||||
},
|
||||
'price': {
|
||||
'min': undefined,
|
||||
'max': undefined,
|
||||
},
|
||||
'cost': {
|
||||
'min': undefined,
|
||||
'max': undefined,
|
||||
},
|
||||
},
|
||||
'cost': {
|
||||
'min': undefined,
|
||||
'max': undefined,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
+2019
File diff suppressed because it is too large.
Load diff
+6
-7
@@ -730,14 +730,13 @@ module.exports = class hitbtc extends Exchange {
|
||||
}
|
||||
|
||||
parseOHLCV (ohlcv, market = undefined, timeframe = '1d', since = undefined, limit = undefined) {
|
||||
const timestamp = this.parse8601 (ohlcv['timestamp']);
|
||||
return [
|
||||
timestamp,
|
||||
parseFloat (ohlcv['open']),
|
||||
parseFloat (ohlcv['max']),
|
||||
parseFloat (ohlcv['min']),
|
||||
parseFloat (ohlcv['close']),
|
||||
parseFloat (ohlcv['volume']),
|
||||
this.parse8601 (this.safeString (ohlcv, 'timestamp')),
|
||||
this.safeFloat (ohlcv, 'open'),
|
||||
this.safeFloat (ohlcv, 'max'),
|
||||
this.safeFloat (ohlcv, 'min'),
|
||||
this.safeFloat (ohlcv, 'close'),
|
||||
this.safeFloat (ohlcv, 'volume'),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const hitbtc = require ('./hitbtc');
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
module.exports = class hitbtc2 extends hitbtc {
|
||||
describe () {
|
||||
// this is a temporary stub for backward compatibility
|
||||
// https://github.com/ccxt/ccxt/issues/6678
|
||||
return this.deepExtend (super.describe (), {
|
||||
'id': 'hitbtc2',
|
||||
});
|
||||
}
|
||||
};
|
||||
+27
-1
@@ -163,12 +163,14 @@ module.exports = class huobipro extends Exchange {
|
||||
'exceptions': {
|
||||
'exact': {
|
||||
// err-code
|
||||
'bad-request': BadRequest,
|
||||
'api-not-support-temp-addr': PermissionDenied, // {"status":"error","err-code":"api-not-support-temp-addr","err-msg":"API withdrawal does not support temporary addresses","data":null}
|
||||
'timeout': RequestTimeout, // {"ts":1571653730865,"status":"error","err-code":"timeout","err-msg":"Request Timeout"}
|
||||
'gateway-internal-error': ExchangeNotAvailable, // {"status":"error","err-code":"gateway-internal-error","err-msg":"Failed to load data. Try again later.","data":null}
|
||||
'account-frozen-balance-insufficient-error': InsufficientFunds, // {"status":"error","err-code":"account-frozen-balance-insufficient-error","err-msg":"trade account balance is not enough, left: `0.0027`","data":null}
|
||||
'invalid-amount': InvalidOrder, // eg "Paramemter `amount` is invalid."
|
||||
'order-limitorder-amount-min-error': InvalidOrder, // limit order amount error, min: `0.001`
|
||||
'order-limitorder-amount-max-error': InvalidOrder, // market order amount error, max: `1000000`
|
||||
'order-marketorder-amount-min-error': InvalidOrder, // market order amount error, min: `0.01`
|
||||
'order-limitorder-price-min-error': InvalidOrder, // limit order price error
|
||||
'order-limitorder-price-max-error': InvalidOrder, // limit order price error
|
||||
@@ -331,6 +333,8 @@ module.exports = class huobipro extends Exchange {
|
||||
}
|
||||
|
||||
parseTicker (ticker, market = undefined) {
|
||||
//
|
||||
// fetchTicker
|
||||
//
|
||||
// {
|
||||
// "amount": 26228.672978342216,
|
||||
@@ -346,25 +350,47 @@ module.exports = class huobipro extends Exchange {
|
||||
// "bid": [ 9146.86, 0.080758 ],
|
||||
// }
|
||||
//
|
||||
// fetchTickers
|
||||
// {
|
||||
// symbol: "bhdht",
|
||||
// open: 2.3938,
|
||||
// high: 2.4151,
|
||||
// low: 2.3323,
|
||||
// close: 2.3909,
|
||||
// amount: 628.992,
|
||||
// vol: 1493.71841095,
|
||||
// count: 2088,
|
||||
// bid: 2.3643,
|
||||
// bidSize: 0.7136,
|
||||
// ask: 2.4061,
|
||||
// askSize: 0.4156
|
||||
// }
|
||||
//
|
||||
let symbol = undefined;
|
||||
if (market !== undefined) {
|
||||
symbol = market['symbol'];
|
||||
}
|
||||
const timestamp = this.safeInteger (ticker, 'ts');
|
||||
let bid = undefined;
|
||||
let ask = undefined;
|
||||
let bidVolume = undefined;
|
||||
let ask = undefined;
|
||||
let askVolume = undefined;
|
||||
if ('bid' in ticker) {
|
||||
if (Array.isArray (ticker['bid'])) {
|
||||
bid = this.safeFloat (ticker['bid'], 0);
|
||||
bidVolume = this.safeFloat (ticker['bid'], 1);
|
||||
} else {
|
||||
bid = this.safeFloat (ticker, 'bid');
|
||||
bidVolume = this.safeValue (ticker, 'bidSize');
|
||||
}
|
||||
}
|
||||
if ('ask' in ticker) {
|
||||
if (Array.isArray (ticker['ask'])) {
|
||||
ask = this.safeFloat (ticker['ask'], 0);
|
||||
askVolume = this.safeFloat (ticker['ask'], 1);
|
||||
} else {
|
||||
ask = this.safeFloat (ticker, 'ask');
|
||||
askVolume = this.safeValue (ticker, 'askSize');
|
||||
}
|
||||
}
|
||||
const open = this.safeFloat (ticker, 'open');
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const Exchange = require ('./base/Exchange');
|
||||
const { ExchangeError, AuthenticationError } = require ('./base/errors');
|
||||
const { ExchangeError, AuthenticationError, ArgumentsRequired } = require ('./base/errors');
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -221,7 +221,7 @@ module.exports = class ice3x extends Exchange {
|
||||
const type = this.safeString (params, 'type');
|
||||
if ((type !== 'ask') && (type !== 'bid')) {
|
||||
// eslint-disable-next-line quotes
|
||||
throw new ExchangeError (this.id + " fetchOrderBook requires an exchange-specific extra 'type' param ('bid' or 'ask') when used with a limit");
|
||||
throw new ArgumentsRequired (this.id + " fetchOrderBook requires an exchange-specific extra 'type' param ('bid' or 'ask') when used with a limit");
|
||||
} else {
|
||||
request['items_per_page'] = limit;
|
||||
}
|
||||
|
||||
+3
-3
@@ -362,7 +362,7 @@ module.exports = class indodax extends Exchange {
|
||||
|
||||
async fetchOrder (id, symbol = undefined, params = {}) {
|
||||
if (symbol === undefined) {
|
||||
throw new ExchangeError (this.id + ' fetchOrder requires a symbol');
|
||||
throw new ArgumentsRequired (this.id + ' fetchOrder requires a symbol');
|
||||
}
|
||||
await this.loadMarkets ();
|
||||
const market = this.market (symbol);
|
||||
@@ -409,7 +409,7 @@ module.exports = class indodax extends Exchange {
|
||||
|
||||
async fetchClosedOrders (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
||||
if (symbol === undefined) {
|
||||
throw new ExchangeError (this.id + ' fetchOrders requires a symbol');
|
||||
throw new ArgumentsRequired (this.id + ' fetchOrders requires a symbol argument');
|
||||
}
|
||||
await this.loadMarkets ();
|
||||
const request = {};
|
||||
@@ -458,7 +458,7 @@ module.exports = class indodax extends Exchange {
|
||||
}
|
||||
const side = this.safeValue (params, 'side');
|
||||
if (side === undefined) {
|
||||
throw new ExchangeError (this.id + ' cancelOrder requires an extra "side" param');
|
||||
throw new ArgumentsRequired (this.id + ' cancelOrder requires an extra "side" param');
|
||||
}
|
||||
await this.loadMarkets ();
|
||||
const market = this.market (symbol);
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const Exchange = require ('./base/Exchange');
|
||||
const { ExchangeError, AuthenticationError } = require ('./base/errors');
|
||||
const { ExchangeError, AuthenticationError, ArgumentsRequired } = require ('./base/errors');
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -254,7 +254,7 @@ module.exports = class itbit extends Exchange {
|
||||
await this.loadMarkets ();
|
||||
const walletId = this.safeString (params, 'walletId');
|
||||
if (walletId === undefined) {
|
||||
throw new ExchangeError (this.id + ' fetchMyTrades requires a walletId parameter');
|
||||
throw new ArgumentsRequired (this.id + ' fetchMyTrades requires a walletId parameter');
|
||||
}
|
||||
const request = {
|
||||
'walletId': walletId,
|
||||
|
||||
+263
-32
@@ -36,6 +36,7 @@ module.exports = class kraken extends Exchange {
|
||||
'withdraw': true,
|
||||
'fetchLedgerEntry': true,
|
||||
'fetchLedger': true,
|
||||
'fetchOrderTrades': 'emulated',
|
||||
},
|
||||
'marketsByAltname': {},
|
||||
'timeframes': {
|
||||
@@ -54,7 +55,7 @@ module.exports = class kraken extends Exchange {
|
||||
'api': {
|
||||
'public': 'https://api.kraken.com',
|
||||
'private': 'https://api.kraken.com',
|
||||
'zendesk': 'https://support.kraken.com/hc/en-us/articles',
|
||||
'zendesk': 'https://kraken.zendesk.com/api/v2/help_center/en-us/articles', // use the public zendesk api to receive article bodies and bypass new anti-spam protections
|
||||
},
|
||||
'www': 'https://www.kraken.com',
|
||||
'doc': 'https://www.kraken.com/features/api',
|
||||
@@ -149,9 +150,9 @@ module.exports = class kraken extends Exchange {
|
||||
'get': [
|
||||
// we should really refrain from putting fixed fee numbers and stop hardcoding
|
||||
// we will be using their web APIs to scrape all numbers from these articles
|
||||
'205893708-What-is-the-minimum-order-size-',
|
||||
'201396777-What-are-the-deposit-fees-',
|
||||
'201893608-What-are-the-withdrawal-fees-',
|
||||
'205893708', // -What-is-the-minimum-order-size-
|
||||
'360000292886', // -What-are-the-deposit-fees-
|
||||
'201893608', // -What-are-the-withdrawal-fees-
|
||||
],
|
||||
},
|
||||
'public': {
|
||||
@@ -234,12 +235,14 @@ module.exports = class kraken extends Exchange {
|
||||
return this.decimalToPrecision (fee, TRUNCATE, this.markets[symbol]['precision']['amount'], DECIMAL_PLACES);
|
||||
}
|
||||
|
||||
async fetchMinOrderAmounts () {
|
||||
const html = await this.zendeskGet205893708WhatIsTheMinimumOrderSize ();
|
||||
async fetchMinOrderAmounts (params = {}) {
|
||||
const response = await this.zendeskGet205893708 (params);
|
||||
const article = this.safeValue (response, 'article');
|
||||
const html = this.safeString (article, 'body');
|
||||
const parts = html.split ('<td class="wysiwyg-text-align-right">');
|
||||
const numParts = parts.length;
|
||||
if (numParts < 3) {
|
||||
throw new NotSupported (this.id + ' fetchMinOrderAmounts HTML page markup has changed: https://support.kraken.com/hc/en-us/articles/205893708-What-is-the-minimum-order-size-');
|
||||
throw new NotSupported (this.id + ' fetchMinOrderAmounts HTML page markup has changed: https://kraken.zendesk.com/api/v2/help_center/en-us/articles/205893708');
|
||||
}
|
||||
const result = {};
|
||||
// skip the part before the header and the header itself
|
||||
@@ -262,6 +265,52 @@ module.exports = class kraken extends Exchange {
|
||||
|
||||
async fetchMarkets (params = {}) {
|
||||
const response = await this.publicGetAssetPairs (params);
|
||||
//
|
||||
// {
|
||||
// "error":[],
|
||||
// "result":{
|
||||
// "ADAETH":{
|
||||
// "altname":"ADAETH",
|
||||
// "wsname":"ADA\/ETH",
|
||||
// "aclass_base":"currency",
|
||||
// "base":"ADA",
|
||||
// "aclass_quote":"currency",
|
||||
// "quote":"XETH",
|
||||
// "lot":"unit",
|
||||
// "pair_decimals":7,
|
||||
// "lot_decimals":8,
|
||||
// "lot_multiplier":1,
|
||||
// "leverage_buy":[],
|
||||
// "leverage_sell":[],
|
||||
// "fees":[
|
||||
// [0,0.26],
|
||||
// [50000,0.24],
|
||||
// [100000,0.22],
|
||||
// [250000,0.2],
|
||||
// [500000,0.18],
|
||||
// [1000000,0.16],
|
||||
// [2500000,0.14],
|
||||
// [5000000,0.12],
|
||||
// [10000000,0.1]
|
||||
// ],
|
||||
// "fees_maker":[
|
||||
// [0,0.16],
|
||||
// [50000,0.14],
|
||||
// [100000,0.12],
|
||||
// [250000,0.1],
|
||||
// [500000,0.08],
|
||||
// [1000000,0.06],
|
||||
// [2500000,0.04],
|
||||
// [5000000,0.02],
|
||||
// [10000000,0]
|
||||
// ],
|
||||
// "fee_volume_currency":"ZUSD",
|
||||
// "margin_call":80,
|
||||
// "margin_stop":40
|
||||
// },
|
||||
// }
|
||||
// }
|
||||
//
|
||||
const fetchMinOrderAmounts = this.safeValue (this.options, 'fetchMinOrderAmounts', false);
|
||||
let limits = {};
|
||||
if (fetchMinOrderAmounts) {
|
||||
@@ -441,6 +490,13 @@ module.exports = class kraken extends Exchange {
|
||||
};
|
||||
}
|
||||
|
||||
parseBidAsk (bidask, priceKey = 0, amountKey = 1) {
|
||||
const price = this.safeFloat (bidask, priceKey);
|
||||
const amount = this.safeFloat (bidask, amountKey);
|
||||
const timestamp = this.safeInteger (bidask, 2);
|
||||
return [ price, amount, timestamp ];
|
||||
}
|
||||
|
||||
async fetchOrderBook (symbol, limit = undefined, params = {}) {
|
||||
await this.loadMarkets ();
|
||||
const market = this.market (symbol);
|
||||
@@ -454,7 +510,27 @@ module.exports = class kraken extends Exchange {
|
||||
request['count'] = limit; // 100
|
||||
}
|
||||
const response = await this.publicGetDepth (this.extend (request, params));
|
||||
const orderbook = response['result'][market['id']];
|
||||
//
|
||||
// {
|
||||
// "error":[],
|
||||
// "result":{
|
||||
// "XETHXXBT":{
|
||||
// "asks":[
|
||||
// ["0.023480","4.000",1586321307],
|
||||
// ["0.023490","50.095",1586321306],
|
||||
// ["0.023500","28.535",1586321302],
|
||||
// ],
|
||||
// "bids":[
|
||||
// ["0.023470","59.580",1586321307],
|
||||
// ["0.023460","20.000",1586321301],
|
||||
// ["0.023440","67.832",1586321306],
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
const result = this.safeValue (response, 'result', {});
|
||||
const orderbook = this.safeValue (result, market['id']);
|
||||
return this.parseOrderBook (orderbook);
|
||||
}
|
||||
|
||||
@@ -708,26 +784,46 @@ module.exports = class kraken extends Exchange {
|
||||
}
|
||||
|
||||
parseTrade (trade, market = undefined) {
|
||||
//
|
||||
// fetchTrades (public)
|
||||
//
|
||||
// [
|
||||
// "0.032310", // price
|
||||
// "4.28169434", // amount
|
||||
// 1541390792.763, // timestamp
|
||||
// "s", // sell or buy
|
||||
// "l", // limit or market
|
||||
// ""
|
||||
// ]
|
||||
//
|
||||
// fetchOrderTrades (private)
|
||||
//
|
||||
// {
|
||||
// id: 'TIMIRG-WUNNE-RRJ6GT', // injected from outside
|
||||
// ordertxid: 'OQRPN2-LRHFY-HIFA7D',
|
||||
// postxid: 'TKH2SE-M7IF5-CFI7LT',
|
||||
// pair: 'USDCUSDT',
|
||||
// time: 1586340086.457,
|
||||
// type: 'sell',
|
||||
// ordertype: 'market',
|
||||
// price: '0.99860000',
|
||||
// cost: '22.16892001',
|
||||
// fee: '0.04433784',
|
||||
// vol: '22.20000000',
|
||||
// margin: '0.00000000',
|
||||
// misc: ''
|
||||
// }
|
||||
//
|
||||
let timestamp = undefined;
|
||||
let side = undefined;
|
||||
let type = undefined;
|
||||
let price = undefined;
|
||||
let amount = undefined;
|
||||
let cost = undefined;
|
||||
let id = undefined;
|
||||
let order = undefined;
|
||||
let fee = undefined;
|
||||
const marketId = this.safeString (trade, 'pair');
|
||||
const foundMarket = this.findMarketByAltnameOrId (marketId);
|
||||
let symbol = undefined;
|
||||
if (foundMarket !== undefined) {
|
||||
market = foundMarket;
|
||||
} else if (marketId !== undefined) {
|
||||
// delisted market ids go here
|
||||
market = this.getDelistedMarketById (marketId);
|
||||
}
|
||||
if (market !== undefined) {
|
||||
symbol = market['symbol'];
|
||||
}
|
||||
if (Array.isArray (trade)) {
|
||||
timestamp = this.safeTimestamp (trade, 2);
|
||||
side = (trade[3] === 's') ? 'sell' : 'buy';
|
||||
@@ -738,17 +834,27 @@ module.exports = class kraken extends Exchange {
|
||||
if (tradeLength > 6) {
|
||||
id = this.safeString (trade, 6); // artificially added as per #1794
|
||||
}
|
||||
} else if (typeof trade === 'string') {
|
||||
id = trade;
|
||||
} else if ('ordertxid' in trade) {
|
||||
const marketId = this.safeString (trade, 'pair');
|
||||
const foundMarket = this.findMarketByAltnameOrId (marketId);
|
||||
if (foundMarket !== undefined) {
|
||||
market = foundMarket;
|
||||
} else if (marketId !== undefined) {
|
||||
// delisted market ids go here
|
||||
market = this.getDelistedMarketById (marketId);
|
||||
}
|
||||
order = trade['ordertxid'];
|
||||
id = this.safeString2 (trade, 'id', 'postxid');
|
||||
timestamp = this.safeTimestamp (trade, 'time');
|
||||
side = trade['type'];
|
||||
type = trade['ordertype'];
|
||||
side = this.safeString (trade, 'type');
|
||||
type = this.safeString (trade, 'ordertype');
|
||||
price = this.safeFloat (trade, 'price');
|
||||
amount = this.safeFloat (trade, 'vol');
|
||||
if ('fee' in trade) {
|
||||
let currency = undefined;
|
||||
if (market) {
|
||||
if (market !== undefined) {
|
||||
currency = market['quote'];
|
||||
}
|
||||
fee = {
|
||||
@@ -757,6 +863,14 @@ module.exports = class kraken extends Exchange {
|
||||
};
|
||||
}
|
||||
}
|
||||
if (market !== undefined) {
|
||||
symbol = market['symbol'];
|
||||
}
|
||||
if (price !== undefined) {
|
||||
if (amount !== undefined) {
|
||||
cost = price * amount;
|
||||
}
|
||||
}
|
||||
return {
|
||||
'id': id,
|
||||
'order': order,
|
||||
@@ -769,7 +883,7 @@ module.exports = class kraken extends Exchange {
|
||||
'takerOrMaker': undefined,
|
||||
'price': price,
|
||||
'amount': amount,
|
||||
'cost': price * amount,
|
||||
'cost': cost,
|
||||
'fee': fee,
|
||||
};
|
||||
}
|
||||
@@ -986,6 +1100,11 @@ module.exports = class kraken extends Exchange {
|
||||
const status = this.parseOrderStatus (this.safeString (order, 'status'));
|
||||
const id = this.safeString (order, 'id');
|
||||
const clientOrderId = this.safeString (order, 'userref');
|
||||
const rawTrades = this.safeValue (order, 'trades');
|
||||
let trades = undefined;
|
||||
if (rawTrades !== undefined) {
|
||||
trades = this.parseTrades (rawTrades, market, undefined, undefined, { 'order': id });
|
||||
}
|
||||
return {
|
||||
'id': id,
|
||||
'clientOrderId': clientOrderId,
|
||||
@@ -1004,8 +1123,7 @@ module.exports = class kraken extends Exchange {
|
||||
'average': average,
|
||||
'remaining': remaining,
|
||||
'fee': fee,
|
||||
// 'trades': this.parseTrades (order['trades'], market),
|
||||
'trades': undefined,
|
||||
'trades': trades,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1026,16 +1144,129 @@ module.exports = class kraken extends Exchange {
|
||||
|
||||
async fetchOrder (id, symbol = undefined, params = {}) {
|
||||
await this.loadMarkets ();
|
||||
const response = await this.privatePostQueryOrders (this.extend ({
|
||||
const clientOrderId = this.safeValue2 (params, 'userref', 'clientOrderId');
|
||||
const request = {
|
||||
'trades': true, // whether or not to include trades in output (optional, default false)
|
||||
'txid': id, // do not comma separate a list of ids - use fetchOrdersByIds instead
|
||||
// 'txid': id, // do not comma separate a list of ids - use fetchOrdersByIds instead
|
||||
// 'userref': 'optional', // restrict results to given user reference id (optional)
|
||||
}, params));
|
||||
const orders = response['result'];
|
||||
};
|
||||
let query = params;
|
||||
if (clientOrderId !== undefined) {
|
||||
request['userref'] = clientOrderId;
|
||||
query = this.omit (params, [ 'userref', 'clientOrderId' ]);
|
||||
} else {
|
||||
request['txid'] = id;
|
||||
}
|
||||
const response = await this.privatePostQueryOrders (this.extend (request, query));
|
||||
//
|
||||
// {
|
||||
// "error":[],
|
||||
// "result":{
|
||||
// "OTLAS3-RRHUF-NDWH5A":{
|
||||
// "refid":null,
|
||||
// "userref":null,
|
||||
// "status":"closed",
|
||||
// "reason":null,
|
||||
// "opentm":1586822919.3342,
|
||||
// "closetm":1586822919.365,
|
||||
// "starttm":0,
|
||||
// "expiretm":0,
|
||||
// "descr":{
|
||||
// "pair":"XBTUSDT",
|
||||
// "type":"sell",
|
||||
// "ordertype":"market",
|
||||
// "price":"0",
|
||||
// "price2":"0",
|
||||
// "leverage":"none",
|
||||
// "order":"sell 0.21804000 XBTUSDT @ market",
|
||||
// "close":""
|
||||
// },
|
||||
// "vol":"0.21804000",
|
||||
// "vol_exec":"0.21804000",
|
||||
// "cost":"1493.9",
|
||||
// "fee":"3.8",
|
||||
// "price":"6851.5",
|
||||
// "stopprice":"0.00000",
|
||||
// "limitprice":"0.00000",
|
||||
// "misc":"",
|
||||
// "oflags":"fciq",
|
||||
// "trades":["TT5UC3-GOIRW-6AZZ6R"]
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
const orders = this.safeValue (response, 'result', []);
|
||||
const order = this.parseOrder (this.extend ({ 'id': id }, orders[id]));
|
||||
return this.extend ({ 'info': response }, order);
|
||||
}
|
||||
|
||||
async fetchOrderTrades (id, symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
||||
const orderTrades = this.safeValue (params, 'trades');
|
||||
const tradeIds = [];
|
||||
if (orderTrades === undefined) {
|
||||
throw new ArgumentsRequired (this.id + " fetchOrderTrades requires a unified order structure in the params argument or a 'trades' param (an array of trade id strings)");
|
||||
} else {
|
||||
for (let i = 0; i < orderTrades.length; i++) {
|
||||
const orderTrade = orderTrades[i];
|
||||
if (typeof orderTrade === 'string') {
|
||||
tradeIds.push (orderTrade);
|
||||
} else {
|
||||
tradeIds.push (orderTrade['id']);
|
||||
}
|
||||
}
|
||||
}
|
||||
await this.loadMarkets ();
|
||||
const options = this.safeValue (this.options, 'fetchOrderTrades', {});
|
||||
const batchSize = this.safeInteger (options, 'batchSize', 20);
|
||||
let numBatches = parseInt (tradeIds / batchSize);
|
||||
numBatches = this.sum (numBatches, 1);
|
||||
const numTradeIds = tradeIds.length;
|
||||
let result = [];
|
||||
for (let j = 0; j < numBatches; j++) {
|
||||
const requestIds = [];
|
||||
for (let k = 0; k < batchSize; k++) {
|
||||
const index = this.sum (j * batchSize, k);
|
||||
if (index < numTradeIds) {
|
||||
requestIds.push (tradeIds[index]);
|
||||
}
|
||||
}
|
||||
const request = {
|
||||
'txid': requestIds.join (','),
|
||||
};
|
||||
const response = await this.privatePostQueryTrades (request);
|
||||
//
|
||||
// {
|
||||
// error: [],
|
||||
// result: {
|
||||
// 'TIMIRG-WUNNE-RRJ6GT': {
|
||||
// ordertxid: 'OQRPN2-LRHFY-HIFA7D',
|
||||
// postxid: 'TKH2SE-M7IF5-CFI7LT',
|
||||
// pair: 'USDCUSDT',
|
||||
// time: 1586340086.457,
|
||||
// type: 'sell',
|
||||
// ordertype: 'market',
|
||||
// price: '0.99860000',
|
||||
// cost: '22.16892001',
|
||||
// fee: '0.04433784',
|
||||
// vol: '22.20000000',
|
||||
// margin: '0.00000000',
|
||||
// misc: ''
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
const rawTrades = this.safeValue (response, 'result');
|
||||
const ids = Object.keys (rawTrades);
|
||||
for (let i = 0; i < ids.length; i++) {
|
||||
rawTrades[ids[i]]['id'] = ids[i];
|
||||
}
|
||||
const trades = this.parseTrades (rawTrades, undefined, since, limit);
|
||||
const tradesFilteredBySymbol = this.filterBySymbol (trades, symbol);
|
||||
result = this.arrayConcat (result, tradesFilteredBySymbol);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
async fetchOrdersByIds (ids, symbol = undefined, params = {}) {
|
||||
await this.loadMarkets ();
|
||||
const response = await this.privatePostQueryOrders (this.extend ({
|
||||
@@ -1248,11 +1479,11 @@ module.exports = class kraken extends Exchange {
|
||||
}
|
||||
|
||||
async fetchDeposits (code = undefined, since = undefined, limit = undefined, params = {}) {
|
||||
await this.loadMarkets ();
|
||||
// https://www.kraken.com/en-us/help/api#deposit-status
|
||||
if (code === undefined) {
|
||||
throw new ArgumentsRequired (this.id + ' fetchDeposits requires a currency code argument');
|
||||
}
|
||||
await this.loadMarkets ();
|
||||
const currency = this.currency (code);
|
||||
const request = {
|
||||
'asset': currency['id'],
|
||||
@@ -1275,11 +1506,11 @@ module.exports = class kraken extends Exchange {
|
||||
}
|
||||
|
||||
async fetchWithdrawals (code = undefined, since = undefined, limit = undefined, params = {}) {
|
||||
await this.loadMarkets ();
|
||||
// https://www.kraken.com/en-us/help/api#withdraw-status
|
||||
if (code === undefined) {
|
||||
throw new ArgumentsRequired (this.id + ' fetchWithdrawals requires a currency code argument');
|
||||
}
|
||||
await this.loadMarkets ();
|
||||
const currency = this.currency (code);
|
||||
const request = {
|
||||
'asset': currency['id'],
|
||||
@@ -1328,7 +1559,7 @@ module.exports = class kraken extends Exchange {
|
||||
}
|
||||
method = this.options['depositMethods'][code][0]['method'];
|
||||
} else {
|
||||
throw new ExchangeError (this.id + ' fetchDepositAddress() requires an extra `method` parameter. Use fetchDepositMethods ("' + code + '") to get a list of available deposit methods or enable the exchange property .options["cacheDepositMethodsOnFetchDepositAddress"] = true');
|
||||
throw new ArgumentsRequired (this.id + ' fetchDepositAddress() requires an extra `method` parameter. Use fetchDepositMethods ("' + code + '") to get a list of available deposit methods or enable the exchange property .options["cacheDepositMethodsOnFetchDepositAddress"] = true');
|
||||
}
|
||||
}
|
||||
const request = {
|
||||
|
||||
+121
-41
@@ -69,7 +69,9 @@ module.exports = class kucoin extends Exchange {
|
||||
'public': {
|
||||
'get': [
|
||||
'timestamp',
|
||||
'status',
|
||||
'symbols',
|
||||
'markets',
|
||||
'market/allTickers',
|
||||
'market/orderbook/level{level}',
|
||||
'market/orderbook/level2',
|
||||
@@ -81,6 +83,9 @@ module.exports = class kucoin extends Exchange {
|
||||
'market/stats',
|
||||
'currencies',
|
||||
'currencies/{currency}',
|
||||
'prices',
|
||||
'mark-price/{symbol}/current',
|
||||
'margin/config',
|
||||
],
|
||||
'post': [
|
||||
'bullet-public',
|
||||
@@ -92,6 +97,10 @@ module.exports = class kucoin extends Exchange {
|
||||
'accounts/{accountId}',
|
||||
'accounts/{accountId}/ledgers',
|
||||
'accounts/{accountId}/holds',
|
||||
'accounts/transferable',
|
||||
'sub/user',
|
||||
'sub-accounts',
|
||||
'sub-accounts/{subUserId}',
|
||||
'deposit-addresses',
|
||||
'deposits',
|
||||
'hist-deposits',
|
||||
@@ -101,8 +110,20 @@ module.exports = class kucoin extends Exchange {
|
||||
'withdrawals/quotas',
|
||||
'orders',
|
||||
'orders/{orderId}',
|
||||
'limit/orders',
|
||||
'fills',
|
||||
'limit/fills',
|
||||
'margin/account',
|
||||
'margin/borrow',
|
||||
'margin/borrow/outstanding',
|
||||
'margin/borrow/borrow/repaid',
|
||||
'margin/lend/active',
|
||||
'margin/lend/done',
|
||||
'margin/lend/trade/unsettled',
|
||||
'margin/lend/trade/settled',
|
||||
'margin/lend/assets',
|
||||
'margin/market',
|
||||
'margin/margin/trade/last',
|
||||
],
|
||||
'post': [
|
||||
'accounts',
|
||||
@@ -111,11 +132,19 @@ module.exports = class kucoin extends Exchange {
|
||||
'deposit-addresses',
|
||||
'withdrawals',
|
||||
'orders',
|
||||
'orders/multi',
|
||||
'margin/borrow',
|
||||
'margin/repay/all',
|
||||
'margin/repay/single',
|
||||
'margin/lend',
|
||||
'margin/toggle-auto-lend',
|
||||
'bullet-private',
|
||||
],
|
||||
'delete': [
|
||||
'withdrawals/{withdrawalId}',
|
||||
'orders',
|
||||
'orders/{orderId}',
|
||||
'margin/lend/{orderId}',
|
||||
],
|
||||
},
|
||||
},
|
||||
@@ -247,18 +276,20 @@ module.exports = class kucoin extends Exchange {
|
||||
async fetchMarkets (params = {}) {
|
||||
const response = await this.publicGetSymbols (params);
|
||||
//
|
||||
// { quoteCurrency: 'BTC',
|
||||
// symbol: 'KCS-BTC',
|
||||
// quoteMaxSize: '9999999',
|
||||
// quoteIncrement: '0.000001',
|
||||
// baseMinSize: '0.01',
|
||||
// quoteMinSize: '0.00001',
|
||||
// enableTrading: true,
|
||||
// priceIncrement: '0.00000001',
|
||||
// name: 'KCS-BTC',
|
||||
// baseIncrement: '0.01',
|
||||
// baseMaxSize: '9999999',
|
||||
// baseCurrency: 'KCS' }
|
||||
// {
|
||||
// quoteCurrency: 'BTC',
|
||||
// symbol: 'KCS-BTC',
|
||||
// quoteMaxSize: '9999999',
|
||||
// quoteIncrement: '0.000001',
|
||||
// baseMinSize: '0.01',
|
||||
// quoteMinSize: '0.00001',
|
||||
// enableTrading: true,
|
||||
// priceIncrement: '0.00000001',
|
||||
// name: 'KCS-BTC',
|
||||
// baseIncrement: '0.01',
|
||||
// baseMaxSize: '9999999',
|
||||
// baseCurrency: 'KCS'
|
||||
// }
|
||||
//
|
||||
const data = response['data'];
|
||||
const result = [];
|
||||
@@ -344,20 +375,27 @@ module.exports = class kucoin extends Exchange {
|
||||
async fetchAccounts (params = {}) {
|
||||
const response = await this.privateGetAccounts (params);
|
||||
//
|
||||
// { code: "200000",
|
||||
// data: [ { balance: "0.00009788",
|
||||
// {
|
||||
// code: "200000",
|
||||
// data: [
|
||||
// {
|
||||
// balance: "0.00009788",
|
||||
// available: "0.00009788",
|
||||
// holds: "0",
|
||||
// currency: "BTC",
|
||||
// id: "5c6a4fd399a1d81c4f9cc4d0",
|
||||
// type: "trade" },
|
||||
// ...,
|
||||
// { balance: "0.00000001",
|
||||
// holds: "0",
|
||||
// currency: "BTC",
|
||||
// id: "5c6a4fd399a1d81c4f9cc4d0",
|
||||
// type: "trade"
|
||||
// },
|
||||
// {
|
||||
// balance: "0.00000001",
|
||||
// available: "0.00000001",
|
||||
// holds: "0",
|
||||
// currency: "ETH",
|
||||
// id: "5c6a49ec99a1d819392e8e9f",
|
||||
// type: "trade" } ] }
|
||||
// holds: "0",
|
||||
// currency: "ETH",
|
||||
// id: "5c6a49ec99a1d819392e8e9f",
|
||||
// type: "trade"
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
//
|
||||
const data = this.safeValue (response, 'data');
|
||||
const result = [];
|
||||
@@ -641,30 +679,72 @@ module.exports = class kucoin extends Exchange {
|
||||
};
|
||||
}
|
||||
|
||||
async fetchL3OrderBook (symbol, limit = undefined, params = {}) {
|
||||
return await this.fetchOrderBook (symbol, limit, { 'level': 3 });
|
||||
}
|
||||
|
||||
async fetchOrderBook (symbol, limit = undefined, params = {}) {
|
||||
let level = '2';
|
||||
if (limit !== undefined) {
|
||||
if ((limit !== 20) && (limit !== 100)) {
|
||||
throw new ExchangeError (this.id + ' fetchOrderBook limit argument must be undefined, 20 or 100');
|
||||
const level = this.safeInteger (params, 'level', 2);
|
||||
let levelLimit = level.toString ();
|
||||
if (level === '2') {
|
||||
if (limit !== undefined) {
|
||||
if ((limit !== 20) && (limit !== 100)) {
|
||||
throw new ExchangeError (this.id + ' fetchOrderBook limit argument must be undefined, 20 or 100');
|
||||
}
|
||||
levelLimit += '_' + limit.toString ();
|
||||
}
|
||||
level += '_' + limit.toString ();
|
||||
}
|
||||
await this.loadMarkets ();
|
||||
const marketId = this.marketId (symbol);
|
||||
const request = this.extend ({ 'symbol': marketId, 'level': level }, params);
|
||||
const response = await this.publicGetMarketOrderbookLevelLevel (request);
|
||||
const request = { 'symbol': marketId, 'level': levelLimit };
|
||||
const response = await this.publicGetMarketOrderbookLevelLevel (this.extend (request, params));
|
||||
//
|
||||
// { sequence: '1547731421688',
|
||||
// asks: [ [ '5c419328ef83c75456bd615c', '0.9', '0.09' ], ... ],
|
||||
// bids: [ [ '5c419328ef83c75456bd615c', '0.9', '0.09' ], ... ], }
|
||||
// 'market/orderbook/level2'
|
||||
// 'market/orderbook/level2_20'
|
||||
// 'market/orderbook/level2_100'
|
||||
//
|
||||
const data = response['data'];
|
||||
// {
|
||||
// "code":"200000",
|
||||
// "data":{
|
||||
// "sequence":"1583235112106",
|
||||
// "asks":[
|
||||
// // ...
|
||||
// ["0.023197","12.5067468"],
|
||||
// ["0.023194","1.8"],
|
||||
// ["0.023191","8.1069672"]
|
||||
// ],
|
||||
// "bids":[
|
||||
// ["0.02319","1.6000002"],
|
||||
// ["0.023189","2.2842325"],
|
||||
// ],
|
||||
// "time":1586584067274
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// 'market/orderbook/level3'
|
||||
//
|
||||
// {
|
||||
// "code":"200000",
|
||||
// "data":{
|
||||
// "sequence":"1583731857120",
|
||||
// "asks":[
|
||||
// // id, price, size, timestamp in nanoseconds
|
||||
// ["5e915f8acd26670009675300","6925.7","0.2","1586585482194286069"],
|
||||
// ["5e915f8ace35a200090bba48","6925.7","0.001","1586585482229569826"],
|
||||
// ["5e915f8a8857740009ca7d33","6926","0.00001819","1586585482149148621"],
|
||||
// ],
|
||||
// "bids":[
|
||||
// ["5e915f8acca406000ac88194","6925.6","0.05","1586585482384384842"],
|
||||
// ["5e915f93cd26670009676075","6925.6","0.08","1586585491334914600"],
|
||||
// ["5e915f906aa6e200099b49f6","6925.4","0.2","1586585488941126340"],
|
||||
// ],
|
||||
// "time":1586585492487
|
||||
// }
|
||||
// }
|
||||
//
|
||||
const data = this.safeValue (response, 'data', {});
|
||||
const timestamp = this.safeInteger (data, 'time');
|
||||
// level can be a string such as 2_20 or 2_100
|
||||
const levelString = this.safeString (request, 'level');
|
||||
const levelParts = levelString.split ('_');
|
||||
const offset = parseInt (levelParts[0]);
|
||||
const orderbook = this.parseOrderBook (data, timestamp, 'bids', 'asks', offset - 2, offset - 1);
|
||||
const orderbook = this.parseOrderBook (data, timestamp, 'bids', 'asks', level - 2, level - 1);
|
||||
orderbook['nonce'] = this.safeInteger (data, 'sequence');
|
||||
return orderbook;
|
||||
}
|
||||
@@ -715,7 +795,7 @@ module.exports = class kucoin extends Exchange {
|
||||
'datetime': this.iso8601 (timestamp),
|
||||
'fee': undefined,
|
||||
'status': 'open',
|
||||
'clientOid': clientOid,
|
||||
'clientOrderId': clientOid,
|
||||
'info': data,
|
||||
};
|
||||
if (!this.safeValue (params, 'quoteAmount')) {
|
||||
|
||||
+21
-1
@@ -18,11 +18,12 @@ module.exports = class kuna extends acx {
|
||||
'has': {
|
||||
'CORS': false,
|
||||
'fetchTickers': true,
|
||||
'fetchOHLCV': false,
|
||||
'fetchOHLCV': 'emulated',
|
||||
'fetchOpenOrders': true,
|
||||
'fetchMyTrades': true,
|
||||
'withdraw': false,
|
||||
},
|
||||
'timeframes': undefined,
|
||||
'urls': {
|
||||
'referral': 'https://kuna.io?r=kunaid-gvfihe8az7o4',
|
||||
'logo': 'https://user-images.githubusercontent.com/1294454/31697638-912824fa-b3c1-11e7-8c36-cf9606eb94ac.jpg',
|
||||
@@ -191,4 +192,23 @@ module.exports = class kuna extends acx {
|
||||
const response = await this.privateGetTradesMy (this.extend (request, params));
|
||||
return this.parseTrades (response, market, since, limit);
|
||||
}
|
||||
|
||||
async fetchOHLCV (symbol, timeframe = '1m', since = undefined, limits = undefined, params = {}) {
|
||||
await this.loadMarkets ();
|
||||
const trades = await this.fetchTrades (symbol, since, limits, params);
|
||||
const ohlcvc = this.buildOHLCVC (trades, timeframe, since, limits);
|
||||
const result = [];
|
||||
for (let i = 0; i < ohlcvc.length; i++) {
|
||||
const ohlcv = ohlcvc[i];
|
||||
result.push ([
|
||||
ohlcv[0],
|
||||
ohlcv[1],
|
||||
ohlcv[2],
|
||||
ohlcv[3],
|
||||
ohlcv[4],
|
||||
ohlcv[5],
|
||||
]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
+59
-22
@@ -3,7 +3,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const Exchange = require ('./base/Exchange');
|
||||
const { ExchangeError } = require ('./base/errors');
|
||||
const { ExchangeError, AuthenticationError, BadSymbol, InvalidOrder, InsufficientFunds } = require ('./base/errors');
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -14,6 +14,7 @@ module.exports = class lakebtc extends Exchange {
|
||||
'name': 'LakeBTC',
|
||||
'countries': [ 'US' ],
|
||||
'version': 'api_v2',
|
||||
'rateLimit': 1000,
|
||||
'has': {
|
||||
'CORS': true,
|
||||
'createMarketOrder': false,
|
||||
@@ -55,6 +56,14 @@ module.exports = class lakebtc extends Exchange {
|
||||
'taker': 0.2 / 100,
|
||||
},
|
||||
},
|
||||
'exceptions': {
|
||||
'broad': {
|
||||
'Signature': AuthenticationError,
|
||||
'invalid symbol': BadSymbol,
|
||||
'Volume doit': InvalidOrder,
|
||||
'insufficient_balance': InsufficientFunds,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -248,40 +257,68 @@ module.exports = class lakebtc extends Exchange {
|
||||
} else {
|
||||
this.checkRequiredCredentials ();
|
||||
const nonce = this.nonce ();
|
||||
const nonceAsString = nonce.toString ();
|
||||
const requestId = this.seconds ();
|
||||
let queryParams = '';
|
||||
if ('params' in params) {
|
||||
const paramsList = params['params'];
|
||||
queryParams = paramsList.join (',');
|
||||
const stringParams = [];
|
||||
for (let i = 0; i < paramsList.length; i++) {
|
||||
let param = paramsList[i];
|
||||
if (typeof paramsList !== 'string') {
|
||||
param = param.toString ();
|
||||
}
|
||||
stringParams.push (param);
|
||||
}
|
||||
queryParams = stringParams.join (',');
|
||||
body = {
|
||||
'method': path,
|
||||
'params': params['params'],
|
||||
'id': requestId,
|
||||
};
|
||||
} else {
|
||||
body = {
|
||||
'method': path,
|
||||
'params': '',
|
||||
'id': requestId,
|
||||
};
|
||||
}
|
||||
const query = this.urlencode ({
|
||||
'tonce': nonce,
|
||||
'accesskey': this.apiKey,
|
||||
'requestmethod': method.toLowerCase (),
|
||||
'id': nonce,
|
||||
'method': path,
|
||||
'params': queryParams,
|
||||
});
|
||||
body = this.json ({
|
||||
'method': path,
|
||||
'params': queryParams,
|
||||
'id': nonce,
|
||||
});
|
||||
body = this.json (body);
|
||||
let query = [
|
||||
'tonce=' + nonceAsString,
|
||||
'accesskey=' + this.apiKey,
|
||||
'requestmethod=' + method.toLowerCase (),
|
||||
'id=' + requestId.toString (),
|
||||
'method=' + path,
|
||||
'params=' + queryParams,
|
||||
];
|
||||
query = query.join ('&');
|
||||
const signature = this.hmac (this.encode (query), this.encode (this.secret), 'sha1');
|
||||
const auth = this.encode (this.apiKey + ':' + signature);
|
||||
const signature64 = this.decode (this.stringToBase64 (auth));
|
||||
headers = {
|
||||
'Json-Rpc-Tonce': nonce.toString (),
|
||||
'Authorization': 'Basic ' + this.decode (this.stringToBase64 (auth)),
|
||||
'Json-Rpc-Tonce': nonceAsString,
|
||||
'Authorization': 'Basic ' + signature64,
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
}
|
||||
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
||||
}
|
||||
|
||||
async request (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
||||
const response = await this.fetch2 (path, api, method, params, headers, body);
|
||||
if ('error' in response) {
|
||||
throw new ExchangeError (this.id + ' ' + this.json (response));
|
||||
handleErrors (code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
|
||||
if (response === undefined) {
|
||||
return; // fallback to the default error handler
|
||||
}
|
||||
//
|
||||
// {"error":"Failed to submit order: invalid symbol"}
|
||||
// {"error":"Failed to submit order: La validation a échoué : Volume doit être supérieur ou égal à 1.0"}
|
||||
// {"error":"Failed to submit order: insufficient_balance"}
|
||||
//
|
||||
const feedback = this.id + ' ' + body;
|
||||
const error = this.safeString (response, 'error');
|
||||
if (error !== undefined) {
|
||||
this.throwBroadlyMatchedException (this.exceptions['broad'], error, feedback);
|
||||
throw new ExchangeError (feedback); // unknown message
|
||||
}
|
||||
return response;
|
||||
}
|
||||
};
|
||||
+3
-3
@@ -3,7 +3,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const Exchange = require ('./base/Exchange');
|
||||
const { ExchangeError, DDoSProtection, AuthenticationError, InvalidOrder } = require ('./base/errors');
|
||||
const { ExchangeError, DDoSProtection, AuthenticationError, InvalidOrder, ArgumentsRequired } = require ('./base/errors');
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -339,10 +339,10 @@ module.exports = class lbank extends Exchange {
|
||||
await this.loadMarkets ();
|
||||
const market = this.market (symbol);
|
||||
if (since === undefined) {
|
||||
throw new ExchangeError (this.id + ' fetchOHLCV requires a `since` argument');
|
||||
throw new ArgumentsRequired (this.id + ' fetchOHLCV requires a `since` argument');
|
||||
}
|
||||
if (limit === undefined) {
|
||||
throw new ExchangeError (this.id + ' fetchOHLCV requires a `limit` argument');
|
||||
throw new ArgumentsRequired (this.id + ' fetchOHLCV requires a `limit` argument');
|
||||
}
|
||||
const request = {
|
||||
'symbol': market['id'],
|
||||
|
||||
+64
-8
@@ -177,7 +177,7 @@ module.exports = class liquid extends Exchange {
|
||||
}
|
||||
|
||||
async fetchMarkets (params = {}) {
|
||||
const markets = await this.publicGetProducts ();
|
||||
const spot = await this.publicGetProducts (params);
|
||||
//
|
||||
// [
|
||||
// {
|
||||
@@ -208,20 +208,69 @@ module.exports = class liquid extends Exchange {
|
||||
// },
|
||||
// ]
|
||||
//
|
||||
const perpetual = await this.publicGetProducts ({ 'perpetual': '1' });
|
||||
//
|
||||
// [
|
||||
// {
|
||||
// "id": "603",
|
||||
// "product_type": "Perpetual",
|
||||
// "code": "CASH",
|
||||
// "name": null,
|
||||
// "market_ask": "1143900",
|
||||
// "market_bid": "1143250",
|
||||
// "currency": "JPY",
|
||||
// "currency_pair_code": "P-BTCJPY",
|
||||
// "pusher_channel": "product_cash_p-btcjpy_603",
|
||||
// "taker_fee": "0.0",
|
||||
// "maker_fee": "0.0",
|
||||
// "low_market_bid": "1124450.0",
|
||||
// "high_market_ask": "1151750.0",
|
||||
// "volume_24h": "0.1756",
|
||||
// "last_price_24h": "1129850.0",
|
||||
// "last_traded_price": "1144700.0",
|
||||
// "last_traded_quantity": "0.014",
|
||||
// "quoted_currency": "JPY",
|
||||
// "base_currency": "P-BTC",
|
||||
// "tick_size": "50.0",
|
||||
// "perpetual_enabled": true,
|
||||
// "index_price": "1142636.03935",
|
||||
// "mark_price": "1143522.18417",
|
||||
// "funding_rate": "0.00033",
|
||||
// "fair_price": "1143609.31009",
|
||||
// "timestamp": "1581558659.195353100",
|
||||
// },
|
||||
// ]
|
||||
//
|
||||
const currencies = await this.fetchCurrencies ();
|
||||
const currenciesByCode = this.indexBy (currencies, 'code');
|
||||
const result = [];
|
||||
const markets = this.arrayConcat (spot, perpetual);
|
||||
for (let i = 0; i < markets.length; i++) {
|
||||
const market = markets[i];
|
||||
const id = market['id'].toString ();
|
||||
const baseId = market['base_currency'];
|
||||
const quoteId = market['quoted_currency'];
|
||||
const id = this.safeString (market, 'id');
|
||||
const baseId = this.safeString (market, 'base_currency');
|
||||
const quoteId = this.safeString (market, 'quoted_currency');
|
||||
const productType = this.safeString (market, 'product_type');
|
||||
let type = 'spot';
|
||||
let spot = true;
|
||||
let swap = false;
|
||||
if (productType === 'Perpetual') {
|
||||
spot = false;
|
||||
swap = true;
|
||||
type = 'swap';
|
||||
}
|
||||
const base = this.safeCurrencyCode (baseId);
|
||||
const quote = this.safeCurrencyCode (quoteId);
|
||||
const symbol = base + '/' + quote;
|
||||
let symbol = undefined;
|
||||
if (swap) {
|
||||
symbol = this.safeString (market, 'currency_pair_code');
|
||||
} else {
|
||||
symbol = base + '/' + quote;
|
||||
}
|
||||
const maker = this.safeFloat (market, 'maker_fee');
|
||||
const taker = this.safeFloat (market, 'taker_fee');
|
||||
const active = !market['disabled'];
|
||||
const disabled = this.safeValue (market, 'disabled', false);
|
||||
const active = !disabled;
|
||||
const baseCurrency = this.safeValue (currenciesByCode, base);
|
||||
const quoteCurrency = this.safeValue (currenciesByCode, quote);
|
||||
const precision = {
|
||||
@@ -265,6 +314,9 @@ module.exports = class liquid extends Exchange {
|
||||
'quote': quote,
|
||||
'baseId': baseId,
|
||||
'quoteId': quoteId,
|
||||
'type': type,
|
||||
'spot': spot,
|
||||
'swap': swap,
|
||||
'maker': maker,
|
||||
'taker': taker,
|
||||
'limits': limits,
|
||||
@@ -393,7 +445,7 @@ module.exports = class liquid extends Exchange {
|
||||
return this.parseTicker (response, market);
|
||||
}
|
||||
|
||||
parseTrade (trade, market) {
|
||||
parseTrade (trade, market = undefined) {
|
||||
// { id: 12345,
|
||||
// quantity: "6.789",
|
||||
// price: "98765.4321",
|
||||
@@ -420,13 +472,17 @@ module.exports = class liquid extends Exchange {
|
||||
}
|
||||
}
|
||||
const id = this.safeString (trade, 'id');
|
||||
let symbol = undefined;
|
||||
if (market !== undefined) {
|
||||
symbol = market['symbol'];
|
||||
}
|
||||
return {
|
||||
'info': trade,
|
||||
'id': id,
|
||||
'order': orderId,
|
||||
'timestamp': timestamp,
|
||||
'datetime': this.iso8601 (timestamp),
|
||||
'symbol': market['symbol'],
|
||||
'symbol': symbol,
|
||||
'type': undefined,
|
||||
'side': side,
|
||||
'takerOrMaker': takerOrMaker,
|
||||
|
||||
+19
-7
@@ -439,7 +439,18 @@ module.exports = class livecoin extends Exchange {
|
||||
}
|
||||
}
|
||||
let symbol = undefined;
|
||||
if (market !== undefined) {
|
||||
const marketId = this.safeString (trade, 'symbol');
|
||||
if (marketId !== undefined) {
|
||||
if (marketId in this.markets_by_id) {
|
||||
market = this.markets_by_id[marketId];
|
||||
} else {
|
||||
const [ baseId, quoteId ] = marketId.split ('/');
|
||||
const base = this.safeCurrencyCode (baseId);
|
||||
const quote = this.safeCurrencyCode (quoteId);
|
||||
symbol = base + '/' + quote;
|
||||
}
|
||||
}
|
||||
if ((symbol === undefined) && (market !== undefined)) {
|
||||
symbol = market['symbol'];
|
||||
}
|
||||
return {
|
||||
@@ -460,16 +471,17 @@ module.exports = class livecoin extends Exchange {
|
||||
}
|
||||
|
||||
async fetchMyTrades (symbol = undefined, since = undefined, limit = undefined, params = {}) {
|
||||
if (symbol === undefined) {
|
||||
throw new ArgumentsRequired (this.id + ' fetchMyTrades requires a symbol argument');
|
||||
}
|
||||
await this.loadMarkets ();
|
||||
const market = this.market (symbol);
|
||||
const request = {
|
||||
'currencyPair': market['id'],
|
||||
// orderDesc': 'true', // or 'false', if true then new orders will be first, otherwise old orders will be first.
|
||||
// 'currencyPair': market['id'],
|
||||
// 'orderDesc': 'true', // or 'false', if true then new orders will be first, otherwise old orders will be first.
|
||||
// 'offset': 0, // page offset, position of the first item on the page
|
||||
};
|
||||
let market = undefined;
|
||||
if (symbol !== undefined) {
|
||||
market = this.market (symbol);
|
||||
request['currencyPair'] = market['id'];
|
||||
}
|
||||
if (limit !== undefined) {
|
||||
request['limit'] = limit;
|
||||
}
|
||||
|
||||
+3
-3
@@ -399,17 +399,17 @@ module.exports = class mercado extends Exchange {
|
||||
if (code === 'BRL') {
|
||||
const account_ref = ('account_ref' in params);
|
||||
if (!account_ref) {
|
||||
throw new ExchangeError (this.id + ' requires account_ref parameter to withdraw ' + code);
|
||||
throw new ArgumentsRequired (this.id + ' requires account_ref parameter to withdraw ' + code);
|
||||
}
|
||||
} else if (code !== 'LTC') {
|
||||
const tx_fee = ('tx_fee' in params);
|
||||
if (!tx_fee) {
|
||||
throw new ExchangeError (this.id + ' requires tx_fee parameter to withdraw ' + code);
|
||||
throw new ArgumentsRequired (this.id + ' requires tx_fee parameter to withdraw ' + code);
|
||||
}
|
||||
if (code === 'XRP') {
|
||||
if (tag === undefined) {
|
||||
if (!('destination_tag' in params)) {
|
||||
throw new ExchangeError (this.id + ' requires a tag argument or destination_tag parameter to withdraw ' + code);
|
||||
throw new ArgumentsRequired (this.id + ' requires a tag argument or destination_tag parameter to withdraw ' + code);
|
||||
}
|
||||
} else {
|
||||
request['destination_tag'] = tag;
|
||||
|
||||
+27
-40
@@ -3,7 +3,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const Exchange = require ('./base/Exchange');
|
||||
const { ExchangeError, ExchangeNotAvailable, ArgumentsRequired, BadRequest, AccountSuspended, InvalidAddress, PermissionDenied, DDoSProtection, InsufficientFunds, InvalidNonce, CancelPending, InvalidOrder, OrderNotFound, AuthenticationError, RequestTimeout, NotSupported, BadSymbol } = require ('./base/errors');
|
||||
const { ExchangeError, ExchangeNotAvailable, OnMaintenance, ArgumentsRequired, BadRequest, AccountSuspended, InvalidAddress, PermissionDenied, DDoSProtection, InsufficientFunds, InvalidNonce, CancelPending, InvalidOrder, OrderNotFound, AuthenticationError, RequestTimeout, NotSupported, BadSymbol } = require ('./base/errors');
|
||||
const { TICK_SIZE, TRUNCATE } = require ('./base/functions/number');
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -61,6 +61,9 @@ module.exports = class okex extends Exchange {
|
||||
'doc': 'https://www.okex.com/docs/en/',
|
||||
'fees': 'https://www.okex.com/pages/products/fees.html',
|
||||
'referral': 'https://www.okex.com/join/1888677',
|
||||
'test': {
|
||||
'rest': 'https://testnet.okex.com',
|
||||
},
|
||||
},
|
||||
'api': {
|
||||
'general': {
|
||||
@@ -348,8 +351,9 @@ module.exports = class okex extends Exchange {
|
||||
'30034': ExchangeError, // { "code": 30034, "message": "exchange ID does not exist" }
|
||||
'30035': ExchangeError, // { "code": 30035, "message": "trading is not supported in this website" }
|
||||
'30036': ExchangeError, // { "code": 30036, "message": "no relevant data" }
|
||||
'30038': AuthenticationError, // { "code": 30038, "message": "user does not exist" }
|
||||
'30037': ExchangeNotAvailable, // { "code": 30037, "message": "endpoint is offline or unavailable" }
|
||||
// '30038': AuthenticationError, // { "code": 30038, "message": "user does not exist" }
|
||||
'30038': OnMaintenance, // {"client_oid":"","code":"30038","error_code":"30038","error_message":"Matching engine is being upgraded. Please try in about 1 minute.","message":"Matching engine is being upgraded. Please try in about 1 minute.","order_id":"-1","result":false}
|
||||
// futures
|
||||
'32001': AccountSuspended, // { "code": 32001, "message": "futures account suspended" }
|
||||
'32002': PermissionDenied, // { "code": 32002, "message": "futures account does not exist" }
|
||||
@@ -792,14 +796,6 @@ module.exports = class okex extends Exchange {
|
||||
'price': this.safeFloat (market, 'tick_size'),
|
||||
};
|
||||
const minAmount = this.safeFloat2 (market, 'min_size', 'base_min_size');
|
||||
let minPrice = this.safeFloat (market, 'tick_size');
|
||||
if (precision['price'] !== undefined) {
|
||||
minPrice = Math.pow (10, -precision['price']);
|
||||
}
|
||||
let minCost = undefined;
|
||||
if (minAmount !== undefined && minPrice !== undefined) {
|
||||
minCost = minAmount * minPrice;
|
||||
}
|
||||
const active = true;
|
||||
const fees = this.safeValue2 (this.fees, marketType, 'trading', {});
|
||||
return this.extend (fees, {
|
||||
@@ -823,11 +819,11 @@ module.exports = class okex extends Exchange {
|
||||
'max': undefined,
|
||||
},
|
||||
'price': {
|
||||
'min': minPrice,
|
||||
'min': precision['price'],
|
||||
'max': undefined,
|
||||
},
|
||||
'cost': {
|
||||
'min': minCost,
|
||||
'min': precision['price'],
|
||||
'max': undefined,
|
||||
},
|
||||
},
|
||||
@@ -1360,8 +1356,18 @@ module.exports = class okex extends Exchange {
|
||||
'instrument_id': market['id'],
|
||||
'granularity': this.timeframes[timeframe],
|
||||
};
|
||||
const duration = this.parseTimeframe (timeframe);
|
||||
if (since !== undefined) {
|
||||
if (limit !== undefined) {
|
||||
request['end'] = this.iso8601 (this.sum (since, limit * duration * 1000));
|
||||
}
|
||||
request['start'] = this.iso8601 (since);
|
||||
} else {
|
||||
const now = this.milliseconds ();
|
||||
if (limit !== undefined) {
|
||||
request['start'] = this.iso8601 (now - limit * duration * 1000);
|
||||
request['end'] = this.iso8601 (now);
|
||||
}
|
||||
}
|
||||
const response = await this[method] (this.extend (request, params));
|
||||
//
|
||||
@@ -1841,28 +1847,7 @@ module.exports = class okex extends Exchange {
|
||||
// "result":true
|
||||
// }
|
||||
//
|
||||
const timestamp = this.milliseconds ();
|
||||
const id = this.safeString (response, 'order_id');
|
||||
return {
|
||||
'info': response,
|
||||
'id': id,
|
||||
'timestamp': timestamp,
|
||||
'datetime': this.iso8601 (timestamp),
|
||||
'lastTradeTimestamp': undefined,
|
||||
'status': undefined,
|
||||
'symbol': symbol,
|
||||
'type': type,
|
||||
'side': side,
|
||||
'price': price,
|
||||
'amount': amount,
|
||||
'filled': undefined,
|
||||
'remaining': undefined,
|
||||
'cost': undefined,
|
||||
'trades': undefined,
|
||||
'fee': undefined,
|
||||
'clientOrderId': undefined,
|
||||
'average': undefined,
|
||||
};
|
||||
return this.parseOrder (response, market);
|
||||
}
|
||||
|
||||
async cancelOrder (id, symbol = undefined, params = {}) {
|
||||
@@ -2302,9 +2287,11 @@ module.exports = class okex extends Exchange {
|
||||
}
|
||||
|
||||
parseDepositAddresses (addresses) {
|
||||
const result = [];
|
||||
const result = {};
|
||||
for (let i = 0; i < addresses.length; i++) {
|
||||
result.push (this.parseDepositAddress (addresses[i]));
|
||||
const address = this.parseDepositAddress (addresses[i]);
|
||||
const code = address['currency'];
|
||||
result[code] = address;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -2350,11 +2337,11 @@ module.exports = class okex extends Exchange {
|
||||
// ]
|
||||
//
|
||||
const addresses = this.parseDepositAddresses (response);
|
||||
const numAddresses = addresses.length;
|
||||
if (numAddresses < 1) {
|
||||
const address = this.safeValue (addresses, code);
|
||||
if (address === undefined) {
|
||||
throw new InvalidAddress (this.id + ' fetchDepositAddress cannot return nonexistent addresses, you should create withdrawal addresses with the exchange website first');
|
||||
}
|
||||
return addresses[0];
|
||||
return address;
|
||||
}
|
||||
|
||||
async withdraw (code, amount, address, tag = undefined, params = {}) {
|
||||
@@ -2366,7 +2353,7 @@ module.exports = class okex extends Exchange {
|
||||
}
|
||||
const fee = this.safeString (params, 'fee');
|
||||
if (fee === undefined) {
|
||||
throw new ExchangeError (this.id + " withdraw() requires a `fee` string parameter, network transaction fee must be ≥ 0. Withdrawals to OKCoin or OKEx are fee-free, please set '0'. Withdrawing to external digital asset address requires network transaction fee.");
|
||||
throw new ArgumentsRequired (this.id + " withdraw() requires a `fee` string parameter, network transaction fee must be ≥ 0. Withdrawals to OKCoin or OKEx are fee-free, please set '0'. Withdrawing to external digital asset address requires network transaction fee.");
|
||||
}
|
||||
const request = {
|
||||
'currency': currency['id'],
|
||||
|
||||
+18
-11
@@ -27,6 +27,7 @@ module.exports = class paymium extends Exchange {
|
||||
'https://github.com/Paymium/api-documentation',
|
||||
'https://www.paymium.com/page/developers',
|
||||
],
|
||||
'referral': 'https://www.paymium.com/page/sign-up?referral=eDAzPoRQFMvaAB8sf-qj',
|
||||
},
|
||||
'api': {
|
||||
'public': {
|
||||
@@ -41,12 +42,12 @@ module.exports = class paymium extends Exchange {
|
||||
},
|
||||
'private': {
|
||||
'get': [
|
||||
'merchant/get_payment/{UUID}',
|
||||
'merchant/get_payment/{uuid}',
|
||||
'user',
|
||||
'user/addresses',
|
||||
'user/addresses/{btc_address}',
|
||||
'user/orders',
|
||||
'user/orders/{UUID}',
|
||||
'user/orders/{uuid}',
|
||||
'user/price_alerts',
|
||||
],
|
||||
'post': [
|
||||
@@ -57,7 +58,7 @@ module.exports = class paymium extends Exchange {
|
||||
'merchant/create_payment',
|
||||
],
|
||||
'delete': [
|
||||
'user/orders/{UUID}/cancel',
|
||||
'user/orders/{uuid}/cancel',
|
||||
'user/price_alerts/{id}',
|
||||
],
|
||||
},
|
||||
@@ -204,9 +205,9 @@ module.exports = class paymium extends Exchange {
|
||||
|
||||
async cancelOrder (id, symbol = undefined, params = {}) {
|
||||
const request = {
|
||||
'UUID': id,
|
||||
'uuid': id,
|
||||
};
|
||||
return await this.privateDeleteUserOrdersUUIDCancel (this.extend (request, params));
|
||||
return await this.privateDeleteUserOrdersUuidCancel (this.extend (request, params));
|
||||
}
|
||||
|
||||
sign (path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
|
||||
@@ -220,18 +221,24 @@ module.exports = class paymium extends Exchange {
|
||||
this.checkRequiredCredentials ();
|
||||
const nonce = this.nonce ().toString ();
|
||||
let auth = nonce + url;
|
||||
headers = {
|
||||
'Api-Key': this.apiKey,
|
||||
'Api-Nonce': nonce,
|
||||
};
|
||||
if (method === 'POST') {
|
||||
if (Object.keys (query).length) {
|
||||
body = this.json (query);
|
||||
auth += body;
|
||||
headers['Content-Type'] = 'application/json';
|
||||
}
|
||||
} else {
|
||||
if (Object.keys (query).length) {
|
||||
const queryString = this.urlencode (query);
|
||||
auth += queryString;
|
||||
url += '?' + queryString;
|
||||
}
|
||||
}
|
||||
headers = {
|
||||
'Api-Key': this.apiKey,
|
||||
'Api-Signature': this.hmac (this.encode (auth), this.encode (this.secret)),
|
||||
'Api-Nonce': nonce,
|
||||
'Content-Type': 'application/json',
|
||||
};
|
||||
headers['Api-Signature'] = this.hmac (this.encode (auth), this.encode (this.secret));
|
||||
}
|
||||
return { 'url': url, 'method': method, 'body': body, 'headers': headers };
|
||||
}
|
||||
|
||||
+2
-1
@@ -3,7 +3,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const Exchange = require ('./base/Exchange');
|
||||
const { ExchangeError, ExchangeNotAvailable, RequestTimeout, AuthenticationError, PermissionDenied, DDoSProtection, InsufficientFunds, OrderNotFound, OrderNotCached, InvalidOrder, AccountSuspended, CancelPending, InvalidNonce } = require ('./base/errors');
|
||||
const { ExchangeError, ExchangeNotAvailable, RequestTimeout, AuthenticationError, PermissionDenied, DDoSProtection, InsufficientFunds, OrderNotFound, OrderNotCached, InvalidOrder, AccountSuspended, CancelPending, InvalidNonce, OnMaintenance } = require ('./base/errors');
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -170,6 +170,7 @@ module.exports = class poloniex extends Exchange {
|
||||
'Permission denied': PermissionDenied,
|
||||
'Connection timed out. Please try again.': RequestTimeout,
|
||||
'Internal error. Please try again.': ExchangeNotAvailable,
|
||||
'Currently in maintenance mode.': OnMaintenance,
|
||||
'Order not found, or you are not the person who placed it.': OrderNotFound,
|
||||
'Invalid API key/secret pair.': AuthenticationError,
|
||||
'Please do not make more than 8 API calls per second.': DDoSProtection,
|
||||
|
||||
-1
@@ -17,7 +17,6 @@ module.exports = async (exchange, symbol) => {
|
||||
'btcalpha', // issue with 404 on a documented endpoint https://travis-ci.org/ccxt/ccxt/builds/643930431#L2213
|
||||
'bitmex', // an issue with null values,to be resolved later
|
||||
'cex',
|
||||
'mandala',
|
||||
]
|
||||
|
||||
if (skippedExchanges.includes (exchange.id)) {
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ const log = require ('ololog')
|
||||
|
||||
module.exports = async (exchange) => {
|
||||
|
||||
const randomSymbols = exchange.symbols.sort (() => 0.5 - Math.random ()).slice (0, 2)
|
||||
const randomSymbols = exchange.symbols.slice ().sort (() => 0.5 - Math.random ()).slice (0, 2)
|
||||
const customExchangeParams = ([
|
||||
'yobit',
|
||||
'tidex',
|
||||
|
||||
-1
@@ -14,7 +14,6 @@ const log = require ('ololog')
|
||||
module.exports = async (exchange, symbol) => {
|
||||
|
||||
const skippedExchanges = [
|
||||
'mandala',
|
||||
'rightbtc',
|
||||
]
|
||||
|
||||
|
||||
-1
@@ -76,7 +76,6 @@ module.exports = (exchange, ticker, method, symbol) => {
|
||||
'xbtce',
|
||||
'coss',
|
||||
'idex',
|
||||
'mandala',
|
||||
'mercado',
|
||||
'okex',
|
||||
'southxchange', // https://user-images.githubusercontent.com/1294454/59953532-314bea80-9489-11e9-85b3-2a711ca49aa7.png
|
||||
|
||||
+5
@@ -25,6 +25,8 @@ assert (toWei ('0.001', 18) === '1000000000000000');
|
||||
assert (toWei (0.1, 18) === '100000000000000000');
|
||||
assert (toWei (0.01, 18) === '10000000000000000');
|
||||
assert (toWei (0.001, 18) === '1000000000000000');
|
||||
assert (toWei ('0.3323340739', 18) === '332334073900000000');
|
||||
assert (toWei (0.3323340739, 18) === '332334073900000000');
|
||||
|
||||
// let us test that we get the inverse for all these test
|
||||
assert (fromWei ('1000000000000000000', 18) === 1.0);
|
||||
@@ -43,6 +45,8 @@ assert (fromWei ('1000000000000000', 18) === 0.001);
|
||||
assert (fromWei (100000000000000000, 18) === 0.1);
|
||||
assert (fromWei (10000000000000000, 18) === 0.01);
|
||||
assert (fromWei (1000000000000000, 18) === 0.001);
|
||||
assert (fromWei ('332334073900000000', 18) === 0.3323340739);
|
||||
assert (fromWei (332334073900000000, 18) === 0.3323340739);
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// numberToString
|
||||
@@ -58,6 +62,7 @@ assert (numberToString (7.9e27) === '7900000000000000000000000000');
|
||||
assert (numberToString (-12.345) === '-12.345');
|
||||
assert (numberToString (12.345) === '12.345');
|
||||
assert (numberToString (0) === '0');
|
||||
assert (numberToString (7.35946e21) === '7359460000000000000000');
|
||||
// the following line breaks the test
|
||||
// see https://github.com/ccxt/ccxt/issues/5744
|
||||
// assert (numberToString (0.00000001) === '0.00000001');
|
||||
|
||||
+3
@@ -370,9 +370,12 @@ let tryAllProxies = async function (exchange, proxies) {
|
||||
;(async function test () {
|
||||
|
||||
if (exchangeSymbol) {
|
||||
|
||||
await loadExchange (exchange)
|
||||
await testSymbol (exchange, exchangeSymbol)
|
||||
|
||||
} else {
|
||||
|
||||
await tryAllProxies (exchange, proxies)
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -180,6 +180,9 @@ module.exports = class theocean extends Exchange {
|
||||
}
|
||||
|
||||
async fetchOHLCV (symbol, timeframe = '5m', since = undefined, limit = undefined, params = {}) {
|
||||
if (since === undefined) {
|
||||
throw new ArgumentsRequired (this.id + ' fetchOHLCV requires a since argument');
|
||||
}
|
||||
await this.loadMarkets ();
|
||||
const market = this.market (symbol);
|
||||
const request = {
|
||||
@@ -187,9 +190,6 @@ module.exports = class theocean extends Exchange {
|
||||
'quoteTokenAddress': market['quoteId'],
|
||||
'interval': this.timeframes[timeframe],
|
||||
};
|
||||
if (since === undefined) {
|
||||
throw new ExchangeError (this.id + ' fetchOHLCV requires a since argument');
|
||||
}
|
||||
since = parseInt (since);
|
||||
request['startTime'] = since;
|
||||
const response = await this.publicGetCandlesticks (this.extend (request, params));
|
||||
|
||||
+2
-2
@@ -3,7 +3,7 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const Exchange = require ('./base/Exchange');
|
||||
const { ExchangeError, InsufficientFunds, OrderNotFound } = require ('./base/errors');
|
||||
const { ExchangeError, InsufficientFunds, OrderNotFound, ArgumentsRequired } = require ('./base/errors');
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -460,7 +460,7 @@ module.exports = class tidebit extends Exchange {
|
||||
const currency = this.currency (code);
|
||||
const id = this.safeString (params, 'id');
|
||||
if (id === undefined) {
|
||||
throw new ExchangeError (this.id + ' withdraw() requires an extra `id` param (withdraw account id according to withdraws/bind_account_list endpoint');
|
||||
throw new ArgumentsRequired (this.id + ' withdraw() requires an extra `id` param (withdraw account id according to withdraws/bind_account_list endpoint');
|
||||
}
|
||||
const request = {
|
||||
'id': id,
|
||||
|
||||
+30
-13
@@ -42,6 +42,7 @@ module.exports = class timex extends Exchange {
|
||||
'api': 'https://plasma-relay-backend.timex.io',
|
||||
'www': 'https://timex.io',
|
||||
'doc': 'https://docs.timex.io',
|
||||
'referral': 'https://timex.io/?refcode=1x27vNkTbP1uwkCck',
|
||||
},
|
||||
'api': {
|
||||
'custody': {
|
||||
@@ -892,7 +893,21 @@ module.exports = class timex extends Exchange {
|
||||
// "active": true,
|
||||
// "withdrawalFee": "50000000000000000",
|
||||
// "purchaseCommissions": []
|
||||
// },
|
||||
// }
|
||||
//
|
||||
// https://github.com/ccxt/ccxt/issues/6878
|
||||
//
|
||||
// {
|
||||
// "symbol":"XRP",
|
||||
// "name":"Ripple",
|
||||
// "address":"0x0dc8882914f3ddeebf4cec6dc20edb99df3def6c",
|
||||
// "decimals":6,
|
||||
// "tradeDecimals":16,
|
||||
// "depositEnabled":true,
|
||||
// "withdrawalEnabled":true,
|
||||
// "transferEnabled":true,
|
||||
// "active":true
|
||||
// }
|
||||
//
|
||||
const id = this.safeString (currency, 'symbol');
|
||||
const code = this.safeCurrencyCode (id);
|
||||
@@ -901,20 +916,22 @@ module.exports = class timex extends Exchange {
|
||||
const active = this.safeValue (currency, 'active');
|
||||
// const fee = this.safeFloat (currency, 'withdrawalFee');
|
||||
const feeString = this.safeString (currency, 'withdrawalFee');
|
||||
const feeStringLen = feeString.length;
|
||||
const tradeDecimals = this.safeInteger (currency, 'tradeDecimals');
|
||||
let fee = undefined;
|
||||
const dotIndex = feeStringLen - tradeDecimals;
|
||||
if (dotIndex > 0) {
|
||||
const whole = feeString.slice (0, dotIndex);
|
||||
const fraction = feeString.slice (-dotIndex);
|
||||
fee = parseFloat (whole + '.' + fraction);
|
||||
} else {
|
||||
let fraction = '.';
|
||||
for (let i = 0; i < -dotIndex; i++) {
|
||||
fraction += '0';
|
||||
if ((feeString !== undefined) && (tradeDecimals !== undefined)) {
|
||||
const feeStringLen = feeString.length;
|
||||
const dotIndex = feeStringLen - tradeDecimals;
|
||||
if (dotIndex > 0) {
|
||||
const whole = feeString.slice (0, dotIndex);
|
||||
const fraction = feeString.slice (-dotIndex);
|
||||
fee = parseFloat (whole + '.' + fraction);
|
||||
} else {
|
||||
let fraction = '.';
|
||||
for (let i = 0; i < -dotIndex; i++) {
|
||||
fraction += '0';
|
||||
}
|
||||
fee = parseFloat (fraction + feeString);
|
||||
}
|
||||
fee = parseFloat (fraction + feeString);
|
||||
}
|
||||
return {
|
||||
'id': code,
|
||||
@@ -1105,7 +1122,7 @@ module.exports = class timex extends Exchange {
|
||||
this.safeFloat (ohlcv, 'high'),
|
||||
this.safeFloat (ohlcv, 'low'),
|
||||
this.safeFloat (ohlcv, 'close'),
|
||||
this.safeFloat (ohlcv, 'volumeQuote'),
|
||||
this.safeFloat (ohlcv, 'volume'),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
+4
-2
@@ -1324,9 +1324,11 @@ module.exports = class upbit extends Exchange {
|
||||
}
|
||||
|
||||
parseDepositAddresses (addresses) {
|
||||
const result = [];
|
||||
const result = {};
|
||||
for (let i = 0; i < addresses.length; i++) {
|
||||
result.push (this.parseDepositAddress (addresses[i]));
|
||||
const address = this.parseDepositAddress (addresses[i]);
|
||||
const code = address['currency'];
|
||||
result[code] = address;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
+2
-1
@@ -167,11 +167,12 @@ module.exports = class yobit extends Exchange {
|
||||
'api key dont have trade permission': AuthenticationError,
|
||||
'invalid parameter': InvalidOrder,
|
||||
'invalid order': InvalidOrder,
|
||||
'The given order has already been cancelled': InvalidOrder,
|
||||
'Requests too often': DDoSProtection,
|
||||
'not available': ExchangeNotAvailable,
|
||||
'data unavailable': ExchangeNotAvailable,
|
||||
'external service unavailable': ExchangeNotAvailable,
|
||||
'Total transaction amount': ExchangeError, // { "success": 0, "error": "Total transaction amount is less than minimal total: 0.00010000"}
|
||||
'Total transaction amount': InvalidOrder, // { "success": 0, "error": "Total transaction amount is less than minimal total: 0.00010000"}
|
||||
'Insufficient funds': InsufficientFunds,
|
||||
'invalid key': AuthenticationError,
|
||||
'invalid nonce': InvalidNonce, // {"success":0,"error":"invalid nonce (has already been used)"}'
|
||||
|
||||
+2
-2
@@ -453,7 +453,7 @@ module.exports = class zb extends Exchange {
|
||||
|
||||
async fetchOrders (symbol = undefined, since = undefined, limit = 50, params = {}) {
|
||||
if (symbol === undefined) {
|
||||
throw new ExchangeError (this.id + 'fetchOrders requires a symbol parameter');
|
||||
throw new ArgumentsRequired (this.id + 'fetchOrders requires a symbol argument');
|
||||
}
|
||||
await this.loadMarkets ();
|
||||
const market = this.market (symbol);
|
||||
@@ -481,7 +481,7 @@ module.exports = class zb extends Exchange {
|
||||
|
||||
async fetchOpenOrders (symbol = undefined, since = undefined, limit = 10, params = {}) {
|
||||
if (symbol === undefined) {
|
||||
throw new ExchangeError (this.id + 'fetchOpenOrders requires a symbol parameter');
|
||||
throw new ArgumentsRequired (this.id + 'fetchOpenOrders requires a symbol argument');
|
||||
}
|
||||
await this.loadMarkets ();
|
||||
const market = this.market (symbol);
|
||||
|
||||
+14
-15
@@ -1,27 +1,26 @@
|
||||
{
|
||||
"_from": "ccxt@1.25.80",
|
||||
"_id": "ccxt@1.25.80",
|
||||
"_from": "ccxt@^1.25.80",
|
||||
"_id": "ccxt@1.27.45",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-AUWagxMa8PMexRabbktWezlmVacj6L2Ep4844ebIXUOyME2Ommg7O/9/pq0F2Ne1IHcJnNJzHrMYQvkh2gBtlw==",
|
||||
"_integrity": "sha512-4ADlbcIWDzIWjtLvsrtux5jMFj7pU4kVuiqtI2Btq6NEhQ4r/4+LirXdEFlCF6/wIU3XSHabxMd/8nu8HC1KJw==",
|
||||
"_location": "/ccxt",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "ccxt@1.25.80",
|
||||
"raw": "ccxt@^1.25.80",
|
||||
"name": "ccxt",
|
||||
"escapedName": "ccxt",
|
||||
"rawSpec": "1.25.80",
|
||||
"rawSpec": "^1.25.80",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "1.25.80"
|
||||
"fetchSpec": "^1.25.80"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#USER",
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/ccxt/-/ccxt-1.25.80.tgz",
|
||||
"_shasum": "aee14637402aecc53d8a7d78af78bb7d730c84d5",
|
||||
"_spec": "ccxt@1.25.80",
|
||||
"_resolved": "https://registry.npmjs.org/ccxt/-/ccxt-1.27.45.tgz",
|
||||
"_shasum": "d4470a16dbff881da7fcccd38b0efa277f5a9c37",
|
||||
"_spec": "ccxt@^1.25.80",
|
||||
"_where": "C:\\Users\\Luis\\source\\repos\\AAMasters\\TaskServer",
|
||||
"author": {
|
||||
"name": "Igor Kroitor",
|
||||
@@ -447,8 +446,6 @@
|
||||
"Binance Jersey",
|
||||
"bequant.io",
|
||||
"Bequant",
|
||||
"mandalaex.com",
|
||||
"Mandala",
|
||||
"dx.exchange",
|
||||
"DX.Exchange",
|
||||
"oceanex.pro.com",
|
||||
@@ -491,7 +488,9 @@
|
||||
"Bybit",
|
||||
"aofex.com",
|
||||
"AOFEX",
|
||||
"byte-trade.com"
|
||||
"byte-trade.com",
|
||||
"hbtc.com",
|
||||
"HBTC"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "./ccxt.js",
|
||||
@@ -539,5 +538,5 @@
|
||||
},
|
||||
"types": "./ccxt.d.ts",
|
||||
"unpkg": "dist/ccxt.browser.js",
|
||||
"version": "1.25.80"
|
||||
"version": "1.27.45"
|
||||
}
|
||||
+6
-7
@@ -1,27 +1,26 @@
|
||||
{
|
||||
"_from": "dotenv@8.2.0",
|
||||
"_from": "dotenv@^8.2.0",
|
||||
"_id": "dotenv@8.2.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==",
|
||||
"_location": "/dotenv",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "dotenv@8.2.0",
|
||||
"raw": "dotenv@^8.2.0",
|
||||
"name": "dotenv",
|
||||
"escapedName": "dotenv",
|
||||
"rawSpec": "8.2.0",
|
||||
"rawSpec": "^8.2.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "8.2.0"
|
||||
"fetchSpec": "^8.2.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#USER",
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/dotenv/-/dotenv-8.2.0.tgz",
|
||||
"_shasum": "97e619259ada750eea3e4ea3e26bceea5424b16a",
|
||||
"_spec": "dotenv@8.2.0",
|
||||
"_spec": "dotenv@^8.2.0",
|
||||
"_where": "C:\\Users\\Luis\\source\\repos\\AAMasters\\TaskServer",
|
||||
"bugs": {
|
||||
"url": "https://github.com/motdotla/dotenv/issues"
|
||||
|
||||
+5
@@ -330,6 +330,11 @@ class TelegrafContext {
|
||||
return this.telegram.kickChatMember(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
unbanChatMember (...args) {
|
||||
this.assert(this.chat, 'unbanChatMember')
|
||||
return this.telegram.unbanChatMember(this.chat.id, ...args)
|
||||
}
|
||||
|
||||
restrictChatMember (...args) {
|
||||
this.assert(this.chat, 'restrictChatMember')
|
||||
return this.telegram.restrictChatMember(this.chat.id, ...args)
|
||||
|
||||
+85
-45
@@ -164,15 +164,91 @@ class Markup {
|
||||
}
|
||||
|
||||
static formatHTML (text = '', entities = []) {
|
||||
const chars = ['', ...text.split(''), ''].map(escapeHTMLChar)
|
||||
entities.forEach(entity => {
|
||||
const tag = getHTMLTag(entity)
|
||||
const openPos = entity.offset
|
||||
const closePos = entity.offset + entity.length + 1
|
||||
chars[openPos] += tag.open
|
||||
chars[closePos] = tag.close + chars[closePos]
|
||||
})
|
||||
return chars.join('')
|
||||
const chars = [...text]
|
||||
const available = [...entities]
|
||||
const opened = []
|
||||
const result = []
|
||||
for (let offset = 0; offset < chars.length; offset++) {
|
||||
while (true) {
|
||||
const index = available.findIndex((entity) => entity.offset === offset)
|
||||
if (index === -1) {
|
||||
break
|
||||
}
|
||||
const entity = available[index]
|
||||
switch (entity.type) {
|
||||
case 'bold':
|
||||
result.push('<b>')
|
||||
break
|
||||
case 'italic':
|
||||
result.push('<i>')
|
||||
break
|
||||
case 'code':
|
||||
result.push('<code>')
|
||||
break
|
||||
case 'pre':
|
||||
if (entity.language) {
|
||||
result.push(`<pre><code class="language-${entity.language}">`)
|
||||
} else {
|
||||
result.push('<pre>')
|
||||
}
|
||||
break
|
||||
case 'strikethrough':
|
||||
result.push('<s>')
|
||||
break
|
||||
case 'underline':
|
||||
result.push('<u>')
|
||||
break
|
||||
case 'text_mention':
|
||||
result.push(`<a href="tg://user?id=${entity.user.id}">`)
|
||||
break
|
||||
case 'text_link':
|
||||
result.push(`<a href="${entity.url}">`)
|
||||
break
|
||||
}
|
||||
opened.unshift(entity)
|
||||
available.splice(index, 1)
|
||||
}
|
||||
|
||||
result.push(chars[offset])
|
||||
|
||||
while (true) {
|
||||
const index = opened.findIndex((entity) => entity.offset + entity.length - 1 === offset)
|
||||
if (index === -1) {
|
||||
break
|
||||
}
|
||||
const entity = opened[index]
|
||||
switch (entity.type) {
|
||||
case 'bold':
|
||||
result.push('</b>')
|
||||
break
|
||||
case 'italic':
|
||||
result.push('</i>')
|
||||
break
|
||||
case 'code':
|
||||
result.push('</code>')
|
||||
break
|
||||
case 'pre':
|
||||
if (entity.language) {
|
||||
result.push('</code></pre>')
|
||||
} else {
|
||||
result.push('</pre>')
|
||||
}
|
||||
break
|
||||
case 'strikethrough':
|
||||
result.push('</s>')
|
||||
break
|
||||
case 'underline':
|
||||
result.push('</u>')
|
||||
break
|
||||
case 'text_mention':
|
||||
case 'text_link':
|
||||
result.push('</a>')
|
||||
break
|
||||
}
|
||||
opened.splice(index, 1)
|
||||
}
|
||||
}
|
||||
return result.join('')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,40 +279,4 @@ function buildKeyboard (buttons, options) {
|
||||
return result
|
||||
}
|
||||
|
||||
function escapeHTMLChar (c) {
|
||||
switch (c) {
|
||||
case '&': return '&'
|
||||
case '"': return '"'
|
||||
case '\'': return '''
|
||||
case '<': return '<'
|
||||
default : return c
|
||||
}
|
||||
}
|
||||
|
||||
function tag (name, params) {
|
||||
return {
|
||||
open: params
|
||||
? `<${name} ${Object.entries(params).map(([key, value]) => `${key}="${value.replace(/[<&"]/g, escapeHTMLChar)}"`).join(' ')}>`
|
||||
: `<${name}>`,
|
||||
close: `</${name}>`
|
||||
}
|
||||
}
|
||||
|
||||
const HTMLTags = new Map([
|
||||
['bold', tag('b')],
|
||||
['italic', tag('i')],
|
||||
['code', tag('code')],
|
||||
['pre', tag('pre')],
|
||||
['strikethrough', tag('s')],
|
||||
['underline', tag('u')],
|
||||
['text_link', ({ url }) => tag('a', { href: url })],
|
||||
['text_mention', ({ user }) => tag('a', { href: `tg://user?id=${user.id}` })]
|
||||
])
|
||||
|
||||
function getHTMLTag (entity) {
|
||||
const tag = HTMLTags.get(entity.type || 'unknown')
|
||||
if (!tag) return { open: '', close: '' }
|
||||
return typeof tag === 'function' ? tag(entity) : tag
|
||||
}
|
||||
|
||||
module.exports = Markup
|
||||
+13
-13
@@ -1,34 +1,33 @@
|
||||
{
|
||||
"_from": "telegraf@3.37.0",
|
||||
"_id": "telegraf@3.37.0",
|
||||
"_from": "telegraf@^3.37.0",
|
||||
"_id": "telegraf@3.38.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-V3448qwfOolBqkIc87yxjW4zMvR2P6AIF24pPTlX9WhZPwA1TF/x3nQhnWPRLtGh2SJuvDcr83iTkXPXT7Opnw==",
|
||||
"_integrity": "sha512-va4VlrKWp64JrowFoZX/NPzzA6q38kvaIukVXOWFO1V+jR1G8+hCfgJy4TX8Z3rwLJzwaBEet1QhikHDRZWl3A==",
|
||||
"_location": "/telegraf",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "version",
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "telegraf@3.37.0",
|
||||
"raw": "telegraf@^3.37.0",
|
||||
"name": "telegraf",
|
||||
"escapedName": "telegraf",
|
||||
"rawSpec": "3.37.0",
|
||||
"rawSpec": "^3.37.0",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "3.37.0"
|
||||
"fetchSpec": "^3.37.0"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"#USER",
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/telegraf/-/telegraf-3.37.0.tgz",
|
||||
"_shasum": "f88ae3d4bddac6f479137d4c867489acf3f57b66",
|
||||
"_spec": "telegraf@3.37.0",
|
||||
"_resolved": "https://registry.npmjs.org/telegraf/-/telegraf-3.38.0.tgz",
|
||||
"_shasum": "745b447547a8e6cdb626055e4d616058aaae0759",
|
||||
"_spec": "telegraf@^3.37.0",
|
||||
"_where": "C:\\Users\\Luis\\source\\repos\\AAMasters\\TaskServer",
|
||||
"author": {
|
||||
"name": "Vitaly Domnikov",
|
||||
"email": "oss@vitaly.codes"
|
||||
},
|
||||
"bin": {
|
||||
"telegraf": "bin/telegraf"
|
||||
"telegraf": "./bin/telegraf"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/telegraf/telegraf/issues"
|
||||
@@ -55,6 +54,7 @@
|
||||
"eslint-plugin-promise": "^4.0.0",
|
||||
"eslint-plugin-standard": "^4.0.0",
|
||||
"husky": "^4.2.0",
|
||||
"prettier": "^2.0.5",
|
||||
"typescript": "^3.0.1"
|
||||
},
|
||||
"engines": {
|
||||
@@ -91,5 +91,5 @@
|
||||
},
|
||||
"type": "commonjs",
|
||||
"types": "./typings/index.d.ts",
|
||||
"version": "3.37.0"
|
||||
"version": "3.38.0"
|
||||
}
|
||||
+1
@@ -213,6 +213,7 @@ module.exports = Object.assign(Telegraf, {
|
||||
Extra,
|
||||
Markup,
|
||||
Router,
|
||||
Telegraf,
|
||||
Telegram,
|
||||
Stage,
|
||||
BaseScene,
|
||||
|
||||
+1
-18
@@ -92,7 +92,7 @@ function toBuffer(data) {
|
||||
if (data instanceof ArrayBuffer) {
|
||||
buf = Buffer.from(data);
|
||||
} else if (ArrayBuffer.isView(data)) {
|
||||
buf = viewToBuffer(data);
|
||||
buf = Buffer.from(data.buffer, data.byteOffset, data.byteLength);
|
||||
} else {
|
||||
buf = Buffer.from(data);
|
||||
toBuffer.readOnly = false;
|
||||
@@ -101,23 +101,6 @@ function toBuffer(data) {
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts an `ArrayBuffer` view into a buffer.
|
||||
*
|
||||
* @param {(DataView|TypedArray)} view The view to convert
|
||||
* @return {Buffer} Converted view
|
||||
* @private
|
||||
*/
|
||||
function viewToBuffer(view) {
|
||||
const buf = Buffer.from(view.buffer);
|
||||
|
||||
if (view.byteLength !== view.buffer.byteLength) {
|
||||
return buf.slice(view.byteOffset, view.byteOffset + view.byteLength);
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
try {
|
||||
const bufferUtil = require('bufferutil');
|
||||
const bu = bufferUtil.BufferUtil || bufferUtil;
|
||||
|
||||
+22
-15
@@ -109,11 +109,16 @@ const EventTarget = {
|
||||
/**
|
||||
* Register an event listener.
|
||||
*
|
||||
* @param {String} method A string representing the event type to listen for
|
||||
* @param {String} type A string representing the event type to listen for
|
||||
* @param {Function} listener The listener to add
|
||||
* @param {Object} options An options object specifies characteristics about
|
||||
* the event listener
|
||||
* @param {Boolean} options.once A `Boolean`` indicating that the listener
|
||||
* should be invoked at most once after being added. If `true`, the
|
||||
* listener would be automatically removed when invoked.
|
||||
* @public
|
||||
*/
|
||||
addEventListener(method, listener) {
|
||||
addEventListener(type, listener, options) {
|
||||
if (typeof listener !== 'function') return;
|
||||
|
||||
function onMessage(data) {
|
||||
@@ -132,36 +137,38 @@ const EventTarget = {
|
||||
listener.call(this, new OpenEvent(this));
|
||||
}
|
||||
|
||||
if (method === 'message') {
|
||||
const method = options && options.once ? 'once' : 'on';
|
||||
|
||||
if (type === 'message') {
|
||||
onMessage._listener = listener;
|
||||
this.on(method, onMessage);
|
||||
} else if (method === 'close') {
|
||||
this[method](type, onMessage);
|
||||
} else if (type === 'close') {
|
||||
onClose._listener = listener;
|
||||
this.on(method, onClose);
|
||||
} else if (method === 'error') {
|
||||
this[method](type, onClose);
|
||||
} else if (type === 'error') {
|
||||
onError._listener = listener;
|
||||
this.on(method, onError);
|
||||
} else if (method === 'open') {
|
||||
this[method](type, onError);
|
||||
} else if (type === 'open') {
|
||||
onOpen._listener = listener;
|
||||
this.on(method, onOpen);
|
||||
this[method](type, onOpen);
|
||||
} else {
|
||||
this.on(method, listener);
|
||||
this[method](type, listener);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Remove an event listener.
|
||||
*
|
||||
* @param {String} method A string representing the event type to remove
|
||||
* @param {String} type A string representing the event type to remove
|
||||
* @param {Function} listener The listener to remove
|
||||
* @public
|
||||
*/
|
||||
removeEventListener(method, listener) {
|
||||
const listeners = this.listeners(method);
|
||||
removeEventListener(type, listener) {
|
||||
const listeners = this.listeners(type);
|
||||
|
||||
for (let i = 0; i < listeners.length; i++) {
|
||||
if (listeners[i] === listener || listeners[i]._listener === listener) {
|
||||
this.removeListener(method, listeners[i]);
|
||||
this.removeListener(type, listeners[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -125,8 +125,8 @@ function createWebSocketStream(ws, options) {
|
||||
if (ws._socket === null) return;
|
||||
|
||||
if (ws._socket._writableState.finished) {
|
||||
if (duplex._readableState.endEmitted) duplex.destroy();
|
||||
callback();
|
||||
if (duplex._readableState.endEmitted) duplex.destroy();
|
||||
} else {
|
||||
ws._socket.once('finish', function finish() {
|
||||
// `duplex` is not destroyed here because the `'end'` event will be
|
||||
|
||||
+10
-12
@@ -7,10 +7,9 @@ const { createServer, STATUS_CODES } = require('http');
|
||||
const PerMessageDeflate = require('./permessage-deflate');
|
||||
const WebSocket = require('./websocket');
|
||||
const { format, parse } = require('./extension');
|
||||
const { GUID } = require('./constants');
|
||||
const { GUID, kWebSocket } = require('./constants');
|
||||
|
||||
const keyRegex = /^[+/0-9A-Za-z]{22}==$/;
|
||||
const kUsedByWebSocketServer = Symbol('kUsedByWebSocketServer');
|
||||
|
||||
/**
|
||||
* Class representing a WebSocket server.
|
||||
@@ -79,13 +78,6 @@ class WebSocketServer extends EventEmitter {
|
||||
callback
|
||||
);
|
||||
} else if (options.server) {
|
||||
if (options.server[kUsedByWebSocketServer]) {
|
||||
throw new Error(
|
||||
'The HTTP/S server is already being used by another WebSocket server'
|
||||
);
|
||||
}
|
||||
|
||||
options.server[kUsedByWebSocketServer] = true;
|
||||
this._server = options.server;
|
||||
}
|
||||
|
||||
@@ -153,8 +145,6 @@ class WebSocketServer extends EventEmitter {
|
||||
server.close(() => this.emit('close'));
|
||||
return;
|
||||
}
|
||||
|
||||
delete server[kUsedByWebSocketServer];
|
||||
}
|
||||
|
||||
process.nextTick(emitClose, this);
|
||||
@@ -264,6 +254,7 @@ class WebSocketServer extends EventEmitter {
|
||||
* @param {net.Socket} socket The network socket between the server and client
|
||||
* @param {Buffer} head The first packet of the upgraded stream
|
||||
* @param {Function} cb Callback
|
||||
* @throws {Error} If called more than once with the same socket
|
||||
* @private
|
||||
*/
|
||||
completeUpgrade(key, extensions, req, socket, head, cb) {
|
||||
@@ -272,6 +263,13 @@ class WebSocketServer extends EventEmitter {
|
||||
//
|
||||
if (!socket.readable || !socket.writable) return socket.destroy();
|
||||
|
||||
if (socket[kWebSocket]) {
|
||||
throw new Error(
|
||||
'server.handleUpgrade() was called more than once with the same ' +
|
||||
'socket, possibly due to a misconfiguration'
|
||||
);
|
||||
}
|
||||
|
||||
const digest = createHash('sha1')
|
||||
.update(key + GUID)
|
||||
.digest('base64');
|
||||
@@ -386,7 +384,7 @@ function abortHandshake(socket, code, message, headers) {
|
||||
message = message || STATUS_CODES[code];
|
||||
headers = {
|
||||
Connection: 'close',
|
||||
'Content-type': 'text/html',
|
||||
'Content-Type': 'text/html',
|
||||
'Content-Length': Buffer.byteLength(message),
|
||||
...headers
|
||||
};
|
||||
|
||||
-1
@@ -456,7 +456,6 @@ function initAsClient(websocket, address, protocols, options) {
|
||||
protocol: undefined,
|
||||
timeout: undefined,
|
||||
method: undefined,
|
||||
auth: undefined,
|
||||
host: undefined,
|
||||
path: undefined,
|
||||
port: undefined
|
||||
|
||||
+21
-60
@@ -1,52 +1,38 @@
|
||||
{
|
||||
"_args": [
|
||||
[
|
||||
"ws@^7.1.2",
|
||||
"C:\\Users\\Luis\\source\\repos\\AAMasters\\TaskServer"
|
||||
]
|
||||
],
|
||||
"_from": "ws@>=7.1.2-0 <8.0.0-0",
|
||||
"_hasShrinkwrap": false,
|
||||
"_id": "ws@7.2.3",
|
||||
"_inCache": true,
|
||||
"_from": "ws@^7.1.2",
|
||||
"_id": "ws@7.3.0",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-iFtXzngZVXPGgpTlP1rBqsUK82p9tKqsWRPg5L56egiljujJT3vGAYnHANvFxBieXrTFavhzhxW52jnaWV+w2w==",
|
||||
"_location": "/ws",
|
||||
"_nodeVersion": "13.10.1",
|
||||
"_npmOperationalInternal": {
|
||||
"host": "s3://npm-registry-packages",
|
||||
"tmp": "tmp/ws_7.2.3_1583774852485_0.5683086237203219"
|
||||
},
|
||||
"_npmUser": {
|
||||
"email": "luigipinca@gmail.com",
|
||||
"name": "lpinca"
|
||||
},
|
||||
"_npmVersion": "6.13.7",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"name": "ws",
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "ws@^7.1.2",
|
||||
"name": "ws",
|
||||
"escapedName": "ws",
|
||||
"rawSpec": "^7.1.2",
|
||||
"scope": null,
|
||||
"spec": ">=7.1.2-0 <8.0.0-0",
|
||||
"type": "range"
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^7.1.2"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz",
|
||||
"_shasum": "a5411e1fb04d5ed0efee76d26d5c46d830c39b46",
|
||||
"_shrinkwrap": null,
|
||||
"_resolved": "https://registry.npmjs.org/ws/-/ws-7.3.0.tgz",
|
||||
"_shasum": "4b2f7f219b3d3737bc1a2fbf145d825b94d38ffd",
|
||||
"_spec": "ws@^7.1.2",
|
||||
"_where": "C:\\Users\\Luis\\source\\repos\\AAMasters\\TaskServer",
|
||||
"author": {
|
||||
"email": "einaros@gmail.com",
|
||||
"name": "Einar Otto Stangvik",
|
||||
"email": "einaros@gmail.com",
|
||||
"url": "http://2x.io"
|
||||
},
|
||||
"browser": "browser.js",
|
||||
"bugs": {
|
||||
"url": "https://github.com/websockets/ws/issues"
|
||||
},
|
||||
"dependencies": {},
|
||||
"bundleDependencies": false,
|
||||
"deprecated": false,
|
||||
"description": "Simple to use, blazing fast and thoroughly tested websocket client and server for Node.js",
|
||||
"devDependencies": {
|
||||
"benchmark": "^2.1.4",
|
||||
@@ -60,19 +46,14 @@
|
||||
"prettier": "^1.17.0",
|
||||
"utf-8-validate": "^5.0.2"
|
||||
},
|
||||
"directories": {},
|
||||
"dist": {
|
||||
"fileCount": 17,
|
||||
"integrity": "sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ==",
|
||||
"npm-signature": "-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeZnyFCRA9TVsSAnZWagAAUvwP/jAz5ASUvvHJjDMOS+r/\npDkuV2MoMwz6ccV+qfbVRWUKq9DqnK7bZBApyNlzV2I+APDqLOVU+2BazNKh\nqoTcVHYcBYe5oBIYUvEeSK2qyBCNJUcz2f79lVxWagdcax5nl5tOcW3B8v4X\n9T2hSvSuDNz8vg0uhCnLboZ+F4SPXd3lHwwfcZFkNSjTcRog4W4QNQTEaPbi\noqPawUw/NXDJMFILS2m/rerFnEyrDl4VpoAS9GyitCE31g22N03bCbsmaUMo\nHmFmefATEhmtIExXMDW9JGLL9FtTwVEIAJEfAWqjLt3JeAuWHvYKKd7rU/y1\nwPUQJxwGM1HDYaxbDLXRBVYkOja3YHB5txB8d2lHLt98c5DQ/lZCz1XQIRao\nPv48dpOX2Qg69IpMzSHktoRUJpt+0KkLWUhb7XGVY79kCgqt6ZqYxBs7coae\nOeReUBaKc+yuM3k45sHxyqiKCsw/qejgzScPnmU/BaC32vEdjqpysRNDtfZj\nNmizo+cLoiO8stLVCHGBwpIxegM8aGj3/C8emNEsSFi4rXT6LGHaWvNfv3FR\nVY2/4QZFL/ddUQ3yAOKF4znsHBY2qfbpPJVnW7IyxZ2h39HX3PpITCcYDPzu\nj4LV/wXFESBSre9RANqfPfkJC+A3k0V8eAB0bYQJKImeUAiqkOkYMyrX+2Ea\nHUeL\r\n=aUaH\r\n-----END PGP SIGNATURE-----\r\n",
|
||||
"shasum": "a5411e1fb04d5ed0efee76d26d5c46d830c39b46",
|
||||
"tarball": "https://registry.npmjs.org/ws/-/ws-7.2.3.tgz",
|
||||
"unpackedSize": 109814
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8.3.0"
|
||||
},
|
||||
"gitHead": "5fcdc42ef76d2d0ab920aa37631468e6f1066bcd",
|
||||
"files": [
|
||||
"browser.js",
|
||||
"index.js",
|
||||
"lib/*.js"
|
||||
],
|
||||
"greenkeeper": {
|
||||
"commitMessages": {
|
||||
"dependencyUpdate": "[pkg] Update ${dependency} to version ${version}",
|
||||
@@ -80,7 +61,6 @@
|
||||
}
|
||||
},
|
||||
"homepage": "https://github.com/websockets/ws",
|
||||
"installable": true,
|
||||
"keywords": [
|
||||
"HyBi",
|
||||
"Push",
|
||||
@@ -91,26 +71,7 @@
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"maintainers": [
|
||||
{
|
||||
"email": "npm@3rd-Eden.com",
|
||||
"name": "3rdeden"
|
||||
},
|
||||
{
|
||||
"email": "einaros@gmail.com",
|
||||
"name": "einaros"
|
||||
},
|
||||
{
|
||||
"email": "luigipinca@gmail.com",
|
||||
"name": "lpinca"
|
||||
},
|
||||
{
|
||||
"email": "npm@3rd-Eden.com",
|
||||
"name": "v1"
|
||||
}
|
||||
],
|
||||
"name": "ws",
|
||||
"optionalDependencies": {},
|
||||
"peerDependencies": {
|
||||
"bufferutil": "^4.0.1",
|
||||
"utf-8-validate": "^5.0.2"
|
||||
@@ -132,5 +93,5 @@
|
||||
"lint": "eslint --ignore-path .gitignore . && prettier --check --ignore-path .gitignore \"**/*.{json,md,yaml,yml}\"",
|
||||
"test": "npm run lint && nyc --reporter=html --reporter=text mocha --throw-deprecation test/*.test.js"
|
||||
},
|
||||
"version": "7.2.3"
|
||||
"version": "7.3.0"
|
||||
}
|
||||
Reference in new issue
Block a user