Snapshots

This commit is contained in:
Luis Fernando Molina committed 2020-05-10 14:17:33 +02:00
1 parent e91125801d
commit 6368221937
75 files changed
+8943 -4332

No files matched your search

+263 -32
View File
@@ -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 = {