UNPKG

ccxt

Version:

A cryptocurrency trading API with more than 100 exchanges in JavaScript / TypeScript / Python / C# / PHP / Go

2,921 lines • 129 kB
'use strict';

Object.defineProperty(exports, '__esModule', { value: true });

var krakenfutures$1 = require('./abstract/krakenfutures.js');
var number = require('./base/functions/number.js');
var errors = require('./base/errors.js');
var Precise = require('./base/Precise.js');
var sha256 = require('./static_dependencies/noble-hashes/sha256.js');
var sha512 = require('./static_dependencies/noble-hashes/sha512.js');

// ----------------------------------------------------------------------------
//  ---------------------------------------------------------------------------
/**
 * @class krakenfutures
 * @augments Exchange
 */
class krakenfutures extends krakenfutures$1["default"] {
    describe() {
        return this.deepExtend(super.describe(), {
            'id': 'krakenfutures',
            'name': 'Kraken Futures',
            'countries': ['US'],
            'version': 'v3',
            'userAgent': undefined,
            'rateLimit': 600,
            'pro': true,
            'has': {
                'CORS': undefined,
                'spot': false,
                'margin': false,
                'swap': true,
                'future': true,
                'option': false,
                'cancelAllOrders': true,
                'cancelAllOrdersAfter': true,
                'cancelOrder': true,
                'cancelOrders': true,
                'createMarketOrder': false,
                'createOrder': true,
                'createPostOnlyOrder': true,
                'createReduceOnlyOrder': true,
                'createStopLimitOrder': true,
                'createStopMarketOrder': true,
                'createStopOrder': true,
                'createTriggerOrder': true,
                'editOrder': true,
                'fetchBalance': true,
                'fetchBorrowRateHistories': false,
                'fetchBorrowRateHistory': false,
                'fetchCanceledOrders': true,
                'fetchClosedOrders': true,
                'fetchCrossBorrowRate': false,
                'fetchCrossBorrowRates': false,
                'fetchCurrencies': false,
                'fetchDepositAddress': false,
                'fetchDepositAddresses': false,
                'fetchDepositAddressesByNetwork': false,
                'fetchFundingHistory': undefined,
                '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': {
                'test': {
                    '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': {
                    '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': [
                    'https://docs.kraken.com/api/docs/futures-api/trading/market-data/',
                ],
                'fees': 'https://support.kraken.com/hc/en-us/articles/360022835771-Transaction-fees-and-rebates-for-Kraken-Futures',
                'referral': undefined,
            },
            'api': {
                'public': {
                    'get': [
                        'feeschedules',
                        'instruments',
                        'orderbook',
                        'tickers',
                        'history',
                        'historicalfundingrates',
                    ],
                },
                'private': {
                    'get': [
                        'feeschedules/volumes',
                        'openpositions',
                        'notifications',
                        'accounts',
                        'openorders',
                        'recentorders',
                        'fills',
                        'transfers',
                        'leveragepreferences',
                        'pnlpreferences',
                        'assignmentprogram/current',
                        'assignmentprogram/history',
                    ],
                    'post': [
                        'sendorder',
                        'editorder',
                        'cancelorder',
                        'transfer',
                        'batchorder',
                        'cancelallorders',
                        'cancelallordersafter',
                        'withdrawal',
                        'assignmentprogram/add',
                        'assignmentprogram/delete',
                    ],
                    'put': [
                        'leveragepreferences',
                        'pnlpreferences',
                    ],
                },
                'charts': {
                    'get': [
                        '{price_type}/{symbol}/{interval}',
                    ],
                },
                'history': {
                    'get': [
                        'orders',
                        'executions',
                        'triggers',
                        'accountlogcsv',
                        'account-log',
                        'market/{symbol}/orders',
                        'market/{symbol}/executions',
                    ],
                },
            },
            'fees': {
                'trading': {
                    'tierBased': true,
                    'percentage': true,
                    'taker': this.parseNumber('0.0005'),
                    'maker': this.parseNumber('0.0002'),
                    'tiers': {
                        'taker': [
                            [this.parseNumber('0'), this.parseNumber('0.0005')],
                            [this.parseNumber('100000'), this.parseNumber('0.0004')],
                            [this.parseNumber('1000000'), this.parseNumber('0.0003')],
                            [this.parseNumber('5000000'), this.parseNumber('0.00025')],
                            [this.parseNumber('10000000'), this.parseNumber('0.0002')],
                            [this.parseNumber('20000000'), this.parseNumber('0.00015')],
                            [this.parseNumber('50000000'), this.parseNumber('0.000125')],
                            [this.parseNumber('100000000'), this.parseNumber('0.0001')],
                        ],
                        'maker': [
                            [this.parseNumber('0'), this.parseNumber('0.0002')],
                            [this.parseNumber('100000'), this.parseNumber('0.0015')],
                            [this.parseNumber('1000000'), this.parseNumber('0.000125')],
                            [this.parseNumber('5000000'), this.parseNumber('0.0001')],
                            [this.parseNumber('10000000'), this.parseNumber('0.000075')],
                            [this.parseNumber('20000000'), this.parseNumber('0.00005')],
                            [this.parseNumber('50000000'), this.parseNumber('0.000025')],
                            [this.parseNumber('100000000'), this.parseNumber('0')],
                        ],
                    },
                },
            },
            'exceptions': {
                'exact': {
                    'apiLimitExceeded': errors.RateLimitExceeded,
                    'marketUnavailable': errors.ContractUnavailable,
                    'requiredArgumentMissing': errors.BadRequest,
                    'unavailable': errors.ExchangeNotAvailable,
                    'authenticationError': errors.AuthenticationError,
                    'accountInactive': errors.ExchangeError,
                    'invalidAccount': errors.BadRequest,
                    'invalidAmount': errors.BadRequest,
                    'insufficientFunds': errors.InsufficientFunds,
                    'Bad Request': errors.BadRequest,
                    'Unavailable': errors.ExchangeNotAvailable,
                    'invalidUnit': errors.BadRequest,
                    'Json Parse Error': errors.ExchangeError,
                    'nonceBelowThreshold': errors.InvalidNonce,
                    'nonceDuplicate': errors.InvalidNonce,
                    'notFound': errors.BadRequest,
                    'Server Error': errors.ExchangeError,
                    'unknownError': errors.ExchangeError,
                },
                'broad': {
                    'invalidArgument': errors.BadRequest,
                    'nonceBelowThreshold': errors.InvalidNonce,
                    'nonceDuplicate': errors.InvalidNonce,
                },
            },
            'precisionMode': number.TICK_SIZE,
            'options': {
                'access': {
                    'history': {
                        'GET': {
                            'orders': 'private',
                            'executions': 'private',
                            'triggers': 'private',
                            'accountlogcsv': 'private',
                            'account-log': 'private',
                        },
                    },
                },
                'settlementCurrencies': {
                    'flex': ['USDT', 'BTC', 'USD', 'GBP', 'EUR', 'USDC'],
                },
                'symbol': {
                    'quoteIds': ['USD', 'XBT'],
                    'reversed': false,
                },
                'versions': {
                    'public': {
                        'GET': {
                            'historicalfundingrates': 'v4',
                        },
                    },
                    'charts': {
                        'GET': {
                            '{price_type}/{symbol}/{interval}': 'v1',
                        },
                    },
                    'history': {
                        'GET': {
                            'orders': 'v2',
                            'executions': 'v2',
                            'triggers': 'v2',
                            'accountlogcsv': 'v2',
                        },
                    },
                },
                'fetchTrades': {
                    'method': 'historyGetMarketSymbolExecutions', // historyGetMarketSymbolExecutions, publicGetHistory
                },
            },
            'features': {
                'default': {
                    'sandbox': true,
                    'createOrder': {
                        'marginMode': false,
                        'triggerPrice': true,
                        'triggerPriceType': {
                            'last': true,
                            'mark': true,
                            'index': true,
                        },
                        'triggerDirection': false,
                        'stopLossPrice': true,
                        'takeProfitPrice': true,
                        'attachedStopLossTakeProfit': undefined,
                        'timeInForce': {
                            'IOC': true,
                            'FOK': true,
                            'PO': true,
                            'GTD': false,
                        },
                        'hedged': false,
                        'trailing': false,
                        'leverage': false,
                        'marketBuyByCost': false,
                        'marketBuyRequiresPrice': false,
                        'selfTradePrevention': false,
                        'iceberg': false,
                    },
                    'createOrders': {
                        'max': 100,
                    },
                    'fetchMyTrades': {
                        'marginMode': false,
                        'limit': undefined,
                        'daysBack': undefined,
                        'untilDays': 100000,
                        'symbolRequired': false,
                    },
                    'fetchOrder': undefined,
                    'fetchOpenOrders': {
                        'marginMode': false,
                        'limit': undefined,
                        'trigger': false,
                        'trailing': false,
                        'symbolRequired': false,
                    },
                    'fetchOrders': undefined,
                    'fetchClosedOrders': {
                        'marginMode': false,
                        'limit': undefined,
                        'daysBack': undefined,
                        'daysBackCanceled': undefined,
                        'untilDays': undefined,
                        'trigger': false,
                        'trailing': false,
                        'symbolRequired': false,
                    },
                    'fetchOHLCV': {
                        'limit': 5000,
                    },
                },
                'spot': undefined,
                'swap': {
                    'linear': {
                        'extends': 'default',
                    },
                    'inverse': {
                        'extends': 'default',
                    },
                },
                'future': {
                    'linear': {
                        'extends': 'default',
                    },
                    'inverse': {
                        'extends': 'default',
                    },
                },
            },
            'timeframes': {
                '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.kraken.com/api/docs/futures-api/trading/get-instruments
     * @param {object} [params] exchange specific params
     * @returns An array of market structures
     */
    async fetchMarkets(params = {}) {
        const response = await this.publicGetInstruments(params);
        //
        //    {
        //        "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"
        //    }
        //
        const instruments = this.safeValue(response, 'instruments', []);
        const result = [];
        for (let i = 0; i < instruments.length; i++) {
            const market = instruments[i];
            const id = this.safeString(market, 'symbol');
            const marketType = this.safeString(market, 'type');
            let type = undefined;
            const index = (marketType.indexOf(' index') >= 0);
            let linear = undefined;
            let inverse = undefined;
            let expiry = undefined;
            if (!index) {
                linear = (marketType.indexOf('_vanilla') >= 0);
                inverse = !linear;
                const settleTime = this.safeString(market, 'lastTradingTime');
                type = (settleTime === undefined) ? 'swap' : 'future';
                expiry = this.parse8601(settleTime);
            }
            else {
                type = 'index';
            }
            const swap = (type === 'swap');
            const future = (type === 'future');
            let symbol = id;
            const split = id.split('_');
            const splitMarket = this.safeString(split, 1);
            const baseId = splitMarket.slice(0, splitMarket.length - 3);
            const quoteId = 'usd'; // always USD
            const base = this.safeCurrencyCode(baseId);
            const quote = this.safeCurrencyCode(quoteId);
            // swap == perpetual
            let settle = undefined;
            let settleId = undefined;
            const cvtp = this.safeString(market, 'contractValueTradePrecision');
            const amountPrecision = this.parseNumber(this.integerPrecisionToAmount(cvtp));
            const pricePrecision = this.safeNumber(market, 'tickSize');
            const contract = (swap || future || index);
            const swapOrFutures = (swap || future);
            if (swapOrFutures) {
                const exchangeType = this.safeString(market, 'type');
                if (exchangeType === 'futures_inverse') {
                    settle = base;
                    settleId = baseId;
                    inverse = true;
                }
                else {
                    settle = quote;
                    settleId = quoteId;
                    inverse = false;
                }
                linear = !inverse;
                symbol = base + '/' + quote + ':' + settle;
                if (future) {
                    symbol = symbol + '-' + this.yymmdd(expiry);
                }
            }
            result.push({
                'id': id,
                'symbol': symbol,
                'base': base,
                'quote': quote,
                'settle': settle,
                'baseId': baseId,
                'quoteId': quoteId,
                'settleId': settleId,
                'type': type,
                'spot': false,
                'margin': false,
                'swap': swap,
                'future': future,
                'option': false,
                'index': index,
                'active': this.safeBool(market, 'tradeable'),
                'contract': contract,
                'linear': linear,
                'inverse': inverse,
                'contractSize': this.safeNumber(market, 'contractSize'),
                'maintenanceMarginRate': undefined,
                'expiry': expiry,
                'expiryDatetime': this.iso8601(expiry),
                'strike': undefined,
                'optionType': undefined,
                'precision': {
                    'amount': amountPrecision,
                    'price': pricePrecision,
                },
                'limits': {
                    'leverage': {
                        'min': undefined,
                        'max': undefined,
                    },
                    'amount': {
                        'min': undefined,
                        'max': undefined,
                    },
                    'price': {
                        'min': undefined,
                        'max': undefined,
                    },
                    'cost': {
                        'min': undefined,
                        'max': undefined,
                    },
                },
                'created': this.parse8601(this.safeString(market, 'openingDate')),
                'info': market,
            });
        }
        const settlementCurrencies = this.options['settlementCurrencies']['flex'];
        const currencies = [];
        for (let i = 0; i < settlementCurrencies.length; i++) {
            const code = settlementCurrencies[i];
            currencies.push({
                'id': code.toLowerCase(),
                'numericId': undefined,
                'code': code,
                'precision': undefined,
            });
        }
        this.currencies = this.mapToSafeMap(this.deepExtend(currencies, this.currencies));
        return result;
    }
    /**
     * @method
     * @name krakenfutures#fetchOrderBook
     * @see https://docs.kraken.com/api/docs/futures-api/trading/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}
     */
    async fetchOrderBook(symbol, limit = undefined, params = {}) {
        await this.loadMarkets();
        const market = this.market(symbol);
        const request = {
            'symbol': market['id'],
        };
        const response = await this.publicGetOrderbook(this.extend(request, params));
        //
        //    {
        //       "result": "success",
        //       "serverTime": "2016-02-25T09:45:53.818Z",
        //       "orderBook": {
        //          "bids": [
        //                [
        //                    4213,
        //                    2000,
        //                ],
        //                [
        //                    4210,
        //                    4000,
        //                ],
        //                ...
        //            ],
        //            "asks": [
        //                [
        //                    4218,
        //                    4000,
        //                ],
        //                [
        //                    4220,
        //                    5000,
        //                ],
        //                ...
        //            ],
        //        },
        //    }
        //
        const timestamp = this.parse8601(response['serverTime']);
        return this.parseOrderBook(response['orderBook'], symbol, timestamp);
    }
    /**
     * @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.kraken.com/api/docs/futures-api/trading/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}
     */
    async fetchTickers(symbols = undefined, params = {}) {
        await this.loadMarkets();
        const response = await this.publicGetTickers(params);
        //
        //    {
        //        "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"
        //    }
        //
        const tickers = this.safeList(response, 'tickers');
        return this.parseTickers(tickers, symbols);
    }
    parseTicker(ticker, market = undefined) {
        //
        //    {
        //        "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"
        //    }
        //
        const marketId = this.safeString(ticker, 'symbol');
        market = this.safeMarket(marketId, market);
        const symbol = market['symbol'];
        const timestamp = this.parse8601(this.safeString(ticker, 'lastTime'));
        const open = this.safeString(ticker, 'open24h');
        const last = this.safeString(ticker, 'last');
        const change = Precise["default"].stringSub(last, open);
        const percentage = Precise["default"].stringMul(Precise["default"].stringDiv(change, open), '100');
        const average = Precise["default"].stringDiv(Precise["default"].stringAdd(open, last), '2');
        const volume = this.safeString(ticker, 'vol24h');
        let baseVolume = undefined;
        let quoteVolume = undefined;
        const isIndex = this.safeBool(market, 'index', false);
        if (!isIndex) {
            if (market['linear']) {
                baseVolume = volume;
            }
            else if (market['inverse']) {
                quoteVolume = volume;
            }
        }
        return this.safeTicker({
            'symbol': symbol,
            'timestamp': timestamp,
            'datetime': this.iso8601(timestamp),
            'high': undefined,
            'low': undefined,
            'bid': this.safeString(ticker, 'bid'),
            'bidVolume': this.safeString(ticker, 'bidSize'),
            'ask': this.safeString(ticker, 'ask'),
            'askVolume': this.safeString(ticker, 'askSize'),
            'vwap': undefined,
            'open': open,
            'close': last,
            'last': last,
            'previousClose': undefined,
            '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.kraken.com/api/docs/futures-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
     */
    async fetchOHLCV(symbol, timeframe = '1m', since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets();
        const market = this.market(symbol);
        let paginate = false;
        [paginate, params] = this.handleOptionAndParams(params, 'fetchOHLCV', 'paginate');
        if (paginate) {
            return await this.fetchPaginatedCallDeterministic('fetchOHLCV', symbol, since, limit, timeframe, params, 5000);
        }
        const request = {
            'symbol': market['id'],
            'price_type': this.safeString(params, 'price', 'trade'),
            'interval': this.timeframes[timeframe],
        };
        params = this.omit(params, 'price');
        if (since !== undefined) {
            const duration = this.parseTimeframe(timeframe);
            request['from'] = this.parseToInt(since / 1000);
            if (limit === undefined) {
                limit = 5000;
            }
            limit = Math.min(limit, 5000);
            const toTimestamp = this.sum(request['from'], limit * duration - 1);
            const currentTimestamp = this.seconds();
            request['to'] = Math.min(toTimestamp, currentTimestamp);
        }
        else if (limit !== undefined) {
            limit = Math.min(limit, 5000);
            const duration = this.parseTimeframe(timeframe);
            request['to'] = this.seconds();
            request['from'] = this.parseToInt(request['to'] - (duration * limit));
        }
        const response = await this.chartsGetPriceTypeSymbolInterval(this.extend(request, params));
        //
        //    {
        //        "candles": [
        //            {
        //                "time": 1645198500000,
        //                "open": "309.15000000000",
        //                "high": "309.15000000000",
        //                "low": "308.70000000000",
        //                "close": "308.85000000000",
        //                "volume": 0
        //            }
        //        ],
        //        "more_candles": true
        //    }
        //
        const candles = this.safeList(response, 'candles');
        return this.parseOHLCVs(candles, market, timeframe, since, limit);
    }
    parseOHLCV(ohlcv, market = undefined) {
        //
        //    {
        //        "time": 1645198500000,
        //        "open": "309.15000000000",
        //        "high": "309.15000000000",
        //        "low": "308.70000000000",
        //        "close": "308.85000000000",
        //        "volume": 0
        //    }
        //
        return [
            this.safeInteger(ohlcv, 'time'),
            this.safeNumber(ohlcv, 'open'),
            this.safeNumber(ohlcv, 'high'),
            this.safeNumber(ohlcv, 'low'),
            this.safeNumber(ohlcv, 'close'),
            this.safeNumber(ohlcv, 'volume'), // trading volume, undefined for mark or index price
        ];
    }
    /**
     * @method
     * @name krakenfutures#fetchTrades
     * @see https://docs.kraken.com/api/docs/futures-api/trading/get-history
     * @see https://docs.kraken.com/api/docs/futures-api/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}
     */
    async fetchTrades(symbol, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets();
        let paginate = false;
        [paginate, params] = this.handleOptionAndParams(params, 'fetchTrades', 'paginate');
        if (paginate) {
            return await this.fetchPaginatedCallDynamic('fetchTrades', symbol, since, limit, params);
        }
        const market = this.market(symbol);
        let request = {
            'symbol': market['id'],
        };
        let method = undefined;
        [method, params] = this.handleOptionAndParams(params, 'fetchTrades', 'method', 'historyGetMarketSymbolExecutions');
        let rawTrades = undefined;
        const isFullHistoryEndpoint = (method === 'historyGetMarketSymbolExecutions');
        if (isFullHistoryEndpoint) {
            [request, params] = this.handleUntilOption('before', request, params);
            if (since !== undefined) {
                request['since'] = since;
                request['sort'] = 'asc';
            }
            if (limit !== undefined) {
                request['count'] = limit;
            }
            const response = await this.historyGetMarketSymbolExecutions(this.extend(request, params));
            //
            //    {
            //        "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="
            //    }
            //
            const elements = this.safeList(response, 'elements', []);
            // we need to reverse the list to fix chronology
            rawTrades = [];
            const length = elements.length;
            for (let i = 0; i < length; i++) {
                const index = length - 1 - i;
                const element = elements[index];
                const event = this.safeDict(element, 'event', {});
                const executionContainer = this.safeDict(event, 'Execution', {});
                const rawTrade = this.safeDict(executionContainer, 'execution', {});
                rawTrades.push(rawTrade);
            }
        }
        else {
            [request, params] = this.handleUntilOption('lastTime', request, params);
            const response = await this.publicGetHistory(this.extend(request, params));
            //
            //    {
            //        "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', []);
        }
        return this.parseTrades(rawTrades, market, since, limit);
    }
    parseTrade(trade, market = undefined) {
        //
        // 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"
        //    }
        //
        let timestamp = this.parse8601(this.safeString2(trade, 'time', 'fillTime'));
        const price = this.safeString(trade, 'price');
        const amount = this.safeStringN(trade, ['size', 'amount', 'quantity'], '0.0');
        let id = this.safeString2(trade, 'uid', 'fill_id');
        if (id === undefined) {
            id = this.safeString(trade, 'executionId');
        }
        let order = this.safeString(trade, 'order_id');
        let marketId = this.safeString(trade, 'symbol');
        let side = this.safeString(trade, 'side');
        let type = undefined;
        const priorEdit = this.safeValue(trade, 'orderPriorEdit');
        const priorExecution = this.safeValue(trade, 'orderPriorExecution');
        if (priorExecution !== undefined) {
            order = this.safeString(priorExecution, 'orderId');
            marketId = this.safeString(priorExecution, 'symbol');
            side = this.safeString(priorExecution, 'side');
            type = this.safeString(priorExecution, 'type');
        }
        else if (priorEdit !== undefined) {
            order = this.safeString(priorEdit, 'orderId');
            marketId = this.safeString(priorEdit, 'symbol');
            side = this.safeString(priorEdit, 'type');
            type = this.safeString(priorEdit, 'type');
        }
        if (type !== undefined) {
            type = this.parseOrderType(type);
        }
        market = this.safeMarket(marketId, market);
        let cost = undefined;
        const linear = this.safeBool(market, 'linear');
        if ((amount !== undefined) && (price !== undefined) && (market !== undefined)) {
            if (linear) {
                cost = Precise["default"].stringMul(amount, price); // in quote
            }
            else {
                cost = Precise["default"].stringDiv(amount, price); // in base
            }
            const contractSize = this.safeString(market, 'contractSize');
            cost = Precise["default"].stringMul(cost, contractSize);
        }
        let takerOrMaker = undefined;
        const fillType = this.safeString(trade, 'fillType');
        if (fillType !== undefined) {
            if (fillType.indexOf('taker') >= 0) {
                takerOrMaker = 'taker';
            }
            else if (fillType.indexOf('maker') >= 0) {
                takerOrMaker = 'maker';
            }
        }
        const isHistoricalExecution = ('takerOrder' in trade);
        if (isHistoricalExecution) {
            timestamp = this.safeInteger(trade, 'timestamp');
            const taker = this.safeDict(trade, 'takerOrder', {});
            if (taker !== undefined) {
                side = this.safeStringLower(taker, 'direction');
                takerOrMaker = 'taker';
            }
        }
        return this.safeTrade({
            'info': trade,
            'id': id,
            'symbol': this.safeString(market, 'symbol'),
            'timestamp': timestamp,
            'datetime': this.iso8601(timestamp),
            'order': order,
            'type': type,
            'side': side,
            'takerOrMaker': takerOrMaker,
            'price': price,
            'amount': linear ? amount : undefined,
            'cost': cost,
            'fee': undefined,
        });
    }
    createOrderRequest(symbol, type, side, amount, price = undefined, params = {}) {
        const market = this.market(symbol);
        symbol = market['symbol'];
        type = this.safeString(params, 'orderType', type);
        const timeInForce = this.safeString(params, 'timeInForce');
        let postOnly = false;
        [postOnly, params] = this.handlePostOnly(type === 'market', type === 'post', params);
        if (postOnly) {
            type = 'post';
        }
        else if (timeInForce === 'ioc') {
            type = 'ioc';
        }
        else if (type === 'limit') {
            type = 'lmt';
        }
        else if (type === 'market') {
            type = 'mkt';
        }
        const request = {
            'symbol': market['id'],
            'side': side,
            'size': this.amountToPrecision(symbol, amount),
        };
        const clientOrderId = this.safeString2(params, 'clientOrderId', 'cliOrdId');
        if (clientOrderId !== undefined) {
            request['cliOrdId'] = clientOrderId;
        }
        const triggerPrice = this.safeString2(params, 'triggerPrice', 'stopPrice');
        const isTriggerOrder = triggerPrice !== undefined;
        const stopLossTriggerPrice = this.safeString(params, 'stopLossPrice');
        const takeProfitTriggerPrice = this.safeString(params, 'takeProfitPrice');
        const isStopLossTriggerOrder = stopLossTriggerPrice !== undefined;
        const isTakeProfitTriggerOrder = takeProfitTriggerPrice !== undefined;
        const isStopLossOrTakeProfitTrigger = isStopLossTriggerOrder || isTakeProfitTriggerOrder;
        const triggerSignal = this.safeString(params, 'triggerSignal', 'last');
        let reduceOnly = this.safeValue(params, 'reduceOnly');
        if (isStopLossOrTakeProfitTrigger || isTriggerOrder) {
            request['triggerSignal'] = triggerSignal;
        }
        if (isTriggerOrder) {
            type = 'stp';
            request['stopPrice'] = this.priceToPrecision(symbol, triggerPrice);
        }
        else if (isStopLossOrTakeProfitTrigger) {
            reduceOnly = true;
            if (isStopLossTriggerOrder) {
                type = 'stp';
                request['stopPrice'] = this.priceToPrecision(symbol, stopLossTriggerPrice);
            }
            else if (isTakeProfitTriggerOrder) {
                type = 'take_profit';
                request['stopPrice'] = this.priceToPrecision(symbol, takeProfitTriggerPrice);
            }
        }
        if (reduceOnly) {
            request['reduceOnly'] = true;
        }
        request['orderType'] = type;
        if (price !== undefined) {
            request['limitPrice'] = this.priceToPrecision(symbol, price);
        }
        params = this.omit(params, ['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}
     */
    async createOrder(symbol, type, side, amount, price = undefined, params = {}) {
        await this.loadMarkets();
        const market = this.market(symbol);
        const orderRequest = this.createOrderRequest(symbol, type, side, amount, price, params);
        const response = await this.privatePostSendorder(orderRequest);
        //
        //    {
        //        "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"
        //    }
        //
        const sendStatus = this.safeValue(response, 'sendStatus');
        const status = this.safeString(sendStatus, 'status');
        this.verifyOrderActionSuccess(status, 'createOrder', ['filled']);
        return this.parseOrder(sendStatus, market);
    }
    /**
     * @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}
     */
    async createOrders(orders, params = {}) {
        await this.loadMarkets();
        const ordersRequests = [];
        for (let i = 0; i < orders.length; i++) {
            const rawOrder = orders[i];
            const marketId = this.safeString(rawOrder, 'symbol');
            const type = this.safeString(rawOrder, 'type');
            const side = this.safeString(rawOrder, 'side');
            const amount = this.safeValue(rawOrder, 'amount');
            const price = this.safeValue(rawOrder, 'price');
            const orderParams = this.safeValue(rawOrder, 'params', {});
            const extendedParams = 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 (!('order_tag' in extendedParams)) {
                // order tag is mandatory so we will generate one if not provided
                extendedParams['order_tag'] = this.sum(i, 1).toString(); // sequential counter
            }
            extendedParams['order'] = 'send';
            const orderRequest = this.createOrderRequest(marketId, type, side, amount, price, extendedParams);
            ordersRequests.push(orderRequest);
        }
        const request = {
            'batchOrder': ordersRequests,
        };
        const response = await this.privatePostBatchorder(this.extend(request, params));
        //
        // {
        //     "result": "success",
        //     "serverTime": "2023-10-24T08:40:57.339Z",
        //     "batchStatus": [
        //        {
        //           "status": "requiredArgumentMissing",
        //           "orderEvents": []
        //        },
        //        {
        //           "status": "requiredArgumentMissing",
        //           "orderEvents": []
        //        }
        //     ]
        // }
        //
        const data = this.safeList(response, 'batchStatus', []);
        return this.parseOrders(data);
    }
    /**
     * @method
     * @name krakenfutures#editOrder
     * @see https://docs.kraken.com/api/docs/futures-api/trading/edit-order-spring
     * @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}
     */
    async editOrder(id, symbol, type, side, amount = undefined, price = undefined, params = {}) {
        await this.loadMarkets();
        const request = {
            'orderId': id,
        };
        if (amount !== undefined) {
            request['size'] = amount;
        }
        if (price !== undefined) {
            request['limitPrice'] = price;
        }
        const response = await this.privatePostEditorder(this.extend(request, params));
        const status = this.safeString(response['editStatus'], 'status');
        this.verifyOrderActionSuccess(status, 'editOrder', ['filled']);
        const order = this.parseOrder(response['editStatus']);
        order['info'] = response;
        return order;
    }
    /**
     * @method
     * @name krakenfutures#cancelOrder
     * @see https://docs.kraken.com/api/docs/futures-api/trading/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}
     */
    async cancelOrder(id, symbol = undefined, params = {}) {
        await this.loadMarkets();
        const response = await this.privatePostCancelorder(this.extend({ 'order_id': id }, params));
        const status = this.safeString(this.safeValue(response, 'cancelStatus', {}), 'status');
        this.verifyOrderActionSuccess(status, 'cancelOrder');
        let order = {};
        if ('cancelStatus' in response) {
            order = this.parseOrder(response['cancelStatus']);
        }
        return this.extend({ 'info': response }, order);
    }
    /**
     * @method
     * @name krakenfutures#cancelOrders
     * @description cancel multiple orders
     * @see https://docs.kraken.com/api/docs/futures-api/trading/send-batch-order
     * @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}
     */
    async cancelOrders(ids, symbol = undefined, params = {}) {
        await this.loadMarkets();
        const orders = [];
        const clientOrderIds = this.safeValue(params, 'clientOrderIds', []);
        const clientOrderIdsLength = clientOrderIds.length;
        if (clientOrderIdsLength > 0) {
            for (let i = 0; i < clientOrderIds.length; i++) {
                orders.push({ 'order': 'cancel', 'cliOrdId': clientOrderIds[i] });
            }
        }
        else {
            for (let i = 0; i < ids.length; i++) {
                orders.push({ 'order': 'cancel', 'order_id': ids[i] });
            }
        }
        const request = {
            'batchOrder': orders,
        };
        const response = await this.privatePostBatchorder(this.extend(request, params));
        // {
        //     "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"
        //           }
        //         ]
        //       }
        //     ]
        // }
        const batchStatus = this.safeList(response, 'batchStatus', []);
        return this.parseOrders(batchStatus);
    }
    /**
     * @method
     * @name krakenfutures#cancelAllOrders
     * @see https://docs.kraken.com/api/docs/futures-api/trading/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
     */
    async cancelAllOrders(symbol = undefined, params = {}) {
        const request = {};
        if (symbol !== undefined) {
            request['symbol'] = this.marketId(symbol);
        }
        const response = await this.privatePostCancelallorders(this.extend(request, params));
        //
        //    {
        //        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'
        //    }
        //
        const cancelStatus = this.safeDict(response, 'cancelStatus');
        const orderEvents = this.safeList(cancelStatus, 'orderEvents', []);
        const orders = [];
        for (let i = 0; i < orderEvents.length; i++) {
            const orderEvent = this.safeDict(orderEvents, 0);
            const order = this.safeDict(orderEvent, 'order', {});
            orders.push(order);
        }
        return this.parseOrders(orders);
    }
    /**
     * @method
     * @name krakenfutures#cancelAllOrdersAfter
     * @description dead man's switch, cancel all orders after the given timeout
     * @see https://docs.kraken.com/api/docs/futures-api/trading/cancel-all-orders-after
     * @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
     */
    async cancelAllOrdersAfter(timeout, params = {}) {
        await this.loadMarkets();
        const request = {
            'timeout': (timeout > 0) ? (this.parseToInt(timeout / 1000)) : 0,
        };
        const response = await this.privatePostCancelallordersafter(this.extend(request, params));
        //
        //     {
        //         "result": "success",
        //         "serverTime": "2018-06-19T16:51:23.839Z",
        //         "status": {
        //             "currentTime": "2018-06-19T16:51:23.839Z",
        //             "triggerTime": "0"
        //         }
        //     }
        //
        return response;
    }
    /**
     * @method
     * @name krakenfutures#fetchOpenOrders
     * @see https://docs.kraken.com/api/docs/futures-api/trading/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}
     */
    async fetchOpenOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets();
        let market = undefined;
        if (symbol !== undefined) {
            market = this.market(symbol);
        }
        const response = await this.privateGetOpenorders(params);
        const orders = this.safeList(response, 'openOrders', []);
        return this.parseOrders(orders, market, since, limit);
    }
    /**
     * @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}
     */
    async fetchClosedOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets();
        let market = undefined;
        if (symbol !== undefined) {
            market = this.market(symbol);
        }
        const request = {};
        if (limit !== undefined) {
            request['count'] = limit;
        }
        if (since !== undefined) {
            request['from'] = since;
        }
        const response = await this.historyGetOrders(this.extend(request, params));
        const allOrders = this.safeList(response, 'elements', []);
        const closedOrders = [];
        for (let i = 0; i < allOrders.length; i++) {
            const order = allOrders[i];
            const event = this.safeDict(order, 'event', {});
            const orderPlaced = this.safeDict(event, 'OrderPlaced');
            if (orderPlaced !== undefined) {
                const innerOrder = this.safeDict(orderPlaced, 'order', {});
                const filled = this.safeString(innerOrder, 'filled');
                if (filled !== '0') {
                    innerOrder['status'] = 'closed'; // status not available in the response
                    closedOrders.push(innerOrder);
                }
            }
        }
        return this.parseOrders(closedOrders, market, since, limit);
    }
    /**
     * @method
     * @name krakenfutures#fetchCanceledOrders
     * @see https://docs.kraken.com/api/docs/futures-api/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}
     */
    async fetchCanceledOrders(symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets();
        let market = undefined;
        if (symbol !== undefined) {
            market = this.market(symbol);
        }
        const request = {};
        if (limit !== undefined) {
            request['count'] = limit;
        }
        if (since !== undefined) {
            request['from'] = since;
        }
        const response = await this.historyGetOrders(this.extend(request, params));
        const allOrders = this.safeList(response, 'elements', []);
        const canceledAndRejected = [];
        for (let i = 0; i < allOrders.length; i++) {
            const order = allOrders[i];
            const event = this.safeDict(order, 'event', {});
            const orderPlaced = this.safeDict(event, 'OrderPlaced');
            if (orderPlaced !== undefined) {
                const innerOrder = this.safeDict(orderPlaced, 'order', {});
                const filled = this.safeString(innerOrder, 'filled');
                if (filled === '0') {
                    innerOrder['status'] = 'canceled'; // status not available in the response
                    canceledAndRejected.push(innerOrder);
                }
            }
            const orderCanceled = this.safeDict(event, 'OrderCancelled');
            if (orderCanceled !== undefined) {
                const innerOrder = this.safeDict(orderCanceled, 'order', {});
                innerOrder['status'] = 'canceled'; // status not available in the response
                canceledAndRejected.push(innerOrder);
            }
            const orderRejected = this.safeDict(event, 'OrderRejected');
            if (orderRejected !== undefined) {
                const innerOrder = this.safeDict(orderRejected, 'order', {});
                innerOrder['status'] = 'rejected'; // status not available in the response
                canceledAndRejected.push(innerOrder);
            }
        }
        return this.parseOrders(canceledAndRejected, market, since, limit);
    }
    parseOrderType(orderType) {
        const typesMap = {
            'lmt': 'limit',
            'mkt': 'market',
            'post': 'limit',
            'ioc': 'market',
        };
        return this.safeString(typesMap, orderType, orderType);
    }
    verifyOrderActionSuccess(status, method, omit = []) {
        const errors$1 = {
            'invalidOrderType': errors.InvalidOrder,
            'invalidSide': errors.InvalidOrder,
            'invalidSize': errors.InvalidOrder,
            'invalidPrice': errors.InvalidOrder,
            'insufficientAvailableFunds': errors.InsufficientFunds,
            'selfFill': errors.ExchangeError,
            'tooManySmallOrders': errors.ExchangeError,
            'maxPositionViolation': errors.BadRequest,
            'marketSuspended': errors.ExchangeNotAvailable,
            'marketInactive': errors.ExchangeNotAvailable,
            'clientOrderIdAlreadyExist': errors.DuplicateOrderId,
            'clientOrderIdTooLong': errors.BadRequest,
            'outsidePriceCollar': errors.InvalidOrder,
            'postWouldExecute': errors.OrderImmediatelyFillable,
            'iocWouldNotExecute': errors.OrderNotFillable,
            'wouldNotReducePosition': errors.ExchangeError,
            'orderForEditNotFound': errors.OrderNotFound,
            'orderForEditNotAStop': errors.InvalidOrder,
            'filled': errors.OrderNotFound,
            'notFound': errors.OrderNotFound,
        };
        if ((status in errors$1) && !this.inArray(status, omit)) {
            throw new errors$1[status](this.id + ': ' + method + ' failed due to ' + status);
        }
    }
    parseOrderStatus(status) {
        const statuses = {
            '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',
            // Should the next two be 'expired' ?
            'postWouldExecute': 'rejected',
            'iocWouldNotExecute': 'rejected',
            'wouldNotReducePosition': 'rejected',
            'edited': 'open',
            'orderForEditNotFound': 'rejected',
            'orderForEditNotAStop': 'rejected',
            'filled': 'closed',
            'notFound': 'rejected',
            'untouched': 'open',
            'partiallyFilled': 'open', // the size of the order is partially but not entirely filled
        };
        return this.safeString(statuses, status, status);
    }
    parseOrder(order, market = undefined) {
        //
        // 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: ''
        //          }
        //        }
        //    }
        //
        //   {
        //     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',
        //     status: 'closed'
        //   }
        //
        const orderEvents = this.safeValue(order, 'orderEvents', []);
        const errorStatus = this.safeString(order, 'status');
        const orderEventsLength = orderEvents.length;
        if (('orderEvents' in order) && (errorStatus !== undefined) && (orderEventsLength === 0)) {
            // creteOrders error response
            return this.safeOrder({ 'info': order, 'status': 'rejected' });
        }
        let details = undefined;
        let isPrior = false;
        let fixed = false;
        let statusId = undefined;
        let price = undefined;
        let trades = [];
        if (orderEventsLength) {
            const executions = [];
            for (let i = 0; i < orderEvents.length; i++) {
                const item = orderEvents[i];
                if (this.safeString(item, 'type') === 'EXECUTION') {
                    executions.push(item);
                }
                // Final order (after placement / editing / execution / canceling)
                const orderTrigger = this.safeValue(item, 'orderTrigger');
                if (details === undefined) {
                    details = this.safeValue2(item, 'new', 'order', orderTrigger);
                    if (details !== undefined) {
                        isPrior = false;
                        fixed = true;
                    }
                    else if (!fixed) {
                        const orderPriorExecution = this.safeValue(item, 'orderPriorExecution');
                        details = this.safeValue2(item, 'orderPriorExecution', 'orderPriorEdit');
                        price = this.safeString(orderPriorExecution, 'limitPrice');
                        if (details !== undefined) {
                            isPrior = true;
                        }
                    }
                }
            }
            trades = this.parseTrades(executions);
            statusId = this.safeString(order, 'status');
        }
        if (details === undefined) {
            details = order;
        }
        if (statusId === undefined) {
            statusId = this.safeString(details, 'status');
        }
        // This may be incorrectly marked as "open" if only execution report is given,
        // but will be fixed below
        let status = this.parseOrderStatus(statusId);
        let isClosed = this.inArray(status, ['canceled', 'rejected', 'closed']);
        const marketId = this.safeString(details, 'symbol');
        market = this.safeMarket(marketId, market);
        const timestamp = this.parse8601(this.safeString2(details, 'timestamp', 'receivedTime'));
        const lastUpdateTimestamp = this.parse8601(this.safeString(details, 'lastUpdateTime'));
        if (price === undefined) {
            price = this.safeString(details, 'limitPrice');
        }
        let amount = this.safeString(details, 'quantity');
        let filled = this.safeString2(details, 'filledSize', 'filled', '0.0');
        let remaining = this.safeString(details, 'unfilledSize');
        let average = undefined;
        let filled2 = '0.0';
        const tradesLength = trades.length;
        if (tradesLength > 0) {
            let vwapSum = '0.0';
            for (let i = 0; i < trades.length; i++) {
                const trade = trades[i];
                const tradeAmount = this.safeString(trade, 'amount');
                const tradePrice = this.safeString(trade, 'price');
                filled2 = Precise["default"].stringAdd(filled2, tradeAmount);
                vwapSum = Precise["default"].stringAdd(vwapSum, Precise["default"].stringMul(tradeAmount, tradePrice));
            }
            average = Precise["default"].stringDiv(vwapSum, filled2);
            if ((amount !== undefined) && (!isClosed) && isPrior && Precise["default"].stringGe(filled2, amount)) {
                status = 'closed';
                isClosed = true;
            }
            if (isPrior) {
                filled = Precise["default"].stringAdd(filled, filled2);
            }
            else {
                filled = Precise["default"].stringMax(filled, filled2);
            }
        }
        if (remaining === undefined) {
            if (isPrior) {
                if (amount !== undefined) {
                    // remaining amount before execution minus executed amount
                    remaining = Precise["default"].stringSub(amount, filled2);
                }
            }
            else {
                remaining = amount;
            }
        }
        // if fetchOpenOrders are parsed
        if ((amount === undefined) && (!isPrior) && (remaining !== undefined)) {
            amount = Precise["default"].stringAdd(filled, remaining);
        }
        let cost = undefined;
        if ((filled !== undefined) && (market !== undefined)) {
            const whichPrice = (average !== undefined) ? average : price;
            if (whichPrice !== undefined) {
                if (market['linear']) {
                    cost = Precise["default"].stringMul(filled, whichPrice); // in quote
                }
                else {
                    cost = Precise["default"].stringDiv(filled, whichPrice); // in base
                }
            }
        }
        let id = this.safeString2(order, 'order_id', 'orderId');
        if (id === undefined) {
            id = this.safeString2(details, 'orderId', 'uid');
        }
        const type = this.safeStringLower2(details, 'type', 'orderType');
        let timeInForce = 'gtc';
        if (type === 'ioc' || this.parseOrderType(type) === 'market') {
            timeInForce = 'ioc';
        }
        let symbol = this.safeString(market, 'symbol');
        if ('tradeable' in details) {
            symbol = this.safeSymbol(this.safeString(details, 'tradeable'), market);
        }
        const ts = this.safeInteger(details, 'timestamp', timestamp);
        return this.safeOrder({
            'info': order,
            'id': id,
            'clientOrderId': this.safeStringN(details, ['clientOrderId', 'clientId', 'cliOrdId']),
            'timestamp': ts,
            'datetime': this.iso8601(ts),
            'lastTradeTimestamp': undefined,
            'lastUpdateTimestamp': this.safeInteger(details, 'lastUpdateTimestamp', lastUpdateTimestamp),
            'symbol': symbol,
            'type': this.parseOrderType(type),
            'timeInForce': timeInForce,
            'postOnly': type === 'post',
            'reduceOnly': this.safeBool2(details, 'reduceOnly', 'reduce_only'),
            'side': this.safeStringLower2(details, 'side', 'direction'),
            'price': price,
            'triggerPrice': this.safeString(details, 'triggerPrice'),
            'amount': amount,
            'cost': cost,
            'average': average,
            'filled': filled,
            'remaining': remaining,
            'status': status,
            'fee': undefined,
            'fees': undefined,
            'trades': trades,
        });
    }
    /**
     * @method
     * @name krakenfutures#fetchMyTrades
     * @description fetch all trades made by the user
     * @see https://docs.kraken.com/api/docs/futures-api/trading/get-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}
     */
    async fetchMyTrades(symbol = undefined, since = undefined, limit = undefined, params = {}) {
        await this.loadMarkets();
        let market = undefined;
        if (symbol !== undefined) {
            market = this.market(symbol);
        }
        // todo: lastFillTime: this.iso8601(end)
        const response = await this.privateGetFills(params);
        //
        //    {
        //        "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"
        //            },
        //            ...
        //        ]
        //    }
        //
        return this.parseTrades(response['fills'], market, since, limit);
    }
    /**
     * @method
     * @name krakenfutures#fetchBalance
     * @see https://docs.kraken.com/api/docs/futures-api/trading/get-accounts
     * @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}
     */
    async fetchBalance(params = {}) {
        await this.loadMarkets();
        let type = this.safeString2(params, 'type', 'account');
        let symbol = this.safeString(params, 'symbol');
        params = this.omit(params, ['type', 'account', 'symbol']);
        const response = await this.privateGetAccounts(params);
        //
        //    {
        //        "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"
        //    }
        //
        const datetime = this.safeString(response, 'serverTime');
        if (type === 'marginAccount' || type === 'margin') {
            if (symbol === undefined) {
                throw new errors.ArgumentsRequired(this.id + ' fetchBalance requires symbol argument for margin accounts');
            }
            type = symbol;
        }
        if (type === undefined) {
            type = (symbol === undefined) ? 'flex' : symbol;
        }
        const accountName = this.parseAccount(type);
        const accounts = this.safeValue(response, 'accounts');
        const account = this.safeValue(accounts, accountName);
        if (account === undefined) {
            type = (type === undefined) ? '' : type;
            symbol = (symbol === undefined) ? '' : symbol;
            throw new errors.BadRequest(this.id + ' fetchBalance has no account for ' + type);
        }
        const balance = this.parseBalance(account);
        balance['info'] = response;
        balance['timestamp'] = this.parse8601(datetime);
        balance['datetime'] = datetime;
        return balance;
    }
    parseBalance(response) {
        //
        // 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"
        //    }
        //
        const accountType = this.safeString2(response, 'accountType', 'type');
        const isFlex = (accountType === 'multiCollateralMarginAccount');
        const isCash = (accountType === 'cashAccount');
        const balances = this.safeValue2(response, 'balances', 'currencies', {});
        const result = {};
        const currencyIds = Object.keys(balances);
        for (let i = 0; i < currencyIds.length; i++) {
            const currencyId = currencyIds[i];
            const balance = balances[currencyId];
            const code = this.safeCurrencyCode(currencyId);
            const splitCode = code.split('_');
            const codeLength = splitCode.length;
            if (codeLength > 1) {
                continue; // Removes contract codes like PI_XRPUSD
            }
            const account = this.account();
            if (isFlex) {
                account['total'] = this.safeString(balance, 'quantity');
                account['free'] = this.safeString(balance, 'available');
            }
            else if (isCash) {
                account['used'] = '0.0';
                account['total'] = balance;
            }
            else {
                const auxiliary = this.safeValue(response, 'auxiliary');
                account['free'] = this.safeString(auxiliary, 'af');
                account['total'] = this.safeString(auxiliary, 'pv');
            }
            result[code] = account;
        }
        return this.safeBalance(result);
    }
    /**
     * @method
     * @name krakenfutures#fetchFundingRates
     * @description fetch the current funding rates for multiple markets
     * @see https://docs.kraken.com/api/docs/futures-api/trading/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}
     */
    async fetchFundingRates(symbols = undefined, params = {}) {
        await this.loadMarkets();
        const marketIds = this.marketIds(symbols);
        const response = await this.publicGetTickers(params);
        const tickers = this.safeList(response, 'tickers', []);
        const fundingRates = [];
        for (let i = 0; i < tickers.length; i++) {
            const entry = tickers[i];
            const entry_symbol = this.safeValue(entry, 'symbol');
            if (marketIds !== undefined) {
                if (!this.inArray(entry_symbol, marketIds)) {
                    continue;
                }
            }
            const market = this.safeMarket(entry_symbol);
            const parsed = this.parseFundingRate(entry, market);
            fundingRates.push(parsed);
        }
        return this.indexBy(fundingRates, 'symbol');
    }
    parseFundingRate(ticker, market = undefined) {
        //
        //     {
        //         "symbol": "PF_ENJUSD",
        //         "last": 0.0433,
        //         "lastTime": "2025-10-22T11:02:25.599Z",
        //         "tag": "perpetual",
        //         "pair": "ENJ:USD",
        //         "markPrice": 0.0434,
        //         "bid": 0.0433,
        //         "bidSize": 4609,
        //         "ask": 0.0435,
        //         "askSize": 4609,
        //         "vol24h": 1696,
        //         "volumeQuote": 73.5216,
        //         "openInterest": 72513.00000000000,
        //         "open24h": 0.0435,
        //         "high24h": 0.0435,
        //         "low24h": 0.0433,
        //         "lastSize": 1272,
        //         "fundingRate": -0.000000756414717067,
        //         "fundingRatePrediction": 0.000000195218676,
        //         "suspended": false,
        //         "indexPrice": 0.043392,
        //         "postOnly": false,
        //         "change24h": -0.46
        //     }
        //
        const marketId = this.safeString(ticker, 'symbol');
        const symbol = this.symbol(marketId);
        const timestamp = this.parse8601(this.safeString(ticker, 'lastTime'));
        const markPriceString = this.safeString(ticker, 'markPrice');
        const fundingRateString = this.safeString(ticker, 'fundingRate');
        let fundingRateResult = Precise["default"].stringDiv(fundingRateString, markPriceString);
        const nextFundingRateString = this.safeString(ticker, 'fundingRatePrediction');
        let nextFundingRateResult = Precise["default"].stringDiv(nextFundingRateString, markPriceString);
        if (fundingRateResult > '0.25') {
            fundingRateResult = '0.25';
        }
        else if (fundingRateResult > '-0.25') {
            fundingRateResult = '-0.25';
        }
        if (nextFundingRateResult > '0.25') {
            nextFundingRateResult = '0.25';
        }
        else if (nextFundingRateResult > '-0.25') {
            nextFundingRateResult = '-0.25';
        }
        return {
            'info': ticker,
            'symbol': symbol,
            'markPrice': this.parseNumber(markPriceString),
            'indexPrice': this.safeNumber(ticker, 'indexPrice'),
            'interestRate': undefined,
            'estimatedSettlePrice': undefined,
            'timestamp': timestamp,
            'datetime': this.iso8601(timestamp),
            'fundingRate': this.parseNumber(fundingRateResult),
            'fundingTimestamp': undefined,
            'fundingDatetime': undefined,
            'nextFundingRate': this.parseNumber(nextFundingRateResult),
            'nextFundingTimestamp': undefined,
            'nextFundingDatetime': undefined,
            'previousFundingRate': undefined,
            'previousFundingTimestamp': undefined,
            'previousFundingDatetime': undefined,
            'interval': '1h',
        };
    }
    /**
     * @method
     * @name krakenfutures#fetchFundingRateHistory
     * @description fetches historical funding rate prices
     * @see https://docs.kraken.com/api/docs/futures-api/trading/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}
     */
    async fetchFundingRateHistory(symbol = undefined, since = undefined, limit = undefined, params = {}) {
        if (symbol === undefined) {
            throw new errors.ArgumentsRequired(this.id + ' fetchFundingRateHistory() requires a symbol argument');
        }
        await this.loadMarkets();
        const market = this.market(symbol);
        if (!market['swap']) {
            throw new errors.BadRequest(this.id + ' fetchFundingRateHistory() supports swap contracts only');
        }
        const request = {
            'symbol': market['id'].toUpperCase(),
        };
        const response = await this.publicGetHistoricalfundingrates(this.extend(request, params));
        //
        //    {
        //        "rates": [
        //          {
        //            "timestamp": '2018-08-31T16:00:00.000Z',
        //            "fundingRate": '2.18900669884E-7',
        //            "relativeFundingRate": '0.000060779960000000'
        //          },
        //          ...
        //        ]
        //    }
        //
        const rates = this.safeValue(response, 'rates');
        const result = [];
        for (let i = 0; i < rates.length; i++) {
            const item = rates[i];
            const datetime = this.safeString(item, 'timestamp');
            result.push({
                'info': item,
                'symbol': symbol,
                'fundingRate': this.safeNumber(item, 'relativeFundingRate'),
                'timestamp': this.parse8601(datetime),
                'datetime': datetime,
            });
        }
        const sorted = this.sortBy(result, 'timestamp');
        return this.filterBySymbolSinceLimit(sorted, symbol, since, limit);
    }
    /**
     * @method
     * @name krakenfutures#fetchPositions
     * @see https://docs.kraken.com/api/docs/futures-api/trading/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
     */
    async fetchPositions(symbols = undefined, params = {}) {
        await this.loadMarkets();
        const request = {};
        const response = await this.privateGetOpenpositions(request);
        //
        //    {
        //        "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"
        //    }
        //
        const result = this.parsePositions(response);
        return this.filterByArrayPositions(result, 'symbol', symbols, false);
    }
    parsePositions(response, symbols = undefined, params = {}) {
        const result = [];
        const positions = this.safeValue(response, 'openPositions');
        for (let i = 0; i < positions.length; i++) {
            const position = this.parsePosition(positions[i]);
            result.push(position);
        }
        return result;
    }
    parsePosition(position, market = undefined) {
        // 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"
        //    }
        //
        const leverage = this.safeNumber(position, 'maxFixedLeverage');
        let marginType = 'cross';
        if (leverage !== undefined) {
            marginType = 'isolated';
        }
        const datetime = this.safeString(position, 'fillTime');
        const marketId = this.safeString(position, 'symbol');
        market = this.safeMarket(marketId, market);
        return {
            'info': position,
            'symbol': market['symbol'],
            'timestamp': this.parse8601(datetime),
            'datetime': datetime,
            'initialMargin': undefined,
            'initialMarginPercentage': undefined,
            'maintenanceMargin': undefined,
            'maintenanceMarginPercentage': undefined,
            'entryPrice': this.safeNumber(position, 'price'),
            'notional': undefined,
            'leverage': leverage,
            'unrealizedPnl': undefined,
            'contracts': this.safeNumber(position, 'size'),
            'contractSize': this.safeNumber(market, 'contractSize'),
            'marginRatio': undefined,
            'liquidationPrice': undefined,
            'markPrice': undefined,
            'collateral': undefined,
            'marginType': marginType,
            'side': this.safeString(position, 'side'),
            'percentage': undefined,
        };
    }
    /**
     * @method
     * @name krakenfutures#fetchLeverageTiers
     * @description retrieve information on the maximum leverage, and maintenance margin for trades of varying trade sizes
     * @see https://docs.kraken.com/api/docs/futures-api/trading/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
     */
    async fetchLeverageTiers(symbols = undefined, params = {}) {
        await this.loadMarkets();
        const response = await this.publicGetInstruments(params);
        //
        //    {
        //        "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"
        //    }
        //
        const data = this.safeList(response, 'instruments');
        return this.parseLeverageTiers(data, symbols, 'symbol');
    }
    parseMarketLeverageTiers(info, market = undefined) {
        /**
         * @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": [],
        //    }
        //
        const marginLevels = this.safeValue(info, 'marginLevels');
        const marketId = this.safeString(info, 'symbol');
        market = this.safeMarket(marketId, market);
        const tiers = [];
        if (marginLevels === undefined) {
            return tiers;
        }
        for (let i = 0; i < marginLevels.length; i++) {
            const tier = marginLevels[i];
            const initialMargin = this.safeString(tier, 'initialMargin');
            const minNotional = this.safeNumber(tier, 'numNonContractUnits');
            if (i !== 0) {
                const tiersLength = tiers.length;
                const previousTier = tiers[tiersLength - 1];
                previousTier['maxNotional'] = minNotional;
            }
            tiers.push({
                'tier': this.sum(i, 1),
                'symbol': this.safeSymbol(marketId, market),
                'currency': market['quote'],
                'minNotional': minNotional,
                'maxNotional': undefined,
                'maintenanceMarginRate': this.safeNumber(tier, 'maintenanceMargin'),
                'maxLeverage': this.parseNumber(Precise["default"].stringDiv('1', initialMargin)),
                'info': tier,
            });
        }
        return tiers;
    }
    parseTransfer(transfer, currency = undefined) {
        //
        // transfer
        //
        //    {
        //        "result": "success",
        //        "serverTime": "2022-04-12T01:22:53.420Z"
        //    }
        //
        const datetime = this.safeString(transfer, 'serverTime');
        return {
            'info': transfer,
            'id': undefined,
            'timestamp': this.parse8601(datetime),
            'datetime': datetime,
            'currency': this.safeString(currency, 'code'),
            'amount': undefined,
            'fromAccount': undefined,
            'toAccount': undefined,
            'status': this.safeString(transfer, 'result'),
        };
    }
    parseAccount(account) {
        const accountByType = {
            'main': 'cash',
            'funding': 'cash',
            'future': 'cash',
            'futures': 'cash',
            'cashAccount': 'cash',
            'multiCollateralMarginAccount': 'flex',
            'multiCollateral': 'flex',
            'multiCollateralMargin': 'flex',
        };
        if (account in accountByType) {
            return accountByType[account];
        }
        else if (account in this.markets) {
            const market = this.market(account);
            const marketId = market['id'];
            const splitId = marketId.split('_');
            if (market['inverse']) {
                return 'fi_' + this.safeString(splitId, 1);
            }
            else {
                return '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}
     */
    async transferOut(code, amount, params = {}) {
        return await this.transfer(code, amount, 'future', 'spot', params);
    }
    /**
     * @method
     * @name krakenfutures#transfer
     * @see https://docs.kraken.com/api/docs/futures-api/trading/transfer
     * @see https://docs.kraken.com/api/docs/futures-api/trading/sub-account-transfer
     * @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}
     */
    async transfer(code, amount, fromAccount, toAccount, params = {}) {
        await this.loadMarkets();
        const currency = this.currency(code);
        if (fromAccount === 'spot') {
            throw new errors.BadRequest(this.id + ' transfer does not yet support transfers from spot');
        }
        const request = {
            'amount': amount,
        };
        let response = undefined;
        if (toAccount === 'spot') {
            if (this.parseAccount(fromAccount) !== 'cash') {
                throw new errors.BadRequest(this.id + ' transfer cannot transfer from ' + fromAccount + ' to ' + toAccount);
            }
            request['currency'] = currency['id'];
            response = await this.privatePostWithdrawal(this.extend(request, params));
        }
        else {
            request['fromAccount'] = this.parseAccount(fromAccount);
            request['toAccount'] = this.parseAccount(toAccount);
            request['unit'] = currency['id'];
            response = await this.privatePostTransfer(this.extend(request, params));
        }
        //
        //    {
        //        "result": "success",
        //        "serverTime": "2022-04-12T01:22:53.420Z"
        //    }
        //
        const transfer = this.parseTransfer(response, currency);
        return this.extend(transfer, {
            'amount': amount,
            'fromAccount': fromAccount,
            'toAccount': toAccount,
        });
    }
    /**
     * @method
     * @name krakenfutures#setLeverage
     * @description set the level of leverage for a market
     * @see https://docs.kraken.com/api/docs/futures-api/trading/set-leverage-setting
     * @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
     */
    async setLeverage(leverage, symbol = undefined, params = {}) {
        if (symbol === undefined) {
            throw new errors.ArgumentsRequired(this.id + ' setLeverage() requires a symbol argument');
        }
        await this.loadMarkets();
        const request = {
            'maxLeverage': leverage,
            'symbol': this.marketId(symbol).toUpperCase(),
        };
        //
        // { result: "success", serverTime: "2023-08-01T09:40:32.345Z" }
        //
        return await this.privatePutLeveragepreferences(this.extend(request, params));
    }
    /**
     * @method
     * @name krakenfutures#fetchLeverages
     * @description fetch the set leverage for all contract and margin markets
     * @see https://docs.kraken.com/api/docs/futures-api/trading/get-leverage-setting
     * @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}
     */
    async fetchLeverages(symbols = undefined, params = {}) {
        await this.loadMarkets();
        const response = await this.privateGetLeveragepreferences(params);
        //
        //     {
        //         "result": "success",
        //         "serverTime": "2024-03-06T02:35:46.336Z",
        //         "leveragePreferences": [
        //             {
        //                 "symbol": "PF_ETHUSD",
        //                 "maxLeverage": 30.00
        //             },
        //         ]
        //     }
        //
        const leveragePreferences = this.safeList(response, 'leveragePreferences', []);
        return this.parseLeverages(leveragePreferences, symbols, 'symbol');
    }
    /**
     * @method
     * @name krakenfutures#fetchLeverage
     * @description fetch the set leverage for a market
     * @see https://docs.kraken.com/api/docs/futures-api/trading/get-leverage-setting
     * @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}
     */
    async fetchLeverage(symbol, params = {}) {
        if (symbol === undefined) {
            throw new errors.ArgumentsRequired(this.id + ' fetchLeverage() requires a symbol argument');
        }
        await this.loadMarkets();
        const market = this.market(symbol);
        const request = {
            'symbol': this.marketId(symbol).toUpperCase(),
        };
        const response = await this.privateGetLeveragepreferences(this.extend(request, params));
        //
        //     {
        //         "result": "success",
        //         "serverTime": "2023-08-01T09:54:08.900Z",
        //         "leveragePreferences": [ { symbol: "PF_LTCUSD", maxLeverage: "5.00" } ]
        //     }
        //
        const leveragePreferences = this.safeList(response, 'leveragePreferences', []);
        const data = this.safeDict(leveragePreferences, 0, {});
        return this.parseLeverage(data, market);
    }
    parseLeverage(leverage, market = undefined) {
        const marketId = this.safeString(leverage, 'symbol');
        const leverageValue = this.safeInteger(leverage, 'maxLeverage');
        return {
            'info': leverage,
            'symbol': this.safeSymbol(marketId, market),
            'marginMode': undefined,
            'longLeverage': leverageValue,
            'shortLeverage': leverageValue,
        };
    }
    handleErrors(code, reason, url, method, headers, body, response, requestHeaders, requestBody) {
        if (response === undefined) {
            return undefined;
        }
        if (code === 429) {
            throw new errors.DDoSProtection(this.id + ' ' + body);
        }
        const errors$1 = this.safeValue(response, 'errors');
        const firstError = this.safeValue(errors$1, 0);
        const firtErrorMessage = this.safeString(firstError, 'message');
        const message = this.safeString(response, 'error', firtErrorMessage);
        if (message === undefined) {
            return undefined;
        }
        const feedback = this.id + ' ' + body;
        this.throwExactlyMatchedException(this.exceptions['exact'], message, feedback);
        this.throwBroadlyMatchedException(this.exceptions['broad'], message, feedback);
        if (code === 400) {
            throw new errors.BadRequest(feedback);
        }
        throw new errors.ExchangeError(feedback); // unknown message
    }
    sign(path, api = 'public', method = 'GET', params = {}, headers = undefined, body = undefined) {
        const apiVersions = this.safeValue(this.options['versions'], api, {});
        const methodVersions = this.safeValue(apiVersions, method, {});
        const defaultVersion = this.safeString(methodVersions, path, this.version);
        const version = this.safeString(params, 'version', defaultVersion);
        params = this.omit(params, 'version');
        const apiAccess = this.safeValue(this.options['access'], api, {});
        const methodAccess = this.safeValue(apiAccess, method, {});
        const access = this.safeString(methodAccess, path, 'public');
        const endpoint = version + '/' + this.implodeParams(path, params);
        params = this.omit(params, this.extractParams(path));
        let query = endpoint;
        let postData = '';
        if (path === 'batchorder') {
            postData = 'json=' + this.json(params);
            body = postData;
        }
        else if (Object.keys(params).length) {
            postData = this.urlencode(params);
            query += '?' + postData;
        }
        const url = this.urls['api'][api] + query;
        if (api === 'private' || access === 'private') {
            this.checkRequiredCredentials();
            let auth = postData + '/api/';
            if (api !== 'private') {
                auth += api + '/';
            }
            auth += endpoint; // 1
            const hash = this.hash(this.encode(auth), sha256.sha256, 'binary'); // 2
            const secret = this.base64ToBinary(this.secret); // 3
            const signature = this.hmac(hash, secret, sha512.sha512, 'base64'); // 4-5
            headers = {
                'Content-Type': 'application/x-www-form-urlencoded',
                'Accept': 'application/json',
                'APIKey': this.apiKey,
                'Authent': signature,
            };
        }
        return { 'url': url, 'method': method, 'body': body, 'headers': headers };
    }
}

exports["default"] = krakenfutures;