package ccxt // PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN: // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code type krakenfutures struct { Exchange } func NewKrakenfuturesCore() krakenfutures { p := krakenfutures{} setDefaults(&p) return p } func (this *krakenfutures) Describe() interface{} { return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} { "id": "krakenfutures", "name": "Kraken Futures", "countries": []interface{}{"US"}, "version": "v3", "userAgent": nil, "rateLimit": 600, "pro": true, "has": map[string]interface{} { "CORS": nil, "spot": false, "margin": false, "swap": true, "future": true, "option": false, "cancelAllOrders": true, "cancelAllOrdersAfter": true, "cancelOrder": true, "cancelOrders": true, "createMarketOrder": false, "createOrder": true, "createStopOrder": true, "createTriggerOrder": true, "editOrder": true, "fetchBalance": true, "fetchBorrowRateHistories": false, "fetchBorrowRateHistory": false, "fetchCanceledOrders": true, "fetchClosedOrders": true, "fetchCrossBorrowRate": false, "fetchCrossBorrowRates": false, "fetchDepositAddress": false, "fetchDepositAddresses": false, "fetchDepositAddressesByNetwork": false, "fetchFundingHistory": nil, "fetchFundingRate": "emulated", "fetchFundingRateHistory": true, "fetchFundingRates": true, "fetchIndexOHLCV": false, "fetchIsolatedBorrowRate": false, "fetchIsolatedBorrowRates": false, "fetchIsolatedPositions": false, "fetchLeverage": true, "fetchLeverages": true, "fetchLeverageTiers": true, "fetchMarketLeverageTiers": "emulated", "fetchMarkets": true, "fetchMarkOHLCV": true, "fetchMyTrades": true, "fetchOHLCV": true, "fetchOpenOrders": true, "fetchOrder": false, "fetchOrderBook": true, "fetchOrders": false, "fetchPositions": true, "fetchPremiumIndexOHLCV": false, "fetchTickers": true, "fetchTrades": true, "sandbox": true, "setLeverage": true, "setMarginMode": false, "transfer": true, }, "urls": map[string]interface{} { "test": map[string]interface{} { "public": "https://demo-futures.kraken.com/derivatives/api/", "private": "https://demo-futures.kraken.com/derivatives/api/", "charts": "https://demo-futures.kraken.com/api/charts/", "history": "https://demo-futures.kraken.com/api/history/", "www": "https://demo-futures.kraken.com", }, "logo": "https://user-images.githubusercontent.com/24300605/81436764-b22fd580-9172-11ea-9703-742783e6376d.jpg", "api": map[string]interface{} { "charts": "https://futures.kraken.com/api/charts/", "history": "https://futures.kraken.com/api/history/", "feeschedules": "https://futures.kraken.com/api/feeschedules/", "public": "https://futures.kraken.com/derivatives/api/", "private": "https://futures.kraken.com/derivatives/api/", }, "www": "https://futures.kraken.com/", "doc": []interface{}{"https://docs.futures.kraken.com/#introduction"}, "fees": "https://support.kraken.com/hc/en-us/articles/360022835771-Transaction-fees-and-rebates-for-Kraken-Futures", "referral": nil, }, "api": map[string]interface{} { "public": map[string]interface{} { "get": []interface{}{"feeschedules", "instruments", "orderbook", "tickers", "history", "historicalfundingrates"}, }, "private": map[string]interface{} { "get": []interface{}{"feeschedules/volumes", "openpositions", "notifications", "accounts", "openorders", "recentorders", "fills", "transfers", "leveragepreferences", "pnlpreferences", "assignmentprogram/current", "assignmentprogram/history"}, "post": []interface{}{"sendorder", "editorder", "cancelorder", "transfer", "batchorder", "cancelallorders", "cancelallordersafter", "withdrawal", "assignmentprogram/add", "assignmentprogram/delete"}, "put": []interface{}{"leveragepreferences", "pnlpreferences"}, }, "charts": map[string]interface{} { "get": []interface{}{"{price_type}/{symbol}/{interval}"}, }, "history": map[string]interface{} { "get": []interface{}{"orders", "executions", "triggers", "accountlogcsv", "account-log", "market/{symbol}/orders", "market/{symbol}/executions"}, }, }, "fees": map[string]interface{} { "trading": map[string]interface{} { "tierBased": true, "percentage": true, "taker": this.ParseNumber("0.0005"), "maker": this.ParseNumber("0.0002"), "tiers": map[string]interface{} { "taker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.0005")}, []interface{}{this.ParseNumber("100000"), this.ParseNumber("0.0004")}, []interface{}{this.ParseNumber("1000000"), this.ParseNumber("0.0003")}, []interface{}{this.ParseNumber("5000000"), this.ParseNumber("0.00025")}, []interface{}{this.ParseNumber("10000000"), this.ParseNumber("0.0002")}, []interface{}{this.ParseNumber("20000000"), this.ParseNumber("0.00015")}, []interface{}{this.ParseNumber("50000000"), this.ParseNumber("0.000125")}, []interface{}{this.ParseNumber("100000000"), this.ParseNumber("0.0001")}}, "maker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.0002")}, []interface{}{this.ParseNumber("100000"), this.ParseNumber("0.0015")}, []interface{}{this.ParseNumber("1000000"), this.ParseNumber("0.000125")}, []interface{}{this.ParseNumber("5000000"), this.ParseNumber("0.0001")}, []interface{}{this.ParseNumber("10000000"), this.ParseNumber("0.000075")}, []interface{}{this.ParseNumber("20000000"), this.ParseNumber("0.00005")}, []interface{}{this.ParseNumber("50000000"), this.ParseNumber("0.000025")}, []interface{}{this.ParseNumber("100000000"), this.ParseNumber("0")}}, }, }, }, "exceptions": map[string]interface{} { "exact": map[string]interface{} { "apiLimitExceeded": RateLimitExceeded, "marketUnavailable": ContractUnavailable, "requiredArgumentMissing": BadRequest, "unavailable": ExchangeNotAvailable, "authenticationError": AuthenticationError, "accountInactive": ExchangeError, "invalidAccount": BadRequest, "invalidAmount": BadRequest, "insufficientFunds": InsufficientFunds, "Bad Request": BadRequest, "Unavailable": ExchangeNotAvailable, "invalidUnit": BadRequest, "Json Parse Error": ExchangeError, "nonceBelowThreshold": InvalidNonce, "nonceDuplicate": InvalidNonce, "notFound": BadRequest, "Server Error": ExchangeError, "unknownError": ExchangeError, }, "broad": map[string]interface{} { "invalidArgument": BadRequest, "nonceBelowThreshold": InvalidNonce, "nonceDuplicate": InvalidNonce, }, }, "precisionMode": TICK_SIZE, "options": map[string]interface{} { "access": map[string]interface{} { "history": map[string]interface{} { "GET": map[string]interface{} { "orders": "private", "executions": "private", "triggers": "private", "accountlogcsv": "private", }, }, }, "settlementCurrencies": map[string]interface{} { "flex": []interface{}{"USDT", "BTC", "USD", "GBP", "EUR", "USDC"}, }, "symbol": map[string]interface{} { "quoteIds": []interface{}{"USD", "XBT"}, "reversed": false, }, "versions": map[string]interface{} { "public": map[string]interface{} { "GET": map[string]interface{} { "historicalfundingrates": "v4", }, }, "charts": map[string]interface{} { "GET": map[string]interface{} { "{price_type}/{symbol}/{interval}": "v1", }, }, "history": map[string]interface{} { "GET": map[string]interface{} { "orders": "v2", "executions": "v2", "triggers": "v2", "accountlogcsv": "v2", }, }, }, "fetchTrades": map[string]interface{} { "method": "historyGetMarketSymbolExecutions", }, }, "features": map[string]interface{} { "default": map[string]interface{} { "sandbox": true, "createOrder": map[string]interface{} { "marginMode": false, "triggerPrice": true, "triggerPriceType": map[string]interface{} { "last": true, "mark": true, "index": true, }, "triggerDirection": false, "stopLossPrice": true, "takeProfitPrice": true, "attachedStopLossTakeProfit": nil, "timeInForce": map[string]interface{} { "IOC": true, "FOK": true, "PO": true, "GTD": false, }, "hedged": false, "trailing": false, "leverage": false, "marketBuyByCost": false, "marketBuyRequiresPrice": false, "selfTradePrevention": false, "iceberg": false, }, "createOrders": map[string]interface{} { "max": 100, }, "fetchMyTrades": map[string]interface{} { "marginMode": false, "limit": nil, "daysBack": nil, "untilDays": 100000, "symbolRequired": false, }, "fetchOrder": nil, "fetchOpenOrders": map[string]interface{} { "marginMode": false, "limit": nil, "trigger": false, "trailing": false, "symbolRequired": false, }, "fetchOrders": nil, "fetchClosedOrders": map[string]interface{} { "marginMode": false, "limit": nil, "daysBack": nil, "daysBackCanceled": nil, "untilDays": nil, "trigger": false, "trailing": false, "symbolRequired": false, }, "fetchOHLCV": map[string]interface{} { "limit": 5000, }, }, "spot": nil, "swap": map[string]interface{} { "linear": map[string]interface{} { "extends": "default", }, "inverse": map[string]interface{} { "extends": "default", }, }, "future": map[string]interface{} { "linear": map[string]interface{} { "extends": "default", }, "inverse": map[string]interface{} { "extends": "default", }, }, }, "timeframes": map[string]interface{} { "1m": "1m", "5m": "5m", "15m": "15m", "30m": "30m", "1h": "1h", "4h": "4h", "12h": "12h", "1d": "1d", "1w": "1w", }, }) } /** * @method * @name krakenfutures#fetchMarkets * @description Fetches the available trading markets from the exchange, Multi-collateral markets are returned as linear markets, but can be settled in multiple currencies * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-instrument-details-get-instruments * @param {object} [params] exchange specific params * @returns An array of market structures */ func (this *krakenfutures) FetchMarkets(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params response:= (<-this.PublicGetInstruments(params)) PanicOnError(response) // // { // "result": "success", // "instruments": [ // { // "symbol": "fi_ethusd_180928", // "type": "futures_inverse", // futures_vanilla // spot index // "underlying": "rr_ethusd", // "lastTradingTime": "2018-09-28T15:00:00.000Z", // "tickSize": 0.1, // "contractSize": 1, // "tradeable": true, // "marginLevels": [ // { // "contracts":0, // "initialMargin":0.02, // "maintenanceMargin":0.01 // }, // { // "contracts":250000, // "initialMargin":0.04, // "maintenanceMargin":0.02 // }, // ... // ], // "isin": "GB00JVMLMP88", // "retailMarginLevels": [ // { // "contracts": 0, // "initialMargin": 0.5, // "maintenanceMargin": 0.25 // } // ], // "tags": [], // }, // { // "symbol": "in_xbtusd", // "type": "spot index", // "tradeable":false // } // ] // "serverTime": "2018-07-19T11:32:39.433Z" // } // var instruments interface{} = this.SafeValue(response, "instruments", []interface{}{}) var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(instruments)); i++ { var market interface{} = GetValue(instruments, i) var id interface{} = this.SafeString(market, "symbol") var marketType interface{} = this.SafeString(market, "type") var typeVar interface{} = nil var index interface{} = (IsGreaterThanOrEqual(GetIndexOf(marketType, " index"), 0)) var linear interface{} = nil var inverse interface{} = nil var expiry interface{} = nil if !IsTrue(index) { linear = (IsGreaterThanOrEqual(GetIndexOf(marketType, "_vanilla"), 0)) inverse = !IsTrue(linear) var settleTime interface{} = this.SafeString(market, "lastTradingTime") typeVar = Ternary(IsTrue((IsEqual(settleTime, nil))), "swap", "future") expiry = this.Parse8601(settleTime) } else { typeVar = "index" } var swap interface{} = (IsEqual(typeVar, "swap")) var future interface{} = (IsEqual(typeVar, "future")) var symbol interface{} = id var split interface{} = Split(id, "_") var splitMarket interface{} = this.SafeString(split, 1) var baseId interface{} = Slice(splitMarket, 0, Subtract(GetLength(splitMarket), 3)) var quoteId interface{} = "usd" // always USD var base interface{} = this.SafeCurrencyCode(baseId) var quote interface{} = this.SafeCurrencyCode(quoteId) // swap == perpetual var settle interface{} = nil var settleId interface{} = nil var cvtp interface{} = this.SafeString(market, "contractValueTradePrecision") var amountPrecision interface{} = this.ParseNumber(this.IntegerPrecisionToAmount(cvtp)) var pricePrecision interface{} = this.SafeNumber(market, "tickSize") var contract interface{} = (IsTrue(IsTrue(swap) || IsTrue(future)) || IsTrue(index)) var swapOrFutures interface{} = (IsTrue(swap) || IsTrue(future)) if IsTrue(swapOrFutures) { var exchangeType interface{} = this.SafeString(market, "type") if IsTrue(IsEqual(exchangeType, "futures_inverse")) { settle = base settleId = baseId inverse = true } else { settle = quote settleId = quoteId inverse = false } linear = !IsTrue(inverse) symbol = Add(Add(Add(Add(base, "/"), quote), ":"), settle) if IsTrue(future) { symbol = Add(Add(symbol, "-"), this.Yymmdd(expiry)) } } AppendToArray(&result,map[string]interface{} { "id": id, "symbol": symbol, "base": base, "quote": quote, "settle": settle, "baseId": baseId, "quoteId": quoteId, "settleId": settleId, "type": typeVar, "spot": false, "margin": false, "swap": swap, "future": future, "option": false, "index": index, "active": nil, "contract": contract, "linear": linear, "inverse": inverse, "contractSize": this.SafeNumber(market, "contractSize"), "maintenanceMarginRate": nil, "expiry": expiry, "expiryDatetime": this.Iso8601(expiry), "strike": nil, "optionType": nil, "precision": map[string]interface{} { "amount": amountPrecision, "price": pricePrecision, }, "limits": map[string]interface{} { "leverage": map[string]interface{} { "min": nil, "max": nil, }, "amount": map[string]interface{} { "min": nil, "max": nil, }, "price": map[string]interface{} { "min": nil, "max": nil, }, "cost": map[string]interface{} { "min": nil, "max": nil, }, }, "created": this.Parse8601(this.SafeString(market, "openingDate")), "info": market, }) } var settlementCurrencies interface{} = GetValue(GetValue(this.Options, "settlementCurrencies"), "flex") var currencies interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(settlementCurrencies)); i++ { var code interface{} = GetValue(settlementCurrencies, i) AppendToArray(¤cies,map[string]interface{} { "id": ToLower(code), "numericId": nil, "code": code, "precision": nil, }) } this.Currencies = this.DeepExtend(currencies, this.Currencies) ch <- result return nil }() return ch } /** * @method * @name krakenfutures#fetchOrderBook * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-market-data-get-orderbook * @description Fetches a list of open orders in a market * @param {string} symbol Unified market symbol * @param {int} [limit] Not used by krakenfutures * @param {object} [params] exchange specific params * @returns An [order book structure]{@link https://docs.ccxt.com/#/?id=order-book-structure} */ func (this *krakenfutures) FetchOrderBook(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) limit := GetArg(optionalArgs, 0, nil) _ = limit params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes5448 := (<-this.LoadMarkets()) PanicOnError(retRes5448) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } response:= (<-this.PublicGetOrderbook(this.Extend(request, params))) PanicOnError(response) // // { // "result": "success", // "serverTime": "2016-02-25T09:45:53.818Z", // "orderBook": { // "bids": [ // [ // 4213, // 2000, // ], // [ // 4210, // 4000, // ], // ... // ], // "asks": [ // [ // 4218, // 4000, // ], // [ // 4220, // 5000, // ], // ... // ], // }, // } // var timestamp interface{} = this.Parse8601(GetValue(response, "serverTime")) ch <- this.ParseOrderBook(GetValue(response, "orderBook"), symbol, timestamp) return nil }() return ch } /** * @method * @name krakenfutures#fetchTickers * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-market-data-get-tickers * @param {string[]} symbols unified symbols of the markets to fetch the ticker for, all market tickers are returned if not assigned * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an array of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure} */ func (this *krakenfutures) FetchTickers(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbols := GetArg(optionalArgs, 0, nil) _ = symbols params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes5948 := (<-this.LoadMarkets()) PanicOnError(retRes5948) response:= (<-this.PublicGetTickers(params)) PanicOnError(response) // // { // "result": "success", // "tickers": [ // { // "tag": 'semiannual', // 'month', 'quarter', "perpetual", "semiannual", // "pair": "ETH:USD", // "symbol": "fi_ethusd_220624", // "markPrice": "2925.72", // "bid": "2923.8", // "bidSize": "16804", // "ask": "2928.65", // "askSize": "1339", // "vol24h": "860493", // "openInterest": "3023363.00000000", // "open24h": "3021.25", // "indexPrice": "2893.71", // "last": "2942.25", // "lastTime": "2022-02-18T14:08:15.578Z", // "lastSize": "151", // "suspended": false // }, // { // "symbol": "in_xbtusd", // "rr_xbtusd", // "last": "40411", // "lastTime": "2022-02-18T14:16:28.000Z" // }, // ... // ], // "serverTime": "2022-02-18T14:16:29.440Z" // } // var tickers interface{} = this.SafeList(response, "tickers") ch <- this.ParseTickers(tickers, symbols) return nil }() return ch } func (this *krakenfutures) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} { // // { // "tag": 'semiannual', // 'month', 'quarter', "perpetual", "semiannual", // "pair": "ETH:USD", // "symbol": "fi_ethusd_220624", // "markPrice": "2925.72", // "bid": "2923.8", // "bidSize": "16804", // "ask": "2928.65", // "askSize": "1339", // "vol24h": "860493", // "openInterest": "3023363.00000000", // "open24h": "3021.25", // "indexPrice": "2893.71", // "last": "2942.25", // "lastTime": "2022-02-18T14:08:15.578Z", // "lastSize": "151", // "suspended": false // } // // { // "symbol": "in_xbtusd", // "rr_xbtusd", // "last": "40411", // "lastTime": "2022-02-18T14:16:28.000Z" // } // market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString(ticker, "symbol") market = this.SafeMarket(marketId, market) var symbol interface{} = GetValue(market, "symbol") var timestamp interface{} = this.Parse8601(this.SafeString(ticker, "lastTime")) var open interface{} = this.SafeString(ticker, "open24h") var last interface{} = this.SafeString(ticker, "last") var change interface{} = Precise.StringSub(last, open) var percentage interface{} = Precise.StringMul(Precise.StringDiv(change, open), "100") var average interface{} = Precise.StringDiv(Precise.StringAdd(open, last), "2") var volume interface{} = this.SafeString(ticker, "vol24h") var baseVolume interface{} = nil var quoteVolume interface{} = nil var isIndex interface{} = this.SafeBool(market, "index", false) if !IsTrue(isIndex) { if IsTrue(GetValue(market, "linear")) { baseVolume = volume } else if IsTrue(GetValue(market, "inverse")) { quoteVolume = volume } } return this.SafeTicker(map[string]interface{} { "symbol": symbol, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "high": nil, "low": nil, "bid": this.SafeString(ticker, "bid"), "bidVolume": this.SafeString(ticker, "bidSize"), "ask": this.SafeString(ticker, "ask"), "askVolume": this.SafeString(ticker, "askSize"), "vwap": nil, "open": open, "close": last, "last": last, "previousClose": nil, "change": change, "percentage": percentage, "average": average, "baseVolume": baseVolume, "quoteVolume": quoteVolume, "markPrice": this.SafeString(ticker, "markPrice"), "indexPrice": this.SafeString(ticker, "indexPrice"), "info": ticker, }) } /** * @method * @name krakenfutures#fetchOHLCV * @see https://docs.futures.kraken.com/#http-api-charts-candles * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @param {string} symbol unified symbol of the market to fetch OHLCV data for * @param {string} timeframe the length of time each candle represents * @param {int} [since] timestamp in ms of the earliest candle to fetch * @param {int} [limit] the maximum amount of candles to fetch * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume */ func (this *krakenfutures) FetchOHLCV(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) timeframe := GetArg(optionalArgs, 0, "1m") _ = timeframe since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes7198 := (<-this.LoadMarkets()) PanicOnError(retRes7198) var market interface{} = this.Market(symbol) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOHLCV", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes72419 := (<-this.FetchPaginatedCallDeterministic("fetchOHLCV", symbol, since, limit, timeframe, params, 5000)) PanicOnError(retRes72419) ch <- retRes72419 return nil } var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), "price_type": this.SafeString(params, "price", "trade"), "interval": GetValue(this.Timeframes, timeframe), } params = this.Omit(params, "price") if IsTrue(!IsEqual(since, nil)) { var duration interface{} = this.ParseTimeframe(timeframe) AddElementToObject(request, "from", this.ParseToInt(Divide(since, 1000))) if IsTrue(IsEqual(limit, nil)) { limit = 5000 } limit = mathMin(limit, 5000) var toTimestamp interface{} = this.Sum(GetValue(request, "from"), Subtract(Multiply(limit, duration), 1)) var currentTimestamp interface{} = this.Seconds() AddElementToObject(request, "to", mathMin(toTimestamp, currentTimestamp)) } else if IsTrue(!IsEqual(limit, nil)) { limit = mathMin(limit, 5000) var duration interface{} = this.ParseTimeframe(timeframe) AddElementToObject(request, "to", this.Seconds()) AddElementToObject(request, "from", this.ParseToInt(Subtract(GetValue(request, "to"), (Multiply(duration, limit))))) } response:= (<-this.ChartsGetPriceTypeSymbolInterval(this.Extend(request, params))) PanicOnError(response) // // { // "candles": [ // { // "time": 1645198500000, // "open": "309.15000000000", // "high": "309.15000000000", // "low": "308.70000000000", // "close": "308.85000000000", // "volume": 0 // } // ], // "more_candles": true // } // var candles interface{} = this.SafeList(response, "candles") ch <- this.ParseOHLCVs(candles, market, timeframe, since, limit) return nil }() return ch } func (this *krakenfutures) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} { // // { // "time": 1645198500000, // "open": "309.15000000000", // "high": "309.15000000000", // "low": "308.70000000000", // "close": "308.85000000000", // "volume": 0 // } // market := GetArg(optionalArgs, 0, nil) _ = market return []interface{}{this.SafeInteger(ohlcv, "time"), this.SafeNumber(ohlcv, "open"), this.SafeNumber(ohlcv, "high"), this.SafeNumber(ohlcv, "low"), this.SafeNumber(ohlcv, "close"), this.SafeNumber(ohlcv, "volume")} } /** * @method * @name krakenfutures#fetchTrades * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-market-data-get-trade-history * @see https://docs.futures.kraken.com/#http-api-history-market-history-get-public-execution-events * @description Fetch a history of filled trades that this account has made * @param {string} symbol Unified CCXT market symbol * @param {int} [since] Timestamp in ms of earliest trade. Not used by krakenfutures except in combination with params.until * @param {int} [limit] Total number of trades, cannot exceed 100 * @param {object} [params] Exchange specific params * @param {int} [params.until] Timestamp in ms of latest trade * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @param {string} [params.method] The method to use to fetch trades. Can be 'historyGetMarketSymbolExecutions' or 'publicGetHistory' default is 'historyGetMarketSymbolExecutions' * @returns An array of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure} */ func (this *krakenfutures) FetchTrades(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) since := GetArg(optionalArgs, 0, nil) _ = since limit := GetArg(optionalArgs, 1, nil) _ = limit params := GetArg(optionalArgs, 2, map[string]interface{} {}) _ = params retRes8058 := (<-this.LoadMarkets()) PanicOnError(retRes8058) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchTrades", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes80919 := (<-this.FetchPaginatedCallDynamic("fetchTrades", symbol, since, limit, params)) PanicOnError(retRes80919) ch <- retRes80919 return nil } var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } var method interface{} = nil methodparamsVariable := this.HandleOptionAndParams(params, "fetchTrades", "method", "historyGetMarketSymbolExecutions"); method = GetValue(methodparamsVariable,0); params = GetValue(methodparamsVariable,1) var rawTrades interface{} = nil var isFullHistoryEndpoint interface{} = (IsEqual(method, "historyGetMarketSymbolExecutions")) if IsTrue(isFullHistoryEndpoint) { requestparamsVariable := this.HandleUntilOption("before", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "since", since) AddElementToObject(request, "sort", "asc") } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "count", limit) } response:= (<-this.HistoryGetMarketSymbolExecutions(this.Extend(request, params))) PanicOnError(response) // // { // "elements": [ // { // "uid": "a5105030-f054-44cc-98ab-30d5cae96bef", // "timestamp": "1710150778607", // "event": { // "Execution": { // "execution": { // "uid": "2d485b71-cd28-4a1e-9364-371a127550d2", // "makerOrder": { // "uid": "0a25f66b-1109-49ec-93a3-d17bf9e9137e", // "tradeable": "PF_XBTUSD", // "direction": "Buy", // "quantity": "0.26500", // "timestamp": "1710150778570", // "limitPrice": "71907", // "orderType": "Post", // "reduceOnly": false, // "lastUpdateTimestamp": "1710150778570" // }, // "takerOrder": { // "uid": "04de3ee0-9125-4960-bf8f-f63b577b6790", // "tradeable": "PF_XBTUSD", // "direction": "Sell", // "quantity": "0.0002", // "timestamp": "1710150778607", // "limitPrice": "71187.00", // "orderType": "Market", // "reduceOnly": false, // "lastUpdateTimestamp": "1710150778607" // }, // "timestamp": "1710150778607", // "quantity": "0.0002", // "price": "71907", // "markPrice": "71903.32715463147", // "limitFilled": false, // "usdValue": "14.38" // }, // "takerReducedQuantity": "" // } // } // }, // ... followed by older items // ], // "len": "1000", // "continuationToken": "QTexMDE0OTe33NTcyXy8xNDIzAjc1NjY5MwI=" // } // var elements interface{} = this.SafeList(response, "elements", []interface{}{}) // we need to reverse the list to fix chronology rawTrades = []interface{}{} var length interface{} = GetArrayLength(elements) for i := 0; IsLessThan(i, length); i++ { var index interface{} = Subtract(Subtract(length, 1), i) var element interface{} = GetValue(elements, index) var event interface{} = this.SafeDict(element, "event", map[string]interface{} {}) var executionContainer interface{} = this.SafeDict(event, "Execution", map[string]interface{} {}) var rawTrade interface{} = this.SafeDict(executionContainer, "execution", map[string]interface{} {}) AppendToArray(&rawTrades,rawTrade) } } else { requestparamsVariable := this.HandleUntilOption("lastTime", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) response:= (<-this.PublicGetHistory(this.Extend(request, params))) PanicOnError(response) // // { // "result": "success", // "history": [ // { // "time": "2022-03-18T04:55:37.692Z", // "trade_id": 100, // "price": 0.7921, // "size": 1068, // "side": "sell", // "type": "fill", // "uid": "6c5da0b0-f1a8-483f-921f-466eb0388265" // }, // ... // ], // "serverTime": "2022-03-18T06:39:18.056Z" // } // rawTrades = this.SafeList(response, "history", []interface{}{}) } ch <- this.ParseTrades(rawTrades, market, since, limit) return nil }() return ch } func (this *krakenfutures) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} { // // fetchTrades (recent trades) // // { // "time": "2019-02-14T09:25:33.920Z", // "trade_id": 100, // "price": 3574, // "size": 100, // "side": "buy", // "type": "fill" // fill, liquidation, assignment, termination // "uid": "11c3d82c-9e70-4fe9-8115-f643f1b162d4" // } // // fetchTrades (executions history) // // { // "timestamp": "1710152516830", // "price": "71927.0", // "quantity": "0.0695", // "markPrice": "71936.38701675525", // "limitFilled": true, // "usdValue": "4998.93", // "uid": "116ae634-253f-470b-bd20-fa9d429fb8b1", // "makerOrder": { "uid": "17bfe4de-c01e-4938-926c-617d2a2d0597", "tradeable": "PF_XBTUSD", "direction": "Buy", "quantity": "0.0695", "timestamp": "1710152515836", "limitPrice": "71927.0", "orderType": "Post", "reduceOnly": false, "lastUpdateTimestamp": "1710152515836" }, // "takerOrder": { "uid": "d3e437b4-aa70-4108-b5cf-b1eecb9845b5", "tradeable": "PF_XBTUSD", "direction": "Sell", "quantity": "0.940100", "timestamp": "1710152516830", "limitPrice": "71915", "orderType": "IoC", "reduceOnly": false, "lastUpdateTimestamp": "1710152516830" } // } // // fetchMyTrades (private) // // { // "fillTime": "2016-02-25T09:47:01.000Z", // "order_id": "c18f0c17-9971-40e6-8e5b-10df05d422f0", // "fill_id": "522d4e08-96e7-4b44-9694-bfaea8fe215e", // "cliOrdId": "d427f920-ec55-4c18-ba95-5fe241513b30", // OPTIONAL // "symbol": "fi_xbtusd_180615", // "side": "buy", // "size": 2000, // "price": 4255, // "fillType": "maker" // taker, takerAfterEdit, maker, liquidation, assignee // } // // execution report (createOrder, editOrder) // // { // "executionId": "e1ec9f63-2338-4c44-b40a-43486c6732d7", // "price": 7244.5, // "amount": 10, // "orderPriorEdit": null, // "orderPriorExecution": { // "orderId": "61ca5732-3478-42fe-8362-abbfd9465294", // "cliOrdId": null, // "type": "lmt", // "symbol": "pi_xbtusd", // "side": "buy", // "quantity": 10, // "filled": 0, // "limitPrice": 7500, // "reduceOnly": false, // "timestamp": "2019-12-11T17:17:33.888Z", // "lastUpdateTimestamp": "2019-12-11T17:17:33.888Z" // }, // "takerReducedQuantity": null, // "type": "EXECUTION" // } // market := GetArg(optionalArgs, 0, nil) _ = market var timestamp interface{} = this.Parse8601(this.SafeString2(trade, "time", "fillTime")) var price interface{} = this.SafeString(trade, "price") var amount interface{} = this.SafeStringN(trade, []interface{}{"size", "amount", "quantity"}, "0.0") var id interface{} = this.SafeString2(trade, "uid", "fill_id") if IsTrue(IsEqual(id, nil)) { id = this.SafeString(trade, "executionId") } var order interface{} = this.SafeString(trade, "order_id") var marketId interface{} = this.SafeString(trade, "symbol") var side interface{} = this.SafeString(trade, "side") var typeVar interface{} = nil var priorEdit interface{} = this.SafeValue(trade, "orderPriorEdit") var priorExecution interface{} = this.SafeValue(trade, "orderPriorExecution") if IsTrue(!IsEqual(priorExecution, nil)) { order = this.SafeString(priorExecution, "orderId") marketId = this.SafeString(priorExecution, "symbol") side = this.SafeString(priorExecution, "side") typeVar = this.SafeString(priorExecution, "type") } else if IsTrue(!IsEqual(priorEdit, nil)) { order = this.SafeString(priorEdit, "orderId") marketId = this.SafeString(priorEdit, "symbol") side = this.SafeString(priorEdit, "type") typeVar = this.SafeString(priorEdit, "type") } if IsTrue(!IsEqual(typeVar, nil)) { typeVar = this.ParseOrderType(typeVar) } market = this.SafeMarket(marketId, market) var cost interface{} = nil var linear interface{} = this.SafeBool(market, "linear") if IsTrue(IsTrue(IsTrue((!IsEqual(amount, nil))) && IsTrue((!IsEqual(price, nil)))) && IsTrue((!IsEqual(market, nil)))) { if IsTrue(linear) { cost = Precise.StringMul(amount, price) // in quote } else { cost = Precise.StringDiv(amount, price) // in base } var contractSize interface{} = this.SafeString(market, "contractSize") cost = Precise.StringMul(cost, contractSize) } var takerOrMaker interface{} = nil var fillType interface{} = this.SafeString(trade, "fillType") if IsTrue(!IsEqual(fillType, nil)) { if IsTrue(IsGreaterThanOrEqual(GetIndexOf(fillType, "taker"), 0)) { takerOrMaker = "taker" } else if IsTrue(IsGreaterThanOrEqual(GetIndexOf(fillType, "maker"), 0)) { takerOrMaker = "maker" } } var isHistoricalExecution interface{} = (InOp(trade, "takerOrder")) if IsTrue(isHistoricalExecution) { timestamp = this.SafeInteger(trade, "timestamp") var taker interface{} = this.SafeDict(trade, "takerOrder", map[string]interface{} {}) if IsTrue(!IsEqual(taker, nil)) { side = this.SafeStringLower(taker, "direction") takerOrMaker = "taker" } } return this.SafeTrade(map[string]interface{} { "info": trade, "id": id, "symbol": this.SafeString(market, "symbol"), "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "order": order, "type": typeVar, "side": side, "takerOrMaker": takerOrMaker, "price": price, "amount": Ternary(IsTrue(linear), amount, nil), "cost": cost, "fee": nil, }) } func (this *krakenfutures) CreateOrderRequest(symbol interface{}, typeVar interface{}, side interface{}, amount interface{}, optionalArgs ...interface{}) interface{} { price := GetArg(optionalArgs, 0, nil) _ = price params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params var market interface{} = this.Market(symbol) symbol = GetValue(market, "symbol") typeVar = this.SafeString(params, "orderType", typeVar) var timeInForce interface{} = this.SafeString(params, "timeInForce") var postOnly interface{} = false postOnlyparamsVariable := this.HandlePostOnly(IsEqual(typeVar, "market"), IsEqual(typeVar, "post"), params); postOnly = GetValue(postOnlyparamsVariable,0); params = GetValue(postOnlyparamsVariable,1) if IsTrue(postOnly) { typeVar = "post" } else if IsTrue(IsEqual(timeInForce, "ioc")) { typeVar = "ioc" } else if IsTrue(IsEqual(typeVar, "limit")) { typeVar = "lmt" } else if IsTrue(IsEqual(typeVar, "market")) { typeVar = "mkt" } var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), "side": side, "size": this.AmountToPrecision(symbol, amount), } var clientOrderId interface{} = this.SafeString2(params, "clientOrderId", "cliOrdId") if IsTrue(!IsEqual(clientOrderId, nil)) { AddElementToObject(request, "cliOrdId", clientOrderId) } var triggerPrice interface{} = this.SafeString2(params, "triggerPrice", "stopPrice") var isTriggerOrder interface{} = !IsEqual(triggerPrice, nil) var stopLossTriggerPrice interface{} = this.SafeString(params, "stopLossPrice") var takeProfitTriggerPrice interface{} = this.SafeString(params, "takeProfitPrice") var isStopLossTriggerOrder interface{} = !IsEqual(stopLossTriggerPrice, nil) var isTakeProfitTriggerOrder interface{} = !IsEqual(takeProfitTriggerPrice, nil) var isStopLossOrTakeProfitTrigger interface{} = IsTrue(isStopLossTriggerOrder) || IsTrue(isTakeProfitTriggerOrder) var triggerSignal interface{} = this.SafeString(params, "triggerSignal", "last") var reduceOnly interface{} = this.SafeValue(params, "reduceOnly") if IsTrue(IsTrue(isStopLossOrTakeProfitTrigger) || IsTrue(isTriggerOrder)) { AddElementToObject(request, "triggerSignal", triggerSignal) } if IsTrue(isTriggerOrder) { typeVar = "stp" AddElementToObject(request, "stopPrice", this.PriceToPrecision(symbol, triggerPrice)) } else if IsTrue(isStopLossOrTakeProfitTrigger) { reduceOnly = true if IsTrue(isStopLossTriggerOrder) { typeVar = "stp" AddElementToObject(request, "stopPrice", this.PriceToPrecision(symbol, stopLossTriggerPrice)) } else if IsTrue(isTakeProfitTriggerOrder) { typeVar = "take_profit" AddElementToObject(request, "stopPrice", this.PriceToPrecision(symbol, takeProfitTriggerPrice)) } } if IsTrue(reduceOnly) { AddElementToObject(request, "reduceOnly", true) } AddElementToObject(request, "orderType", typeVar) if IsTrue(!IsEqual(price, nil)) { AddElementToObject(request, "limitPrice", this.PriceToPrecision(symbol, price)) } params = this.Omit(params, []interface{}{"clientOrderId", "timeInForce", "triggerPrice", "stopLossPrice", "takeProfitPrice"}) return this.Extend(request, params) } /** * @method * @name krakenfutures#createOrder * @description Create an order on the exchange * @see https://docs.kraken.com/api/docs/futures-api/trading/send-order * @param {string} symbol unified market symbol * @param {string} type 'limit' or 'market' * @param {string} side 'buy' or 'sell' * @param {float} amount number of contracts * @param {float} [price] limit order price * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {bool} [params.reduceOnly] set as true if you wish the order to only reduce an existing position, any order which increases an existing position will be rejected, default is false * @param {bool} [params.postOnly] set as true if you wish to make a postOnly order, default is false * @param {string} [params.clientOrderId] UUID The order identity that is specified from the user, It must be globally unique * @param {float} [params.triggerPrice] the price that a stop order is triggered at * @param {float} [params.stopLossPrice] the price that a stop loss order is triggered at * @param {float} [params.takeProfitPrice] the price that a take profit order is triggered at * @param {string} [params.triggerSignal] for triggerPrice, stopLossPrice and takeProfitPrice orders, the trigger price type, 'last', 'mark' or 'index', default is 'last' * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *krakenfutures) CreateOrder(symbol interface{}, typeVar interface{}, side interface{}, amount interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) price := GetArg(optionalArgs, 0, nil) _ = price params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes11388 := (<-this.LoadMarkets()) PanicOnError(retRes11388) var market interface{} = this.Market(symbol) var orderRequest interface{} = this.CreateOrderRequest(symbol, typeVar, side, amount, price, params) response:= (<-this.PrivatePostSendorder(orderRequest)) PanicOnError(response) // // { // "result": "success", // "sendStatus": { // "order_id": "salf320-e337-47ac-b345-30sdfsalj", // "status": "placed", // "receivedTime": "2022-02-28T19:32:17.122Z", // "orderEvents": [ // { // "order": { // "orderId": "salf320-e337-47ac-b345-30sdfsalj", // "cliOrdId": null, // "type": "lmt", // "symbol": "pi_xrpusd", // "side": "buy", // "quantity": 1, // "filled": 0, // "limitPrice": 0.7, // "reduceOnly": false, // "timestamp": "2022-02-28T19:32:17.122Z", // "lastUpdateTimestamp": "2022-02-28T19:32:17.122Z" // }, // "reducedQuantity": null, // "type": "PLACE" // } // ] // }, // "serverTime": "2022-02-28T19:32:17.122Z" // } // var sendStatus interface{} = this.SafeValue(response, "sendStatus") var status interface{} = this.SafeString(sendStatus, "status") this.VerifyOrderActionSuccess(status, "createOrder", []interface{}{"filled"}) ch <- this.ParseOrder(sendStatus, market) return nil }() return ch } /** * @method * @name krakenfutures#createOrders * @description create a list of trade orders * @see https://docs.kraken.com/api/docs/futures-api/trading/send-batch-order * @param {Array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *krakenfutures) CreateOrders(orders interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes11888 := (<-this.LoadMarkets()) PanicOnError(retRes11888) var ordersRequests interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(orders)); i++ { var rawOrder interface{} = GetValue(orders, i) var marketId interface{} = this.SafeString(rawOrder, "symbol") var typeVar interface{} = this.SafeString(rawOrder, "type") var side interface{} = this.SafeString(rawOrder, "side") var amount interface{} = this.SafeValue(rawOrder, "amount") var price interface{} = this.SafeValue(rawOrder, "price") var orderParams interface{} = this.SafeValue(rawOrder, "params", map[string]interface{} {}) var extendedParams interface{} = this.Extend(orderParams, params) // the request does not accept extra params since it's a list, so we're extending each order with the common params if !IsTrue((InOp(extendedParams, "order_tag"))) { // order tag is mandatory so we will generate one if not provided AddElementToObject(extendedParams, "order_tag", ToString(this.Sum(i, 1))) // sequential counter } AddElementToObject(extendedParams, "order", "send") var orderRequest interface{} = this.CreateOrderRequest(marketId, typeVar, side, amount, price, extendedParams) AppendToArray(&ordersRequests,orderRequest) } var request interface{} = map[string]interface{} { "batchOrder": ordersRequests, } response:= (<-this.PrivatePostBatchorder(this.Extend(request, params))) PanicOnError(response) // // { // "result": "success", // "serverTime": "2023-10-24T08:40:57.339Z", // "batchStatus": [ // { // "status": "requiredArgumentMissing", // "orderEvents": [] // }, // { // "status": "requiredArgumentMissing", // "orderEvents": [] // } // ] // } // var data interface{} = this.SafeList(response, "batchStatus", []interface{}{}) ch <- this.ParseOrders(data) return nil }() return ch } /** * @method * @name krakenfutures#editOrder * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-order-management-edit-order * @description Edit an open order on the exchange * @param {string} id order id * @param {string} symbol Not used by Krakenfutures * @param {string} type Not used by Krakenfutures * @param {string} side Not used by Krakenfutures * @param {float} amount Order size * @param {float} [price] Price to fill order at * @param {object} [params] Exchange specific params * @returns An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *krakenfutures) EditOrder(id interface{}, symbol interface{}, typeVar interface{}, side interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) amount := GetArg(optionalArgs, 0, nil) _ = amount price := GetArg(optionalArgs, 1, nil) _ = price params := GetArg(optionalArgs, 2, map[string]interface{} {}) _ = params retRes12468 := (<-this.LoadMarkets()) PanicOnError(retRes12468) var request interface{} = map[string]interface{} { "orderId": id, } if IsTrue(!IsEqual(amount, nil)) { AddElementToObject(request, "size", amount) } if IsTrue(!IsEqual(price, nil)) { AddElementToObject(request, "limitPrice", price) } response:= (<-this.PrivatePostEditorder(this.Extend(request, params))) PanicOnError(response) var status interface{} = this.SafeString(GetValue(response, "editStatus"), "status") this.VerifyOrderActionSuccess(status, "editOrder", []interface{}{"filled"}) var order interface{} = this.ParseOrder(GetValue(response, "editStatus")) AddElementToObject(order, "info", response) ch <- order return nil }() return ch } /** * @method * @name krakenfutures#cancelOrder * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-order-management-cancel-order * @description Cancel an open order on the exchange * @param {string} id Order id * @param {string} symbol Not used by Krakenfutures * @param {object} [params] Exchange specific params * @returns An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *krakenfutures) CancelOrder(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes12758 := (<-this.LoadMarkets()) PanicOnError(retRes12758) response:= (<-this.PrivatePostCancelorder(this.Extend(map[string]interface{} { "order_id": id, }, params))) PanicOnError(response) var status interface{} = this.SafeString(this.SafeValue(response, "cancelStatus", map[string]interface{} {}), "status") this.VerifyOrderActionSuccess(status, "cancelOrder") var order interface{} = map[string]interface{} {} if IsTrue(InOp(response, "cancelStatus")) { order = this.ParseOrder(GetValue(response, "cancelStatus")) } ch <- this.Extend(map[string]interface{} { "info": response, }, order) return nil }() return ch } /** * @method * @name krakenfutures#cancelOrders * @description cancel multiple orders * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-order-management-batch-order-management * @param {string[]} ids order ids * @param {string} [symbol] unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * * EXCHANGE SPECIFIC PARAMETERS * @param {string[]} [params.clientOrderIds] max length 10 e.g. ["my_id_1","my_id_2"] * @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *krakenfutures) CancelOrders(ids interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes13008 := (<-this.LoadMarkets()) PanicOnError(retRes13008) var orders interface{} = []interface{}{} var clientOrderIds interface{} = this.SafeValue(params, "clientOrderIds", []interface{}{}) var clientOrderIdsLength interface{} = GetArrayLength(clientOrderIds) if IsTrue(IsGreaterThan(clientOrderIdsLength, 0)) { for i := 0; IsLessThan(i, GetArrayLength(clientOrderIds)); i++ { AppendToArray(&orders,map[string]interface{} { "order": "cancel", "cliOrdId": GetValue(clientOrderIds, i), }) } } else { for i := 0; IsLessThan(i, GetArrayLength(ids)); i++ { AppendToArray(&orders,map[string]interface{} { "order": "cancel", "order_id": GetValue(ids, i), }) } } var request interface{} = map[string]interface{} { "batchOrder": orders, } response:= (<-this.PrivatePostBatchorder(this.Extend(request, params))) PanicOnError(response) // { // "result": "success", // "serverTime": "2023-10-23T16:36:51.327Z", // "batchStatus": [ // { // "status": "cancelled", // "order_id": "101c2327-f12e-45f2-8445-7502b87afc0b", // "orderEvents": [ // { // "uid": "101c2327-f12e-45f2-8445-7502b87afc0b", // "order": { // "orderId": "101c2327-f12e-45f2-8445-7502b87afc0b", // "cliOrdId": null, // "type": "lmt", // "symbol": "PF_LTCUSD", // "side": "buy", // "quantity": "0.10000000000", // "filled": "0E-11", // "limitPrice": "50.00000000000", // "reduceOnly": false, // "timestamp": "2023-10-20T10:29:13.005Z", // "lastUpdateTimestamp": "2023-10-20T10:29:13.005Z" // }, // "type": "CANCEL" // } // ] // } // ] // } var batchStatus interface{} = this.SafeList(response, "batchStatus", []interface{}{}) ch <- this.ParseOrders(batchStatus) return nil }() return ch } /** * @method * @name krakenfutures#cancelAllOrders * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-order-management-cancel-all-orders * @description Cancels all orders on the exchange, including trigger orders * @param {str} symbol Unified market symbol * @param {dict} [params] Exchange specific params * @returns Response from exchange api */ func (this *krakenfutures) CancelAllOrders(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(symbol, nil)) { AddElementToObject(request, "symbol", this.MarketId(symbol)) } response:= (<-this.PrivatePostCancelallorders(this.Extend(request, params))) PanicOnError(response) // // { // result: 'success', // cancelStatus: { // receivedTime: '2024-06-06T01:12:44.814Z', // cancelOnly: 'PF_XRPUSD', // status: 'cancelled', // cancelledOrders: [ { order_id: '272fd0ac-45c0-4003-b84d-d39b9e86bd36' } ], // orderEvents: [ // { // uid: '272fd0ac-45c0-4003-b84d-d39b9e86bd36', // order: { // orderId: '272fd0ac-45c0-4003-b84d-d39b9e86bd36', // cliOrdId: null, // type: 'lmt', // symbol: 'PF_XRPUSD', // side: 'buy', // quantity: '10', // filled: '0', // limitPrice: '0.4', // reduceOnly: false, // timestamp: '2024-06-06T01:11:16.045Z', // lastUpdateTimestamp: '2024-06-06T01:11:16.045Z' // }, // type: 'CANCEL' // } // ] // }, // serverTime: '2024-06-06T01:12:44.814Z' // } // var cancelStatus interface{} = this.SafeDict(response, "cancelStatus") var orderEvents interface{} = this.SafeList(cancelStatus, "orderEvents", []interface{}{}) var orders interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(orderEvents)); i++ { var orderEvent interface{} = this.SafeDict(orderEvents, 0) var order interface{} = this.SafeDict(orderEvent, "order", map[string]interface{} {}) AppendToArray(&orders,order) } ch <- this.ParseOrders(orders) return nil }() return ch } /** * @method * @name krakenfutures#cancelAllOrdersAfter * @description dead man's switch, cancel all orders after the given timeout * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-order-management-dead-man-39-s-switch * @param {number} timeout time in milliseconds, 0 represents cancel the timer * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} the api result */ func (this *krakenfutures) CancelAllOrdersAfter(timeout interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes14178 := (<-this.LoadMarkets()) PanicOnError(retRes14178) var request interface{} = map[string]interface{} { "timeout": Ternary(IsTrue((IsGreaterThan(timeout, 0))), (this.ParseToInt(Divide(timeout, 1000))), 0), } response:= (<-this.PrivatePostCancelallordersafter(this.Extend(request, params))) PanicOnError(response) // // { // "result": "success", // "serverTime": "2018-06-19T16:51:23.839Z", // "status": { // "currentTime": "2018-06-19T16:51:23.839Z", // "triggerTime": "0" // } // } // ch <- response return nil }() return ch } /** * @method * @name krakenfutures#fetchOpenOrders * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-order-management-get-open-orders * @description Gets all open orders, including trigger orders, for an account from the exchange api * @param {string} symbol Unified market symbol * @param {int} [since] Timestamp (ms) of earliest order. (Not used by kraken api but filtered internally by CCXT) * @param {int} [limit] How many orders to return. (Not used by kraken api but filtered internally by CCXT) * @param {object} [params] Exchange specific parameters * @returns An array of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *krakenfutures) FetchOpenOrders(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes14478 := (<-this.LoadMarkets()) PanicOnError(retRes14478) var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } response:= (<-this.PrivateGetOpenorders(params)) PanicOnError(response) var orders interface{} = this.SafeList(response, "openOrders", []interface{}{}) ch <- this.ParseOrders(orders, market, since, limit) return nil }() return ch } /** * @method * @name krakenfutures#fetchClosedOrders * @see https://docs.futures.kraken.com/#http-api-history-account-history-get-order-events * @description Gets all closed orders, including trigger orders, for an account from the exchange api * @param {string} symbol Unified market symbol * @param {int} [since] Timestamp (ms) of earliest order. * @param {int} [limit] How many orders to return. * @param {object} [params] Exchange specific parameters * @returns An array of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *krakenfutures) FetchClosedOrders(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes14698 := (<-this.LoadMarkets()) PanicOnError(retRes14698) var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "count", limit) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "from", since) } response:= (<-this.HistoryGetOrders(this.Extend(request, params))) PanicOnError(response) var allOrders interface{} = this.SafeList(response, "elements", []interface{}{}) var closedOrders interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(allOrders)); i++ { var order interface{} = GetValue(allOrders, i) var event interface{} = this.SafeDict(order, "event", map[string]interface{} {}) var orderPlaced interface{} = this.SafeDict(event, "OrderPlaced") if IsTrue(!IsEqual(orderPlaced, nil)) { var innerOrder interface{} = this.SafeDict(orderPlaced, "order", map[string]interface{} {}) var filled interface{} = this.SafeString(innerOrder, "filled") if IsTrue(!IsEqual(filled, "0")) { AddElementToObject(innerOrder, "status", "closed") // status not available in the response AppendToArray(&closedOrders,innerOrder) } } } ch <- this.ParseOrders(closedOrders, market, since, limit) return nil }() return ch } /** * @method * @name krakenfutures#fetchCanceledOrders * @see https://docs.futures.kraken.com/#http-api-history-account-history-get-order-events * @description Gets all canceled orders, including trigger orders, for an account from the exchange api * @param {string} symbol Unified market symbol * @param {int} [since] Timestamp (ms) of earliest order. * @param {int} [limit] How many orders to return. * @param {object} [params] Exchange specific parameters * @returns An array of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *krakenfutures) FetchCanceledOrders(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes15128 := (<-this.LoadMarkets()) PanicOnError(retRes15128) var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "count", limit) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "from", since) } response:= (<-this.HistoryGetOrders(this.Extend(request, params))) PanicOnError(response) var allOrders interface{} = this.SafeList(response, "elements", []interface{}{}) var canceledAndRejected interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(allOrders)); i++ { var order interface{} = GetValue(allOrders, i) var event interface{} = this.SafeDict(order, "event", map[string]interface{} {}) var orderPlaced interface{} = this.SafeDict(event, "OrderPlaced") if IsTrue(!IsEqual(orderPlaced, nil)) { var innerOrder interface{} = this.SafeDict(orderPlaced, "order", map[string]interface{} {}) var filled interface{} = this.SafeString(innerOrder, "filled") if IsTrue(IsEqual(filled, "0")) { AddElementToObject(innerOrder, "status", "canceled") // status not available in the response AppendToArray(&canceledAndRejected,innerOrder) } } var orderCanceled interface{} = this.SafeDict(event, "OrderCancelled") if IsTrue(!IsEqual(orderCanceled, nil)) { var innerOrder interface{} = this.SafeDict(orderCanceled, "order", map[string]interface{} {}) AddElementToObject(innerOrder, "status", "canceled") // status not available in the response AppendToArray(&canceledAndRejected,innerOrder) } var orderRejected interface{} = this.SafeDict(event, "OrderRejected") if IsTrue(!IsEqual(orderRejected, nil)) { var innerOrder interface{} = this.SafeDict(orderRejected, "order", map[string]interface{} {}) AddElementToObject(innerOrder, "status", "rejected") // status not available in the response AppendToArray(&canceledAndRejected,innerOrder) } } ch <- this.ParseOrders(canceledAndRejected, market, since, limit) return nil }() return ch } func (this *krakenfutures) ParseOrderType(orderType interface{}) interface{} { var typesMap interface{} = map[string]interface{} { "lmt": "limit", "mkt": "market", "post": "limit", "ioc": "market", } return this.SafeString(typesMap, orderType, orderType) } func (this *krakenfutures) VerifyOrderActionSuccess(status interface{}, method interface{}, optionalArgs ...interface{}) { omit := GetArg(optionalArgs, 0, []interface{}{}) _ = omit var errors interface{} = map[string]interface{} { "invalidOrderType": InvalidOrder, "invalidSide": InvalidOrder, "invalidSize": InvalidOrder, "invalidPrice": InvalidOrder, "insufficientAvailableFunds": InsufficientFunds, "selfFill": ExchangeError, "tooManySmallOrders": ExchangeError, "maxPositionViolation": BadRequest, "marketSuspended": ExchangeNotAvailable, "marketInactive": ExchangeNotAvailable, "clientOrderIdAlreadyExist": DuplicateOrderId, "clientOrderIdTooLong": BadRequest, "outsidePriceCollar": InvalidOrder, "postWouldExecute": OrderImmediatelyFillable, "iocWouldNotExecute": OrderNotFillable, "wouldNotReducePosition": ExchangeError, "orderForEditNotFound": OrderNotFound, "orderForEditNotAStop": InvalidOrder, "filled": OrderNotFound, "notFound": OrderNotFound, } if IsTrue(IsTrue((InOp(errors, status))) && !IsTrue(this.InArray(status, omit))) { throwDynamicException(GetValue(errors, status), Add(Add(Add(Add(this.Id, ": "), method), " failed due to "), status)); } } func (this *krakenfutures) ParseOrderStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "placed": "open", "cancelled": "canceled", "invalidOrderType": "rejected", "invalidSide": "rejected", "invalidSize": "rejected", "invalidPrice": "rejected", "insufficientAvailableFunds": "rejected", "selfFill": "rejected", "tooManySmallOrders": "rejected", "maxPositionViolation": "rejected", "marketSuspended": "rejected", "marketInactive": "rejected", "clientOrderIdAlreadyExist": "rejected", "clientOrderIdTooLong": "rejected", "outsidePriceCollar": "rejected", "postWouldExecute": "rejected", "iocWouldNotExecute": "rejected", "wouldNotReducePosition": "rejected", "edited": "open", "orderForEditNotFound": "rejected", "orderForEditNotAStop": "rejected", "filled": "closed", "notFound": "rejected", "untouched": "open", "partiallyFilled": "open", } return this.SafeString(statuses, status, status) } func (this *krakenfutures) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} { // // LIMIT // // { // "order_id": "179f9af8-e45e-469d-b3e9-2fd4675cb7d0", // "status": "placed", // "receivedTime": "2019-09-05T16:33:50.734Z", // "orderEvents": [ // { // "uid": "614a5298-0071-450f-83c6-0617ce8c6bc4", // "order": { // "orderId": "179f9af8-e45e-469d-b3e9-2fd4675cb7d0", // "cliOrdId": null, // "type": "lmt", // "symbol": "pi_xbtusd", // "side": "buy", // "quantity": 10000, // "filled": 0, // "limitPrice": 9400, // "reduceOnly": false, // "timestamp": "2019-09-05T16:33:50.734Z", // "lastUpdateTimestamp": "2019-09-05T16:33:50.734Z" // }, // "reducedQuantity": null, // "reason": "WOULD_NOT_REDUCE_POSITION", // REJECTED // "type": "PLACE" // } // ] // } // // CONDITIONAL // // { // "order_id": "1abfd3c6-af93-4b30-91cc-e4a93797f3f5", // "status": "placed", // "receivedTime": "2019-12-05T10:20:50.701Z", // "orderEvents": [ // { // "orderTrigger": { // "uid": "1abfd3c6-af93-4b30-91cc-e4a93797f3f5", // "clientId":null, // "type": "lmt", // "ioc" if stop market // "symbol": "pi_xbtusd", // "side": "buy", // "quantity":10, // "limitPrice":15000, // "triggerPrice":9500, // "triggerSide": "trigger_below", // "triggerSignal": "mark_price", // "reduceOnly":false, // "timestamp": "2019-12-05T10:20:50.701Z", // "lastUpdateTimestamp": "2019-12-05T10:20:50.701Z" // }, // "type": "PLACE" // } // ] // } // // EXECUTION // // { // "order_id": "61ca5732-3478-42fe-8362-abbfd9465294", // "status": "placed", // "receivedTime": "2019-12-11T17:17:33.888Z", // "orderEvents": [ // { // "executionId": "e1ec9f63-2338-4c44-b40a-43486c6732d7", // "price": 7244.5, // "amount": 10, // "orderPriorEdit": null, // "orderPriorExecution": { // "orderId": "61ca5732-3478-42fe-8362-abbfd9465294", // "cliOrdId": null, // "type": "lmt", // "symbol": "pi_xbtusd", // "side": "buy", // "quantity": 10, // "filled": 0, // "limitPrice": 7500, // "reduceOnly": false, // "timestamp": "2019-12-11T17:17:33.888Z", // "lastUpdateTimestamp": "2019-12-11T17:17:33.888Z" // }, // "takerReducedQuantity": null, // "type": "EXECUTION" // } // ] // } // // EDIT ORDER // // { // "status": "edited", // "orderId": "022774bc-2c4a-4f26-9317-436c8d85746d", // "receivedTime": "2019-09-05T16:47:47.521Z", // "orderEvents": [ // { // "old": { // "orderId": "022774bc-2c4a-4f26-9317-436c8d85746d", // "cliOrdId":null, // "type": "lmt", // "symbol": "pi_xbtusd", // "side": "buy", // "quantity":1000, // "filled":0, // "limitPrice":9400.0, // "reduceOnly":false, // "timestamp": "2019-09-05T16:41:35.173Z", // "lastUpdateTimestamp": "2019-09-05T16:41:35.173Z" // }, // "new": { // "orderId": "022774bc-2c4a-4f26-9317-436c8d85746d", // "cliOrdId": null, // "type": "lmt", // "symbol": "pi_xbtusd", // "side": "buy", // "quantity": 1501, // "filled": 0, // "limitPrice": 7200, // "reduceOnly": false, // "timestamp": "2019-09-05T16:41:35.173Z", // "lastUpdateTimestamp": "2019-09-05T16:47:47.519Z" // }, // "reducedQuantity": null, // "type": "EDIT" // } // ] // } // // CANCEL ORDER // // { // "status": "cancelled", // "orderEvents": [ // { // "uid": "85c40002-3f20-4e87-9302-262626c3531b", // "order": { // "orderId": "85c40002-3f20-4e87-9302-262626c3531b", // "cliOrdId": null, // "type": "lmt", // "symbol": "pi_xbtusd", // "side": "buy", // "quantity": 1000, // "filled": 0, // "limitPrice": 10144, // "stopPrice": null, // "reduceOnly": false, // "timestamp": "2019-08-01T15:26:27.790Z" // }, // "type": "CANCEL" // } // ] // } // // cancelAllOrders // // { // "orderId": "85c40002-3f20-4e87-9302-262626c3531b", // "cliOrdId": null, // "type": "lmt", // "symbol": "pi_xbtusd", // "side": "buy", // "quantity": 1000, // "filled": 0, // "limitPrice": 10144, // "stopPrice": null, // "reduceOnly": false, // "timestamp": "2019-08-01T15:26:27.790Z" // } // // FETCH OPEN ORDERS // // { // "order_id": "59302619-41d2-4f0b-941f-7e7914760ad3", // "symbol": "pi_xbtusd", // "side": "sell", // "orderType": "lmt", // "limitPrice": 10640, // "unfilledSize": 304, // "receivedTime": "2019-09-05T17:01:17.410Z", // "status": "untouched", // "filledSize": 0, // "reduceOnly": true, // "lastUpdateTime": "2019-09-05T17:01:17.410Z" // } // // createOrders error // { // "status": "requiredArgumentMissing", // "orderEvents": [] // } // closed orders // { // uid: '2f00cd63-e61d-44f8-8569-adabde885941', // timestamp: '1707258274849', // event: { // OrderPlaced: { // order: { // uid: '85805e01-9eed-4395-8360-ed1a228237c9', // accountUid: '406142dd-7c5c-4a8b-acbc-5f16eca30009', // tradeable: 'PF_LTCUSD', // direction: 'Buy', // quantity: '0', // filled: '0.1', // timestamp: '1707258274849', // limitPrice: '69.2200000000', // orderType: 'IoC', // clientId: '', // reduceOnly: false, // lastUpdateTimestamp: '1707258274849' // }, // reason: 'new_user_order', // reducedQuantity: '', // algoId: '' // } // } // } // market := GetArg(optionalArgs, 0, nil) _ = market var orderEvents interface{} = this.SafeValue(order, "orderEvents", []interface{}{}) var errorStatus interface{} = this.SafeString(order, "status") var orderEventsLength interface{} = GetArrayLength(orderEvents) if IsTrue(IsTrue(IsTrue((InOp(order, "orderEvents"))) && IsTrue((!IsEqual(errorStatus, nil)))) && IsTrue((IsEqual(orderEventsLength, 0)))) { // creteOrders error response return this.SafeOrder(map[string]interface{} { "info": order, "status": "rejected", }) } var details interface{} = nil var isPrior interface{} = false var fixed interface{} = false var statusId interface{} = nil var price interface{} = nil var trades interface{} = []interface{}{} if IsTrue(orderEventsLength) { var executions interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(orderEvents)); i++ { var item interface{} = GetValue(orderEvents, i) if IsTrue(IsEqual(this.SafeString(item, "type"), "EXECUTION")) { AppendToArray(&executions,item) } // Final order (after placement / editing / execution / canceling) var orderTrigger interface{} = this.SafeValue(item, "orderTrigger") if IsTrue(IsEqual(details, nil)) { details = this.SafeValue2(item, "new", "order", orderTrigger) if IsTrue(!IsEqual(details, nil)) { isPrior = false fixed = true } else if !IsTrue(fixed) { var orderPriorExecution interface{} = this.SafeValue(item, "orderPriorExecution") details = this.SafeValue2(item, "orderPriorExecution", "orderPriorEdit") price = this.SafeString(orderPriorExecution, "limitPrice") if IsTrue(!IsEqual(details, nil)) { isPrior = true } } } } trades = this.ParseTrades(executions) statusId = this.SafeString(order, "status") } if IsTrue(IsEqual(details, nil)) { details = order } if IsTrue(IsEqual(statusId, nil)) { statusId = this.SafeString(details, "status") } // This may be incorrectly marked as "open" if only execution report is given, // but will be fixed below var status interface{} = this.ParseOrderStatus(statusId) var isClosed interface{} = this.InArray(status, []interface{}{"canceled", "rejected", "closed"}) var marketId interface{} = this.SafeString(details, "symbol") market = this.SafeMarket(marketId, market) var timestamp interface{} = this.Parse8601(this.SafeString2(details, "timestamp", "receivedTime")) var lastUpdateTimestamp interface{} = this.Parse8601(this.SafeString(details, "lastUpdateTime")) if IsTrue(IsEqual(price, nil)) { price = this.SafeString(details, "limitPrice") } var amount interface{} = this.SafeString(details, "quantity") var filled interface{} = this.SafeString2(details, "filledSize", "filled", "0.0") var remaining interface{} = this.SafeString(details, "unfilledSize") var average interface{} = nil var filled2 interface{} = "0.0" var tradesLength interface{} = GetArrayLength(trades) if IsTrue(IsGreaterThan(tradesLength, 0)) { var vwapSum interface{} = "0.0" for i := 0; IsLessThan(i, GetArrayLength(trades)); i++ { var trade interface{} = GetValue(trades, i) var tradeAmount interface{} = this.SafeString(trade, "amount") var tradePrice interface{} = this.SafeString(trade, "price") filled2 = Precise.StringAdd(filled2, tradeAmount) vwapSum = Precise.StringAdd(vwapSum, Precise.StringMul(tradeAmount, tradePrice)) } average = Precise.StringDiv(vwapSum, filled2) if IsTrue(IsTrue(IsTrue(IsTrue((!IsEqual(amount, nil))) && IsTrue((!IsTrue(isClosed)))) && IsTrue(isPrior)) && IsTrue(Precise.StringGe(filled2, amount))) { status = "closed" isClosed = true } if IsTrue(isPrior) { filled = Precise.StringAdd(filled, filled2) } else { filled = Precise.StringMax(filled, filled2) } } if IsTrue(IsEqual(remaining, nil)) { if IsTrue(isPrior) { if IsTrue(!IsEqual(amount, nil)) { // remaining amount before execution minus executed amount remaining = Precise.StringSub(amount, filled2) } } else { remaining = amount } } // if fetchOpenOrders are parsed if IsTrue(IsTrue(IsTrue((IsEqual(amount, nil))) && IsTrue((!IsTrue(isPrior)))) && IsTrue((!IsEqual(remaining, nil)))) { amount = Precise.StringAdd(filled, remaining) } var cost interface{} = nil if IsTrue(IsTrue((!IsEqual(filled, nil))) && IsTrue((!IsEqual(market, nil)))) { var whichPrice interface{} = Ternary(IsTrue((!IsEqual(average, nil))), average, price) if IsTrue(!IsEqual(whichPrice, nil)) { if IsTrue(GetValue(market, "linear")) { cost = Precise.StringMul(filled, whichPrice) // in quote } else { cost = Precise.StringDiv(filled, whichPrice) // in base } } } var id interface{} = this.SafeString2(order, "order_id", "orderId") if IsTrue(IsEqual(id, nil)) { id = this.SafeString2(details, "orderId", "uid") } var typeVar interface{} = this.SafeStringLower2(details, "type", "orderType") var timeInForce interface{} = "gtc" if IsTrue(IsTrue(IsEqual(typeVar, "ioc")) || IsTrue(IsEqual(this.ParseOrderType(typeVar), "market"))) { timeInForce = "ioc" } return this.SafeOrder(map[string]interface{} { "info": order, "id": id, "clientOrderId": this.SafeStringN(details, []interface{}{"clientOrderId", "clientId", "cliOrdId"}), "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "lastTradeTimestamp": nil, "lastUpdateTimestamp": lastUpdateTimestamp, "symbol": this.SafeString(market, "symbol"), "type": this.ParseOrderType(typeVar), "timeInForce": timeInForce, "postOnly": IsEqual(typeVar, "post"), "reduceOnly": this.SafeBool2(details, "reduceOnly", "reduce_only"), "side": this.SafeString(details, "side"), "price": price, "triggerPrice": this.SafeString(details, "triggerPrice"), "amount": amount, "cost": cost, "average": average, "filled": filled, "remaining": remaining, "status": status, "fee": nil, "fees": nil, "trades": trades, }) } /** * @method * @name krakenfutures#fetchMyTrades * @description fetch all trades made by the user * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-historical-data-get-your-fills * @param {string} symbol unified market symbol * @param {int} [since] *not used by the api* the earliest time in ms to fetch trades for * @param {int} [limit] the maximum number of trades structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] the latest time in ms to fetch entries for * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure} */ func (this *krakenfutures) FetchMyTrades(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes20028 := (<-this.LoadMarkets()) PanicOnError(retRes20028) var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } // todo: lastFillTime: this.iso8601(end) response:= (<-this.PrivateGetFills(params)) PanicOnError(response) // // { // "result": "success", // "serverTime": "2016-02-25T09:45:53.818Z", // "fills": [ // { // "fillTime": "2016-02-25T09:47:01.000Z", // "order_id": "c18f0c17-9971-40e6-8e5b-10df05d422f0", // "fill_id": "522d4e08-96e7-4b44-9694-bfaea8fe215e", // "cliOrdId": "d427f920-ec55-4c18-ba95-5fe241513b30", // EXTRA // "symbol": "fi_xbtusd_180615", // "side": "buy", // "size": 2000, // "price": 4255, // "fillType": "maker" // }, // ... // ] // } // ch <- this.ParseTrades(GetValue(response, "fills"), market, since, limit) return nil }() return ch } /** * @method * @name krakenfutures#fetchBalance * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-account-information-get-wallets * @description Fetch the balance for a sub-account, all sub-account balances are inside 'info' in the response * @param {object} [params] Exchange specific parameters * @param {string} [params.type] The sub-account type to query the balance of, possible values include 'flex', 'cash'/'main'/'funding', or a market symbol * defaults to 'flex' * * @param {string} [params.symbol] A unified market symbol, when assigned the balance for a trading market that matches the symbol is returned * @returns A [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure} */ func (this *krakenfutures) FetchBalance(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes20438 := (<-this.LoadMarkets()) PanicOnError(retRes20438) var typeVar interface{} = this.SafeString2(params, "type", "account") var symbol interface{} = this.SafeString(params, "symbol") params = this.Omit(params, []interface{}{"type", "account", "symbol"}) response:= (<-this.PrivateGetAccounts(params)) PanicOnError(response) // // { // "result": "success", // "accounts": { // "fi_xbtusd": { // "auxiliary": { usd: "0", pv: '0.0', pnl: '0.0', af: '0.0', funding: "0.0" }, // "marginRequirements": { im: '0.0', mm: '0.0', lt: '0.0', tt: "0.0" }, // "triggerEstimates": { im: '0', mm: '0', lt: "0", tt: "0" }, // "balances": { xbt: "0.0" }, // "currency": "xbt", // "type": "marginAccount" // }, // "cash": { // "balances": { // "eur": "0.0", // "gbp": "0.0", // "bch": "0.0", // "xrp": "2.20188538338", // "usd": "0.0", // "eth": "0.0", // "usdt": "0.0", // "ltc": "0.0", // "usdc": "0.0", // "xbt": "0.0" // }, // "type": "cashAccount" // }, // "fv_xrpxbt": { // "auxiliary": { usd: "0", pv: '0.0', pnl: '0.0', af: '0.0', funding: "0.0" }, // "marginRequirements": { im: '0.0', mm: '0.0', lt: '0.0', tt: "0.0" }, // "triggerEstimates": { im: '0', mm: '0', lt: "0", tt: "0" }, // "balances": { xbt: "0.0" }, // "currency": "xbt", // "type": "marginAccount" // }, // "fi_xrpusd": { // "auxiliary": { usd: "0", pv: '11.0', pnl: '0.0', af: '11.0', funding: "0.0" }, // "marginRequirements": { im: '0.0', mm: '0.0', lt: '0.0', tt: "0.0" }, // "triggerEstimates": { im: '0', mm: '0', lt: "0", tt: "0" }, // "balances": { xrp: "11.0" }, // "currency": "xrp", // "type": "marginAccount" // }, // "fi_ethusd": { // "auxiliary": { usd: "0", pv: '0.0', pnl: '0.0', af: '0.0', funding: "0.0" }, // "marginRequirements": { im: '0.0', mm: '0.0', lt: '0.0', tt: "0.0" }, // "triggerEstimates": { im: '0', mm: '0', lt: "0", tt: "0" }, // "balances": { eth: "0.0" }, // "currency": "eth", // "type": "marginAccount" // }, // "fi_ltcusd": { // "auxiliary": { usd: "0", pv: '0.0', pnl: '0.0', af: '0.0', funding: "0.0" }, // "marginRequirements": { im: '0.0', mm: '0.0', lt: '0.0', tt: "0.0" }, // "triggerEstimates": { im: '0', mm: '0', lt: "0", tt: "0" }, // "balances": { ltc: "0.0" }, // "currency": "ltc", // "type": "marginAccount" // }, // "fi_bchusd": { // "auxiliary": { usd: "0", pv: '0.0', pnl: '0.0', af: '0.0', funding: "0.0" }, // "marginRequirements": { im: '0.0', mm: '0.0', lt: '0.0', tt: "0.0" }, // "triggerEstimates": { im: '0', mm: '0', lt: "0", tt: "0" }, // "balances": { bch: "0.0" }, // "currency": "bch", // "type": "marginAccount" // }, // "flex": { // "currencies": {}, // "initialMargin": "0.0", // "initialMarginWithOrders": "0.0", // "maintenanceMargin": "0.0", // "balanceValue": "0.0", // "portfolioValue": "0.0", // "collateralValue": "0.0", // "pnl": "0.0", // "unrealizedFunding": "0.0", // "totalUnrealized": "0.0", // "totalUnrealizedAsMargin": "0.0", // "availableMargin": "0.0", // "marginEquity": "0.0", // "type": "multiCollateralMarginAccount" // } // }, // "serverTime": "2022-04-12T07:48:07.475Z" // } // var datetime interface{} = this.SafeString(response, "serverTime") if IsTrue(IsTrue(IsEqual(typeVar, "marginAccount")) || IsTrue(IsEqual(typeVar, "margin"))) { if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchBalance requires symbol argument for margin accounts"))) } typeVar = symbol } if IsTrue(IsEqual(typeVar, nil)) { typeVar = Ternary(IsTrue((IsEqual(symbol, nil))), "flex", symbol) } var accountName interface{} = this.ParseAccount(typeVar) var accounts interface{} = this.SafeValue(response, "accounts") var account interface{} = this.SafeValue(accounts, accountName) if IsTrue(IsEqual(account, nil)) { typeVar = Ternary(IsTrue((IsEqual(typeVar, nil))), "", typeVar) symbol = Ternary(IsTrue((IsEqual(symbol, nil))), "", symbol) panic(BadRequest(Add(Add(this.Id, " fetchBalance has no account for "), typeVar))) } var balance interface{} = this.ParseBalance(account) AddElementToObject(balance, "info", response) AddElementToObject(balance, "timestamp", this.Parse8601(datetime)) AddElementToObject(balance, "datetime", datetime) ch <- balance return nil }() return ch } func (this *krakenfutures) ParseBalance(response interface{}) interface{} { // // cashAccount // // { // "balances": { // "eur": "0.0", // "gbp": "0.0", // "bch": "0.0", // "xrp": "2.20188538338", // "usd": "0.0", // "eth": "0.0", // "usdt": "0.0", // "ltc": "0.0", // "usdc": "0.0", // "xbt": "0.0" // }, // "type": "cashAccount" // } // // marginAccount e,g, fi_xrpusd // // { // "auxiliary": { // "usd": "0", // "pv": "11.0", // "pnl": "0.0", // "af": "11.0", // "funding": "0.0" // }, // "marginRequirements": { im: '0.0', mm: '0.0', lt: '0.0', tt: "0.0" }, // "triggerEstimates": { im: '0', mm: '0', lt: "0", tt: "0" }, // "balances": { xrp: "11.0" }, // "currency": "xrp", // "type": "marginAccount" // } // // flex/multiCollateralMarginAccount // // { // "currencies": { // "USDT": { // "quantity": "1", // "value": "1.0001", // "collateral": "0.9477197625", // "available": "1.0" // } // }, // "initialMargin": "0.0", // "initialMarginWithOrders": "0.0", // "maintenanceMargin": "0.0", // "balanceValue": "1.0", // "portfolioValue": "1.0", // "collateralValue": "0.95", // "pnl": "0.0", // "unrealizedFunding": "0.0", // "totalUnrealized": "0.0", // "totalUnrealizedAsMargin": "0.0", // "availableMargin": "0.95", // "marginEquity": "0.95", // "type": "multiCollateralMarginAccount" // } // var accountType interface{} = this.SafeString2(response, "accountType", "type") var isFlex interface{} = (IsEqual(accountType, "multiCollateralMarginAccount")) var isCash interface{} = (IsEqual(accountType, "cashAccount")) var balances interface{} = this.SafeValue2(response, "balances", "currencies", map[string]interface{} {}) var result interface{} = map[string]interface{} {} var currencyIds interface{} = ObjectKeys(balances) for i := 0; IsLessThan(i, GetArrayLength(currencyIds)); i++ { var currencyId interface{} = GetValue(currencyIds, i) var balance interface{} = GetValue(balances, currencyId) var code interface{} = this.SafeCurrencyCode(currencyId) var splitCode interface{} = Split(code, "_") var codeLength interface{} = GetArrayLength(splitCode) if IsTrue(IsGreaterThan(codeLength, 1)) { continue } var account interface{} = this.Account() if IsTrue(isFlex) { AddElementToObject(account, "total", this.SafeString(balance, "quantity")) AddElementToObject(account, "free", this.SafeString(balance, "available")) } else if IsTrue(isCash) { AddElementToObject(account, "used", "0.0") AddElementToObject(account, "total", balance) } else { var auxiliary interface{} = this.SafeValue(response, "auxiliary") AddElementToObject(account, "free", this.SafeString(auxiliary, "af")) AddElementToObject(account, "total", this.SafeString(auxiliary, "pv")) } AddElementToObject(result, code, account) } return this.SafeBalance(result) } /** * @method * @name krakenfutures#fetchFundingRates * @description fetch the current funding rates for multiple markets * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-market-data-get-tickers * @param {string[]} symbols unified market symbols * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {Order[]} an array of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-structure} */ func (this *krakenfutures) FetchFundingRates(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbols := GetArg(optionalArgs, 0, nil) _ = symbols params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes22658 := (<-this.LoadMarkets()) PanicOnError(retRes22658) var marketIds interface{} = this.MarketIds(symbols) response:= (<-this.PublicGetTickers(params)) PanicOnError(response) var tickers interface{} = this.SafeList(response, "tickers", []interface{}{}) var fundingRates interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(tickers)); i++ { var entry interface{} = GetValue(tickers, i) var entry_symbol interface{} = this.SafeValue(entry, "symbol") if IsTrue(!IsEqual(marketIds, nil)) { if !IsTrue(this.InArray(entry_symbol, marketIds)) { continue } } var market interface{} = this.SafeMarket(entry_symbol) var parsed interface{} = this.ParseFundingRate(entry, market) AppendToArray(&fundingRates,parsed) } ch <- this.IndexBy(fundingRates, "symbol") return nil }() return ch } func (this *krakenfutures) ParseFundingRate(ticker interface{}, optionalArgs ...interface{}) interface{} { // // {"ask": 26.283, // "askSize": 4.6, // "bid": 26.201, // "bidSize": 190, // "fundingRate": -0.000944642727438883, // "fundingRatePrediction": -0.000872671532340275, // "indexPrice": 26.253, // "last": 26.3, // "lastSize": 0.1, // "lastTime": "2023-06-11T18:55:28.958Z", // "markPrice": 26.239, // "open24h": 26.3, // "openInterest": 641.1, // "pair": "COMP:USD", // "postOnly": False, // "suspended": False, // "symbol": "pf_compusd", // "tag": "perpetual", // "vol24h": 0.1, // "volumeQuote": 2.63} // market := GetArg(optionalArgs, 0, nil) _ = market var fundingRateMultiplier interface{} = "8" // https://support.kraken.com/hc/en-us/articles/9618146737172-Perpetual-Contracts-Funding-Rate-Method-Prior-to-September-29-2022 var marketId interface{} = this.SafeString(ticker, "symbol") var symbol interface{} = this.Symbol(marketId) var timestamp interface{} = this.Parse8601(this.SafeString(ticker, "lastTime")) var indexPrice interface{} = this.SafeNumber(ticker, "indexPrice") var markPriceString interface{} = this.SafeString(ticker, "markPrice") var markPrice interface{} = this.ParseNumber(markPriceString) var fundingRateString interface{} = this.SafeString(ticker, "fundingRate") var fundingRateResult interface{} = Precise.StringDiv(Precise.StringMul(fundingRateString, fundingRateMultiplier), markPriceString) var fundingRate interface{} = this.ParseNumber(fundingRateResult) var nextFundingRateString interface{} = this.SafeString(ticker, "fundingRatePrediction") var nextFundingRateResult interface{} = Precise.StringDiv(Precise.StringMul(nextFundingRateString, fundingRateMultiplier), markPriceString) var nextFundingRate interface{} = this.ParseNumber(nextFundingRateResult) return map[string]interface{} { "info": ticker, "symbol": symbol, "markPrice": markPrice, "indexPrice": indexPrice, "interestRate": nil, "estimatedSettlePrice": nil, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "fundingRate": fundingRate, "fundingTimestamp": nil, "fundingDatetime": nil, "nextFundingRate": nextFundingRate, "nextFundingTimestamp": nil, "nextFundingDatetime": nil, "previousFundingRate": nil, "previousFundingTimestamp": nil, "previousFundingDatetime": nil, "interval": nil, } } /** * @method * @name krakenfutures#fetchFundingRateHistory * @description fetches historical funding rate prices * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-historical-funding-rates-historical-funding-rates * @param {string} symbol unified symbol of the market to fetch the funding rate history for * @param {int} [since] timestamp in ms of the earliest funding rate to fetch * @param {int} [limit] the maximum amount of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} to fetch * @param {object} [params] extra parameters specific to the api endpoint * @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-history-structure} */ func (this *krakenfutures) FetchFundingRateHistory(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchFundingRateHistory() requires a symbol argument"))) } retRes23588 := (<-this.LoadMarkets()) PanicOnError(retRes23588) var market interface{} = this.Market(symbol) if !IsTrue(GetValue(market, "swap")) { panic(BadRequest(Add(this.Id, " fetchFundingRateHistory() supports swap contracts only"))) } var request interface{} = map[string]interface{} { "symbol": ToUpper(GetValue(market, "id")), } response:= (<-this.PublicGetHistoricalfundingrates(this.Extend(request, params))) PanicOnError(response) // // { // "rates": [ // { // "timestamp": '2018-08-31T16:00:00.000Z', // "fundingRate": '2.18900669884E-7', // "relativeFundingRate": '0.000060779960000000' // }, // ... // ] // } // var rates interface{} = this.SafeValue(response, "rates") var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(rates)); i++ { var item interface{} = GetValue(rates, i) var datetime interface{} = this.SafeString(item, "timestamp") AppendToArray(&result,map[string]interface{} { "info": item, "symbol": symbol, "fundingRate": this.SafeNumber(item, "relativeFundingRate"), "timestamp": this.Parse8601(datetime), "datetime": datetime, }) } var sorted interface{} = this.SortBy(result, "timestamp") ch <- this.FilterBySymbolSinceLimit(sorted, symbol, since, limit) return nil }() return ch } /** * @method * @name krakenfutures#fetchPositions * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-account-information-get-open-positions * @description Fetches current contract trading positions * @param {string[]} symbols List of unified symbols * @param {object} [params] Not used by krakenfutures * @returns Parsed exchange response for positions */ func (this *krakenfutures) FetchPositions(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbols := GetArg(optionalArgs, 0, nil) _ = symbols params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes24068 := (<-this.LoadMarkets()) PanicOnError(retRes24068) var request interface{} = map[string]interface{} {} response:= (<-this.PrivateGetOpenpositions(request)) PanicOnError(response) // // { // "result": "success", // "openPositions": [ // { // "side": "long", // "symbol": "pi_xrpusd", // "price": "0.7533", // "fillTime": "2022-03-03T22:51:16.566Z", // "size": "230", // "unrealizedFunding": "-0.001878596918214635" // } // ], // "serverTime": "2022-03-03T22:51:16.566Z" // } // var result interface{} = this.ParsePositions(response) ch <- this.FilterByArrayPositions(result, "symbol", symbols, false) return nil }() return ch } func (this *krakenfutures) ParsePositions(response interface{}, optionalArgs ...interface{}) interface{} { symbols := GetArg(optionalArgs, 0, nil) _ = symbols params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params var result interface{} = []interface{}{} var positions interface{} = this.SafeValue(response, "openPositions") for i := 0; IsLessThan(i, GetArrayLength(positions)); i++ { var position interface{} = this.ParsePosition(GetValue(positions, i)) AppendToArray(&result,position) } return result } func (this *krakenfutures) ParsePosition(position interface{}, optionalArgs ...interface{}) interface{} { // cross // { // "side": "long", // "symbol": "pi_xrpusd", // "price": "0.7533", // "fillTime": "2022-03-03T22:51:16.566Z", // "size": "230", // "unrealizedFunding": "-0.001878596918214635" // } // // isolated // { // "side":"long", // "symbol":"pf_ftmusd", // "price":"0.4921", // "fillTime":"2023-02-22T11:37:16.685Z", // "size":"1", // "unrealizedFunding":"-8.155240068885155E-8", // "pnlCurrency":"USD", // "maxFixedLeverage":"1.0" // } // market := GetArg(optionalArgs, 0, nil) _ = market var leverage interface{} = this.SafeNumber(position, "maxFixedLeverage") var marginType interface{} = "cross" if IsTrue(!IsEqual(leverage, nil)) { marginType = "isolated" } var datetime interface{} = this.SafeString(position, "fillTime") var marketId interface{} = this.SafeString(position, "symbol") market = this.SafeMarket(marketId, market) return map[string]interface{} { "info": position, "symbol": GetValue(market, "symbol"), "timestamp": this.Parse8601(datetime), "datetime": datetime, "initialMargin": nil, "initialMarginPercentage": nil, "maintenanceMargin": nil, "maintenanceMarginPercentage": nil, "entryPrice": this.SafeNumber(position, "price"), "notional": nil, "leverage": leverage, "unrealizedPnl": nil, "contracts": this.SafeNumber(position, "size"), "contractSize": this.SafeNumber(market, "contractSize"), "marginRatio": nil, "liquidationPrice": nil, "markPrice": nil, "collateral": nil, "marginType": marginType, "side": this.SafeString(position, "side"), "percentage": nil, } } /** * @method * @name krakenfutures#fetchLeverageTiers * @description retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-instrument-details-get-instruments * @param {string[]|undefined} symbols list of unified market symbols * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a dictionary of [leverage tiers structures]{@link https://docs.ccxt.com/#/?id=leverage-tiers-structure}, indexed by market symbols */ func (this *krakenfutures) FetchLeverageTiers(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbols := GetArg(optionalArgs, 0, nil) _ = symbols params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes25058 := (<-this.LoadMarkets()) PanicOnError(retRes25058) response:= (<-this.PublicGetInstruments(params)) PanicOnError(response) // // { // "result": "success", // "instruments": [ // { // "symbol": "fi_ethusd_180928", // "type": "futures_inverse", // futures_vanilla // spot index // "underlying": "rr_ethusd", // "lastTradingTime": "2018-09-28T15:00:00.000Z", // "tickSize": 0.1, // "contractSize": 1, // "tradeable": true, // "marginLevels": [ // { // "contracts":0, // "initialMargin":0.02, // "maintenanceMargin":0.01 // }, // { // "contracts":250000, // "initialMargin":0.04, // "maintenanceMargin":0.02 // }, // ... // ], // "isin": "GB00JVMLMP88", // "retailMarginLevels": [ // { // "contracts": 0, // "initialMargin": 0.5, // "maintenanceMargin": 0.25 // } // ], // "tags": [], // }, // { // "symbol": "in_xbtusd", // "type": "spot index", // "tradeable":false // } // ] // "serverTime": "2018-07-19T11:32:39.433Z" // } // var data interface{} = this.SafeList(response, "instruments") ch <- this.ParseLeverageTiers(data, symbols, "symbol") return nil }() return ch } func (this *krakenfutures) ParseMarketLeverageTiers(info interface{}, optionalArgs ...interface{}) interface{} { /** * @method * @ignore * @param info Exchange market response for 1 market * @param market CCXT market */ // // { // "symbol": "fi_ethusd_180928", // "type": "futures_inverse", // futures_vanilla // spot index // "underlying": "rr_ethusd", // "lastTradingTime": "2018-09-28T15:00:00.000Z", // "tickSize": 0.1, // "contractSize": 1, // "tradeable": true, // "marginLevels": [ // { // "contracts":0, // "initialMargin":0.02, // "maintenanceMargin":0.01 // }, // { // "contracts":250000, // "initialMargin":0.04, // "maintenanceMargin":0.02 // }, // ... // ], // "isin": "GB00JVMLMP88", // "retailMarginLevels": [ // { // "contracts": 0, // "initialMargin": 0.5, // "maintenanceMargin": 0.25 // } // ], // "tags": [], // } // market := GetArg(optionalArgs, 0, nil) _ = market var marginLevels interface{} = this.SafeValue(info, "marginLevels") var marketId interface{} = this.SafeString(info, "symbol") market = this.SafeMarket(marketId, market) var tiers interface{} = []interface{}{} if IsTrue(IsEqual(marginLevels, nil)) { return tiers } for i := 0; IsLessThan(i, GetArrayLength(marginLevels)); i++ { var tier interface{} = GetValue(marginLevels, i) var initialMargin interface{} = this.SafeString(tier, "initialMargin") var minNotional interface{} = this.SafeNumber(tier, "numNonContractUnits") if IsTrue(!IsEqual(i, 0)) { var tiersLength interface{} = GetArrayLength(tiers) var previousTier interface{} = GetValue(tiers, Subtract(tiersLength, 1)) AddElementToObject(previousTier, "maxNotional", minNotional) } AppendToArray(&tiers,map[string]interface{} { "tier": this.Sum(i, 1), "symbol": this.SafeSymbol(marketId, market), "currency": GetValue(market, "quote"), "minNotional": minNotional, "maxNotional": nil, "maintenanceMarginRate": this.SafeNumber(tier, "maintenanceMargin"), "maxLeverage": this.ParseNumber(Precise.StringDiv("1", initialMargin)), "info": tier, }) } return tiers } func (this *krakenfutures) ParseTransfer(transfer interface{}, optionalArgs ...interface{}) interface{} { // // transfer // // { // "result": "success", // "serverTime": "2022-04-12T01:22:53.420Z" // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var datetime interface{} = this.SafeString(transfer, "serverTime") return map[string]interface{} { "info": transfer, "id": nil, "timestamp": this.Parse8601(datetime), "datetime": datetime, "currency": this.SafeString(currency, "code"), "amount": nil, "fromAccount": nil, "toAccount": nil, "status": this.SafeString(transfer, "result"), } } func (this *krakenfutures) ParseAccount(account interface{}) interface{} { var accountByType interface{} = map[string]interface{} { "main": "cash", "funding": "cash", "future": "cash", "futures": "cash", "cashAccount": "cash", "multiCollateralMarginAccount": "flex", "multiCollateral": "flex", "multiCollateralMargin": "flex", } if IsTrue(InOp(accountByType, account)) { return GetValue(accountByType, account) } else if IsTrue(InOp(this.Markets, account)) { var market interface{} = this.Market(account) var marketId interface{} = GetValue(market, "id") var splitId interface{} = Split(marketId, "_") if IsTrue(GetValue(market, "inverse")) { return Add("fi_", this.SafeString(splitId, 1)) } else { return Add("fv_", this.SafeString(splitId, 1)) } } else { return account } } /** * @method * @name krakenfutures#transferOut * @description transfer from futures wallet to spot wallet * @param {str} code Unified currency code * @param {float} amount Size of the transfer * @param {dict} [params] Exchange specific parameters * @returns a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure} */ func (this *krakenfutures) TransferOut(code interface{}, amount interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes268515 := (<-this.Transfer(code, amount, "future", "spot", params)) PanicOnError(retRes268515) ch <- retRes268515 return nil }() return ch } /** * @method * @name krakenfutures#transfer * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-transfers-initiate-wallet-transfer * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-transfers-initiate-withdrawal-to-spot-wallet * @description transfers currencies between sub-accounts * @param {string} code Unified currency code * @param {float} amount Size of the transfer * @param {string} fromAccount 'main'/'funding'/'future', 'flex', or a unified market symbol * @param {string} toAccount 'main'/'funding', 'flex', 'spot' or a unified market symbol * @param {object} [params] Exchange specific parameters * @returns a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure} */ func (this *krakenfutures) Transfer(code interface{}, amount interface{}, fromAccount interface{}, toAccount interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes27028 := (<-this.LoadMarkets()) PanicOnError(retRes27028) var currency interface{} = this.Currency(code) if IsTrue(IsEqual(fromAccount, "spot")) { panic(BadRequest(Add(this.Id, " transfer does not yet support transfers from spot"))) } var request interface{} = map[string]interface{} { "amount": amount, } var response interface{} = nil if IsTrue(IsEqual(toAccount, "spot")) { if IsTrue(!IsEqual(this.ParseAccount(fromAccount), "cash")) { panic(BadRequest(Add(Add(Add(Add(this.Id, " transfer cannot transfer from "), fromAccount), " to "), toAccount))) } AddElementToObject(request, "currency", GetValue(currency, "id")) response = (<-this.PrivatePostWithdrawal(this.Extend(request, params))) PanicOnError(response) } else { AddElementToObject(request, "fromAccount", this.ParseAccount(fromAccount)) AddElementToObject(request, "toAccount", this.ParseAccount(toAccount)) AddElementToObject(request, "unit", GetValue(currency, "id")) response = (<-this.PrivatePostTransfer(this.Extend(request, params))) PanicOnError(response) } // // { // "result": "success", // "serverTime": "2022-04-12T01:22:53.420Z" // } // var transfer interface{} = this.ParseTransfer(response, currency) ch <- this.Extend(transfer, map[string]interface{} { "amount": amount, "fromAccount": fromAccount, "toAccount": toAccount, }) return nil }() return ch } /** * @method * @name krakenfutures#setLeverage * @description set the level of leverage for a market * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-multi-collateral-set-the-leverage-setting-for-a-market * @param {float} leverage the rate of leverage * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} response from the exchange */ func (this *krakenfutures) SetLeverage(leverage interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " setLeverage() requires a symbol argument"))) } retRes27518 := (<-this.LoadMarkets()) PanicOnError(retRes27518) var request interface{} = map[string]interface{} { "maxLeverage": leverage, "symbol": ToUpper(this.MarketId(symbol)), } retRes275915 := (<-this.PrivatePutLeveragepreferences(this.Extend(request, params))) PanicOnError(retRes275915) // // { result: "success", serverTime: "2023-08-01T09:40:32.345Z" } // ch <- retRes275915 return nil }() return ch } /** * @method * @name krakenfutures#fetchLeverages * @description fetch the set leverage for all contract and margin markets * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-multi-collateral-get-the-leverage-setting-for-a-market * @param {string[]} [symbols] a list of unified market symbols * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a list of [leverage structures]{@link https://docs.ccxt.com/#/?id=leverage-structure} */ func (this *krakenfutures) FetchLeverages(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbols := GetArg(optionalArgs, 0, nil) _ = symbols params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes27728 := (<-this.LoadMarkets()) PanicOnError(retRes27728) response:= (<-this.PrivateGetLeveragepreferences(params)) PanicOnError(response) // // { // "result": "success", // "serverTime": "2024-03-06T02:35:46.336Z", // "leveragePreferences": [ // { // "symbol": "PF_ETHUSD", // "maxLeverage": 30.00 // }, // ] // } // var leveragePreferences interface{} = this.SafeList(response, "leveragePreferences", []interface{}{}) ch <- this.ParseLeverages(leveragePreferences, symbols, "symbol") return nil }() return ch } /** * @method * @name krakenfutures#fetchLeverage * @description fetch the set leverage for a market * @see https://docs.futures.kraken.com/#http-api-trading-v3-api-multi-collateral-get-the-leverage-setting-for-a-market * @param {string} symbol unified market symbol * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [leverage structure]{@link https://docs.ccxt.com/#/?id=leverage-structure} */ func (this *krakenfutures) FetchLeverage(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchLeverage() requires a symbol argument"))) } retRes28038 := (<-this.LoadMarkets()) PanicOnError(retRes28038) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": ToUpper(this.MarketId(symbol)), } response:= (<-this.PrivateGetLeveragepreferences(this.Extend(request, params))) PanicOnError(response) // // { // "result": "success", // "serverTime": "2023-08-01T09:54:08.900Z", // "leveragePreferences": [ { symbol: "PF_LTCUSD", maxLeverage: "5.00" } ] // } // var leveragePreferences interface{} = this.SafeList(response, "leveragePreferences", []interface{}{}) var data interface{} = this.SafeDict(leveragePreferences, 0, map[string]interface{} {}) ch <- this.ParseLeverage(data, market) return nil }() return ch } func (this *krakenfutures) ParseLeverage(leverage interface{}, optionalArgs ...interface{}) interface{} { market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString(leverage, "symbol") var leverageValue interface{} = this.SafeInteger(leverage, "maxLeverage") return map[string]interface{} { "info": leverage, "symbol": this.SafeSymbol(marketId, market), "marginMode": nil, "longLeverage": leverageValue, "shortLeverage": leverageValue, } } func (this *krakenfutures) HandleErrors(code interface{}, reason interface{}, url interface{}, method interface{}, headers interface{}, body interface{}, response interface{}, requestHeaders interface{}, requestBody interface{}) interface{} { if IsTrue(IsEqual(response, nil)) { return nil } if IsTrue(IsEqual(code, 429)) { panic(DDoSProtection(Add(Add(this.Id, " "), body))) } var errors interface{} = this.SafeValue(response, "errors") var firstError interface{} = this.SafeValue(errors, 0) var firtErrorMessage interface{} = this.SafeString(firstError, "message") var message interface{} = this.SafeString(response, "error", firtErrorMessage) if IsTrue(IsEqual(message, nil)) { return nil } var feedback interface{} = Add(Add(this.Id, " "), body) this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), message, feedback) this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), message, feedback) if IsTrue(IsEqual(code, 400)) { panic(BadRequest(feedback)) } panic(ExchangeError(feedback)) } func (this *krakenfutures) Sign(path interface{}, optionalArgs ...interface{}) interface{} { api := GetArg(optionalArgs, 0, "public") _ = api method := GetArg(optionalArgs, 1, "GET") _ = method params := GetArg(optionalArgs, 2, map[string]interface{} {}) _ = params headers := GetArg(optionalArgs, 3, nil) _ = headers body := GetArg(optionalArgs, 4, nil) _ = body var apiVersions interface{} = this.SafeValue(GetValue(this.Options, "versions"), api, map[string]interface{} {}) var methodVersions interface{} = this.SafeValue(apiVersions, method, map[string]interface{} {}) var defaultVersion interface{} = this.SafeString(methodVersions, path, this.Version) var version interface{} = this.SafeString(params, "version", defaultVersion) params = this.Omit(params, "version") var apiAccess interface{} = this.SafeValue(GetValue(this.Options, "access"), api, map[string]interface{} {}) var methodAccess interface{} = this.SafeValue(apiAccess, method, map[string]interface{} {}) var access interface{} = this.SafeString(methodAccess, path, "public") var endpoint interface{} = Add(Add(version, "/"), this.ImplodeParams(path, params)) params = this.Omit(params, this.ExtractParams(path)) var query interface{} = endpoint var postData interface{} = "" if IsTrue(IsEqual(path, "batchorder")) { postData = Add("json=", this.Json(params)) body = postData } else if IsTrue(GetArrayLength(ObjectKeys(params))) { postData = this.Urlencode(params) query = Add(query, Add("?", postData)) } var url interface{} = Add(GetValue(GetValue(this.Urls, "api"), api), query) if IsTrue(IsTrue(IsEqual(api, "private")) || IsTrue(IsEqual(access, "private"))) { this.CheckRequiredCredentials() var auth interface{} = Add(postData, "/api/") if IsTrue(!IsEqual(api, "private")) { auth = Add(auth, Add(api, "/")) } auth = Add(auth, endpoint) // 1 var hash interface{} = this.Hash(this.Encode(auth), sha256, "binary") // 2 var secret interface{} = this.Base64ToBinary(this.Secret) // 3 var signature interface{} = this.Hmac(hash, secret, sha512, "base64") // 4-5 headers = map[string]interface{} { "Content-Type": "application/x-www-form-urlencoded", "Accept": "application/json", "APIKey": this.ApiKey, "Authent": signature, } } return map[string]interface{} { "url": url, "method": method, "body": body, "headers": headers, } } func (this *krakenfutures) Init(userConfig map[string]interface{}) { this.Exchange = Exchange{} this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this) this.Exchange.DerivedExchange = this }