CCXT updated to latest version 1.42.77

This commit is contained in:
Luis Fernando Molina committed 2021-03-11 16:14:50 +01:00
1 parent 3fbf95be13
commit f7d93ed994
28 files changed
+738 -162

No files matched your search

@@ -229,13 +229,13 @@ console.log (ccxt.exchanges) // print all available exchanges
All-in-one browser bundle (dependencies included), served from a CDN of your choice:
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@1.42.67/dist/ccxt.browser.js
* unpkg: https://unpkg.com/ccxt@1.42.67/dist/ccxt.browser.js
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@1.42.77/dist/ccxt.browser.js
* unpkg: https://unpkg.com/ccxt@1.42.77/dist/ccxt.browser.js
CDNs are not updated in real-time and may have delays. Defaulting to the most recent version without specifying the version number is not recommended. Please, keep in mind that we are not responsible for the correct operation of those CDN servers.
```HTML
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@1.42.67/dist/ccxt.browser.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@1.42.77/dist/ccxt.browser.js"></script>
```
Creates a global `ccxt` object:
@@ -1080,19 +1080,37 @@ class Transpiler {
// ========================================================================
exportTypeScriptDeclarations (file, classes) {
exportTypeScriptClassNames (file, classes) {
log.bright.cyan ('Exporting TypeScript declarations →', file.yellow)
log.bright.cyan ('Exporting TypeScript class names →', file.yellow)
const regex = /\/[\n]{2}(?: export class [^\s]+ extends [^\s]+ \{\}[\r]?[\n])+/
const replacement = "/\n\n" + Object.keys (classes).map (className => {
const baseClass = classes[className]
const baseClass = classes[className].replace (/ccxt\.[a-z_]+/, 'Exchange')
return ' export class ' + className + ' extends ' + baseClass + " {}"
}).join ("\n") + "\n"
replaceInFile (file, regex, replacement)
}
exportTypeScriptExchangeIds (file, classes) {
log.bright.cyan ('Exporting TypeScript exchange ids →', file.yellow)
const regex = /\/[\n]{2} export type ExchangeId =\n(?: \| \'[a-z0-9_]+\'[\r]?[\n])+/
const replacement = "/\n\n export type ExchangeId =\n" + Object.keys (classes).map (className => {
return " | '" + className + "'"
}).join ("\n") + "\n"
replaceInFile (file, regex, replacement)
}
exportTypeScriptDeclarations (file, classes) {
this.exportTypeScriptClassNames (file, classes)
this.exportTypeScriptExchangeIds (file, classes)
}
// ========================================================================
transpileErrorHierarchy () {
@@ -551,4 +551,132 @@ declare module 'ccxt' {
/* tslint:enable */
export type ExchangeId =
| 'aax'
| 'acx'
| 'aofex'
| 'bequant'
| 'bibox'
| 'bigone'
| 'binance'
| 'binanceus'
| 'bit2c'
| 'bitbank'
| 'bitbay'
| 'bitcoincom'
| 'bitfinex'
| 'bitfinex2'
| 'bitflyer'
| 'bitforex'
| 'bitget'
| 'bithumb'
| 'bitkk'
| 'bitmart'
| 'bitmax'
| 'bitmex'
| 'bitpanda'
| 'bitso'
| 'bitstamp'
| 'bitstamp1'
| 'bittrex'
| 'bitvavo'
| 'bitz'
| 'bl3p'
| 'bleutrade'
| 'braziliex'
| 'btcalpha'
| 'btcbox'
| 'btcmarkets'
| 'btctradeua'
| 'btcturk'
| 'buda'
| 'bw'
| 'bybit'
| 'bytetrade'
| 'cdax'
| 'cex'
| 'chilebit'
| 'coinbase'
| 'coinbaseprime'
| 'coinbasepro'
| 'coincheck'
| 'coinegg'
| 'coinex'
| 'coinfalcon'
| 'coinfloor'
| 'coingi'
| 'coinmarketcap'
| 'coinmate'
| 'coinone'
| 'coinspot'
| 'crex24'
| 'currencycom'
| 'delta'
| 'deribit'
| 'digifinex'
| 'dsx'
| 'equos'
| 'eterbase'
| 'exmo'
| 'exx'
| 'fcoin'
| 'fcoinjp'
| 'flowbtc'
| 'foxbit'
| 'ftx'
| 'gateio'
| 'gemini'
| 'gopax'
| 'hbtc'
| 'hitbtc'
| 'hollaex'
| 'huobijp'
| 'huobipro'
| 'ice3x'
| 'idex'
| 'independentreserve'
| 'indodax'
| 'itbit'
| 'kraken'
| 'kucoin'
| 'kuna'
| 'lakebtc'
| 'latoken'
| 'lbank'
| 'liquid'
| 'luno'
| 'lykke'
| 'mercado'
| 'mixcoins'
| 'ndax'
| 'novadax'
| 'oceanex'
| 'okcoin'
| 'okex'
| 'paymium'
| 'phemex'
| 'poloniex'
| 'probit'
| 'qtrade'
| 'rightbtc'
| 'ripio'
| 'southxchange'
| 'stex'
| 'surbitcoin'
| 'therock'
| 'tidebit'
| 'tidex'
| 'timex'
| 'upbit'
| 'vaultoro'
| 'vbtc'
| 'vcc'
| 'wavesexchange'
| 'whitebit'
| 'xbtce'
| 'xena'
| 'yobit'
| 'zaif'
| 'zb'
}
@@ -35,7 +35,7 @@ const Exchange = require ('./js/base/Exchange')
//-----------------------------------------------------------------------------
// this is updated by vss.js when building
const version = '1.42.67'
const version = '1.42.77'
Exchange.ccxtVersion = version
@@ -43,7 +43,7 @@ const Exchange = require ('./js/base/Exchange')
//-----------------------------------------------------------------------------
// this is updated by vss.js when building
const version = '1.42.67'
const version = '1.42.77'
Exchange.ccxtVersion = version
@@ -4956,8 +4956,77 @@ module.exports = class Exchange {
integerPow (a, b) {
return new BN (a).pow (new BN (b))
}
}
safeOrder (order) {
// Cost
// Remaining
// Average
// Price
// Amount
// Filled
//
// First we try to calculate filled from the trades
const parseFilled = order['filled'] === undefined;
const parseCost = order['cost'] === undefined;
if (parseFilled) {
order['filled'] = 0
}
if (parseCost) {
order['cost'] = 0
}
if (parseFilled || parseCost) {
if (Array.isArray (order['trades'])) {
for (let i = 0; i < order['trades'].length; i++) {
const trade = order['trades'][i]
if (parseFilled) {
order['filled'] = this.sum (order['filled'], trade['amount'])
}
if (parseCost) {
order['cost'] = this.sum (order['cost'], trade['cost'])
}
}
}
}
// We ensure amount = filled + remaining
if (order['amount'] === undefined) {
if (order['filled'] !== undefined && order['remaining'] !== undefined) {
order['amount'] = this.sum (order['filled'], order['remaining'])
}
}
if (order['filled'] === undefined) {
if (order['amount'] !== undefined && order['remaining'] !== undefined) {
order['filled'] = Math.max (this.sum (order['amount'], -order['remaining']), 0)
}
}
if (order['remaining'] === undefined) {
if (order['amount'] !== undefined && order['filled'] !== undefined) {
order['remaining'] = Math.max (this.sum (order['amount'], -order['filled']), 0)
}
}
// We ensure that the average field is calculated correctly
if (order['average'] === undefined) {
if (order['filled'] !== undefined && order['cost'] !== undefined && order['cost'] > 0) {
order['average'] = order['filled'] / order['cost']
}
}
// We also ensure the cost field is calculated correctly
const costPriceExists = (order['average'] !== undefined) || (order['price'] !== undefined)
if ((order['filled'] !== undefined) && costPriceExists) {
let costPrice = undefined;
if (order['average'] === undefined) {
costPrice = order['price']
} else {
costPrice = order['average']
}
order['cost'] = costPrice * order['filled']
}
// We add support for market orders
if (order['price'] === undefined && order['type'] === 'market') {
order['price'] = order['average']
}
return order
}
}
},{"../static_dependencies/BN/bn":126,"./errors":8,"./functions":9}],7:[function(require,module,exports){
'use strict';
@@ -50697,10 +50766,11 @@ module.exports = class coincheck extends Exchange {
'markets': {
'BTC/JPY': { 'id': 'btc_jpy', 'symbol': 'BTC/JPY', 'base': 'BTC', 'quote': 'JPY', 'baseId': 'btc', 'quoteId': 'jpy' }, // the only real pair
// 'ETH/JPY': { 'id': 'eth_jpy', 'symbol': 'ETH/JPY', 'base': 'ETH', 'quote': 'JPY', 'baseId': 'eth', 'quoteId': 'jpy' },
// 'ETC/JPY': { 'id': 'etc_jpy', 'symbol': 'ETC/JPY', 'base': 'ETC', 'quote': 'JPY', 'baseId': 'etc', 'quoteId': 'jpy' },
'ETC/JPY': { 'id': 'etc_jpy', 'symbol': 'ETC/JPY', 'base': 'ETC', 'quote': 'JPY', 'baseId': 'etc', 'quoteId': 'jpy' },
// 'DAO/JPY': { 'id': 'dao_jpy', 'symbol': 'DAO/JPY', 'base': 'DAO', 'quote': 'JPY', 'baseId': 'dao', 'quoteId': 'jpy' },
// 'LSK/JPY': { 'id': 'lsk_jpy', 'symbol': 'LSK/JPY', 'base': 'LSK', 'quote': 'JPY', 'baseId': 'lsk', 'quoteId': 'jpy' },
// 'FCT/JPY': { 'id': 'fct_jpy', 'symbol': 'FCT/JPY', 'base': 'FCT', 'quote': 'JPY', 'baseId': 'fct', 'quoteId': 'jpy' },
'FCT/JPY': { 'id': 'fct_jpy', 'symbol': 'FCT/JPY', 'base': 'FCT', 'quote': 'JPY', 'baseId': 'fct', 'quoteId': 'jpy' },
'MONA/JPY': { 'id': 'mona_jpy', 'symbol': 'MONA/JPY', 'base': 'MONA', 'quote': 'JPY', 'baseId': 'mona', 'quoteId': 'jpy' },
// 'XMR/JPY': { 'id': 'xmr_jpy', 'symbol': 'XMR/JPY', 'base': 'XMR', 'quote': 'JPY', 'baseId': 'xmr', 'quoteId': 'jpy' },
// 'REP/JPY': { 'id': 'rep_jpy', 'symbol': 'REP/JPY', 'base': 'REP', 'quote': 'JPY', 'baseId': 'rep', 'quoteId': 'jpy' },
// 'XRP/JPY': { 'id': 'xrp_jpy', 'symbol': 'XRP/JPY', 'base': 'XRP', 'quote': 'JPY', 'baseId': 'xrp', 'quoteId': 'jpy' },
@@ -50709,7 +50779,7 @@ module.exports = class coincheck extends Exchange {
// 'LTC/JPY': { 'id': 'ltc_jpy', 'symbol': 'LTC/JPY', 'base': 'LTC', 'quote': 'JPY', 'baseId': 'ltc', 'quoteId': 'jpy' },
// 'DASH/JPY': { 'id': 'dash_jpy', 'symbol': 'DASH/JPY', 'base': 'DASH', 'quote': 'JPY', 'baseId': 'dash', 'quoteId': 'jpy' },
// 'ETH/BTC': { 'id': 'eth_btc', 'symbol': 'ETH/BTC', 'base': 'ETH', 'quote': 'BTC', 'baseId': 'eth', 'quoteId': 'btc' },
// 'ETC/BTC': { 'id': 'etc_btc', 'symbol': 'ETC/BTC', 'base': 'ETC', 'quote': 'BTC', 'baseId': 'etc', 'quoteId': 'btc' },
'ETC/BTC': { 'id': 'etc_btc', 'symbol': 'ETC/BTC', 'base': 'ETC', 'quote': 'BTC', 'baseId': 'etc', 'quoteId': 'btc' },
// 'LSK/BTC': { 'id': 'lsk_btc', 'symbol': 'LSK/BTC', 'base': 'LSK', 'quote': 'BTC', 'baseId': 'lsk', 'quoteId': 'btc' },
// 'FCT/BTC': { 'id': 'fct_btc', 'symbol': 'FCT/BTC', 'base': 'FCT', 'quote': 'BTC', 'baseId': 'fct', 'quoteId': 'btc' },
// 'XMR/BTC': { 'id': 'xmr_btc', 'symbol': 'XMR/BTC', 'base': 'XMR', 'quote': 'BTC', 'baseId': 'xmr', 'quoteId': 'btc' },
@@ -50827,11 +50897,12 @@ module.exports = class coincheck extends Exchange {
}
async fetchOrderBook (symbol, limit = undefined, params = {}) {
if (symbol !== 'BTC/JPY') {
throw new BadSymbol (this.id + ' fetchOrderBook () supports BTC/JPY only');
}
await this.loadMarkets ();
const response = await this.publicGetOrderBooks (params);
const market = this.market (symbol);
const request = {
'pair': market['id'],
};
const response = await this.publicGetOrderBooks (this.extend (request, params));
return this.parseOrderBook (response);
}
@@ -50840,7 +50911,11 @@ module.exports = class coincheck extends Exchange {
throw new BadSymbol (this.id + ' fetchTicker () supports BTC/JPY only');
}
await this.loadMarkets ();
const ticker = await this.publicGetTicker (params);
const market = this.market (symbol);
const request = {
'pair': market['id'],
};
const ticker = await this.publicGetTicker (this.extend (request, params));
const timestamp = this.safeTimestamp (ticker, 'timestamp');
const last = this.safeFloat (ticker, 'last');
return {
@@ -50954,9 +51029,6 @@ module.exports = class coincheck extends Exchange {
}
async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
if (symbol !== 'BTC/JPY') {
throw new BadSymbol (this.id + ' fetchTrades () supports BTC/JPY only');
}
await this.loadMarkets ();
const market = this.market (symbol);
const request = {
@@ -70802,6 +70874,8 @@ module.exports = class ftx extends Exchange {
'Missing parameter price': InvalidOrder, // {"error":"Missing parameter price","success":false}
'Order not found': OrderNotFound, // {"error":"Order not found","success":false}
'Order already closed': InvalidOrder, // {"error":"Order already closed","success":false}
'Trigger price too high': InvalidOrder, // {"error":"Trigger price too high","success":false}
'Trigger price too low': InvalidOrder, // {"error":"Trigger price too low","success":false}
'Order already queued for cancellation': CancelPending, // {"error":"Order already queued for cancellation","success":false}
},
'broad': {
@@ -77728,6 +77802,10 @@ module.exports = class hitbtc extends Exchange {
},
'urls': {
'logo': 'https://user-images.githubusercontent.com/1294454/27766555-8eaec20e-5edc-11e7-9c5b-6dc69fc42f5e.jpg',
'test': {
'public': 'https://api.demo.hitbtc.com',
'private': 'https://api.demo.hitbtc.com',
},
'api': {
'public': 'https://api.hitbtc.com',
'private': 'https://api.hitbtc.com',
@@ -82899,16 +82977,8 @@ module.exports = class idex extends Exchange {
const type = this.safeString (order, 'type');
const amount = this.safeFloat (order, 'originalQuantity');
const filled = this.safeFloat (order, 'executedQuantity');
let remaining = undefined;
if ((amount !== undefined) && (filled !== undefined)) {
remaining = amount - filled;
}
const average = this.safeFloat (order, 'avgExecutionPrice');
const price = this.safeFloat (order, 'price', average); // for market orders
let cost = undefined;
if ((amount !== undefined) && (price !== undefined)) {
cost = amount * price;
}
const price = this.safeFloat (order, 'price');
const rawStatus = this.safeString (order, 'status');
const status = this.parseOrderStatus (rawStatus);
const fee = {
@@ -82922,7 +82992,7 @@ module.exports = class idex extends Exchange {
fee['cost'] = this.sum (fee['cost'], lastTrade['fee']['cost']);
}
const lastTradeTimestamp = this.safeInteger (lastTrade, 'timestamp');
return {
return this.safeOrder ({
'info': order,
'id': id,
'clientOrderId': clientOrderId,
@@ -82937,14 +83007,14 @@ module.exports = class idex extends Exchange {
'price': price,
'stopPrice': undefined,
'amount': amount,
'cost': cost,
'cost': undefined,
'average': average,
'filled': filled,
'remaining': remaining,
'remaining': undefined,
'status': status,
'fee': fee,
'trades': trades,
};
});
}
async associateWallet (walletAddress, params = {}) {
@@ -92726,15 +92796,16 @@ module.exports = class luno extends Exchange {
if (type === 'market') {
method += 'Marketorder';
request['type'] = side.toUpperCase ();
// todo add createMarketBuyOrderRequires price logic as it is implemented in the other exchanges
if (side === 'buy') {
request['counter_volume'] = amount;
request['counter_volume'] = parseFloat (this.amountToPrecision (symbol, amount));
} else {
request['base_volume'] = amount;
request['base_volume'] = parseFloat (this.amountToPrecision (symbol, amount));
}
} else {
method += 'Postorder';
request['volume'] = amount;
request['price'] = price;
request['volume'] = parseFloat (this.amountToPrecision (symbol, amount));
request['price'] = parseFloat (this.priceToPrecision (symbol, price));
request['type'] = (side === 'buy') ? 'BID' : 'ASK';
}
const response = await this[method] (this.extend (request, params));
@@ -135007,7 +135078,7 @@ module.exports = class timex extends Exchange {
'symbol': market['id'],
'quantity': this.amountToPrecision (symbol, amount),
'side': uppercaseSide,
'type': uppercaseType,
'orderTypes': uppercaseType,
// 'clientOrderId': '123',
// 'expireIn': 1575523308, // in seconds
// 'expireTime': 1575523308, // unix timestamp
@@ -1392,5 +1392,74 @@ module.exports = class Exchange {
integerPow (a, b) {
return new BN (a).pow (new BN (b))
}
}
safeOrder (order) {
// Cost
// Remaining
// Average
// Price
// Amount
// Filled
//
// First we try to calculate filled from the trades
const parseFilled = order['filled'] === undefined;
const parseCost = order['cost'] === undefined;
if (parseFilled) {
order['filled'] = 0
}
if (parseCost) {
order['cost'] = 0
}
if (parseFilled || parseCost) {
if (Array.isArray (order['trades'])) {
for (let i = 0; i < order['trades'].length; i++) {
const trade = order['trades'][i]
if (parseFilled) {
order['filled'] = this.sum (order['filled'], trade['amount'])
}
if (parseCost) {
order['cost'] = this.sum (order['cost'], trade['cost'])
}
}
}
}
// We ensure amount = filled + remaining
if (order['amount'] === undefined) {
if (order['filled'] !== undefined && order['remaining'] !== undefined) {
order['amount'] = this.sum (order['filled'], order['remaining'])
}
}
if (order['filled'] === undefined) {
if (order['amount'] !== undefined && order['remaining'] !== undefined) {
order['filled'] = Math.max (this.sum (order['amount'], -order['remaining']), 0)
}
}
if (order['remaining'] === undefined) {
if (order['amount'] !== undefined && order['filled'] !== undefined) {
order['remaining'] = Math.max (this.sum (order['amount'], -order['filled']), 0)
}
}
// We ensure that the average field is calculated correctly
if (order['average'] === undefined) {
if (order['filled'] !== undefined && order['cost'] !== undefined && order['cost'] > 0) {
order['average'] = order['filled'] / order['cost']
}
}
// We also ensure the cost field is calculated correctly
const costPriceExists = (order['average'] !== undefined) || (order['price'] !== undefined)
if ((order['filled'] !== undefined) && costPriceExists) {
let costPrice = undefined;
if (order['average'] === undefined) {
costPrice = order['price']
} else {
costPrice = order['average']
}
order['cost'] = costPrice * order['filled']
}
// We add support for market orders
if (order['price'] === undefined && order['type'] === 'market') {
order['price'] = order['average']
}
return order
}
}
@@ -81,10 +81,11 @@ module.exports = class coincheck extends Exchange {
'markets': {
'BTC/JPY': { 'id': 'btc_jpy', 'symbol': 'BTC/JPY', 'base': 'BTC', 'quote': 'JPY', 'baseId': 'btc', 'quoteId': 'jpy' }, // the only real pair
// 'ETH/JPY': { 'id': 'eth_jpy', 'symbol': 'ETH/JPY', 'base': 'ETH', 'quote': 'JPY', 'baseId': 'eth', 'quoteId': 'jpy' },
// 'ETC/JPY': { 'id': 'etc_jpy', 'symbol': 'ETC/JPY', 'base': 'ETC', 'quote': 'JPY', 'baseId': 'etc', 'quoteId': 'jpy' },
'ETC/JPY': { 'id': 'etc_jpy', 'symbol': 'ETC/JPY', 'base': 'ETC', 'quote': 'JPY', 'baseId': 'etc', 'quoteId': 'jpy' },
// 'DAO/JPY': { 'id': 'dao_jpy', 'symbol': 'DAO/JPY', 'base': 'DAO', 'quote': 'JPY', 'baseId': 'dao', 'quoteId': 'jpy' },
// 'LSK/JPY': { 'id': 'lsk_jpy', 'symbol': 'LSK/JPY', 'base': 'LSK', 'quote': 'JPY', 'baseId': 'lsk', 'quoteId': 'jpy' },
// 'FCT/JPY': { 'id': 'fct_jpy', 'symbol': 'FCT/JPY', 'base': 'FCT', 'quote': 'JPY', 'baseId': 'fct', 'quoteId': 'jpy' },
'FCT/JPY': { 'id': 'fct_jpy', 'symbol': 'FCT/JPY', 'base': 'FCT', 'quote': 'JPY', 'baseId': 'fct', 'quoteId': 'jpy' },
'MONA/JPY': { 'id': 'mona_jpy', 'symbol': 'MONA/JPY', 'base': 'MONA', 'quote': 'JPY', 'baseId': 'mona', 'quoteId': 'jpy' },
// 'XMR/JPY': { 'id': 'xmr_jpy', 'symbol': 'XMR/JPY', 'base': 'XMR', 'quote': 'JPY', 'baseId': 'xmr', 'quoteId': 'jpy' },
// 'REP/JPY': { 'id': 'rep_jpy', 'symbol': 'REP/JPY', 'base': 'REP', 'quote': 'JPY', 'baseId': 'rep', 'quoteId': 'jpy' },
// 'XRP/JPY': { 'id': 'xrp_jpy', 'symbol': 'XRP/JPY', 'base': 'XRP', 'quote': 'JPY', 'baseId': 'xrp', 'quoteId': 'jpy' },
@@ -93,7 +94,7 @@ module.exports = class coincheck extends Exchange {
// 'LTC/JPY': { 'id': 'ltc_jpy', 'symbol': 'LTC/JPY', 'base': 'LTC', 'quote': 'JPY', 'baseId': 'ltc', 'quoteId': 'jpy' },
// 'DASH/JPY': { 'id': 'dash_jpy', 'symbol': 'DASH/JPY', 'base': 'DASH', 'quote': 'JPY', 'baseId': 'dash', 'quoteId': 'jpy' },
// 'ETH/BTC': { 'id': 'eth_btc', 'symbol': 'ETH/BTC', 'base': 'ETH', 'quote': 'BTC', 'baseId': 'eth', 'quoteId': 'btc' },
// 'ETC/BTC': { 'id': 'etc_btc', 'symbol': 'ETC/BTC', 'base': 'ETC', 'quote': 'BTC', 'baseId': 'etc', 'quoteId': 'btc' },
'ETC/BTC': { 'id': 'etc_btc', 'symbol': 'ETC/BTC', 'base': 'ETC', 'quote': 'BTC', 'baseId': 'etc', 'quoteId': 'btc' },
// 'LSK/BTC': { 'id': 'lsk_btc', 'symbol': 'LSK/BTC', 'base': 'LSK', 'quote': 'BTC', 'baseId': 'lsk', 'quoteId': 'btc' },
// 'FCT/BTC': { 'id': 'fct_btc', 'symbol': 'FCT/BTC', 'base': 'FCT', 'quote': 'BTC', 'baseId': 'fct', 'quoteId': 'btc' },
// 'XMR/BTC': { 'id': 'xmr_btc', 'symbol': 'XMR/BTC', 'base': 'XMR', 'quote': 'BTC', 'baseId': 'xmr', 'quoteId': 'btc' },
@@ -211,11 +212,12 @@ module.exports = class coincheck extends Exchange {
}
async fetchOrderBook (symbol, limit = undefined, params = {}) {
if (symbol !== 'BTC/JPY') {
throw new BadSymbol (this.id + ' fetchOrderBook () supports BTC/JPY only');
}
await this.loadMarkets ();
const response = await this.publicGetOrderBooks (params);
const market = this.market (symbol);
const request = {
'pair': market['id'],
};
const response = await this.publicGetOrderBooks (this.extend (request, params));
return this.parseOrderBook (response);
}
@@ -224,7 +226,11 @@ module.exports = class coincheck extends Exchange {
throw new BadSymbol (this.id + ' fetchTicker () supports BTC/JPY only');
}
await this.loadMarkets ();
const ticker = await this.publicGetTicker (params);
const market = this.market (symbol);
const request = {
'pair': market['id'],
};
const ticker = await this.publicGetTicker (this.extend (request, params));
const timestamp = this.safeTimestamp (ticker, 'timestamp');
const last = this.safeFloat (ticker, 'last');
return {
@@ -338,9 +344,6 @@ module.exports = class coincheck extends Exchange {
}
async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
if (symbol !== 'BTC/JPY') {
throw new BadSymbol (this.id + ' fetchTrades () supports BTC/JPY only');
}
await this.loadMarkets ();
const market = this.market (symbol);
const request = {
@@ -229,6 +229,8 @@ module.exports = class ftx extends Exchange {
'Missing parameter price': InvalidOrder, // {"error":"Missing parameter price","success":false}
'Order not found': OrderNotFound, // {"error":"Order not found","success":false}
'Order already closed': InvalidOrder, // {"error":"Order already closed","success":false}
'Trigger price too high': InvalidOrder, // {"error":"Trigger price too high","success":false}
'Trigger price too low': InvalidOrder, // {"error":"Trigger price too low","success":false}
'Order already queued for cancellation': CancelPending, // {"error":"Order already queued for cancellation","success":false}
},
'broad': {
@@ -59,6 +59,10 @@ module.exports = class hitbtc extends Exchange {
},
'urls': {
'logo': 'https://user-images.githubusercontent.com/1294454/27766555-8eaec20e-5edc-11e7-9c5b-6dc69fc42f5e.jpg',
'test': {
'public': 'https://api.demo.hitbtc.com',
'private': 'https://api.demo.hitbtc.com',
},
'api': {
'public': 'https://api.hitbtc.com',
'private': 'https://api.hitbtc.com',
@@ -823,16 +823,8 @@ module.exports = class idex extends Exchange {
const type = this.safeString (order, 'type');
const amount = this.safeFloat (order, 'originalQuantity');
const filled = this.safeFloat (order, 'executedQuantity');
let remaining = undefined;
if ((amount !== undefined) && (filled !== undefined)) {
remaining = amount - filled;
}
const average = this.safeFloat (order, 'avgExecutionPrice');
const price = this.safeFloat (order, 'price', average); // for market orders
let cost = undefined;
if ((amount !== undefined) && (price !== undefined)) {
cost = amount * price;
}
const price = this.safeFloat (order, 'price');
const rawStatus = this.safeString (order, 'status');
const status = this.parseOrderStatus (rawStatus);
const fee = {
@@ -846,7 +838,7 @@ module.exports = class idex extends Exchange {
fee['cost'] = this.sum (fee['cost'], lastTrade['fee']['cost']);
}
const lastTradeTimestamp = this.safeInteger (lastTrade, 'timestamp');
return {
return this.safeOrder ({
'info': order,
'id': id,
'clientOrderId': clientOrderId,
@@ -861,14 +853,14 @@ module.exports = class idex extends Exchange {
'price': price,
'stopPrice': undefined,
'amount': amount,
'cost': cost,
'cost': undefined,
'average': average,
'filled': filled,
'remaining': remaining,
'remaining': undefined,
'status': status,
'fee': fee,
'trades': trades,
};
});
}
async associateWallet (walletAddress, params = {}) {
@@ -526,15 +526,16 @@ module.exports = class luno extends Exchange {
if (type === 'market') {
method += 'Marketorder';
request['type'] = side.toUpperCase ();
// todo add createMarketBuyOrderRequires price logic as it is implemented in the other exchanges
if (side === 'buy') {
request['counter_volume'] = amount;
request['counter_volume'] = parseFloat (this.amountToPrecision (symbol, amount));
} else {
request['base_volume'] = amount;
request['base_volume'] = parseFloat (this.amountToPrecision (symbol, amount));
}
} else {
method += 'Postorder';
request['volume'] = amount;
request['price'] = price;
request['volume'] = parseFloat (this.amountToPrecision (symbol, amount));
request['price'] = parseFloat (this.priceToPrecision (symbol, price));
request['type'] = (side === 'buy') ? 'BID' : 'ASK';
}
const response = await this[method] (this.extend (request, params));
@@ -466,7 +466,7 @@ module.exports = class timex extends Exchange {
'symbol': market['id'],
'quantity': this.amountToPrecision (symbol, amount),
'side': uppercaseSide,
'type': uppercaseType,
'orderTypes': uppercaseType,
// 'clientOrderId': '123',
// 'expireIn': 1575523308, // in seconds
// 'expireTime': 1575523308, // unix timestamp
@@ -1,27 +1,27 @@
{
"_from": "ccxt@1.42.67",
"_id": "ccxt@1.42.67",
"_from": "ccxt@1.42.77",
"_id": "ccxt@1.42.77",
"_inBundle": false,
"_integrity": "sha512-AOq5kwJpPVHHQC+V1Nh/Ab7/sP0UGfjZ49pF2kP/lW68gtP6XTFA4J/O76UYFHbfzBgwQJHzH3IkMIC1PG96Cw==",
"_integrity": "sha512-vPaw8G3hr9iq1iJ59EHuA6iqjufgK6dNC7MjT3qV8YQbpEJoD2ynoFwfl1hbuvlyKlFjiOa3gHwhRV64UacBDQ==",
"_location": "/ccxt",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "ccxt@1.42.67",
"raw": "ccxt@1.42.77",
"name": "ccxt",
"escapedName": "ccxt",
"rawSpec": "1.42.67",
"rawSpec": "1.42.77",
"saveSpec": null,
"fetchSpec": "1.42.67"
"fetchSpec": "1.42.77"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/ccxt/-/ccxt-1.42.67.tgz",
"_shasum": "3032fa256d75891af2834f0c5777012ab155cf6f",
"_spec": "ccxt@1.42.67",
"_resolved": "https://registry.npmjs.org/ccxt/-/ccxt-1.42.77.tgz",
"_shasum": "8ab5f8e7190854e163da6d4fcf44530794d0a21c",
"_spec": "ccxt@1.42.77",
"_where": "C:\\Superalgos\\Projects\\Superalgos\\TS\\Bot-Modules\\Sensor-Bot\\Exchange-Raw-Data",
"author": {
"name": "Igor Kroitor",
@@ -587,5 +587,5 @@
},
"types": "./ccxt.d.ts",
"unpkg": "dist/ccxt.browser.js",
"version": "1.42.67"
"version": "1.42.77"
}
@@ -3,9 +3,9 @@
"lockfileVersion": 1,
"dependencies": {
"ccxt": {
"version": "1.42.67",
"resolved": "https://registry.npmjs.org/ccxt/-/ccxt-1.42.67.tgz",
"integrity": "sha512-AOq5kwJpPVHHQC+V1Nh/Ab7/sP0UGfjZ49pF2kP/lW68gtP6XTFA4J/O76UYFHbfzBgwQJHzH3IkMIC1PG96Cw=="
"version": "1.42.77",
"resolved": "https://registry.npmjs.org/ccxt/-/ccxt-1.42.77.tgz",
"integrity": "sha512-vPaw8G3hr9iq1iJ59EHuA6iqjufgK6dNC7MjT3qV8YQbpEJoD2ynoFwfl1hbuvlyKlFjiOa3gHwhRV64UacBDQ=="
}
}
}
@@ -229,13 +229,13 @@ console.log (ccxt.exchanges) // print all available exchanges
All-in-one browser bundle (dependencies included), served from a CDN of your choice:
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@1.42.67/dist/ccxt.browser.js
* unpkg: https://unpkg.com/ccxt@1.42.67/dist/ccxt.browser.js
* jsDelivr: https://cdn.jsdelivr.net/npm/ccxt@1.42.77/dist/ccxt.browser.js
* unpkg: https://unpkg.com/ccxt@1.42.77/dist/ccxt.browser.js
CDNs are not updated in real-time and may have delays. Defaulting to the most recent version without specifying the version number is not recommended. Please, keep in mind that we are not responsible for the correct operation of those CDN servers.
```HTML
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@1.42.67/dist/ccxt.browser.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ccxt@1.42.77/dist/ccxt.browser.js"></script>
```
Creates a global `ccxt` object:
@@ -1080,19 +1080,37 @@ class Transpiler {
// ========================================================================
exportTypeScriptDeclarations (file, classes) {
exportTypeScriptClassNames (file, classes) {
log.bright.cyan ('Exporting TypeScript declarations →', file.yellow)
log.bright.cyan ('Exporting TypeScript class names →', file.yellow)
const regex = /\/[\n]{2}(?: export class [^\s]+ extends [^\s]+ \{\}[\r]?[\n])+/
const replacement = "/\n\n" + Object.keys (classes).map (className => {
const baseClass = classes[className]
const baseClass = classes[className].replace (/ccxt\.[a-z_]+/, 'Exchange')
return ' export class ' + className + ' extends ' + baseClass + " {}"
}).join ("\n") + "\n"
replaceInFile (file, regex, replacement)
}
exportTypeScriptExchangeIds (file, classes) {
log.bright.cyan ('Exporting TypeScript exchange ids →', file.yellow)
const regex = /\/[\n]{2} export type ExchangeId =\n(?: \| \'[a-z0-9_]+\'[\r]?[\n])+/
const replacement = "/\n\n export type ExchangeId =\n" + Object.keys (classes).map (className => {
return " | '" + className + "'"
}).join ("\n") + "\n"
replaceInFile (file, regex, replacement)
}
exportTypeScriptDeclarations (file, classes) {
this.exportTypeScriptClassNames (file, classes)
this.exportTypeScriptExchangeIds (file, classes)
}
// ========================================================================
transpileErrorHierarchy () {
@@ -551,4 +551,132 @@ declare module 'ccxt' {
/* tslint:enable */
export type ExchangeId =
| 'aax'
| 'acx'
| 'aofex'
| 'bequant'
| 'bibox'
| 'bigone'
| 'binance'
| 'binanceus'
| 'bit2c'
| 'bitbank'
| 'bitbay'
| 'bitcoincom'
| 'bitfinex'
| 'bitfinex2'
| 'bitflyer'
| 'bitforex'
| 'bitget'
| 'bithumb'
| 'bitkk'
| 'bitmart'
| 'bitmax'
| 'bitmex'
| 'bitpanda'
| 'bitso'
| 'bitstamp'
| 'bitstamp1'
| 'bittrex'
| 'bitvavo'
| 'bitz'
| 'bl3p'
| 'bleutrade'
| 'braziliex'
| 'btcalpha'
| 'btcbox'
| 'btcmarkets'
| 'btctradeua'
| 'btcturk'
| 'buda'
| 'bw'
| 'bybit'
| 'bytetrade'
| 'cdax'
| 'cex'
| 'chilebit'
| 'coinbase'
| 'coinbaseprime'
| 'coinbasepro'
| 'coincheck'
| 'coinegg'
| 'coinex'
| 'coinfalcon'
| 'coinfloor'
| 'coingi'
| 'coinmarketcap'
| 'coinmate'
| 'coinone'
| 'coinspot'
| 'crex24'
| 'currencycom'
| 'delta'
| 'deribit'
| 'digifinex'
| 'dsx'
| 'equos'
| 'eterbase'
| 'exmo'
| 'exx'
| 'fcoin'
| 'fcoinjp'
| 'flowbtc'
| 'foxbit'
| 'ftx'
| 'gateio'
| 'gemini'
| 'gopax'
| 'hbtc'
| 'hitbtc'
| 'hollaex'
| 'huobijp'
| 'huobipro'
| 'ice3x'
| 'idex'
| 'independentreserve'
| 'indodax'
| 'itbit'
| 'kraken'
| 'kucoin'
| 'kuna'
| 'lakebtc'
| 'latoken'
| 'lbank'
| 'liquid'
| 'luno'
| 'lykke'
| 'mercado'
| 'mixcoins'
| 'ndax'
| 'novadax'
| 'oceanex'
| 'okcoin'
| 'okex'
| 'paymium'
| 'phemex'
| 'poloniex'
| 'probit'
| 'qtrade'
| 'rightbtc'
| 'ripio'
| 'southxchange'
| 'stex'
| 'surbitcoin'
| 'therock'
| 'tidebit'
| 'tidex'
| 'timex'
| 'upbit'
| 'vaultoro'
| 'vbtc'
| 'vcc'
| 'wavesexchange'
| 'whitebit'
| 'xbtce'
| 'xena'
| 'yobit'
| 'zaif'
| 'zb'
}
@@ -35,7 +35,7 @@ const Exchange = require ('./js/base/Exchange')
//-----------------------------------------------------------------------------
// this is updated by vss.js when building
const version = '1.42.67'
const version = '1.42.77'
Exchange.ccxtVersion = version
@@ -43,7 +43,7 @@ const Exchange = require ('./js/base/Exchange')
//-----------------------------------------------------------------------------
// this is updated by vss.js when building
const version = '1.42.67'
const version = '1.42.77'
Exchange.ccxtVersion = version
@@ -4956,8 +4956,77 @@ module.exports = class Exchange {
integerPow (a, b) {
return new BN (a).pow (new BN (b))
}
}
safeOrder (order) {
// Cost
// Remaining
// Average
// Price
// Amount
// Filled
//
// First we try to calculate filled from the trades
const parseFilled = order['filled'] === undefined;
const parseCost = order['cost'] === undefined;
if (parseFilled) {
order['filled'] = 0
}
if (parseCost) {
order['cost'] = 0
}
if (parseFilled || parseCost) {
if (Array.isArray (order['trades'])) {
for (let i = 0; i < order['trades'].length; i++) {
const trade = order['trades'][i]
if (parseFilled) {
order['filled'] = this.sum (order['filled'], trade['amount'])
}
if (parseCost) {
order['cost'] = this.sum (order['cost'], trade['cost'])
}
}
}
}
// We ensure amount = filled + remaining
if (order['amount'] === undefined) {
if (order['filled'] !== undefined && order['remaining'] !== undefined) {
order['amount'] = this.sum (order['filled'], order['remaining'])
}
}
if (order['filled'] === undefined) {
if (order['amount'] !== undefined && order['remaining'] !== undefined) {
order['filled'] = Math.max (this.sum (order['amount'], -order['remaining']), 0)
}
}
if (order['remaining'] === undefined) {
if (order['amount'] !== undefined && order['filled'] !== undefined) {
order['remaining'] = Math.max (this.sum (order['amount'], -order['filled']), 0)
}
}
// We ensure that the average field is calculated correctly
if (order['average'] === undefined) {
if (order['filled'] !== undefined && order['cost'] !== undefined && order['cost'] > 0) {
order['average'] = order['filled'] / order['cost']
}
}
// We also ensure the cost field is calculated correctly
const costPriceExists = (order['average'] !== undefined) || (order['price'] !== undefined)
if ((order['filled'] !== undefined) && costPriceExists) {
let costPrice = undefined;
if (order['average'] === undefined) {
costPrice = order['price']
} else {
costPrice = order['average']
}
order['cost'] = costPrice * order['filled']
}
// We add support for market orders
if (order['price'] === undefined && order['type'] === 'market') {
order['price'] = order['average']
}
return order
}
}
},{"../static_dependencies/BN/bn":126,"./errors":8,"./functions":9}],7:[function(require,module,exports){
'use strict';
@@ -50697,10 +50766,11 @@ module.exports = class coincheck extends Exchange {
'markets': {
'BTC/JPY': { 'id': 'btc_jpy', 'symbol': 'BTC/JPY', 'base': 'BTC', 'quote': 'JPY', 'baseId': 'btc', 'quoteId': 'jpy' }, // the only real pair
// 'ETH/JPY': { 'id': 'eth_jpy', 'symbol': 'ETH/JPY', 'base': 'ETH', 'quote': 'JPY', 'baseId': 'eth', 'quoteId': 'jpy' },
// 'ETC/JPY': { 'id': 'etc_jpy', 'symbol': 'ETC/JPY', 'base': 'ETC', 'quote': 'JPY', 'baseId': 'etc', 'quoteId': 'jpy' },
'ETC/JPY': { 'id': 'etc_jpy', 'symbol': 'ETC/JPY', 'base': 'ETC', 'quote': 'JPY', 'baseId': 'etc', 'quoteId': 'jpy' },
// 'DAO/JPY': { 'id': 'dao_jpy', 'symbol': 'DAO/JPY', 'base': 'DAO', 'quote': 'JPY', 'baseId': 'dao', 'quoteId': 'jpy' },
// 'LSK/JPY': { 'id': 'lsk_jpy', 'symbol': 'LSK/JPY', 'base': 'LSK', 'quote': 'JPY', 'baseId': 'lsk', 'quoteId': 'jpy' },
// 'FCT/JPY': { 'id': 'fct_jpy', 'symbol': 'FCT/JPY', 'base': 'FCT', 'quote': 'JPY', 'baseId': 'fct', 'quoteId': 'jpy' },
'FCT/JPY': { 'id': 'fct_jpy', 'symbol': 'FCT/JPY', 'base': 'FCT', 'quote': 'JPY', 'baseId': 'fct', 'quoteId': 'jpy' },
'MONA/JPY': { 'id': 'mona_jpy', 'symbol': 'MONA/JPY', 'base': 'MONA', 'quote': 'JPY', 'baseId': 'mona', 'quoteId': 'jpy' },
// 'XMR/JPY': { 'id': 'xmr_jpy', 'symbol': 'XMR/JPY', 'base': 'XMR', 'quote': 'JPY', 'baseId': 'xmr', 'quoteId': 'jpy' },
// 'REP/JPY': { 'id': 'rep_jpy', 'symbol': 'REP/JPY', 'base': 'REP', 'quote': 'JPY', 'baseId': 'rep', 'quoteId': 'jpy' },
// 'XRP/JPY': { 'id': 'xrp_jpy', 'symbol': 'XRP/JPY', 'base': 'XRP', 'quote': 'JPY', 'baseId': 'xrp', 'quoteId': 'jpy' },
@@ -50709,7 +50779,7 @@ module.exports = class coincheck extends Exchange {
// 'LTC/JPY': { 'id': 'ltc_jpy', 'symbol': 'LTC/JPY', 'base': 'LTC', 'quote': 'JPY', 'baseId': 'ltc', 'quoteId': 'jpy' },
// 'DASH/JPY': { 'id': 'dash_jpy', 'symbol': 'DASH/JPY', 'base': 'DASH', 'quote': 'JPY', 'baseId': 'dash', 'quoteId': 'jpy' },
// 'ETH/BTC': { 'id': 'eth_btc', 'symbol': 'ETH/BTC', 'base': 'ETH', 'quote': 'BTC', 'baseId': 'eth', 'quoteId': 'btc' },
// 'ETC/BTC': { 'id': 'etc_btc', 'symbol': 'ETC/BTC', 'base': 'ETC', 'quote': 'BTC', 'baseId': 'etc', 'quoteId': 'btc' },
'ETC/BTC': { 'id': 'etc_btc', 'symbol': 'ETC/BTC', 'base': 'ETC', 'quote': 'BTC', 'baseId': 'etc', 'quoteId': 'btc' },
// 'LSK/BTC': { 'id': 'lsk_btc', 'symbol': 'LSK/BTC', 'base': 'LSK', 'quote': 'BTC', 'baseId': 'lsk', 'quoteId': 'btc' },
// 'FCT/BTC': { 'id': 'fct_btc', 'symbol': 'FCT/BTC', 'base': 'FCT', 'quote': 'BTC', 'baseId': 'fct', 'quoteId': 'btc' },
// 'XMR/BTC': { 'id': 'xmr_btc', 'symbol': 'XMR/BTC', 'base': 'XMR', 'quote': 'BTC', 'baseId': 'xmr', 'quoteId': 'btc' },
@@ -50827,11 +50897,12 @@ module.exports = class coincheck extends Exchange {
}
async fetchOrderBook (symbol, limit = undefined, params = {}) {
if (symbol !== 'BTC/JPY') {
throw new BadSymbol (this.id + ' fetchOrderBook () supports BTC/JPY only');
}
await this.loadMarkets ();
const response = await this.publicGetOrderBooks (params);
const market = this.market (symbol);
const request = {
'pair': market['id'],
};
const response = await this.publicGetOrderBooks (this.extend (request, params));
return this.parseOrderBook (response);
}
@@ -50840,7 +50911,11 @@ module.exports = class coincheck extends Exchange {
throw new BadSymbol (this.id + ' fetchTicker () supports BTC/JPY only');
}
await this.loadMarkets ();
const ticker = await this.publicGetTicker (params);
const market = this.market (symbol);
const request = {
'pair': market['id'],
};
const ticker = await this.publicGetTicker (this.extend (request, params));
const timestamp = this.safeTimestamp (ticker, 'timestamp');
const last = this.safeFloat (ticker, 'last');
return {
@@ -50954,9 +51029,6 @@ module.exports = class coincheck extends Exchange {
}
async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
if (symbol !== 'BTC/JPY') {
throw new BadSymbol (this.id + ' fetchTrades () supports BTC/JPY only');
}
await this.loadMarkets ();
const market = this.market (symbol);
const request = {
@@ -70802,6 +70874,8 @@ module.exports = class ftx extends Exchange {
'Missing parameter price': InvalidOrder, // {"error":"Missing parameter price","success":false}
'Order not found': OrderNotFound, // {"error":"Order not found","success":false}
'Order already closed': InvalidOrder, // {"error":"Order already closed","success":false}
'Trigger price too high': InvalidOrder, // {"error":"Trigger price too high","success":false}
'Trigger price too low': InvalidOrder, // {"error":"Trigger price too low","success":false}
'Order already queued for cancellation': CancelPending, // {"error":"Order already queued for cancellation","success":false}
},
'broad': {
@@ -77728,6 +77802,10 @@ module.exports = class hitbtc extends Exchange {
},
'urls': {
'logo': 'https://user-images.githubusercontent.com/1294454/27766555-8eaec20e-5edc-11e7-9c5b-6dc69fc42f5e.jpg',
'test': {
'public': 'https://api.demo.hitbtc.com',
'private': 'https://api.demo.hitbtc.com',
},
'api': {
'public': 'https://api.hitbtc.com',
'private': 'https://api.hitbtc.com',
@@ -82899,16 +82977,8 @@ module.exports = class idex extends Exchange {
const type = this.safeString (order, 'type');
const amount = this.safeFloat (order, 'originalQuantity');
const filled = this.safeFloat (order, 'executedQuantity');
let remaining = undefined;
if ((amount !== undefined) && (filled !== undefined)) {
remaining = amount - filled;
}
const average = this.safeFloat (order, 'avgExecutionPrice');
const price = this.safeFloat (order, 'price', average); // for market orders
let cost = undefined;
if ((amount !== undefined) && (price !== undefined)) {
cost = amount * price;
}
const price = this.safeFloat (order, 'price');
const rawStatus = this.safeString (order, 'status');
const status = this.parseOrderStatus (rawStatus);
const fee = {
@@ -82922,7 +82992,7 @@ module.exports = class idex extends Exchange {
fee['cost'] = this.sum (fee['cost'], lastTrade['fee']['cost']);
}
const lastTradeTimestamp = this.safeInteger (lastTrade, 'timestamp');
return {
return this.safeOrder ({
'info': order,
'id': id,
'clientOrderId': clientOrderId,
@@ -82937,14 +83007,14 @@ module.exports = class idex extends Exchange {
'price': price,
'stopPrice': undefined,
'amount': amount,
'cost': cost,
'cost': undefined,
'average': average,
'filled': filled,
'remaining': remaining,
'remaining': undefined,
'status': status,
'fee': fee,
'trades': trades,
};
});
}
async associateWallet (walletAddress, params = {}) {
@@ -92726,15 +92796,16 @@ module.exports = class luno extends Exchange {
if (type === 'market') {
method += 'Marketorder';
request['type'] = side.toUpperCase ();
// todo add createMarketBuyOrderRequires price logic as it is implemented in the other exchanges
if (side === 'buy') {
request['counter_volume'] = amount;
request['counter_volume'] = parseFloat (this.amountToPrecision (symbol, amount));
} else {
request['base_volume'] = amount;
request['base_volume'] = parseFloat (this.amountToPrecision (symbol, amount));
}
} else {
method += 'Postorder';
request['volume'] = amount;
request['price'] = price;
request['volume'] = parseFloat (this.amountToPrecision (symbol, amount));
request['price'] = parseFloat (this.priceToPrecision (symbol, price));
request['type'] = (side === 'buy') ? 'BID' : 'ASK';
}
const response = await this[method] (this.extend (request, params));
@@ -135007,7 +135078,7 @@ module.exports = class timex extends Exchange {
'symbol': market['id'],
'quantity': this.amountToPrecision (symbol, amount),
'side': uppercaseSide,
'type': uppercaseType,
'orderTypes': uppercaseType,
// 'clientOrderId': '123',
// 'expireIn': 1575523308, // in seconds
// 'expireTime': 1575523308, // unix timestamp
@@ -1392,5 +1392,74 @@ module.exports = class Exchange {
integerPow (a, b) {
return new BN (a).pow (new BN (b))
}
}
safeOrder (order) {
// Cost
// Remaining
// Average
// Price
// Amount
// Filled
//
// First we try to calculate filled from the trades
const parseFilled = order['filled'] === undefined;
const parseCost = order['cost'] === undefined;
if (parseFilled) {
order['filled'] = 0
}
if (parseCost) {
order['cost'] = 0
}
if (parseFilled || parseCost) {
if (Array.isArray (order['trades'])) {
for (let i = 0; i < order['trades'].length; i++) {
const trade = order['trades'][i]
if (parseFilled) {
order['filled'] = this.sum (order['filled'], trade['amount'])
}
if (parseCost) {
order['cost'] = this.sum (order['cost'], trade['cost'])
}
}
}
}
// We ensure amount = filled + remaining
if (order['amount'] === undefined) {
if (order['filled'] !== undefined && order['remaining'] !== undefined) {
order['amount'] = this.sum (order['filled'], order['remaining'])
}
}
if (order['filled'] === undefined) {
if (order['amount'] !== undefined && order['remaining'] !== undefined) {
order['filled'] = Math.max (this.sum (order['amount'], -order['remaining']), 0)
}
}
if (order['remaining'] === undefined) {
if (order['amount'] !== undefined && order['filled'] !== undefined) {
order['remaining'] = Math.max (this.sum (order['amount'], -order['filled']), 0)
}
}
// We ensure that the average field is calculated correctly
if (order['average'] === undefined) {
if (order['filled'] !== undefined && order['cost'] !== undefined && order['cost'] > 0) {
order['average'] = order['filled'] / order['cost']
}
}
// We also ensure the cost field is calculated correctly
const costPriceExists = (order['average'] !== undefined) || (order['price'] !== undefined)
if ((order['filled'] !== undefined) && costPriceExists) {
let costPrice = undefined;
if (order['average'] === undefined) {
costPrice = order['price']
} else {
costPrice = order['average']
}
order['cost'] = costPrice * order['filled']
}
// We add support for market orders
if (order['price'] === undefined && order['type'] === 'market') {
order['price'] = order['average']
}
return order
}
}
@@ -81,10 +81,11 @@ module.exports = class coincheck extends Exchange {
'markets': {
'BTC/JPY': { 'id': 'btc_jpy', 'symbol': 'BTC/JPY', 'base': 'BTC', 'quote': 'JPY', 'baseId': 'btc', 'quoteId': 'jpy' }, // the only real pair
// 'ETH/JPY': { 'id': 'eth_jpy', 'symbol': 'ETH/JPY', 'base': 'ETH', 'quote': 'JPY', 'baseId': 'eth', 'quoteId': 'jpy' },
// 'ETC/JPY': { 'id': 'etc_jpy', 'symbol': 'ETC/JPY', 'base': 'ETC', 'quote': 'JPY', 'baseId': 'etc', 'quoteId': 'jpy' },
'ETC/JPY': { 'id': 'etc_jpy', 'symbol': 'ETC/JPY', 'base': 'ETC', 'quote': 'JPY', 'baseId': 'etc', 'quoteId': 'jpy' },
// 'DAO/JPY': { 'id': 'dao_jpy', 'symbol': 'DAO/JPY', 'base': 'DAO', 'quote': 'JPY', 'baseId': 'dao', 'quoteId': 'jpy' },
// 'LSK/JPY': { 'id': 'lsk_jpy', 'symbol': 'LSK/JPY', 'base': 'LSK', 'quote': 'JPY', 'baseId': 'lsk', 'quoteId': 'jpy' },
// 'FCT/JPY': { 'id': 'fct_jpy', 'symbol': 'FCT/JPY', 'base': 'FCT', 'quote': 'JPY', 'baseId': 'fct', 'quoteId': 'jpy' },
'FCT/JPY': { 'id': 'fct_jpy', 'symbol': 'FCT/JPY', 'base': 'FCT', 'quote': 'JPY', 'baseId': 'fct', 'quoteId': 'jpy' },
'MONA/JPY': { 'id': 'mona_jpy', 'symbol': 'MONA/JPY', 'base': 'MONA', 'quote': 'JPY', 'baseId': 'mona', 'quoteId': 'jpy' },
// 'XMR/JPY': { 'id': 'xmr_jpy', 'symbol': 'XMR/JPY', 'base': 'XMR', 'quote': 'JPY', 'baseId': 'xmr', 'quoteId': 'jpy' },
// 'REP/JPY': { 'id': 'rep_jpy', 'symbol': 'REP/JPY', 'base': 'REP', 'quote': 'JPY', 'baseId': 'rep', 'quoteId': 'jpy' },
// 'XRP/JPY': { 'id': 'xrp_jpy', 'symbol': 'XRP/JPY', 'base': 'XRP', 'quote': 'JPY', 'baseId': 'xrp', 'quoteId': 'jpy' },
@@ -93,7 +94,7 @@ module.exports = class coincheck extends Exchange {
// 'LTC/JPY': { 'id': 'ltc_jpy', 'symbol': 'LTC/JPY', 'base': 'LTC', 'quote': 'JPY', 'baseId': 'ltc', 'quoteId': 'jpy' },
// 'DASH/JPY': { 'id': 'dash_jpy', 'symbol': 'DASH/JPY', 'base': 'DASH', 'quote': 'JPY', 'baseId': 'dash', 'quoteId': 'jpy' },
// 'ETH/BTC': { 'id': 'eth_btc', 'symbol': 'ETH/BTC', 'base': 'ETH', 'quote': 'BTC', 'baseId': 'eth', 'quoteId': 'btc' },
// 'ETC/BTC': { 'id': 'etc_btc', 'symbol': 'ETC/BTC', 'base': 'ETC', 'quote': 'BTC', 'baseId': 'etc', 'quoteId': 'btc' },
'ETC/BTC': { 'id': 'etc_btc', 'symbol': 'ETC/BTC', 'base': 'ETC', 'quote': 'BTC', 'baseId': 'etc', 'quoteId': 'btc' },
// 'LSK/BTC': { 'id': 'lsk_btc', 'symbol': 'LSK/BTC', 'base': 'LSK', 'quote': 'BTC', 'baseId': 'lsk', 'quoteId': 'btc' },
// 'FCT/BTC': { 'id': 'fct_btc', 'symbol': 'FCT/BTC', 'base': 'FCT', 'quote': 'BTC', 'baseId': 'fct', 'quoteId': 'btc' },
// 'XMR/BTC': { 'id': 'xmr_btc', 'symbol': 'XMR/BTC', 'base': 'XMR', 'quote': 'BTC', 'baseId': 'xmr', 'quoteId': 'btc' },
@@ -211,11 +212,12 @@ module.exports = class coincheck extends Exchange {
}
async fetchOrderBook (symbol, limit = undefined, params = {}) {
if (symbol !== 'BTC/JPY') {
throw new BadSymbol (this.id + ' fetchOrderBook () supports BTC/JPY only');
}
await this.loadMarkets ();
const response = await this.publicGetOrderBooks (params);
const market = this.market (symbol);
const request = {
'pair': market['id'],
};
const response = await this.publicGetOrderBooks (this.extend (request, params));
return this.parseOrderBook (response);
}
@@ -224,7 +226,11 @@ module.exports = class coincheck extends Exchange {
throw new BadSymbol (this.id + ' fetchTicker () supports BTC/JPY only');
}
await this.loadMarkets ();
const ticker = await this.publicGetTicker (params);
const market = this.market (symbol);
const request = {
'pair': market['id'],
};
const ticker = await this.publicGetTicker (this.extend (request, params));
const timestamp = this.safeTimestamp (ticker, 'timestamp');
const last = this.safeFloat (ticker, 'last');
return {
@@ -338,9 +344,6 @@ module.exports = class coincheck extends Exchange {
}
async fetchTrades (symbol, since = undefined, limit = undefined, params = {}) {
if (symbol !== 'BTC/JPY') {
throw new BadSymbol (this.id + ' fetchTrades () supports BTC/JPY only');
}
await this.loadMarkets ();
const market = this.market (symbol);
const request = {
@@ -229,6 +229,8 @@ module.exports = class ftx extends Exchange {
'Missing parameter price': InvalidOrder, // {"error":"Missing parameter price","success":false}
'Order not found': OrderNotFound, // {"error":"Order not found","success":false}
'Order already closed': InvalidOrder, // {"error":"Order already closed","success":false}
'Trigger price too high': InvalidOrder, // {"error":"Trigger price too high","success":false}
'Trigger price too low': InvalidOrder, // {"error":"Trigger price too low","success":false}
'Order already queued for cancellation': CancelPending, // {"error":"Order already queued for cancellation","success":false}
},
'broad': {
@@ -59,6 +59,10 @@ module.exports = class hitbtc extends Exchange {
},
'urls': {
'logo': 'https://user-images.githubusercontent.com/1294454/27766555-8eaec20e-5edc-11e7-9c5b-6dc69fc42f5e.jpg',
'test': {
'public': 'https://api.demo.hitbtc.com',
'private': 'https://api.demo.hitbtc.com',
},
'api': {
'public': 'https://api.hitbtc.com',
'private': 'https://api.hitbtc.com',
@@ -823,16 +823,8 @@ module.exports = class idex extends Exchange {
const type = this.safeString (order, 'type');
const amount = this.safeFloat (order, 'originalQuantity');
const filled = this.safeFloat (order, 'executedQuantity');
let remaining = undefined;
if ((amount !== undefined) && (filled !== undefined)) {
remaining = amount - filled;
}
const average = this.safeFloat (order, 'avgExecutionPrice');
const price = this.safeFloat (order, 'price', average); // for market orders
let cost = undefined;
if ((amount !== undefined) && (price !== undefined)) {
cost = amount * price;
}
const price = this.safeFloat (order, 'price');
const rawStatus = this.safeString (order, 'status');
const status = this.parseOrderStatus (rawStatus);
const fee = {
@@ -846,7 +838,7 @@ module.exports = class idex extends Exchange {
fee['cost'] = this.sum (fee['cost'], lastTrade['fee']['cost']);
}
const lastTradeTimestamp = this.safeInteger (lastTrade, 'timestamp');
return {
return this.safeOrder ({
'info': order,
'id': id,
'clientOrderId': clientOrderId,
@@ -861,14 +853,14 @@ module.exports = class idex extends Exchange {
'price': price,
'stopPrice': undefined,
'amount': amount,
'cost': cost,
'cost': undefined,
'average': average,
'filled': filled,
'remaining': remaining,
'remaining': undefined,
'status': status,
'fee': fee,
'trades': trades,
};
});
}
async associateWallet (walletAddress, params = {}) {
@@ -526,15 +526,16 @@ module.exports = class luno extends Exchange {
if (type === 'market') {
method += 'Marketorder';
request['type'] = side.toUpperCase ();
// todo add createMarketBuyOrderRequires price logic as it is implemented in the other exchanges
if (side === 'buy') {
request['counter_volume'] = amount;
request['counter_volume'] = parseFloat (this.amountToPrecision (symbol, amount));
} else {
request['base_volume'] = amount;
request['base_volume'] = parseFloat (this.amountToPrecision (symbol, amount));
}
} else {
method += 'Postorder';
request['volume'] = amount;
request['price'] = price;
request['volume'] = parseFloat (this.amountToPrecision (symbol, amount));
request['price'] = parseFloat (this.priceToPrecision (symbol, price));
request['type'] = (side === 'buy') ? 'BID' : 'ASK';
}
const response = await this[method] (this.extend (request, params));
@@ -466,7 +466,7 @@ module.exports = class timex extends Exchange {
'symbol': market['id'],
'quantity': this.amountToPrecision (symbol, amount),
'side': uppercaseSide,
'type': uppercaseType,
'orderTypes': uppercaseType,
// 'clientOrderId': '123',
// 'expireIn': 1575523308, // in seconds
// 'expireTime': 1575523308, // unix timestamp
@@ -1,27 +1,27 @@
{
"_from": "ccxt@1.42.67",
"_id": "ccxt@1.42.67",
"_from": "ccxt@1.42.77",
"_id": "ccxt@1.42.77",
"_inBundle": false,
"_integrity": "sha512-AOq5kwJpPVHHQC+V1Nh/Ab7/sP0UGfjZ49pF2kP/lW68gtP6XTFA4J/O76UYFHbfzBgwQJHzH3IkMIC1PG96Cw==",
"_integrity": "sha512-vPaw8G3hr9iq1iJ59EHuA6iqjufgK6dNC7MjT3qV8YQbpEJoD2ynoFwfl1hbuvlyKlFjiOa3gHwhRV64UacBDQ==",
"_location": "/ccxt",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "ccxt@1.42.67",
"raw": "ccxt@1.42.77",
"name": "ccxt",
"escapedName": "ccxt",
"rawSpec": "1.42.67",
"rawSpec": "1.42.77",
"saveSpec": null,
"fetchSpec": "1.42.67"
"fetchSpec": "1.42.77"
},
"_requiredBy": [
"#USER",
"/"
],
"_resolved": "https://registry.npmjs.org/ccxt/-/ccxt-1.42.67.tgz",
"_shasum": "3032fa256d75891af2834f0c5777012ab155cf6f",
"_spec": "ccxt@1.42.67",
"_resolved": "https://registry.npmjs.org/ccxt/-/ccxt-1.42.77.tgz",
"_shasum": "8ab5f8e7190854e163da6d4fcf44530794d0a21c",
"_spec": "ccxt@1.42.77",
"_where": "C:\\Superalgos\\Projects\\Superalgos\\TS\\Bot-Modules\\Trading-Bot\\Low-Frequency-Trading\\APIs",
"author": {
"name": "Igor Kroitor",
@@ -587,5 +587,5 @@
},
"types": "./ccxt.d.ts",
"unpkg": "dist/ccxt.browser.js",
"version": "1.42.67"
"version": "1.42.77"
}
@@ -3,9 +3,9 @@
"lockfileVersion": 1,
"dependencies": {
"ccxt": {
"version": "1.42.67",
"resolved": "https://registry.npmjs.org/ccxt/-/ccxt-1.42.67.tgz",
"integrity": "sha512-AOq5kwJpPVHHQC+V1Nh/Ab7/sP0UGfjZ49pF2kP/lW68gtP6XTFA4J/O76UYFHbfzBgwQJHzH3IkMIC1PG96Cw=="
"version": "1.42.77",
"resolved": "https://registry.npmjs.org/ccxt/-/ccxt-1.42.77.tgz",
"integrity": "sha512-vPaw8G3hr9iq1iJ59EHuA6iqjufgK6dNC7MjT3qV8YQbpEJoD2ynoFwfl1hbuvlyKlFjiOa3gHwhRV64UacBDQ=="
}
}
}