diff --git a/exchanges.cfg b/exchanges.cfg index 9c8a4608cc09f..70a2036b095e1 100644 --- a/exchanges.cfg +++ b/exchanges.cfg @@ -4,6 +4,6 @@ # Leaving this config empty will build all exchanges. # ------------------------------------------------------------------------------- -# binance -# huobi -# kraken +binance +kraken +kucoin diff --git a/js/src/abstract/kraken.d.ts b/js/src/abstract/kraken.d.ts index d5c5e3185b4fa..5ca32bf2c08e6 100644 --- a/js/src/abstract/kraken.d.ts +++ b/js/src/abstract/kraken.d.ts @@ -15,6 +15,7 @@ interface Exchange { privatePostAddOrder(params?: {}): Promise; privatePostAddOrderBatch(params?: {}): Promise; privatePostAddExport(params?: {}): Promise; + privatePostAmendOrder(params?: {}): Promise; privatePostBalance(params?: {}): Promise; privatePostCancelAll(params?: {}): Promise; privatePostCancelAllOrdersAfter(params?: {}): Promise; diff --git a/ts/src/kraken.ts b/ts/src/kraken.ts index 3be05f645c35b..53124abd7e9d3 100644 --- a/ts/src/kraken.ts +++ b/ts/src/kraken.ts @@ -178,6 +178,7 @@ export default class kraken extends Exchange { 'AddOrder': 0, 'AddOrderBatch': 0, 'AddExport': 3, + 'AmendOrder': 0, 'Balance': 3, 'CancelAll': 3, 'CancelAllOrdersAfter': 3, @@ -1468,6 +1469,7 @@ export default class kraken extends Exchange { * @method * @name kraken#createOrder * @see https://docs.kraken.com/rest/#tag/Spot-Trading/operation/addOrder + * @see https://docs.kraken.com/api/docs/rest-api/add-order/ * @description create a trade order * @param {string} symbol unified symbol of the market to create an order in * @param {string} type 'market' or 'limit' @@ -1483,6 +1485,7 @@ export default class kraken extends Exchange { * @param {string} [params.trailingLimitAmount] *margin only* the quote amount away from the trailingAmount * @param {string} [params.offset] *margin only* '+' or '-' whether you want the trailingLimitAmount value to be positive or negative, default is negative '-' * @param {string} [params.trigger] *margin only* the activation price type, 'last' or 'index', default is 'last' + * @param {int} [params.leverage] the leverage level to use * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ await this.loadMarkets (); @@ -1750,7 +1753,7 @@ export default class kraken extends Exchange { const txid = this.safeList (order, 'txid'); id = this.safeString (txid, 0); } - const clientOrderId = this.safeString2 (order, 'userref', 'newuserref'); + const clientOrderId = this.safeStringN (order, [ 'cl_ord_id', 'userref', 'newuserref' ]); const rawTrades = this.safeValue (order, 'trades', []); const trades = []; for (let i = 0; i < rawTrades.length; i++) { @@ -1801,10 +1804,10 @@ export default class kraken extends Exchange { } orderRequest (method: string, symbol: string, type: string, request: Dict, amount: Num, price: Num = undefined, params = {}) { - const clientOrderId = this.safeString2 (params, 'userref', 'clientOrderId'); - params = this.omit (params, [ 'userref', 'clientOrderId' ]); + const clientOrderId = this.safeString2 (params, 'cl_ord_id', 'clientOrderId'); + params = this.omit (params, [ 'cl_ord_id', 'clientOrderId' ]); if (clientOrderId !== undefined) { - request['userref'] = clientOrderId; + request['cl_ord_id'] = clientOrderId; } const stopLossTriggerPrice = this.safeString (params, 'stopLossPrice'); const takeProfitTriggerPrice = this.safeString (params, 'takeProfitPrice'); @@ -1909,7 +1912,7 @@ export default class kraken extends Exchange { * @method * @name kraken#editOrder * @description edit a trade order - * @see https://docs.kraken.com/rest/#tag/Spot-Trading/operation/editOrder + * @see https://docs.kraken.com/api/docs/rest-api/amend-order/ * @param {string} id order id * @param {string} symbol unified symbol of the market to create an order in * @param {string} type 'market' or 'limit' @@ -1930,33 +1933,39 @@ export default class kraken extends Exchange { if (!market['spot']) { throw new NotSupported (this.id + ' editOrder() does not support ' + market['type'] + ' orders, only spot orders are accepted'); } - const request: Dict = { - 'txid': id, - 'pair': market['id'], - }; + const request: Dict = { 'txid': id }; + const clientOrderId = this.safeString2 (params, 'cl_ord_id', 'clientOrderId'); + params = this.omit (params, [ 'cl_ord_id', 'clientOrderId' ]); + if (clientOrderId !== undefined) { + request['cl_ord_id'] = clientOrderId; + } if (amount !== undefined) { request['volume'] = this.amountToPrecision (symbol, amount); + request['order_qty'] = this.amountToPrecision (symbol, amount); + } + if (price !== undefined) { + const isLimitOrder = type.endsWith ('limit'); // supporting limit, stop-loss-limit, take-profit-limit, etc + if (isLimitOrder) { + request['limit_price'] = this.priceToPrecision (symbol, price); + } else { + request['trigger_price'] = this.priceToPrecision (symbol, price); + } } - const orderRequest = this.orderRequest ('editOrder', symbol, type, request, amount, price, params); - const response = await this.privatePostEditOrder (this.extend (orderRequest[0], orderRequest[1])); + params = this.omit (params, [ 'timeInForce', 'reduceOnly', 'stopLossPrice', 'takeProfitPrice', 'trailingAmount', 'trailingLimitAmount', 'offset' ]); + const response = await this.privatePostAmendOrder (this.extend (request, params)); // - // { - // "error": [], - // "result": { - // "status": "ok", - // "txid": "OAW2BO-7RWEK-PZY5UO", - // "originaltxid": "OXL6SS-UPNMC-26WBE7", - // "volume": "0.00075000", - // "price": "13500.0", - // "orders_cancelled": 1, - // "descr": { - // "order": "buy 0.00075000 XBTUSDT @ limit 13500.0" - // } - // } - // } + // { + // "error": [], + // "result": { + // "amend_id": "TEZA4R-DSDGT-IJBOJK" + // } + // } // - const data = this.safeDict (response, 'result', {}); - return this.parseOrder (data, market); + const error = this.safeList (response, 'error', []); + if (error.length > 0) { + throw new ExchangeError ('Amend error ' + error.toString ()); + } + return this.safeOrder ({ 'id': id }, market); } async fetchOrder (id: string, symbol: Str = undefined, params = {}) { diff --git a/ts/src/pro/kraken.ts b/ts/src/pro/kraken.ts index b7eb6b2b20cc9..c35f0a8622ce4 100644 --- a/ts/src/pro/kraken.ts +++ b/ts/src/pro/kraken.ts @@ -1265,12 +1265,15 @@ export default class kraken extends krakenRest { wsName = this.safeString (description, 'pair', wsName); market = this.safeValue (this.options['marketsByWsName'], wsName, market); let symbol = undefined; - const timestamp = this.safeTimestamp (order, 'opentm'); - amount = this.safeString (order, 'vol', amount); + const timestamp = this.safeTimestamp2 (order, 'lastupdated', 'opentm'); + amount = this.safeString2 (order, 'volume', 'vol', amount); const filled = this.safeString (order, 'vol_exec'); let fee = undefined; const cost = this.safeString (order, 'cost'); - price = this.safeString (description, 'price', price); + price = this.safeString (order, 'price', price); + if ((price === undefined) || (Precise.stringEq (price, '0.0'))) { + price = this.safeString (description, 'price', price); + } if ((price === undefined) || (Precise.stringEq (price, '0.0'))) { price = this.safeString (description, 'price2'); } @@ -1281,17 +1284,13 @@ export default class kraken extends krakenRest { if (market !== undefined) { symbol = market['symbol']; if ('fee' in order) { - const flags = order['oflags']; const feeCost = this.safeString (order, 'fee'); fee = { 'cost': feeCost, 'rate': undefined, }; - if (flags.indexOf ('fciq') >= 0) { - fee['currency'] = market['quote']; - } else if (flags.indexOf ('fcib') >= 0) { - fee['currency'] = market['base']; - } + // Fee currency should always be in quote + fee['currency'] = market['quote']; } } const status = this.parseOrderStatus (this.safeString (order, 'status')); @@ -1300,7 +1299,7 @@ export default class kraken extends krakenRest { const txid = this.safeValue (order, 'txid'); id = this.safeString (txid, 0); } - const clientOrderId = this.safeString (order, 'userref'); + const clientOrderId = this.safeStringN (order, [ 'cl_ord_id', 'userref', 'newuserref' ]); const rawTrades = this.safeValue (order, 'trades'); let trades = undefined; if (rawTrades !== undefined) {