Snapshots
This commit is contained in:
1 parent
e91125801d
commit
6368221937
75 files changed
+8943
-4332
No files matched your search
+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 = {
|
||||
|
||||
Reference in new issue
Block a user