ccxt-go/kraken.go
zhangkun9038@dingtalk.com 1a2ce7046a first add
2025-02-28 10:33:20 +08:00

4081 lines
179 KiB
Go

package ccxt
// PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
// https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code
type kraken struct {
Exchange
}
func NewKrakenCore() kraken {
p := kraken{}
setDefaults(&p)
return p
}
func (this *kraken) Describe() interface{} {
return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} {
"id": "kraken",
"name": "Kraken",
"countries": []interface{}{"US"},
"version": "0",
"rateLimit": 1000,
"certified": false,
"pro": true,
"has": map[string]interface{} {
"CORS": nil,
"spot": true,
"margin": true,
"swap": false,
"future": false,
"option": false,
"addMargin": false,
"cancelAllOrders": true,
"cancelAllOrdersAfter": true,
"cancelOrder": true,
"cancelOrders": true,
"createDepositAddress": true,
"createMarketBuyOrderWithCost": true,
"createMarketOrderWithCost": false,
"createMarketSellOrderWithCost": false,
"createOrder": true,
"createStopLimitOrder": true,
"createStopMarketOrder": true,
"createStopOrder": true,
"createTrailingAmountOrder": true,
"createTrailingPercentOrder": true,
"editOrder": true,
"fetchBalance": true,
"fetchBorrowInterest": false,
"fetchBorrowRateHistories": false,
"fetchBorrowRateHistory": false,
"fetchClosedOrders": true,
"fetchCrossBorrowRate": false,
"fetchCrossBorrowRates": false,
"fetchCurrencies": true,
"fetchDepositAddress": true,
"fetchDepositAddresses": false,
"fetchDepositAddressesByNetwork": false,
"fetchDeposits": true,
"fetchFundingHistory": false,
"fetchFundingRate": false,
"fetchFundingRateHistory": false,
"fetchFundingRates": false,
"fetchIndexOHLCV": false,
"fetchIsolatedBorrowRate": false,
"fetchIsolatedBorrowRates": false,
"fetchLedger": true,
"fetchLedgerEntry": true,
"fetchLeverageTiers": false,
"fetchMarkets": true,
"fetchMarkOHLCV": false,
"fetchMyTrades": true,
"fetchOHLCV": true,
"fetchOpenInterestHistory": false,
"fetchOpenOrders": true,
"fetchOrder": true,
"fetchOrderBook": true,
"fetchOrderTrades": "emulated",
"fetchPositions": true,
"fetchPremiumIndexOHLCV": false,
"fetchStatus": true,
"fetchTicker": true,
"fetchTickers": true,
"fetchTime": true,
"fetchTrades": true,
"fetchTradingFee": true,
"fetchTradingFees": false,
"fetchWithdrawals": true,
"setLeverage": false,
"setMarginMode": false,
"transfer": true,
"withdraw": true,
},
"timeframes": map[string]interface{} {
"1m": 1,
"5m": 5,
"15m": 15,
"30m": 30,
"1h": 60,
"4h": 240,
"1d": 1440,
"1w": 10080,
"2w": 21600,
},
"urls": map[string]interface{} {
"logo": "https://user-images.githubusercontent.com/51840849/76173629-fc67fb00-61b1-11ea-84fe-f2de582f58a3.jpg",
"api": map[string]interface{} {
"public": "https://api.kraken.com",
"private": "https://api.kraken.com",
"zendesk": "https://kraken.zendesk.com/api/v2/help_center/en-us/articles",
},
"www": "https://www.kraken.com",
"doc": "https://docs.kraken.com/rest/",
"fees": "https://www.kraken.com/en-us/features/fee-schedule",
},
"fees": map[string]interface{} {
"trading": map[string]interface{} {
"tierBased": true,
"percentage": true,
"taker": this.ParseNumber("0.0026"),
"maker": this.ParseNumber("0.0016"),
"tiers": map[string]interface{} {
"taker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.0026")}, []interface{}{this.ParseNumber("50000"), this.ParseNumber("0.0024")}, []interface{}{this.ParseNumber("100000"), this.ParseNumber("0.0022")}, []interface{}{this.ParseNumber("250000"), this.ParseNumber("0.0020")}, []interface{}{this.ParseNumber("500000"), this.ParseNumber("0.0018")}, []interface{}{this.ParseNumber("1000000"), this.ParseNumber("0.0016")}, []interface{}{this.ParseNumber("2500000"), this.ParseNumber("0.0014")}, []interface{}{this.ParseNumber("5000000"), this.ParseNumber("0.0012")}, []interface{}{this.ParseNumber("10000000"), this.ParseNumber("0.0001")}},
"maker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.0016")}, []interface{}{this.ParseNumber("50000"), this.ParseNumber("0.0014")}, []interface{}{this.ParseNumber("100000"), this.ParseNumber("0.0012")}, []interface{}{this.ParseNumber("250000"), this.ParseNumber("0.0010")}, []interface{}{this.ParseNumber("500000"), this.ParseNumber("0.0008")}, []interface{}{this.ParseNumber("1000000"), this.ParseNumber("0.0006")}, []interface{}{this.ParseNumber("2500000"), this.ParseNumber("0.0004")}, []interface{}{this.ParseNumber("5000000"), this.ParseNumber("0.0002")}, []interface{}{this.ParseNumber("10000000"), this.ParseNumber("0.0")}},
},
},
},
"handleContentTypeApplicationZip": true,
"api": map[string]interface{} {
"zendesk": map[string]interface{} {
"get": []interface{}{"360000292886", "201893608"},
},
"public": map[string]interface{} {
"get": map[string]interface{} {
"Assets": 1,
"AssetPairs": 1,
"Depth": 1.2,
"OHLC": 1.2,
"Spread": 1,
"SystemStatus": 1,
"Ticker": 1,
"Time": 1,
"Trades": 1.2,
},
},
"private": map[string]interface{} {
"post": map[string]interface{} {
"AddOrder": 0,
"AddOrderBatch": 0,
"AddExport": 3,
"AmendOrder": 0,
"Balance": 3,
"CancelAll": 3,
"CancelAllOrdersAfter": 3,
"CancelOrder": 0,
"CancelOrderBatch": 0,
"ClosedOrders": 3,
"DepositAddresses": 3,
"DepositMethods": 3,
"DepositStatus": 3,
"EditOrder": 0,
"ExportStatus": 3,
"GetWebSocketsToken": 3,
"Ledgers": 6,
"OpenOrders": 3,
"OpenPositions": 3,
"QueryLedgers": 3,
"QueryOrders": 3,
"QueryTrades": 3,
"RetrieveExport": 3,
"RemoveExport": 3,
"BalanceEx": 3,
"TradeBalance": 3,
"TradesHistory": 6,
"TradeVolume": 3,
"Withdraw": 3,
"WithdrawCancel": 3,
"WithdrawInfo": 3,
"WithdrawMethods": 3,
"WithdrawAddresses": 3,
"WithdrawStatus": 3,
"WalletTransfer": 3,
"CreateSubaccount": 3,
"AccountTransfer": 3,
"Earn/Allocate": 3,
"Earn/Deallocate": 3,
"Earn/AllocateStatus": 3,
"Earn/DeallocateStatus": 3,
"Earn/Strategies": 3,
"Earn/Allocations": 3,
},
},
},
"commonCurrencies": map[string]interface{} {
"LUNA": "LUNC",
"LUNA2": "LUNA",
"REPV2": "REP",
"REP": "REPV1",
"UST": "USTC",
"XBT": "BTC",
"XBT.M": "BTC.M",
"XDG": "DOGE",
},
"options": map[string]interface{} {
"timeDifference": 0,
"adjustForTimeDifference": false,
"marketsByAltname": map[string]interface{} {},
"delistedMarketsById": map[string]interface{} {},
"inactiveCurrencies": []interface{}{"CAD", "USD", "JPY", "GBP"},
"networks": map[string]interface{} {
"ETH": "ERC20",
"TRX": "TRC20",
},
"depositMethods": map[string]interface{} {
"1INCH": Add(Add("1inch", " "), "(1INCH)"),
"AAVE": "Aave",
"ADA": "ADA",
"ALGO": "Algorand",
"ANKR": Add(Add("ANKR", " "), "(ANKR)"),
"ANT": Add(Add("Aragon", " "), "(ANT)"),
"ATOM": "Cosmos",
"AXS": Add(Add("Axie Infinity Shards", " "), "(AXS)"),
"BADGER": Add(Add("Bager DAO", " "), "(BADGER)"),
"BAL": Add(Add("Balancer", " "), "(BAL)"),
"BAND": Add(Add("Band Protocol", " "), "(BAND)"),
"BAT": "BAT",
"BCH": "Bitcoin Cash",
"BNC": Add(Add("Bifrost", " "), "(BNC)"),
"BNT": Add(Add("Bancor", " "), "(BNT)"),
"BTC": "Bitcoin",
"CHZ": Add(Add("Chiliz", " "), "(CHZ)"),
"COMP": Add(Add("Compound", " "), "(COMP)"),
"CQT": Add(Add(" Covalent Query Token", " "), "(CQT)"),
"CRV": Add(Add("Curve DAO Token", " "), "(CRV)"),
"CTSI": Add(Add("Cartesi", " "), "(CTSI)"),
"DAI": "Dai",
"DASH": "Dash",
"DOGE": "Dogecoin",
"DOT": "Polkadot",
"DYDX": Add(Add("dYdX", " "), "(DYDX)"),
"ENJ": Add(Add("Enjin Coin", " "), "(ENJ)"),
"EOS": "EOS",
"ETC": Add(Add("Ether Classic", " "), "(Hex)"),
"ETH": Add(Add("Ether", " "), "(Hex)"),
"EWT": "Energy Web Token",
"FEE": "Kraken Fee Credit",
"FIL": "Filecoin",
"FLOW": "Flow",
"GHST": Add(Add("Aavegotchi", " "), "(GHST)"),
"GNO": "GNO",
"GRT": "GRT",
"ICX": "Icon",
"INJ": Add(Add("Injective Protocol", " "), "(INJ)"),
"KAR": Add(Add("Karura", " "), "(KAR)"),
"KAVA": "Kava",
"KEEP": Add(Add("Keep Token", " "), "(KEEP)"),
"KNC": Add(Add("Kyber Network", " "), "(KNC)"),
"KSM": "Kusama",
"LINK": "Link",
"LPT": Add(Add("Livepeer Token", " "), "(LPT)"),
"LRC": Add(Add("Loopring", " "), "(LRC)"),
"LSK": "Lisk",
"LTC": "Litecoin",
"MANA": "MANA",
"MATIC": Add(Add("Polygon", " "), "(MATIC)"),
"MINA": "Mina",
"MIR": Add(Add("Mirror Protocol", " "), "(MIR)"),
"MKR": Add(Add("Maker", " "), "(MKR)"),
"MLN": "MLN",
"MOVR": Add(Add("Moonriver", " "), "(MOVR)"),
"NANO": "NANO",
"OCEAN": "OCEAN",
"OGN": Add(Add("Origin Protocol", " "), "(OGN)"),
"OMG": "OMG",
"OXT": Add(Add("Orchid", " "), "(OXT)"),
"OXY": Add(Add("Oxygen", " "), "(OXY)"),
"PAXG": Add(Add("PAX", " "), "(Gold)"),
"PERP": Add(Add("Perpetual Protocol", " "), "(PERP)"),
"PHA": Add(Add("Phala", " "), "(PHA)"),
"QTUM": "QTUM",
"RARI": Add(Add("Rarible", " "), "(RARI)"),
"RAY": Add(Add("Raydium", " "), "(RAY)"),
"REN": Add(Add("Ren Protocol", " "), "(REN)"),
"REP": "REPv2",
"REPV1": "REP",
"SAND": Add(Add("The Sandbox", " "), "(SAND)"),
"SC": "Siacoin",
"SDN": Add(Add("Shiden", " "), "(SDN)"),
"SOL": "Solana",
"SNX": Add(Add("Synthetix Network", " "), "(SNX)"),
"SRM": "Serum",
"STORJ": Add(Add("Storj", " "), "(STORJ)"),
"SUSHI": Add(Add("Sushiswap", " "), "(SUSHI)"),
"TBTC": "tBTC",
"TRX": "Tron",
"UNI": "UNI",
"USDC": "USDC",
"USDT": Add(Add("Tether USD", " "), "(ERC20)"),
"USDT-TRC20": Add(Add("Tether USD", " "), "(TRC20)"),
"WAVES": "Waves",
"WBTC": Add(Add("Wrapped Bitcoin", " "), "(WBTC)"),
"XLM": "Stellar XLM",
"XMR": "Monero",
"XRP": "Ripple XRP",
"XTZ": "XTZ",
"YFI": "YFI",
"ZEC": Add(Add("Zcash", " "), "(Transparent)"),
"ZRX": Add(Add("0x", " "), "(ZRX)"),
},
"withdrawMethods": map[string]interface{} {
"Lightning": "Lightning",
"Bitcoin": "BTC",
"Ripple": "XRP",
"Litecoin": "LTC",
"Dogecoin": "DOGE",
"Stellar": "XLM",
"Ethereum": "ERC20",
"Arbitrum One": "Arbitrum",
"Polygon": "MATIC",
"Arbitrum Nova": "Arbitrum",
"Optimism": "Optimism",
"zkSync Era": "zkSync",
"Ethereum Classic": "ETC",
"Zcash": "ZEC",
"Monero": "XMR",
"Tron": "TRC20",
"Solana": "SOL",
"EOS": "EOS",
"Bitcoin Cash": "BCH",
"Cardano": "ADA",
"Qtum": "QTUM",
"Tezos": "XTZ",
"Cosmos": "ATOM",
"Nano": "NANO",
"Siacoin": "SC",
"Lisk": "LSK",
"Waves": "WAVES",
"ICON": "ICX",
"Algorand": "ALGO",
"Polygon - USDC.e": "MATIC",
"Arbitrum One - USDC.e": "Arbitrum",
"Polkadot": "DOT",
"Kava": "KAVA",
"Filecoin": "FIL",
"Kusama": "KSM",
"Flow": "FLOW",
"Energy Web": "EW",
"Mina": "MINA",
"Centrifuge": "CFG",
"Karura": "KAR",
"Moonriver": "MOVR",
"Shiden": "SDN",
"Khala": "PHA",
"Bifrost Kusama": "BNC",
"Songbird": "SGB",
"Terra classic": "LUNC",
"KILT": "KILT",
"Basilisk": "BSX",
"Flare": "FLR",
"Avalanche C-Chain": "AVAX",
"Kintsugi": "KINT",
"Altair": "AIR",
"Moonbeam": "GLMR",
"Acala": "ACA",
"Astar": "ASTR",
"Akash": "AKT",
"Robonomics": "XRT",
"Fantom": "FTM",
"Elrond": "EGLD",
"THORchain": "RUNE",
"Secret": "SCRT",
"Near": "NEAR",
"Internet Computer Protocol": "ICP",
"Picasso": "PICA",
"Crust Shadow": "CSM",
"Integritee": "TEER",
"Parallel Finance": "PARA",
"HydraDX": "HDX",
"Interlay": "INTR",
"Fetch.ai": "FET",
"NYM": "NYM",
"Terra 2.0": "LUNA2",
"Juno": "JUNO",
"Nodle": "NODL",
"Stacks": "STX",
"Ethereum PoW": "ETHW",
"Aptos": "APT",
"Sui": "SUI",
"Genshiro": "GENS",
"Aventus": "AVT",
"Sei": "SEI",
"OriginTrail": "OTP",
"Celestia": "TIA",
},
},
"features": map[string]interface{} {
"spot": map[string]interface{} {
"sandbox": false,
"createOrder": map[string]interface{} {
"marginMode": false,
"triggerPrice": false,
"triggerPriceType": nil,
"triggerDirection": false,
"stopLossPrice": true,
"takeProfitPrice": true,
"attachedStopLossTakeProfit": nil,
"timeInForce": map[string]interface{} {
"IOC": true,
"FOK": true,
"PO": true,
"GTD": false,
},
"hedged": false,
"trailing": true,
"leverage": false,
"marketBuyByCost": true,
"marketBuyRequiresPrice": false,
"selfTradePrevention": true,
"iceberg": true,
},
"createOrders": nil,
"fetchMyTrades": map[string]interface{} {
"marginMode": false,
"limit": nil,
"daysBack": nil,
"untilDays": nil,
"symbolRequired": false,
},
"fetchOrder": map[string]interface{} {
"marginMode": false,
"trigger": false,
"trailing": false,
"symbolRequired": false,
},
"fetchOpenOrders": map[string]interface{} {
"marginMode": false,
"limit": nil,
"trigger": false,
"trailing": false,
"symbolRequired": false,
},
"fetchOrders": nil,
"fetchClosedOrders": map[string]interface{} {
"marginMode": false,
"limit": nil,
"daysBack": nil,
"daysBackCanceled": nil,
"untilDays": 100000,
"trigger": false,
"trailing": false,
"symbolRequired": false,
},
"fetchOHLCV": map[string]interface{} {
"limit": 720,
},
},
"swap": map[string]interface{} {
"linear": nil,
"inverse": nil,
},
"future": map[string]interface{} {
"linear": nil,
"inverse": nil,
},
},
"precisionMode": TICK_SIZE,
"exceptions": map[string]interface{} {
"exact": map[string]interface{} {
"EQuery:Invalid asset pair": BadSymbol,
"EAPI:Invalid key": AuthenticationError,
"EFunding:Unknown withdraw key": InvalidAddress,
"EFunding:Invalid amount": InsufficientFunds,
"EService:Unavailable": ExchangeNotAvailable,
"EDatabase:Internal error": ExchangeNotAvailable,
"EService:Busy": ExchangeNotAvailable,
"EQuery:Unknown asset": BadSymbol,
"EAPI:Rate limit exceeded": DDoSProtection,
"EOrder:Rate limit exceeded": DDoSProtection,
"EGeneral:Internal error": ExchangeNotAvailable,
"EGeneral:Temporary lockout": DDoSProtection,
"EGeneral:Permission denied": PermissionDenied,
"EGeneral:Invalid arguments:price": InvalidOrder,
"EOrder:Unknown order": InvalidOrder,
"EOrder:Invalid price:Invalid price argument": InvalidOrder,
"EOrder:Order minimum not met": InvalidOrder,
"EOrder:Insufficient funds": InsufficientFunds,
"EGeneral:Invalid arguments": BadRequest,
"ESession:Invalid session": AuthenticationError,
"EAPI:Invalid nonce": InvalidNonce,
"EFunding:No funding method": BadRequest,
"EFunding:Unknown asset": BadSymbol,
"EService:Market in post_only mode": OnMaintenance,
"EGeneral:Too many requests": DDoSProtection,
"ETrade:User Locked": AccountSuspended,
},
"broad": map[string]interface{} {
":Invalid order": InvalidOrder,
":Invalid arguments:volume": InvalidOrder,
":Invalid arguments:viqc": InvalidOrder,
":Invalid nonce": InvalidNonce,
":IInsufficient funds": InsufficientFunds,
":Cancel pending": CancelPending,
":Rate limit exceeded": RateLimitExceeded,
},
},
})
}
func (this *kraken) FeeToPrecision(symbol interface{}, fee interface{}) interface{} {
return this.DecimalToPrecision(fee, TRUNCATE, GetValue(GetValue(GetValue(this.Markets, symbol), "precision"), "amount"), this.PrecisionMode)
}
/**
* @method
* @name kraken#fetchMarkets
* @description retrieves data on all markets for kraken
* @see https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getTradableAssetPairs
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object[]} an array of objects representing market data
*/
func (this *kraken) FetchMarkets(optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
params := GetArg(optionalArgs, 0, map[string]interface{} {})
_ = params
if IsTrue(GetValue(this.Options, "adjustForTimeDifference")) {
retRes55812 := (<-this.LoadTimeDifference())
PanicOnError(retRes55812)
}
response:= (<-this.PublicGetAssetPairs(params))
PanicOnError(response)
//
// {
// "error": [],
// "result": {
// "ADAETH": {
// "altname": "ADAETH",
// "wsname": "ADA\/ETH",
// "aclass_base": "currency",
// "base": "ADA",
// "aclass_quote": "currency",
// "quote": "XETH",
// "lot": "unit",
// "pair_decimals": 7,
// "lot_decimals": 8,
// "lot_multiplier": 1,
// "leverage_buy": [],
// "leverage_sell": [],
// "fees": [
// [0, 0.26],
// [50000, 0.24],
// [100000, 0.22],
// [250000, 0.2],
// [500000, 0.18],
// [1000000, 0.16],
// [2500000, 0.14],
// [5000000, 0.12],
// [10000000, 0.1]
// ],
// "fees_maker": [
// [0, 0.16],
// [50000, 0.14],
// [100000, 0.12],
// [250000, 0.1],
// [500000, 0.08],
// [1000000, 0.06],
// [2500000, 0.04],
// [5000000, 0.02],
// [10000000, 0]
// ],
// "fee_volume_currency": "ZUSD",
// "margin_call": 80,
// "margin_stop": 40,
// "ordermin": "1"
// },
// }
// }
//
var markets interface{} = this.SafeValue(response, "result", map[string]interface{} {})
var keys interface{} = ObjectKeys(markets)
var result interface{} = []interface{}{}
for i := 0; IsLessThan(i, GetArrayLength(keys)); i++ {
var id interface{} = GetValue(keys, i)
var market interface{} = GetValue(markets, id)
var baseId interface{} = this.SafeString(market, "base")
var quoteId interface{} = this.SafeString(market, "quote")
var base interface{} = this.SafeCurrencyCode(baseId)
var quote interface{} = this.SafeCurrencyCode(quoteId)
var darkpool interface{} = IsGreaterThanOrEqual(GetIndexOf(id, ".d"), 0)
var altname interface{} = this.SafeString(market, "altname")
var makerFees interface{} = this.SafeValue(market, "fees_maker", []interface{}{})
var firstMakerFee interface{} = this.SafeValue(makerFees, 0, []interface{}{})
var firstMakerFeeRate interface{} = this.SafeString(firstMakerFee, 1)
var maker interface{} = nil
if IsTrue(!IsEqual(firstMakerFeeRate, nil)) {
maker = this.ParseNumber(Precise.StringDiv(firstMakerFeeRate, "100"))
}
var takerFees interface{} = this.SafeValue(market, "fees", []interface{}{})
var firstTakerFee interface{} = this.SafeValue(takerFees, 0, []interface{}{})
var firstTakerFeeRate interface{} = this.SafeString(firstTakerFee, 1)
var taker interface{} = nil
if IsTrue(!IsEqual(firstTakerFeeRate, nil)) {
taker = this.ParseNumber(Precise.StringDiv(firstTakerFeeRate, "100"))
}
var leverageBuy interface{} = this.SafeValue(market, "leverage_buy", []interface{}{})
var leverageBuyLength interface{} = GetArrayLength(leverageBuy)
var precisionPrice interface{} = this.ParseNumber(this.ParsePrecision(this.SafeString(market, "pair_decimals")))
var status interface{} = this.SafeString(market, "status")
var isActive interface{} = IsEqual(status, "online")
AppendToArray(&result,map[string]interface{} {
"id": id,
"wsId": this.SafeString(market, "wsname"),
"symbol": Ternary(IsTrue(darkpool), altname, (Add(Add(base, "/"), quote))),
"base": base,
"quote": quote,
"settle": nil,
"baseId": baseId,
"quoteId": quoteId,
"settleId": nil,
"darkpool": darkpool,
"altname": GetValue(market, "altname"),
"type": "spot",
"spot": true,
"margin": (IsGreaterThan(leverageBuyLength, 0)),
"swap": false,
"future": false,
"option": false,
"active": isActive,
"contract": false,
"linear": nil,
"inverse": nil,
"taker": taker,
"maker": maker,
"contractSize": nil,
"expiry": nil,
"expiryDatetime": nil,
"strike": nil,
"optionType": nil,
"precision": map[string]interface{} {
"amount": this.ParseNumber(this.ParsePrecision(this.SafeString(market, "lot_decimals"))),
"price": precisionPrice,
},
"limits": map[string]interface{} {
"leverage": map[string]interface{} {
"min": this.ParseNumber("1"),
"max": this.SafeNumber(leverageBuy, Subtract(leverageBuyLength, 1), 1),
},
"amount": map[string]interface{} {
"min": this.SafeNumber(market, "ordermin"),
"max": nil,
},
"price": map[string]interface{} {
"min": precisionPrice,
"max": nil,
},
"cost": map[string]interface{} {
"min": this.SafeNumber(market, "costmin"),
"max": nil,
},
},
"created": nil,
"info": market,
})
}
result = this.AppendInactiveMarkets(result)
AddElementToObject(this.Options, "marketsByAltname", this.IndexBy(result, "altname"))
ch <- result
return nil
}()
return ch
}
func (this *kraken) SafeCurrency(currencyId interface{}, optionalArgs ...interface{}) interface{} {
currency := GetArg(optionalArgs, 0, nil)
_ = currency
if IsTrue(!IsEqual(currencyId, nil)) {
if IsTrue(IsGreaterThan(GetArrayLength(currencyId), 3)) {
if IsTrue(IsTrue((IsEqual(GetIndexOf(currencyId, "X"), 0))) || IsTrue((IsEqual(GetIndexOf(currencyId, "Z"), 0)))) {
if IsTrue(!IsTrue((IsGreaterThan(GetIndexOf(currencyId, "."), 0))) && IsTrue((!IsEqual(currencyId, "ZEUS")))) {
currencyId = Slice(currencyId, 1, nil)
}
}
}
}
return this.Exchange.SafeCurrency(currencyId, currency)
}
func (this *kraken) AppendInactiveMarkets(result interface{}) interface{} {
// result should be an array to append to
var precision interface{} = map[string]interface{} {
"amount": this.ParseNumber("1e-8"),
"price": this.ParseNumber("1e-8"),
}
var costLimits interface{} = map[string]interface{} {
"min": nil,
"max": nil,
}
var priceLimits interface{} = map[string]interface{} {
"min": GetValue(precision, "price"),
"max": nil,
}
var amountLimits interface{} = map[string]interface{} {
"min": GetValue(precision, "amount"),
"max": nil,
}
var limits interface{} = map[string]interface{} {
"amount": amountLimits,
"price": priceLimits,
"cost": costLimits,
}
var defaults interface{} = map[string]interface{} {
"darkpool": false,
"info": nil,
"maker": nil,
"taker": nil,
"active": false,
"precision": precision,
"limits": limits,
}
var markets interface{} = []interface{}{}
for i := 0; IsLessThan(i, GetArrayLength(markets)); i++ {
AppendToArray(&result,this.Extend(defaults, GetValue(markets, i)))
}
return result
}
/**
* @method
* @name kraken#fetchStatus
* @description the latest known information on the availability of the exchange API
* @see https://docs.kraken.com/api/docs/rest-api/get-system-status/
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure}
*/
func (this *kraken) FetchStatus(optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
params := GetArg(optionalArgs, 0, map[string]interface{} {})
_ = params
response:= (<-this.PublicGetSystemStatus(params))
PanicOnError(response)
//
// {
// error: [],
// result: { status: 'online', timestamp: '2024-07-22T16:34:44Z' }
// }
//
var result interface{} = this.SafeDict(response, "result")
var statusRaw interface{} = this.SafeString(result, "status")
ch <- map[string]interface{} {
"status": Ternary(IsTrue((IsEqual(statusRaw, "online"))), "ok", "maintenance"),
"updated": nil,
"eta": nil,
"url": nil,
"info": response,
}
return nil
}()
return ch
}
/**
* @method
* @name kraken#fetchCurrencies
* @description fetches all available currencies on an exchange
* @see https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getAssetInfo
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} an associative dictionary of currencies
*/
func (this *kraken) FetchCurrencies(optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
params := GetArg(optionalArgs, 0, map[string]interface{} {})
_ = params
response:= (<-this.PublicGetAssets(params))
PanicOnError(response)
//
// {
// "error": [],
// "result": {
// "BCH": {
// "aclass": "currency",
// "altname": "BCH",
// "decimals": 10,
// "display_decimals": 5
// "status": "enabled",
// },
// ...
// },
// }
//
var currencies interface{} = this.SafeValue(response, "result", map[string]interface{} {})
var ids interface{} = ObjectKeys(currencies)
var result interface{} = map[string]interface{} {}
for i := 0; IsLessThan(i, GetArrayLength(ids)); i++ {
var id interface{} = GetValue(ids, i)
var currency interface{} = GetValue(currencies, id)
// todo: will need to rethink the fees
// see: https://support.kraken.com/hc/en-us/articles/201893608-What-are-the-withdrawal-fees-
// to add support for multiple withdrawal/deposit methods and
// differentiated fees for each particular method
var code interface{} = this.SafeCurrencyCode(id)
var precision interface{} = this.ParseNumber(this.ParsePrecision(this.SafeString(currency, "decimals")))
// assumes all currencies are active except those listed above
var active interface{} = IsEqual(this.SafeString(currency, "status"), "enabled")
AddElementToObject(result, code, map[string]interface{} {
"id": id,
"code": code,
"info": currency,
"name": this.SafeString(currency, "altname"),
"active": active,
"deposit": nil,
"withdraw": nil,
"fee": nil,
"precision": precision,
"limits": map[string]interface{} {
"amount": map[string]interface{} {
"min": precision,
"max": nil,
},
"withdraw": map[string]interface{} {
"min": nil,
"max": nil,
},
},
"networks": map[string]interface{} {},
})
}
ch <- result
return nil
}()
return ch
}
/**
* @method
* @name kraken#fetchTradingFee
* @description fetch the trading fees for a market
* @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getTradeVolume
* @param {string} symbol unified market symbol
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} a [fee structure]{@link https://docs.ccxt.com/#/?id=fee-structure}
*/
func (this *kraken) FetchTradingFee(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
params := GetArg(optionalArgs, 0, map[string]interface{} {})
_ = params
retRes8428 := (<-this.LoadMarkets())
PanicOnError(retRes8428)
var market interface{} = this.Market(symbol)
var request interface{} = map[string]interface{} {
"pair": GetValue(market, "id"),
"fee-info": true,
}
response:= (<-this.PrivatePostTradeVolume(this.Extend(request, params)))
PanicOnError(response)
//
// {
// "error": [],
// "result": {
// "currency": 'ZUSD',
// "volume": '0.0000',
// "fees": {
// "XXBTZUSD": {
// "fee": '0.2600',
// "minfee": '0.1000',
// "maxfee": '0.2600',
// "nextfee": '0.2400',
// "tiervolume": '0.0000',
// "nextvolume": '50000.0000'
// }
// },
// "fees_maker": {
// "XXBTZUSD": {
// "fee": '0.1600',
// "minfee": '0.0000',
// "maxfee": '0.1600',
// "nextfee": '0.1400',
// "tiervolume": '0.0000',
// "nextvolume": '50000.0000'
// }
// }
// }
// }
//
var result interface{} = this.SafeValue(response, "result", map[string]interface{} {})
ch <- this.ParseTradingFee(result, market)
return nil
}()
return ch
}
func (this *kraken) ParseTradingFee(response interface{}, market interface{}) interface{} {
var makerFees interface{} = this.SafeValue(response, "fees_maker", map[string]interface{} {})
var takerFees interface{} = this.SafeValue(response, "fees", map[string]interface{} {})
var symbolMakerFee interface{} = this.SafeValue(makerFees, GetValue(market, "id"), map[string]interface{} {})
var symbolTakerFee interface{} = this.SafeValue(takerFees, GetValue(market, "id"), map[string]interface{} {})
return map[string]interface{} {
"info": response,
"symbol": GetValue(market, "symbol"),
"maker": this.ParseNumber(Precise.StringDiv(this.SafeString(symbolMakerFee, "fee"), "100")),
"taker": this.ParseNumber(Precise.StringDiv(this.SafeString(symbolTakerFee, "fee"), "100")),
"percentage": true,
"tierBased": true,
}
}
func (this *kraken) ParseBidAsk(bidask interface{}, optionalArgs ...interface{}) interface{} {
priceKey := GetArg(optionalArgs, 0, 0)
_ = priceKey
amountKey := GetArg(optionalArgs, 1, 1)
_ = amountKey
countOrIdKey := GetArg(optionalArgs, 2, 2)
_ = countOrIdKey
var price interface{} = this.SafeNumber(bidask, priceKey)
var amount interface{} = this.SafeNumber(bidask, amountKey)
var timestamp interface{} = this.SafeInteger(bidask, 2)
return []interface{}{price, amount, timestamp}
}
/**
* @method
* @name kraken#fetchOrderBook
* @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data
* @see https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getOrderBook
* @param {string} symbol unified symbol of the market to fetch the order book for
* @param {int} [limit] the maximum amount of order book entries to return
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols
*/
func (this *kraken) FetchOrderBook(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
limit := GetArg(optionalArgs, 0, nil)
_ = limit
params := GetArg(optionalArgs, 1, map[string]interface{} {})
_ = params
retRes9158 := (<-this.LoadMarkets())
PanicOnError(retRes9158)
var market interface{} = this.Market(symbol)
if IsTrue(GetValue(market, "darkpool")) {
panic(ExchangeError(Add(Add(this.Id, " fetchOrderBook() does not provide an order book for darkpool symbol "), symbol)))
}
var request interface{} = map[string]interface{} {
"pair": GetValue(market, "id"),
}
if IsTrue(!IsEqual(limit, nil)) {
AddElementToObject(request, "count", limit) // 100
}
response:= (<-this.PublicGetDepth(this.Extend(request, params)))
PanicOnError(response)
//
// {
// "error":[],
// "result":{
// "XETHXXBT":{
// "asks":[
// ["0.023480","4.000",1586321307],
// ["0.023490","50.095",1586321306],
// ["0.023500","28.535",1586321302],
// ],
// "bids":[
// ["0.023470","59.580",1586321307],
// ["0.023460","20.000",1586321301],
// ["0.023440","67.832",1586321306],
// ]
// }
// }
// }
//
var result interface{} = this.SafeValue(response, "result", map[string]interface{} {})
var orderbook interface{} = this.SafeValue(result, GetValue(market, "id"))
// sometimes kraken returns wsname instead of market id
// https://github.com/ccxt/ccxt/issues/8662
var marketInfo interface{} = this.SafeValue(market, "info", map[string]interface{} {})
var wsName interface{} = this.SafeValue(marketInfo, "wsname")
if IsTrue(!IsEqual(wsName, nil)) {
orderbook = this.SafeValue(result, wsName, orderbook)
}
ch <- this.ParseOrderBook(orderbook, symbol)
return nil
}()
return ch
}
func (this *kraken) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} {
//
// {
// "a":["2432.77000","1","1.000"],
// "b":["2431.37000","2","2.000"],
// "c":["2430.58000","0.04408910"],
// "v":["4147.94474901","8896.96086304"],
// "p":["2456.22239","2568.63032"],
// "t":[3907,10056],
// "l":["2302.18000","2302.18000"],
// "h":["2621.14000","2860.01000"],
// "o":"2571.56000"
// }
//
market := GetArg(optionalArgs, 0, nil)
_ = market
var symbol interface{} = this.SafeSymbol(nil, market)
var v interface{} = this.SafeValue(ticker, "v", []interface{}{})
var baseVolume interface{} = this.SafeString(v, 1)
var p interface{} = this.SafeValue(ticker, "p", []interface{}{})
var vwap interface{} = this.SafeString(p, 1)
var quoteVolume interface{} = Precise.StringMul(baseVolume, vwap)
var c interface{} = this.SafeValue(ticker, "c", []interface{}{})
var last interface{} = this.SafeString(c, 0)
var high interface{} = this.SafeValue(ticker, "h", []interface{}{})
var low interface{} = this.SafeValue(ticker, "l", []interface{}{})
var bid interface{} = this.SafeValue(ticker, "b", []interface{}{})
var ask interface{} = this.SafeValue(ticker, "a", []interface{}{})
return this.SafeTicker(map[string]interface{} {
"symbol": symbol,
"timestamp": nil,
"datetime": nil,
"high": this.SafeString(high, 1),
"low": this.SafeString(low, 1),
"bid": this.SafeString(bid, 0),
"bidVolume": this.SafeString(bid, 2),
"ask": this.SafeString(ask, 0),
"askVolume": this.SafeString(ask, 2),
"vwap": vwap,
"open": this.SafeString(ticker, "o"),
"close": last,
"last": last,
"previousClose": nil,
"change": nil,
"percentage": nil,
"average": nil,
"baseVolume": baseVolume,
"quoteVolume": quoteVolume,
"info": ticker,
}, market)
}
/**
* @method
* @name kraken#fetchTickers
* @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market
* @see https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getTickerInformation
* @param {string[]|undefined} 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} a dictionary of [ticker structures]{@link https://docs.ccxt.com/#/?id=ticker-structure}
*/
func (this *kraken) FetchTickers(optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
symbols := GetArg(optionalArgs, 0, nil)
_ = symbols
params := GetArg(optionalArgs, 1, map[string]interface{} {})
_ = params
retRes10188 := (<-this.LoadMarkets())
PanicOnError(retRes10188)
var request interface{} = map[string]interface{} {}
if IsTrue(!IsEqual(symbols, nil)) {
symbols = this.MarketSymbols(symbols)
var marketIds interface{} = []interface{}{}
for i := 0; IsLessThan(i, GetArrayLength(symbols)); i++ {
var symbol interface{} = GetValue(symbols, i)
var market interface{} = GetValue(this.Markets, symbol)
if IsTrue(IsTrue(GetValue(market, "active")) && !IsTrue(GetValue(market, "darkpool"))) {
AppendToArray(&marketIds,GetValue(market, "id"))
}
}
AddElementToObject(request, "pair", Join(marketIds, ","))
}
response:= (<-this.PublicGetTicker(this.Extend(request, params)))
PanicOnError(response)
var tickers interface{} = GetValue(response, "result")
var ids interface{} = ObjectKeys(tickers)
var result interface{} = map[string]interface{} {}
for i := 0; IsLessThan(i, GetArrayLength(ids)); i++ {
var id interface{} = GetValue(ids, i)
var market interface{} = this.SafeMarket(id)
var symbol interface{} = GetValue(market, "symbol")
var ticker interface{} = GetValue(tickers, id)
AddElementToObject(result, symbol, this.ParseTicker(ticker, market))
}
ch <- this.FilterByArrayTickers(result, "symbol", symbols)
return nil
}()
return ch
}
/**
* @method
* @name kraken#fetchTicker
* @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market
* @see https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getTickerInformation
* @param {string} symbol unified symbol of the market to fetch the ticker for
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} a [ticker structure]{@link https://docs.ccxt.com/#/?id=ticker-structure}
*/
func (this *kraken) FetchTicker(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
params := GetArg(optionalArgs, 0, map[string]interface{} {})
_ = params
retRes10568 := (<-this.LoadMarkets())
PanicOnError(retRes10568)
var darkpool interface{} = IsGreaterThanOrEqual(GetIndexOf(symbol, ".d"), 0)
if IsTrue(darkpool) {
panic(ExchangeError(Add(Add(this.Id, " fetchTicker() does not provide a ticker for darkpool symbol "), symbol)))
}
var market interface{} = this.Market(symbol)
var request interface{} = map[string]interface{} {
"pair": GetValue(market, "id"),
}
response:= (<-this.PublicGetTicker(this.Extend(request, params)))
PanicOnError(response)
var ticker interface{} = GetValue(GetValue(response, "result"), GetValue(market, "id"))
ch <- this.ParseTicker(ticker, market)
return nil
}()
return ch
}
func (this *kraken) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} {
//
// [
// 1591475640,
// "0.02500",
// "0.02500",
// "0.02500",
// "0.02500",
// "0.02500",
// "9.12201000",
// 5
// ]
//
market := GetArg(optionalArgs, 0, nil)
_ = market
return []interface{}{this.SafeTimestamp(ohlcv, 0), this.SafeNumber(ohlcv, 1), this.SafeNumber(ohlcv, 2), this.SafeNumber(ohlcv, 3), this.SafeNumber(ohlcv, 4), this.SafeNumber(ohlcv, 6)}
}
/**
* @method
* @name kraken#fetchOHLCV
* @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market
* @see https://docs.kraken.com/api/docs/rest-api/get-ohlc-data
* @param {string} symbol unified symbol of the market to fetch OHLCV data for
* @param {string} timeframe the length of time each candle represents
* @param {int} [since] timestamp in ms of the earliest candle to fetch
* @param {int} [limit] the maximum amount of candles to fetch
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params)
* @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume
*/
func (this *kraken) FetchOHLCV(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
timeframe := GetArg(optionalArgs, 0, "1m")
_ = timeframe
since := GetArg(optionalArgs, 1, nil)
_ = since
limit := GetArg(optionalArgs, 2, nil)
_ = limit
params := GetArg(optionalArgs, 3, map[string]interface{} {})
_ = params
retRes11078 := (<-this.LoadMarkets())
PanicOnError(retRes11078)
var paginate interface{} = false
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOHLCV", "paginate");
paginate = GetValue(paginateparamsVariable,0);
params = GetValue(paginateparamsVariable,1)
if IsTrue(paginate) {
retRes111119 := (<-this.FetchPaginatedCallDeterministic("fetchOHLCV", symbol, since, limit, timeframe, params, 720))
PanicOnError(retRes111119)
ch <- retRes111119
return nil
}
var market interface{} = this.Market(symbol)
var parsedTimeframe interface{} = this.SafeInteger(this.Timeframes, timeframe)
var request interface{} = map[string]interface{} {
"pair": GetValue(market, "id"),
}
if IsTrue(!IsEqual(parsedTimeframe, nil)) {
AddElementToObject(request, "interval", parsedTimeframe)
} else {
AddElementToObject(request, "interval", timeframe)
}
if IsTrue(!IsEqual(since, nil)) {
var scaledSince interface{} = this.ParseToInt(Divide(since, 1000))
var timeFrameInSeconds interface{} = Multiply(parsedTimeframe, 60)
AddElementToObject(request, "since", this.NumberToString(Subtract(scaledSince, timeFrameInSeconds))) // expected to be in seconds
}
response:= (<-this.PublicGetOHLC(this.Extend(request, params)))
PanicOnError(response)
//
// {
// "error":[],
// "result":{
// "XETHXXBT":[
// [1591475580,"0.02499","0.02499","0.02499","0.02499","0.00000","0.00000000",0],
// [1591475640,"0.02500","0.02500","0.02500","0.02500","0.02500","9.12201000",5],
// [1591475700,"0.02499","0.02499","0.02499","0.02499","0.02499","1.28681415",2],
// [1591475760,"0.02499","0.02499","0.02499","0.02499","0.02499","0.08800000",1],
// ],
// "last":1591517580
// }
// }
var result interface{} = this.SafeValue(response, "result", map[string]interface{} {})
var ohlcvs interface{} = this.SafeList(result, GetValue(market, "id"), []interface{}{})
ch <- this.ParseOHLCVs(ohlcvs, market, timeframe, since, limit)
return nil
}()
return ch
}
func (this *kraken) ParseLedgerEntryType(typeVar interface{}) interface{} {
var types interface{} = map[string]interface{} {
"trade": "trade",
"withdrawal": "transaction",
"deposit": "transaction",
"transfer": "transfer",
"margin": "margin",
}
return this.SafeString(types, typeVar, typeVar)
}
func (this *kraken) ParseLedgerEntry(item interface{}, optionalArgs ...interface{}) interface{} {
//
// {
// 'LTFK7F-N2CUX-PNY4SX': {
// "refid": "TSJTGT-DT7WN-GPPQMJ",
// "time": 1520102320.555,
// "type": "trade",
// "aclass": "currency",
// "asset": "XETH",
// "amount": "0.1087194600",
// "fee": "0.0000000000",
// "balance": "0.2855851000"
// },
// ...
// }
//
currency := GetArg(optionalArgs, 0, nil)
_ = currency
var id interface{} = this.SafeString(item, "id")
var direction interface{} = nil
var account interface{} = nil
var referenceId interface{} = this.SafeString(item, "refid")
var referenceAccount interface{} = nil
var typeVar interface{} = this.ParseLedgerEntryType(this.SafeString(item, "type"))
var currencyId interface{} = this.SafeString(item, "asset")
var code interface{} = this.SafeCurrencyCode(currencyId, currency)
currency = this.SafeCurrency(currencyId, currency)
var amount interface{} = this.SafeString(item, "amount")
if IsTrue(Precise.StringLt(amount, "0")) {
direction = "out"
amount = Precise.StringAbs(amount)
} else {
direction = "in"
}
var timestamp interface{} = this.SafeIntegerProduct(item, "time", 1000)
return this.SafeLedgerEntry(map[string]interface{} {
"info": item,
"id": id,
"direction": direction,
"account": account,
"referenceId": referenceId,
"referenceAccount": referenceAccount,
"type": typeVar,
"currency": code,
"amount": this.ParseNumber(amount),
"before": nil,
"after": this.SafeNumber(item, "balance"),
"status": "ok",
"timestamp": timestamp,
"datetime": this.Iso8601(timestamp),
"fee": map[string]interface{} {
"cost": this.SafeNumber(item, "fee"),
"currency": code,
},
}, currency)
}
/**
* @method
* @name kraken#fetchLedger
* @description fetch the history of changes, actions done by the user or operations that altered the balance of the user
* @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getLedgers
* @param {string} [code] unified currency code, default is undefined
* @param {int} [since] timestamp in ms of the earliest ledger entry, default is undefined
* @param {int} [limit] max number of ledger entries to return, default is undefined
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {int} [params.until] timestamp in ms of the latest ledger entry
* @param {int} [params.end] timestamp in seconds of the latest ledger entry
* @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger}
*/
func (this *kraken) FetchLedger(optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
// https://www.kraken.com/features/api#get-ledgers-info
code := GetArg(optionalArgs, 0, nil)
_ = code
since := GetArg(optionalArgs, 1, nil)
_ = since
limit := GetArg(optionalArgs, 2, nil)
_ = limit
params := GetArg(optionalArgs, 3, map[string]interface{} {})
_ = params
retRes12288 := (<-this.LoadMarkets())
PanicOnError(retRes12288)
var request interface{} = map[string]interface{} {}
var currency interface{} = nil
if IsTrue(!IsEqual(code, nil)) {
currency = this.Currency(code)
AddElementToObject(request, "asset", GetValue(currency, "id"))
}
if IsTrue(!IsEqual(since, nil)) {
AddElementToObject(request, "start", this.ParseToInt(Divide(since, 1000)))
}
var until interface{} = this.SafeStringN(params, []interface{}{"until", "till"})
if IsTrue(!IsEqual(until, nil)) {
params = this.Omit(params, []interface{}{"until", "till"})
var untilDivided interface{} = Precise.StringDiv(until, "1000")
AddElementToObject(request, "end", this.ParseToInt(Precise.StringAdd(untilDivided, "1")))
}
response:= (<-this.PrivatePostLedgers(this.Extend(request, params)))
PanicOnError(response)
// { error: [],
// "result": { ledger: { 'LPUAIB-TS774-UKHP7X': { refid: "A2B4HBV-L4MDIE-JU4N3N",
// "time": 1520103488.314,
// "type": "withdrawal",
// "aclass": "currency",
// "asset": "XETH",
// "amount": "-0.2805800000",
// "fee": "0.0050000000",
// "balance": "0.0000051000" },
var result interface{} = this.SafeValue(response, "result", map[string]interface{} {})
var ledger interface{} = this.SafeValue(result, "ledger", map[string]interface{} {})
var keys interface{} = ObjectKeys(ledger)
var items interface{} = []interface{}{}
for i := 0; IsLessThan(i, GetArrayLength(keys)); i++ {
var key interface{} = GetValue(keys, i)
var value interface{} = GetValue(ledger, key)
AddElementToObject(value, "id", key)
AppendToArray(&items,value)
}
ch <- this.ParseLedger(items, currency, since, limit)
return nil
}()
return ch
}
func (this *kraken) FetchLedgerEntriesByIds(ids interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
// https://www.kraken.com/features/api#query-ledgers
code := GetArg(optionalArgs, 0, nil)
_ = code
params := GetArg(optionalArgs, 1, map[string]interface{} {})
_ = params
retRes12698 := (<-this.LoadMarkets())
PanicOnError(retRes12698)
ids = Join(ids, ",")
var request interface{} = this.Extend(map[string]interface{} {
"id": ids,
}, params)
response:= (<-this.PrivatePostQueryLedgers(request))
PanicOnError(response)
// { error: [],
// "result": { 'LPUAIB-TS774-UKHP7X': { refid: "A2B4HBV-L4MDIE-JU4N3N",
// "time": 1520103488.314,
// "type": "withdrawal",
// "aclass": "currency",
// "asset": "XETH",
// "amount": "-0.2805800000",
// "fee": "0.0050000000",
// "balance": "0.0000051000" } } }
var result interface{} = GetValue(response, "result")
var keys interface{} = ObjectKeys(result)
var items interface{} = []interface{}{}
for i := 0; IsLessThan(i, GetArrayLength(keys)); i++ {
var key interface{} = GetValue(keys, i)
var value interface{} = GetValue(result, key)
AddElementToObject(value, "id", key)
AppendToArray(&items,value)
}
ch <- this.ParseLedger(items)
return nil
}()
return ch
}
func (this *kraken) FetchLedgerEntry(id interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
code := GetArg(optionalArgs, 0, nil)
_ = code
params := GetArg(optionalArgs, 1, map[string]interface{} {})
_ = params
items:= (<-this.FetchLedgerEntriesByIds([]interface{}{id}, code, params))
PanicOnError(items)
ch <- GetValue(items, 0)
return nil
}()
return ch
}
func (this *kraken) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} {
//
// fetchTrades (public)
//
// [
// "0.032310", // price
// "4.28169434", // amount
// 1541390792.763, // timestamp
// "s", // sell or buy
// "l", // limit or market
// ""
// ]
//
// fetchOrderTrades (private)
//
// {
// "id": 'TIMIRG-WUNNE-RRJ6GT', // injected from outside
// "ordertxid": 'OQRPN2-LRHFY-HIFA7D',
// "postxid": 'TKH2SE-M7IF5-CFI7LT',
// "pair": 'USDCUSDT',
// "time": 1586340086.457,
// "type": 'sell',
// "ordertype": 'market',
// "price": '0.99860000',
// "cost": '22.16892001',
// "fee": '0.04433784',
// "vol": '22.20000000',
// "margin": '0.00000000',
// "misc": ''
// }
//
// fetchMyTrades
//
// {
// "ordertxid": "OSJVN7-A2AE-63WZV",
// "postxid": "TBP7O6-PNXI-CONU",
// "pair": "XXBTZUSD",
// "time": 1710429248.3052235,
// "type": "sell",
// "ordertype": "liquidation market",
// "price": "72026.50000",
// "cost": "7.20265",
// "fee": "0.01873",
// "vol": "0.00010000",
// "margin": "1.44053",
// "leverage": "5",
// "misc": "closing",
// "trade_id": 68230622,
// "maker": false
// }
//
market := GetArg(optionalArgs, 0, nil)
_ = market
var timestamp interface{} = nil
var side interface{} = nil
var typeVar interface{} = nil
var price interface{} = nil
var amount interface{} = nil
var id interface{} = nil
var orderId interface{} = nil
var fee interface{} = nil
var symbol interface{} = nil
if IsTrue(IsArray(trade)) {
timestamp = this.SafeTimestamp(trade, 2)
side = Ternary(IsTrue((IsEqual(GetValue(trade, 3), "s"))), "sell", "buy")
typeVar = Ternary(IsTrue((IsEqual(GetValue(trade, 4), "l"))), "limit", "market")
price = this.SafeString(trade, 0)
amount = this.SafeString(trade, 1)
var tradeLength interface{} = GetArrayLength(trade)
if IsTrue(IsGreaterThan(tradeLength, 6)) {
id = this.SafeString(trade, 6) // artificially added as per #1794
}
} else if IsTrue(IsString(trade)) {
id = trade
} else if IsTrue(InOp(trade, "ordertxid")) {
var marketId interface{} = this.SafeString(trade, "pair")
var foundMarket interface{} = this.FindMarketByAltnameOrId(marketId)
if IsTrue(!IsEqual(foundMarket, nil)) {
market = foundMarket
} else if IsTrue(!IsEqual(marketId, nil)) {
// delisted market ids go here
market = this.GetDelistedMarketById(marketId)
}
orderId = this.SafeString(trade, "ordertxid")
id = this.SafeString2(trade, "id", "postxid")
timestamp = this.SafeTimestamp(trade, "time")
side = this.SafeString(trade, "type")
typeVar = this.SafeString(trade, "ordertype")
price = this.SafeString(trade, "price")
amount = this.SafeString(trade, "vol")
if IsTrue(InOp(trade, "fee")) {
var currency interface{} = nil
if IsTrue(!IsEqual(market, nil)) {
currency = GetValue(market, "quote")
}
fee = map[string]interface{} {
"cost": this.SafeString(trade, "fee"),
"currency": currency,
}
}
}
if IsTrue(!IsEqual(market, nil)) {
symbol = GetValue(market, "symbol")
}
var cost interface{} = this.SafeString(trade, "cost")
var maker interface{} = this.SafeBool(trade, "maker")
var takerOrMaker interface{} = nil
if IsTrue(!IsEqual(maker, nil)) {
takerOrMaker = Ternary(IsTrue(maker), "maker", "taker")
}
return this.SafeTrade(map[string]interface{} {
"id": id,
"order": orderId,
"info": trade,
"timestamp": timestamp,
"datetime": this.Iso8601(timestamp),
"symbol": symbol,
"type": typeVar,
"side": side,
"takerOrMaker": takerOrMaker,
"price": price,
"amount": amount,
"cost": cost,
"fee": fee,
}, market)
}
/**
* @method
* @name kraken#fetchTrades
* @description get the list of most recent trades for a particular symbol
* @see https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getRecentTrades
* @param {string} symbol unified symbol of the market to fetch trades for
* @param {int} [since] timestamp in ms of the earliest trade to fetch
* @param {int} [limit] the maximum amount of trades to fetch
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades}
*/
func (this *kraken) FetchTrades(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
since := GetArg(optionalArgs, 0, nil)
_ = since
limit := GetArg(optionalArgs, 1, nil)
_ = limit
params := GetArg(optionalArgs, 2, map[string]interface{} {})
_ = params
retRes14388 := (<-this.LoadMarkets())
PanicOnError(retRes14388)
var market interface{} = this.Market(symbol)
var id interface{} = GetValue(market, "id")
var request interface{} = map[string]interface{} {
"pair": id,
}
// https://support.kraken.com/hc/en-us/articles/218198197-How-to-pull-all-trade-data-using-the-Kraken-REST-API
// https://github.com/ccxt/ccxt/issues/5677
if IsTrue(!IsEqual(since, nil)) {
AddElementToObject(request, "since", this.NumberToString(this.ParseToInt(Divide(since, 1000)))) // expected to be in seconds
}
if IsTrue(!IsEqual(limit, nil)) {
AddElementToObject(request, "count", limit)
}
response:= (<-this.PublicGetTrades(this.Extend(request, params)))
PanicOnError(response)
//
// {
// "error": [],
// "result": {
// "XETHXXBT": [
// ["0.032310","4.28169434",1541390792.763,"s","l",""]
// ],
// "last": "1541439421200678657"
// }
// }
//
var result interface{} = GetValue(response, "result")
var trades interface{} = GetValue(result, id)
// trades is a sorted array: last (most recent trade) goes last
var length interface{} = GetArrayLength(trades)
if IsTrue(IsLessThanOrEqual(length, 0)) {
ch <- []interface{}{}
return nil
}
var lastTrade interface{} = GetValue(trades, Subtract(length, 1))
var lastTradeId interface{} = this.SafeString(result, "last")
AppendToArray(&lastTrade,lastTradeId)
AddElementToObject(trades, Subtract(length, 1), lastTrade)
ch <- this.ParseTrades(trades, market, since, limit)
return nil
}()
return ch
}
func (this *kraken) ParseBalance(response interface{}) interface{} {
var balances interface{} = this.SafeValue(response, "result", map[string]interface{} {})
var result interface{} = map[string]interface{} {
"info": response,
"timestamp": nil,
"datetime": nil,
}
var currencyIds interface{} = ObjectKeys(balances)
for i := 0; IsLessThan(i, GetArrayLength(currencyIds)); i++ {
var currencyId interface{} = GetValue(currencyIds, i)
var code interface{} = this.SafeCurrencyCode(currencyId)
var balance interface{} = this.SafeValue(balances, currencyId, map[string]interface{} {})
var account interface{} = this.Account()
AddElementToObject(account, "used", this.SafeString(balance, "hold_trade"))
AddElementToObject(account, "total", this.SafeString(balance, "balance"))
AddElementToObject(result, code, account)
}
return this.SafeBalance(result)
}
/**
* @method
* @name kraken#fetchBalance
* @description query for balance and get the amount of funds available for trading or funds locked in orders
* @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getExtendedBalance
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} a [balance structure]{@link https://docs.ccxt.com/#/?id=balance-structure}
*/
func (this *kraken) FetchBalance(optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
params := GetArg(optionalArgs, 0, map[string]interface{} {})
_ = params
retRes15078 := (<-this.LoadMarkets())
PanicOnError(retRes15078)
response:= (<-this.PrivatePostBalanceEx(params))
PanicOnError(response)
//
// {
// "error": [],
// "result": {
// "ZUSD": {
// "balance": 25435.21,
// "hold_trade": 8249.76
// },
// "XXBT": {
// "balance": 1.2435,
// "hold_trade": 0.8423
// }
// }
// }
//
ch <- this.ParseBalance(response)
return nil
}()
return ch
}
/**
* @method
* @name kraken#createMarketOrderWithCost
* @description create a market order by providing the symbol, side and cost
* @see https://docs.kraken.com/rest/#tag/Spot-Trading/operation/addOrder
* @param {string} symbol unified symbol of the market to create an order in (only USD markets are supported)
* @param {string} side 'buy' or 'sell'
* @param {float} cost how much you want to trade in units of the quote currency
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
*/
func (this *kraken) CreateMarketOrderWithCost(symbol interface{}, side interface{}, cost interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
params := GetArg(optionalArgs, 0, map[string]interface{} {})
_ = params
retRes15398 := (<-this.LoadMarkets())
PanicOnError(retRes15398)
// only buy orders are supported by the endpoint
AddElementToObject(params, "cost", cost)
retRes154215 := (<-this.CreateOrder(symbol, "market", side, cost, nil, params))
PanicOnError(retRes154215)
ch <- retRes154215
return nil
}()
return ch
}
/**
* @method
* @name kraken#createMarketBuyOrderWithCost
* @description create a market buy order by providing the symbol, side and cost
* @see https://docs.kraken.com/rest/#tag/Spot-Trading/operation/addOrder
* @param {string} symbol unified symbol of the market to create an order in
* @param {float} cost how much you want to trade in units of the quote currency
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
*/
func (this *kraken) CreateMarketBuyOrderWithCost(symbol interface{}, cost interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
params := GetArg(optionalArgs, 0, map[string]interface{} {})
_ = params
retRes15568 := (<-this.LoadMarkets())
PanicOnError(retRes15568)
retRes155715 := (<-this.CreateMarketOrderWithCost(symbol, "buy", cost, params))
PanicOnError(retRes155715)
ch <- retRes155715
return nil
}()
return ch
}
/**
* @method
* @name kraken#createOrder
* @description create a trade order
* @see https://docs.kraken.com/api/docs/rest-api/add-order
* @param {string} symbol unified symbol of the market to create an order in
* @param {string} type 'market' or 'limit'
* @param {string} side 'buy' or 'sell'
* @param {float} amount how much of currency you want to trade in units of base currency
* @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {bool} [params.postOnly] if true, the order will only be posted to the order book and not executed immediately
* @param {bool} [params.reduceOnly] *margin only* indicates if this order is to reduce the size of a position
* @param {float} [params.stopLossPrice] *margin only* the price that a stop loss order is triggered at
* @param {float} [params.takeProfitPrice] *margin only* the price that a take profit order is triggered at
* @param {string} [params.trailingAmount] *margin only* the quote amount to trail away from the current market price
* @param {string} [params.trailingPercent] *margin only* the percent to trail away from the current market price
* @param {string} [params.trailingLimitAmount] *margin only* the quote amount away from the trailingAmount
* @param {string} [params.trailingLimitPercent] *margin only* the percent away from the trailingAmount
* @param {string} [params.offset] *margin only* '+' or '-' whether you want the trailingLimitAmount value to be positive or negative, default is negative '-'
* @param {string} [params.trigger] *margin only* the activation price type, 'last' or 'index', default is 'last'
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
*/
func (this *kraken) CreateOrder(symbol interface{}, typeVar interface{}, side interface{}, amount interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
price := GetArg(optionalArgs, 0, nil)
_ = price
params := GetArg(optionalArgs, 1, map[string]interface{} {})
_ = params
retRes15848 := (<-this.LoadMarkets())
PanicOnError(retRes15848)
var market interface{} = this.Market(symbol)
var request interface{} = map[string]interface{} {
"pair": GetValue(market, "id"),
"type": side,
"ordertype": typeVar,
"volume": this.AmountToPrecision(symbol, amount),
}
var orderRequest interface{} = this.OrderRequest("createOrder", symbol, typeVar, request, amount, price, params)
response:= (<-this.PrivatePostAddOrder(this.Extend(GetValue(orderRequest, 0), GetValue(orderRequest, 1))))
PanicOnError(response)
//
// {
// "error": [],
// "result": {
// "descr": { order: 'buy 0.02100000 ETHUSDT @ limit 330.00' }, // see more examples in "parseOrder"
// "txid": [ 'OEKVV2-IH52O-TPL6GZ' ]
// }
// }
//
var result interface{} = this.SafeDict(response, "result")
ch <- this.ParseOrder(result)
return nil
}()
return ch
}
func (this *kraken) FindMarketByAltnameOrId(id interface{}) interface{} {
var marketsByAltname interface{} = this.SafeValue(this.Options, "marketsByAltname", map[string]interface{} {})
if IsTrue(InOp(marketsByAltname, id)) {
return GetValue(marketsByAltname, id)
} else {
return this.SafeMarket(id)
}
}
func (this *kraken) GetDelistedMarketById(id interface{}) interface{} {
if IsTrue(IsEqual(id, nil)) {
return id
}
var market interface{} = this.SafeValue(GetValue(this.Options, "delistedMarketsById"), id)
if IsTrue(!IsEqual(market, nil)) {
return market
}
var baseIdStart interface{} = 0
var baseIdEnd interface{} = 3
var quoteIdStart interface{} = 3
var quoteIdEnd interface{} = 6
if IsTrue(IsEqual(GetArrayLength(id), 8)) {
baseIdEnd = 4
quoteIdStart = 4
quoteIdEnd = 8
} else if IsTrue(IsEqual(GetArrayLength(id), 7)) {
baseIdEnd = 4
quoteIdStart = 4
quoteIdEnd = 7
}
var baseId interface{} = Slice(id, baseIdStart, baseIdEnd)
var quoteId interface{} = Slice(id, quoteIdStart, quoteIdEnd)
var base interface{} = this.SafeCurrencyCode(baseId)
var quote interface{} = this.SafeCurrencyCode(quoteId)
var symbol interface{} = Add(Add(base, "/"), quote)
market = map[string]interface{} {
"symbol": symbol,
"base": base,
"quote": quote,
"baseId": baseId,
"quoteId": quoteId,
}
AddElementToObject(GetValue(this.Options, "delistedMarketsById"), id, market)
return market
}
func (this *kraken) ParseOrderStatus(status interface{}) interface{} {
var statuses interface{} = map[string]interface{} {
"pending": "open",
"open": "open",
"closed": "closed",
"canceled": "canceled",
"expired": "expired",
}
return this.SafeString(statuses, status, status)
}
func (this *kraken) ParseOrderType(status interface{}) interface{} {
var statuses interface{} = map[string]interface{} {
"take-profit": "market",
"stop-loss": "market",
"stop-loss-limit": "limit",
"take-profit-limit": "limit",
"trailing-stop-limit": "limit",
}
return this.SafeString(statuses, status, status)
}
func (this *kraken) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} {
//
// createOrder
//
// {
// "descr": {
// "order": "buy 0.02100000 ETHUSDT @ limit 330.00" // limit orders
// "buy 0.12345678 ETHUSDT @ market" // market order
// "sell 0.28002676 ETHUSDT @ stop loss 0.0123 -> limit 0.0.1222" // stop order
// "sell 0.00100000 ETHUSDT @ stop loss 2677.00 -> limit 2577.00 with 5:1 leverage"
// "buy 0.10000000 LTCUSDT @ take profit 75.00000 -> limit 74.00000"
// "sell 10.00000000 XRPEUR @ trailing stop +50.0000%" // trailing stop
// },
// "txid": [ 'OEKVV2-IH52O-TPL6GZ' ]
// }
//
// editOrder
//
// {
// "amend_id": "TJSMEH-AA67V-YUSQ6O"
// }
//
// ws - createOrder
// {
// "descr": 'sell 0.00010000 XBTUSDT @ market',
// "event": 'addOrderStatus',
// "reqid": 1,
// "status": 'ok',
// "txid": 'OAVXZH-XIE54-JCYYDG'
// }
// ws - editOrder
// {
// "descr": "order edited price = 9000.00000000",
// "event": "editOrderStatus",
// "originaltxid": "O65KZW-J4AW3-VFS74A",
// "reqid": 3,
// "status": "ok",
// "txid": "OTI672-HJFAO-XOIPPK"
// }
//
// {
// "error": [],
// "result": {
// "open": {
// "OXVPSU-Q726F-L3SDEP": {
// "refid": null,
// "userref": 0,
// "status": "open",
// "opentm": 1706893367.4656649,
// "starttm": 0,
// "expiretm": 0,
// "descr": {
// "pair": "XRPEUR",
// "type": "sell",
// "ordertype": "trailing-stop",
// "price": "+50.0000%",
// "price2": "0",
// "leverage": "none",
// "order": "sell 10.00000000 XRPEUR @ trailing stop +50.0000%",
// "close": ""
// },
// "vol": "10.00000000",
// "vol_exec": "0.00000000",
// "cost": "0.00000000",
// "fee": "0.00000000",
// "price": "0.00000000",
// "stopprice": "0.23424000",
// "limitprice": "0.46847000",
// "misc": "",
// "oflags": "fciq",
// "trigger": "index"
// }
// }
// }
//
// fetchOpenOrders
//
// {
// "refid": null,
// "userref": null,
// "cl_ord_id": "1234",
// "status": "open",
// "opentm": 1733815269.370054,
// "starttm": 0,
// "expiretm": 0,
// "descr": {
// "pair": "XBTUSD",
// "type": "buy",
// "ordertype": "limit",
// "price": "70000.0",
// "price2": "0",
// "leverage": "none",
// "order": "buy 0.00010000 XBTUSD @ limit 70000.0",
// "close": ""
// },
// "vol": "0.00010000",
// "vol_exec": "0.00000000",
// "cost": "0.00000",
// "fee": "0.00000",
// "price": "0.00000",
// "stopprice": "0.00000",
// "limitprice": "0.00000",
// "misc": "",
// "oflags": "fciq"
// }
//
market := GetArg(optionalArgs, 0, nil)
_ = market
var description interface{} = this.SafeDict(order, "descr", map[string]interface{} {})
var orderDescriptionObj interface{} = this.SafeDict(order, "descr") // can be null
var orderDescription interface{} = nil
if IsTrue(!IsEqual(orderDescriptionObj, nil)) {
orderDescription = this.SafeString(orderDescriptionObj, "order")
} else {
orderDescription = this.SafeString(order, "descr")
}
var side interface{} = nil
var rawType interface{} = nil
var marketId interface{} = nil
var price interface{} = nil
var amount interface{} = nil
var triggerPrice interface{} = nil
if IsTrue(!IsEqual(orderDescription, nil)) {
var parts interface{} = Split(orderDescription, " ")
side = this.SafeString(parts, 0)
amount = this.SafeString(parts, 1)
marketId = this.SafeString(parts, 2)
var part4 interface{} = this.SafeString(parts, 4)
var part5 interface{} = this.SafeString(parts, 5)
if IsTrue(IsTrue(IsEqual(part4, "limit")) || IsTrue(IsEqual(part4, "market"))) {
rawType = part4 // eg, limit, market
} else {
rawType = Add(Add(part4, " "), part5) // eg. stop loss, take profit, trailing stop
}
if IsTrue(IsTrue(IsEqual(rawType, "stop loss")) || IsTrue(IsEqual(rawType, "take profit"))) {
triggerPrice = this.SafeString(parts, 6)
price = this.SafeString(parts, 9)
} else if IsTrue(IsEqual(rawType, "limit")) {
price = this.SafeString(parts, 5)
}
}
side = this.SafeString(description, "type", side)
rawType = this.SafeString(description, "ordertype", rawType) // orderType has dash, e.g. trailing-stop
marketId = this.SafeString(description, "pair", marketId)
var foundMarket interface{} = this.FindMarketByAltnameOrId(marketId)
var symbol interface{} = nil
if IsTrue(!IsEqual(foundMarket, nil)) {
market = foundMarket
} else if IsTrue(!IsEqual(marketId, nil)) {
// delisted market ids go here
market = this.GetDelistedMarketById(marketId)
}
var timestamp interface{} = this.SafeTimestamp(order, "opentm")
amount = this.SafeString(order, "vol", amount)
var filled interface{} = this.SafeString(order, "vol_exec")
var fee interface{} = nil
// kraken truncates the cost in the api response so we will ignore it and calculate it from average & filled
// const cost = this.safeString (order, 'cost');
price = this.SafeString(description, "price", price)
// when type = trailling stop returns price = '+50.0000%'
if IsTrue(IsTrue((!IsEqual(price, nil))) && IsTrue(EndsWith(price, "%"))) {
price = nil // this is not the price we want
}
if IsTrue(IsTrue((IsEqual(price, nil))) || IsTrue(Precise.StringEquals(price, "0"))) {
price = this.SafeString(description, "price2")
}
if IsTrue(IsTrue((IsEqual(price, nil))) || IsTrue(Precise.StringEquals(price, "0"))) {
price = this.SafeString(order, "price", price)
}
var flags interface{} = this.SafeString(order, "oflags", "")
var isPostOnly interface{} = IsGreaterThan(GetIndexOf(flags, "post"), OpNeg(1))
var average interface{} = this.SafeNumber(order, "price")
if IsTrue(!IsEqual(market, nil)) {
symbol = GetValue(market, "symbol")
if IsTrue(InOp(order, "fee")) {
var feeCost interface{} = this.SafeString(order, "fee")
fee = map[string]interface{} {
"cost": feeCost,
"rate": nil,
}
if IsTrue(IsGreaterThanOrEqual(GetIndexOf(flags, "fciq"), 0)) {
AddElementToObject(fee, "currency", GetValue(market, "quote"))
} else if IsTrue(IsGreaterThanOrEqual(GetIndexOf(flags, "fcib"), 0)) {
AddElementToObject(fee, "currency", GetValue(market, "base"))
}
}
}
var status interface{} = this.ParseOrderStatus(this.SafeString(order, "status"))
var id interface{} = this.SafeStringN(order, []interface{}{"id", "txid", "amend_id"})
if IsTrue(IsTrue((IsEqual(id, nil))) || IsTrue((StartsWith(id, "[")))) {
var txid interface{} = this.SafeList(order, "txid")
id = this.SafeString(txid, 0)
}
var userref interface{} = this.SafeString(order, "userref")
var clientOrderId interface{} = this.SafeString(order, "cl_ord_id", userref)
var rawTrades interface{} = this.SafeValue(order, "trades", []interface{}{})
var trades interface{} = []interface{}{}
for i := 0; IsLessThan(i, GetArrayLength(rawTrades)); i++ {
var rawTrade interface{} = GetValue(rawTrades, i)
if IsTrue(IsString(rawTrade)) {
AppendToArray(&trades,this.SafeTrade(map[string]interface{} {
"id": rawTrade,
"orderId": id,
"symbol": symbol,
"info": map[string]interface{} {},
}))
} else {
AppendToArray(&trades,rawTrade)
}
}
// as mentioned in #24192 PR, this field is not something consistent/actual
// triggerPrice = this.omitZero (this.safeString (order, 'stopprice', triggerPrice));
var stopLossPrice interface{} = nil
var takeProfitPrice interface{} = nil
// the dashed strings are not provided from fields (eg. fetch order)
// while spaced strings from "order" sentence (when other fields not available)
if IsTrue(!IsEqual(rawType, nil)) {
if IsTrue(StartsWith(rawType, "take-profit")) {
takeProfitPrice = this.SafeString(description, "price")
price = this.OmitZero(this.SafeString(description, "price2"))
} else if IsTrue(StartsWith(rawType, "stop-loss")) {
stopLossPrice = this.SafeString(description, "price")
price = this.OmitZero(this.SafeString(description, "price2"))
} else if IsTrue(IsEqual(rawType, "take profit")) {
takeProfitPrice = triggerPrice
} else if IsTrue(IsEqual(rawType, "stop loss")) {
stopLossPrice = triggerPrice
}
}
var finalType interface{} = this.ParseOrderType(rawType)
// unlike from endpoints which provide eg: "take-profit-limit"
// for "space-delimited" orders we dont have market/limit suffixes, their format is
// eg: `stop loss > limit 123`, so we need to parse them manually
if IsTrue(this.InArray(finalType, []interface{}{"stop loss", "take profit"})) {
finalType = Ternary(IsTrue((IsEqual(price, nil))), "market", "limit")
}
var amendId interface{} = this.SafeString(order, "amend_id")
if IsTrue(!IsEqual(amendId, nil)) {
isPostOnly = nil
}
return this.SafeOrder(map[string]interface{} {
"id": id,
"clientOrderId": clientOrderId,
"info": order,
"timestamp": timestamp,
"datetime": this.Iso8601(timestamp),
"lastTradeTimestamp": nil,
"status": status,
"symbol": symbol,
"type": finalType,
"timeInForce": nil,
"postOnly": isPostOnly,
"side": side,
"price": price,
"triggerPrice": triggerPrice,
"takeProfitPrice": takeProfitPrice,
"stopLossPrice": stopLossPrice,
"cost": nil,
"amount": amount,
"filled": filled,
"average": average,
"remaining": nil,
"reduceOnly": this.SafeBool2(order, "reduceOnly", "reduce_only"),
"fee": fee,
"trades": trades,
}, market)
}
func (this *kraken) OrderRequest(method interface{}, symbol interface{}, typeVar interface{}, request interface{}, amount interface{}, optionalArgs ...interface{}) interface{} {
price := GetArg(optionalArgs, 0, nil)
_ = price
params := GetArg(optionalArgs, 1, map[string]interface{} {})
_ = params
var clientOrderId interface{} = this.SafeString(params, "clientOrderId")
params = this.Omit(params, []interface{}{"clientOrderId"})
if IsTrue(!IsEqual(clientOrderId, nil)) {
AddElementToObject(request, "cl_ord_id", clientOrderId)
}
var stopLossTriggerPrice interface{} = this.SafeString(params, "stopLossPrice")
var takeProfitTriggerPrice interface{} = this.SafeString(params, "takeProfitPrice")
var isStopLossTriggerOrder interface{} = !IsEqual(stopLossTriggerPrice, nil)
var isTakeProfitTriggerOrder interface{} = !IsEqual(takeProfitTriggerPrice, nil)
var isStopLossOrTakeProfitTrigger interface{} = IsTrue(isStopLossTriggerOrder) || IsTrue(isTakeProfitTriggerOrder)
var trailingAmount interface{} = this.SafeString(params, "trailingAmount")
var trailingPercent interface{} = this.SafeString(params, "trailingPercent")
var trailingLimitAmount interface{} = this.SafeString(params, "trailingLimitAmount")
var trailingLimitPercent interface{} = this.SafeString(params, "trailingLimitPercent")
var isTrailingAmountOrder interface{} = !IsEqual(trailingAmount, nil)
var isTrailingPercentOrder interface{} = !IsEqual(trailingPercent, nil)
var isLimitOrder interface{} = EndsWith(typeVar, "limit") // supporting limit, stop-loss-limit, take-profit-limit, etc
var isMarketOrder interface{} = IsEqual(typeVar, "market")
var cost interface{} = this.SafeString(params, "cost")
var flags interface{} = this.SafeString(params, "oflags")
params = this.Omit(params, []interface{}{"cost", "oflags"})
var isViqcOrder interface{} = IsTrue((!IsEqual(flags, nil))) && IsTrue((IsGreaterThan(GetIndexOf(flags, "viqc"), OpNeg(1)))) // volume in quote currency
if IsTrue(IsTrue(isMarketOrder) && IsTrue((IsTrue(!IsEqual(cost, nil)) || IsTrue(isViqcOrder)))) {
if IsTrue(IsTrue(IsEqual(cost, nil)) && IsTrue((!IsEqual(amount, nil)))) {
AddElementToObject(request, "volume", this.CostToPrecision(symbol, this.NumberToString(amount)))
} else {
AddElementToObject(request, "volume", this.CostToPrecision(symbol, cost))
}
var extendedOflags interface{} = Ternary(IsTrue((!IsEqual(flags, nil))), Add(flags, ",viqc"), "viqc")
AddElementToObject(request, "oflags", extendedOflags)
} else if IsTrue(IsTrue(IsTrue(isLimitOrder) && !IsTrue(isTrailingAmountOrder)) && !IsTrue(isTrailingPercentOrder)) {
AddElementToObject(request, "price", this.PriceToPrecision(symbol, price))
}
var reduceOnly interface{} = this.SafeBool2(params, "reduceOnly", "reduce_only")
if IsTrue(isStopLossOrTakeProfitTrigger) {
if IsTrue(isStopLossTriggerOrder) {
AddElementToObject(request, "price", this.PriceToPrecision(symbol, stopLossTriggerPrice))
if IsTrue(isLimitOrder) {
AddElementToObject(request, "ordertype", "stop-loss-limit")
} else {
AddElementToObject(request, "ordertype", "stop-loss")
}
} else if IsTrue(isTakeProfitTriggerOrder) {
AddElementToObject(request, "price", this.PriceToPrecision(symbol, takeProfitTriggerPrice))
if IsTrue(isLimitOrder) {
AddElementToObject(request, "ordertype", "take-profit-limit")
} else {
AddElementToObject(request, "ordertype", "take-profit")
}
}
if IsTrue(isLimitOrder) {
AddElementToObject(request, "price2", this.PriceToPrecision(symbol, price))
}
} else if IsTrue(IsTrue(isTrailingAmountOrder) || IsTrue(isTrailingPercentOrder)) {
var trailingPercentString interface{} = nil
if IsTrue(!IsEqual(trailingPercent, nil)) {
trailingPercentString = Ternary(IsTrue((EndsWith(trailingPercent, "%"))), (Add("+", trailingPercent)), (Add(Add("+", trailingPercent), "%")))
}
var trailingAmountString interface{} = Ternary(IsTrue((!IsEqual(trailingAmount, nil))), Add("+", trailingAmount), nil) // must use + for this
var offset interface{} = this.SafeString(params, "offset", "-") // can use + or - for this
var trailingLimitAmountString interface{} = Ternary(IsTrue((!IsEqual(trailingLimitAmount, nil))), Add(offset, this.NumberToString(trailingLimitAmount)), nil)
var trailingActivationPriceType interface{} = this.SafeString(params, "trigger", "last")
AddElementToObject(request, "trigger", trailingActivationPriceType)
if IsTrue(IsTrue(IsTrue(isLimitOrder) || IsTrue((!IsEqual(trailingLimitAmount, nil)))) || IsTrue((!IsEqual(trailingLimitPercent, nil)))) {
AddElementToObject(request, "ordertype", "trailing-stop-limit")
if IsTrue(!IsEqual(trailingLimitPercent, nil)) {
var trailingLimitPercentString interface{} = Ternary(IsTrue((EndsWith(trailingLimitPercent, "%"))), (Add(offset, trailingLimitPercent)), (Add(Add(offset, trailingLimitPercent), "%")))
AddElementToObject(request, "price", trailingPercentString)
AddElementToObject(request, "price2", trailingLimitPercentString)
} else if IsTrue(!IsEqual(trailingLimitAmount, nil)) {
AddElementToObject(request, "price", trailingAmountString)
AddElementToObject(request, "price2", trailingLimitAmountString)
}
} else {
AddElementToObject(request, "ordertype", "trailing-stop")
if IsTrue(!IsEqual(trailingPercent, nil)) {
AddElementToObject(request, "price", trailingPercentString)
} else {
AddElementToObject(request, "price", trailingAmountString)
}
}
}
if IsTrue(reduceOnly) {
if IsTrue(IsEqual(method, "createOrderWs")) {
AddElementToObject(request, "reduce_only", true) // ws request can't have stringified bool
} else {
AddElementToObject(request, "reduce_only", "true") // not using boolean in this case, because the urlencodedNested transforms it into 'True' string
}
}
var close interface{} = this.SafeDict(params, "close")
if IsTrue(!IsEqual(close, nil)) {
close = this.Extend(map[string]interface{} {}, close)
var closePrice interface{} = this.SafeValue(close, "price")
if IsTrue(!IsEqual(closePrice, nil)) {
AddElementToObject(close, "price", this.PriceToPrecision(symbol, closePrice))
}
var closePrice2 interface{} = this.SafeValue(close, "price2") // stopPrice
if IsTrue(!IsEqual(closePrice2, nil)) {
AddElementToObject(close, "price2", this.PriceToPrecision(symbol, closePrice2))
}
AddElementToObject(request, "close", close)
}
var timeInForce interface{} = this.SafeString2(params, "timeInForce", "timeinforce")
if IsTrue(!IsEqual(timeInForce, nil)) {
AddElementToObject(request, "timeinforce", timeInForce)
}
var isMarket interface{} = (IsEqual(typeVar, "market"))
var postOnly interface{} = nil
postOnlyparamsVariable := this.HandlePostOnly(isMarket, false, params);
postOnly = GetValue(postOnlyparamsVariable,0);
params = GetValue(postOnlyparamsVariable,1)
if IsTrue(postOnly) {
var extendedPostFlags interface{} = Ternary(IsTrue((!IsEqual(flags, nil))), Add(flags, ",post"), "post")
AddElementToObject(request, "oflags", extendedPostFlags)
}
if IsTrue(IsTrue((!IsEqual(flags, nil))) && !IsTrue((InOp(request, "oflags")))) {
AddElementToObject(request, "oflags", flags)
}
params = this.Omit(params, []interface{}{"timeInForce", "reduceOnly", "stopLossPrice", "takeProfitPrice", "trailingAmount", "trailingPercent", "trailingLimitAmount", "trailingLimitPercent", "offset"})
return []interface{}{request, params}
}
/**
* @method
* @name kraken#editOrder
* @description edit a trade order
* @see https://docs.kraken.com/api/docs/rest-api/amend-order
* @param {string} id order id
* @param {string} symbol unified symbol of the market to create an order in
* @param {string} type 'market' or 'limit'
* @param {string} side 'buy' or 'sell'
* @param {float} [amount] how much of the currency you want to trade in units of the base currency
* @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @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.trailingAmount] the quote amount to trail away from the current market price
* @param {string} [params.trailingPercent] the percent to trail away from the current market price
* @param {string} [params.trailingLimitAmount] the quote amount away from the trailingAmount
* @param {string} [params.trailingLimitPercent] the percent away from the trailingAmount
* @param {string} [params.offset] '+' or '-' whether you want the trailingLimitAmount value to be positive or negative
* @param {boolean} [params.postOnly] if true, the order will only be posted to the order book and not executed immediately
* @param {string} [params.clientOrderId] the orders client order id
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
*/
func (this *kraken) EditOrder(id interface{}, symbol interface{}, typeVar interface{}, side interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
amount := GetArg(optionalArgs, 0, nil)
_ = amount
price := GetArg(optionalArgs, 1, nil)
_ = price
params := GetArg(optionalArgs, 2, map[string]interface{} {})
_ = params
retRes20828 := (<-this.LoadMarkets())
PanicOnError(retRes20828)
var market interface{} = this.Market(symbol)
if !IsTrue(GetValue(market, "spot")) {
panic(NotSupported(Add(Add(Add(this.Id, " editOrder() does not support "), GetValue(market, "type")), " orders, only spot orders are accepted")))
}
var request interface{} = map[string]interface{} {
"txid": id,
}
var clientOrderId interface{} = this.SafeString2(params, "clientOrderId", "cl_ord_id")
if IsTrue(!IsEqual(clientOrderId, nil)) {
AddElementToObject(request, "cl_ord_id", clientOrderId)
params = this.Omit(params, []interface{}{"clientOrderId", "cl_ord_id"})
request = this.Omit(request, "txid")
}
var isMarket interface{} = (IsEqual(typeVar, "market"))
var postOnly interface{} = nil
postOnlyparamsVariable := this.HandlePostOnly(isMarket, false, params);
postOnly = GetValue(postOnlyparamsVariable,0);
params = GetValue(postOnlyparamsVariable,1)
if IsTrue(postOnly) {
AddElementToObject(request, "post_only", "true") // not using boolean in this case, because the urlencodedNested transforms it into 'True' string
}
if IsTrue(!IsEqual(amount, nil)) {
AddElementToObject(request, "order_qty", this.AmountToPrecision(symbol, amount))
}
if IsTrue(!IsEqual(price, nil)) {
AddElementToObject(request, "limit_price", this.PriceToPrecision(symbol, price))
}
var allTriggerPrices interface{} = this.SafeStringN(params, []interface{}{"stopLossPrice", "takeProfitPrice", "trailingAmount", "trailingPercent", "trailingLimitAmount", "trailingLimitPercent"})
if IsTrue(!IsEqual(allTriggerPrices, nil)) {
var offset interface{} = this.SafeString(params, "offset")
params = this.Omit(params, []interface{}{"stopLossPrice", "takeProfitPrice", "trailingAmount", "trailingPercent", "trailingLimitAmount", "trailingLimitPercent", "offset"})
if IsTrue(!IsEqual(offset, nil)) {
allTriggerPrices = Add(offset, allTriggerPrices)
AddElementToObject(request, "trigger_price", allTriggerPrices)
} else {
AddElementToObject(request, "trigger_price", this.PriceToPrecision(symbol, allTriggerPrices))
}
}
response:= (<-this.PrivatePostAmendOrder(this.Extend(request, params)))
PanicOnError(response)
//
// {
// "error": [],
// "result": {
// "amend_id": "TJSMEH-AA67V-YUSQ6O"
// }
// }
//
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
ch <- this.ParseOrder(result, market)
return nil
}()
return ch
}
/**
* @method
* @name kraken#fetchOrder
* @description fetches information on an order made by the user
* @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getOrdersInfo
* @param {string} id order id
* @param {string} symbol not used by kraken fetchOrder
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
*/
func (this *kraken) FetchOrder(id interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
symbol := GetArg(optionalArgs, 0, nil)
_ = symbol
params := GetArg(optionalArgs, 1, map[string]interface{} {})
_ = params
retRes21438 := (<-this.LoadMarkets())
PanicOnError(retRes21438)
var clientOrderId interface{} = this.SafeValue2(params, "userref", "clientOrderId")
var request interface{} = map[string]interface{} {
"trades": true,
"txid": id,
}
var query interface{} = params
if IsTrue(!IsEqual(clientOrderId, nil)) {
AddElementToObject(request, "userref", clientOrderId)
query = this.Omit(params, []interface{}{"userref", "clientOrderId"})
}
response:= (<-this.PrivatePostQueryOrders(this.Extend(request, query)))
PanicOnError(response)
//
// {
// "error":[],
// "result":{
// "OTLAS3-RRHUF-NDWH5A":{
// "refid":null,
// "userref":null,
// "status":"closed",
// "reason":null,
// "opentm":1586822919.3342,
// "closetm":1586822919.365,
// "starttm":0,
// "expiretm":0,
// "descr":{
// "pair":"XBTUSDT",
// "type":"sell",
// "ordertype":"market",
// "price":"0",
// "price2":"0",
// "leverage":"none",
// "order":"sell 0.21804000 XBTUSDT @ market",
// "close":""
// },
// "vol":"0.21804000",
// "vol_exec":"0.21804000",
// "cost":"1493.9",
// "fee":"3.8",
// "price":"6851.5",
// "stopprice":"0.00000",
// "limitprice":"0.00000",
// "misc":"",
// "oflags":"fciq",
// "trades":["TT5UC3-GOIRW-6AZZ6R"]
// }
// }
// }
//
var result interface{} = this.SafeValue(response, "result", []interface{}{})
if !IsTrue((InOp(result, id))) {
panic(OrderNotFound(Add(Add(this.Id, " fetchOrder() could not find order id "), id)))
}
ch <- this.ParseOrder(this.Extend(map[string]interface{} {
"id": id,
}, GetValue(result, id)))
return nil
}()
return ch
}
/**
* @method
* @name kraken#fetchOrderTrades
* @description fetch all the trades made from a single order
* @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getTradesInfo
* @param {string} id order id
* @param {string} symbol unified market symbol
* @param {int} [since] the earliest time in ms to fetch trades for
* @param {int} [limit] the maximum number of trades to retrieve
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
*/
func (this *kraken) FetchOrderTrades(id interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
symbol := GetArg(optionalArgs, 0, nil)
_ = symbol
since := GetArg(optionalArgs, 1, nil)
_ = since
limit := GetArg(optionalArgs, 2, nil)
_ = limit
params := GetArg(optionalArgs, 3, map[string]interface{} {})
_ = params
var orderTrades interface{} = this.SafeValue(params, "trades")
var tradeIds interface{} = []interface{}{}
if IsTrue(IsEqual(orderTrades, nil)) {
panic(ArgumentsRequired(Add(this.Id, " fetchOrderTrades() requires a unified order structure in the params argument or a \\'trades\\' param (an array of trade id strings)")))
} else {
for i := 0; IsLessThan(i, GetArrayLength(orderTrades)); i++ {
var orderTrade interface{} = GetValue(orderTrades, i)
if IsTrue(IsString(orderTrade)) {
AppendToArray(&tradeIds,orderTrade)
} else {
AppendToArray(&tradeIds,GetValue(orderTrade, "id"))
}
}
}
retRes22278 := (<-this.LoadMarkets())
PanicOnError(retRes22278)
if IsTrue(!IsEqual(symbol, nil)) {
symbol = this.Symbol(symbol)
}
var options interface{} = this.SafeValue(this.Options, "fetchOrderTrades", map[string]interface{} {})
var batchSize interface{} = this.SafeInteger(options, "batchSize", 20)
var numTradeIds interface{} = GetArrayLength(tradeIds)
var numBatches interface{} = this.ParseToInt(Divide(numTradeIds, batchSize))
numBatches = this.Sum(numBatches, 1)
var result interface{} = []interface{}{}
for j := 0; IsLessThan(j, numBatches); j++ {
var requestIds interface{} = []interface{}{}
for k := 0; IsLessThan(k, batchSize); k++ {
var index interface{} = this.Sum(Multiply(j, batchSize), k)
if IsTrue(IsLessThan(index, numTradeIds)) {
AppendToArray(&requestIds,GetValue(tradeIds, index))
}
}
var request interface{} = map[string]interface{} {
"txid": Join(requestIds, ","),
}
response:= (<-this.PrivatePostQueryTrades(request))
PanicOnError(response)
//
// {
// "error": [],
// "result": {
// 'TIMIRG-WUNNE-RRJ6GT': {
// "ordertxid": 'OQRPN2-LRHFY-HIFA7D',
// "postxid": 'TKH2SE-M7IF5-CFI7LT',
// "pair": 'USDCUSDT',
// "time": 1586340086.457,
// "type": 'sell',
// "ordertype": 'market',
// "price": '0.99860000',
// "cost": '22.16892001',
// "fee": '0.04433784',
// "vol": '22.20000000',
// "margin": '0.00000000',
// "misc": ''
// }
// }
// }
//
var rawTrades interface{} = this.SafeValue(response, "result")
var ids interface{} = ObjectKeys(rawTrades)
for i := 0; IsLessThan(i, GetArrayLength(ids)); i++ {
AddElementToObject(GetValue(rawTrades, GetValue(ids, i)), "id", GetValue(ids, i))
}
var trades interface{} = this.ParseTrades(rawTrades, nil, since, limit)
var tradesFilteredBySymbol interface{} = this.FilterBySymbol(trades, symbol)
result = this.ArrayConcat(result, tradesFilteredBySymbol)
}
ch <- result
return nil
}()
return ch
}
/**
* @method
* @name kraken#fetchOrdersByIds
* @description fetch orders by the list of order id
* @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getClosedOrders
* @param {string[]} [ids] list of order id
* @param {string} [symbol] unified ccxt market symbol
* @param {object} [params] extra parameters specific to the kraken api endpoint
* @returns {object[]} a list of [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
*/
func (this *kraken) FetchOrdersByIds(ids interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
symbol := GetArg(optionalArgs, 0, nil)
_ = symbol
params := GetArg(optionalArgs, 1, map[string]interface{} {})
_ = params
retRes22938 := (<-this.LoadMarkets())
PanicOnError(retRes22938)
response:= (<-this.PrivatePostQueryOrders(this.Extend(map[string]interface{} {
"trades": true,
"txid": Join(ids, ","),
}, params)))
PanicOnError(response)
var result interface{} = this.SafeValue(response, "result", map[string]interface{} {})
var orders interface{} = []interface{}{}
var orderIds interface{} = ObjectKeys(result)
for i := 0; IsLessThan(i, GetArrayLength(orderIds)); i++ {
var id interface{} = GetValue(orderIds, i)
var item interface{} = GetValue(result, id)
var order interface{} = this.ParseOrder(this.Extend(map[string]interface{} {
"id": id,
}, item))
AppendToArray(&orders,order)
}
ch <- orders
return nil
}()
return ch
}
/**
* @method
* @name kraken#fetchMyTrades
* @description fetch all trades made by the user
* @see https://docs.kraken.com/api/docs/rest-api/get-trade-history
* @param {string} symbol unified market symbol
* @param {int} [since] 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] timestamp in ms of the latest trade entry
* @param {int} [params.end] timestamp in seconds of the latest trade entry
* @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure}
*/
func (this *kraken) FetchMyTrades(optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
symbol := GetArg(optionalArgs, 0, nil)
_ = symbol
since := GetArg(optionalArgs, 1, nil)
_ = since
limit := GetArg(optionalArgs, 2, nil)
_ = limit
params := GetArg(optionalArgs, 3, map[string]interface{} {})
_ = params
retRes23248 := (<-this.LoadMarkets())
PanicOnError(retRes23248)
var request interface{} = map[string]interface{} {}
if IsTrue(!IsEqual(since, nil)) {
AddElementToObject(request, "start", this.ParseToInt(Divide(since, 1000)))
}
var until interface{} = this.SafeStringN(params, []interface{}{"until", "till"})
if IsTrue(!IsEqual(until, nil)) {
params = this.Omit(params, []interface{}{"until", "till"})
var untilDivided interface{} = Precise.StringDiv(until, "1000")
AddElementToObject(request, "end", this.ParseToInt(Precise.StringAdd(untilDivided, "1")))
}
response:= (<-this.PrivatePostTradesHistory(this.Extend(request, params)))
PanicOnError(response)
//
// {
// "error": [],
// "result": {
// "trades": {
// "GJ3NYQ-XJRTF-THZABF": {
// "ordertxid": "TKH2SE-ZIF5E-CFI7LT",
// "postxid": "OEN3VX-M7IF5-JNBJAM",
// "pair": "XICNXETH",
// "time": 1527213229.4491,
// "type": "sell",
// "ordertype": "limit",
// "price": "0.001612",
// "cost": "0.025792",
// "fee": "0.000026",
// "vol": "16.00000000",
// "margin": "0.000000",
// "leverage": "5",
// "misc": ""
// "trade_id": 68230622,
// "maker": false
// },
// ...
// },
// "count": 9760,
// },
// }
//
var trades interface{} = GetValue(GetValue(response, "result"), "trades")
var ids interface{} = ObjectKeys(trades)
for i := 0; IsLessThan(i, GetArrayLength(ids)); i++ {
AddElementToObject(GetValue(trades, GetValue(ids, i)), "id", GetValue(ids, i))
}
var market interface{} = nil
if IsTrue(!IsEqual(symbol, nil)) {
market = this.Market(symbol)
}
ch <- this.ParseTrades(trades, market, since, limit)
return nil
}()
return ch
}
/**
* @method
* @name kraken#cancelOrder
* @description cancels an open order
* @see https://docs.kraken.com/api/docs/rest-api/cancel-order
* @param {string} id order id
* @param {string} [symbol] unified symbol of the market the order was made in
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {string} [params.clientOrderId] the orders client order id
* @param {int} [params.userref] the orders user reference id
* @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure}
*/
func (this *kraken) CancelOrder(id interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
symbol := GetArg(optionalArgs, 0, nil)
_ = symbol
params := GetArg(optionalArgs, 1, map[string]interface{} {})
_ = params
retRes23958 := (<-this.LoadMarkets())
PanicOnError(retRes23958)
var response interface{} = nil
var requestId interface{} = this.SafeValue(params, "userref", id) // string or integer
params = this.Omit(params, "userref")
var request interface{} = map[string]interface{} {
"txid": requestId,
}
var clientOrderId interface{} = this.SafeString2(params, "clientOrderId", "cl_ord_id")
if IsTrue(!IsEqual(clientOrderId, nil)) {
AddElementToObject(request, "cl_ord_id", clientOrderId)
params = this.Omit(params, []interface{}{"clientOrderId", "cl_ord_id"})
request = this.Omit(request, "txid")
}
{ ret__ := func(this *kraken) (ret_ interface{}) {
defer func() {
if e := recover(); e != nil {
if e == "break" {
return
}
ret_ = func(this *kraken) interface{} {
// catch block:
if IsTrue(this.Last_http_response) {
if IsTrue(IsGreaterThanOrEqual(GetIndexOf(this.Last_http_response, "EOrder:Unknown order"), 0)) {
panic(OrderNotFound(Add(Add(this.Id, " cancelOrder() error "), this.Last_http_response)))
}
}
panic(e)
return nil
}(this)
}
}()
// try block:
response = (<-this.PrivatePostCancelOrder(this.Extend(request, params)))
PanicOnError(response)
return nil
}(this)
if ret__ != nil {
return ret__
}
}
ch <- this.SafeOrder(map[string]interface{} {
"info": response,
})
return nil
}()
return ch
}
/**
* @method
* @name kraken#cancelOrders
* @description cancel multiple orders
* @see https://docs.kraken.com/rest/#tag/Spot-Trading/operation/cancelOrderBatch
* @param {string[]} ids open orders transaction ID (txid) or user reference (userref)
* @param {string} symbol unified market symbol
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} an list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
*/
func (this *kraken) CancelOrders(ids interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
symbol := GetArg(optionalArgs, 0, nil)
_ = symbol
params := GetArg(optionalArgs, 1, map[string]interface{} {})
_ = params
var request interface{} = map[string]interface{} {
"orders": ids,
}
response:= (<-this.PrivatePostCancelOrderBatch(this.Extend(request, params)))
PanicOnError(response)
//
// {
// "error": [],
// "result": {
// "count": 2
// }
// }
//
ch <- []interface{}{this.SafeOrder(map[string]interface{} {
"info": response,
})}
return nil
}()
return ch
}
/**
* @method
* @name kraken#cancelAllOrders
* @description cancel all open orders
* @see https://docs.kraken.com/rest/#tag/Spot-Trading/operation/cancelAllOrders
* @param {string} symbol unified market symbol, only orders in the market of this symbol are cancelled when symbol is not undefined
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
*/
func (this *kraken) CancelAllOrders(optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
symbol := GetArg(optionalArgs, 0, nil)
_ = symbol
params := GetArg(optionalArgs, 1, map[string]interface{} {})
_ = params
retRes24718 := (<-this.LoadMarkets())
PanicOnError(retRes24718)
response:= (<-this.PrivatePostCancelAll(params))
PanicOnError(response)
//
// {
// error: [],
// result: {
// count: '1'
// }
// }
//
ch <- []interface{}{this.SafeOrder(map[string]interface{} {
"info": response,
})}
return nil
}()
return ch
}
/**
* @method
* @name kraken#cancelAllOrdersAfter
* @description dead man's switch, cancel all orders after the given timeout
* @see https://docs.kraken.com/rest/#tag/Spot-Trading/operation/cancelAllOrdersAfter
* @param {number} timeout time in milliseconds, 0 represents cancel the timer
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} the api result
*/
func (this *kraken) CancelAllOrdersAfter(timeout interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
params := GetArg(optionalArgs, 0, map[string]interface{} {})
_ = params
if IsTrue(IsGreaterThan(timeout, 86400000)) {
panic(BadRequest(Add(this.Id, " cancelAllOrdersAfter timeout should be less than 86400000 milliseconds")))
}
retRes25018 := (<-this.LoadMarkets())
PanicOnError(retRes25018)
var request interface{} = map[string]interface{} {
"timeout": Ternary(IsTrue((IsGreaterThan(timeout, 0))), (this.ParseToInt(Divide(timeout, 1000))), 0),
}
response:= (<-this.PrivatePostCancelAllOrdersAfter(this.Extend(request, params)))
PanicOnError(response)
//
// {
// "error": [ ],
// "result": {
// "currentTime": "2023-03-24T17:41:56Z",
// "triggerTime": "2023-03-24T17:42:56Z"
// }
// }
//
ch <- response
return nil
}()
return ch
}
/**
* @method
* @name kraken#fetchOpenOrders
* @description fetch all unfilled currently open orders
* @see https://docs.kraken.com/api/docs/rest-api/get-open-orders
* @param {string} [symbol] unified market symbol
* @param {int} [since] the earliest time in ms to fetch open orders for
* @param {int} [limit] the maximum number of open orders structures to retrieve
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {string} [params.clientOrderId] the orders client order id
* @param {int} [params.userref] the orders user reference id
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
*/
func (this *kraken) FetchOpenOrders(optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
symbol := GetArg(optionalArgs, 0, nil)
_ = symbol
since := GetArg(optionalArgs, 1, nil)
_ = since
limit := GetArg(optionalArgs, 2, nil)
_ = limit
params := GetArg(optionalArgs, 3, map[string]interface{} {})
_ = params
retRes25328 := (<-this.LoadMarkets())
PanicOnError(retRes25328)
var request interface{} = map[string]interface{} {}
if IsTrue(!IsEqual(since, nil)) {
AddElementToObject(request, "start", this.ParseToInt(Divide(since, 1000)))
}
var userref interface{} = this.SafeInteger(params, "userref")
if IsTrue(!IsEqual(userref, nil)) {
AddElementToObject(request, "userref", userref)
params = this.Omit(params, "userref")
}
var clientOrderId interface{} = this.SafeString(params, "clientOrderId")
if IsTrue(!IsEqual(clientOrderId, nil)) {
AddElementToObject(request, "cl_ord_id", clientOrderId)
params = this.Omit(params, "clientOrderId")
}
response:= (<-this.PrivatePostOpenOrders(this.Extend(request, params)))
PanicOnError(response)
//
// {
// "error": [],
// "result": {
// "open": {
// "O45M52-BFD5S-YXKQOU": {
// "refid": null,
// "userref": null,
// "cl_ord_id": "1234",
// "status": "open",
// "opentm": 1733815269.370054,
// "starttm": 0,
// "expiretm": 0,
// "descr": {
// "pair": "XBTUSD",
// "type": "buy",
// "ordertype": "limit",
// "price": "70000.0",
// "price2": "0",
// "leverage": "none",
// "order": "buy 0.00010000 XBTUSD @ limit 70000.0",
// "close": ""
// },
// "vol": "0.00010000",
// "vol_exec": "0.00000000",
// "cost": "0.00000",
// "fee": "0.00000",
// "price": "0.00000",
// "stopprice": "0.00000",
// "limitprice": "0.00000",
// "misc": "",
// "oflags": "fciq"
// }
// }
// }
// }
//
var market interface{} = nil
if IsTrue(!IsEqual(symbol, nil)) {
market = this.Market(symbol)
}
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
var open interface{} = this.SafeDict(result, "open", map[string]interface{} {})
var orders interface{} = []interface{}{}
var orderIds interface{} = ObjectKeys(open)
for i := 0; IsLessThan(i, GetArrayLength(orderIds)); i++ {
var id interface{} = GetValue(orderIds, i)
var item interface{} = GetValue(open, id)
AppendToArray(&orders,this.Extend(map[string]interface{} {
"id": id,
}, item))
}
ch <- this.ParseOrders(orders, market, since, limit)
return nil
}()
return ch
}
/**
* @method
* @name kraken#fetchClosedOrders
* @description fetches information on multiple closed orders made by the user
* @see https://docs.kraken.com/api/docs/rest-api/get-closed-orders
* @param {string} [symbol] unified market symbol of the market orders were made in
* @param {int} [since] the earliest time in ms to fetch orders for
* @param {int} [limit] the maximum number of order structures to retrieve
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {int} [params.until] timestamp in ms of the latest entry
* @param {string} [params.clientOrderId] the orders client order id
* @param {int} [params.userref] the orders user reference id
* @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure}
*/
func (this *kraken) FetchClosedOrders(optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
symbol := GetArg(optionalArgs, 0, nil)
_ = symbol
since := GetArg(optionalArgs, 1, nil)
_ = since
limit := GetArg(optionalArgs, 2, nil)
_ = limit
params := GetArg(optionalArgs, 3, map[string]interface{} {})
_ = params
retRes26168 := (<-this.LoadMarkets())
PanicOnError(retRes26168)
var request interface{} = map[string]interface{} {}
if IsTrue(!IsEqual(since, nil)) {
AddElementToObject(request, "start", this.ParseToInt(Divide(since, 1000)))
}
var userref interface{} = this.SafeInteger(params, "userref")
if IsTrue(!IsEqual(userref, nil)) {
AddElementToObject(request, "userref", userref)
params = this.Omit(params, "userref")
}
var clientOrderId interface{} = this.SafeString(params, "clientOrderId")
if IsTrue(!IsEqual(clientOrderId, nil)) {
AddElementToObject(request, "cl_ord_id", clientOrderId)
params = this.Omit(params, "clientOrderId")
}
requestparamsVariable := this.HandleUntilOption("end", request, params);
request = GetValue(requestparamsVariable,0);
params = GetValue(requestparamsVariable,1)
response:= (<-this.PrivatePostClosedOrders(this.Extend(request, params)))
PanicOnError(response)
//
// {
// "error":[],
// "result":{
// "closed":{
// "OETZYO-UL524-QJMXCT":{
// "refid":null,
// "userref":null,
// "status":"canceled",
// "reason":"User requested",
// "opentm":1601489313.3898,
// "closetm":1601489346.5507,
// "starttm":0,
// "expiretm":0,
// "descr":{
// "pair":"ETHUSDT",
// "type":"buy",
// "ordertype":"limit",
// "price":"330.00",
// "price2":"0",
// "leverage":"none",
// "order":"buy 0.02100000 ETHUSDT @ limit 330.00",
// "close":""
// },
// "vol":"0.02100000",
// "vol_exec":"0.00000000",
// "cost":"0.00000",
// "fee":"0.00000",
// "price":"0.00000",
// "stopprice":"0.00000",
// "limitprice":"0.00000",
// "misc":"",
// "oflags":"fciq"
// },
// },
// "count":16
// }
// }
//
var market interface{} = nil
if IsTrue(!IsEqual(symbol, nil)) {
market = this.Market(symbol)
}
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
var closed interface{} = this.SafeDict(result, "closed", map[string]interface{} {})
var orders interface{} = []interface{}{}
var orderIds interface{} = ObjectKeys(closed)
for i := 0; IsLessThan(i, GetArrayLength(orderIds)); i++ {
var id interface{} = GetValue(orderIds, i)
var item interface{} = GetValue(closed, id)
AppendToArray(&orders,this.Extend(map[string]interface{} {
"id": id,
}, item))
}
ch <- this.ParseOrders(orders, market, since, limit)
return nil
}()
return ch
}
func (this *kraken) ParseTransactionStatus(status interface{}) interface{} {
// IFEX transaction states
var statuses interface{} = map[string]interface{} {
"Initial": "pending",
"Pending": "pending",
"Success": "ok",
"Settled": "pending",
"Failure": "failed",
"Partial": "ok",
}
return this.SafeString(statuses, status, status)
}
func (this *kraken) ParseNetwork(network interface{}) interface{} {
var withdrawMethods interface{} = this.SafeValue(this.Options, "withdrawMethods", map[string]interface{} {})
return this.SafeString(withdrawMethods, network, network)
}
func (this *kraken) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} {
//
// fetchDeposits
//
// {
// "method": "Ether (Hex)",
// "aclass": "currency",
// "asset": "XETH",
// "refid": "Q2CANKL-LBFVEE-U4Y2WQ",
// "txid": "0x57fd704dab1a73c20e24c8696099b695d596924b401b261513cfdab23…",
// "info": "0x615f9ba7a9575b0ab4d571b2b36b1b324bd83290",
// "amount": "7.9999257900",
// "fee": "0.0000000000",
// "time": 1529223212,
// "status": "Success"
// }
//
// there can be an additional 'status-prop' field present
// deposit pending review by exchange => 'on-hold'
// the deposit is initiated by the exchange => 'return'
//
// {
// "type": 'deposit',
// "method": 'Fidor Bank AG (Wire Transfer)',
// "aclass": 'currency',
// "asset": 'ZEUR',
// "refid": 'xxx-xxx-xxx',
// "txid": '12341234',
// "info": 'BANKCODEXXX',
// "amount": '38769.08',
// "fee": '0.0000',
// "time": 1644306552,
// "status": 'Success',
// status-prop: 'on-hold'
// }
//
//
// fetchWithdrawals
//
// {
// "method": "Ether",
// "aclass": "currency",
// "asset": "XETH",
// "refid": "A2BF34S-O7LBNQ-UE4Y4O",
// "txid": "0x288b83c6b0904d8400ef44e1c9e2187b5c8f7ea3d838222d53f701a15b5c274d",
// "info": "0x7cb275a5e07ba943fee972e165d80daa67cb2dd0",
// "amount": "9.9950000000",
// "fee": "0.0050000000",
// "time": 1530481750,
// "status": "Success"
// "key":"Huobi wallet",
// "network":"Tron"
// status-prop: 'on-hold' // this field might not be present in some cases
// }
//
// withdraw
//
// {
// "refid": "AGBSO6T-UFMTTQ-I7KGS6"
// }
//
currency := GetArg(optionalArgs, 0, nil)
_ = currency
var id interface{} = this.SafeString(transaction, "refid")
var txid interface{} = this.SafeString(transaction, "txid")
var timestamp interface{} = this.SafeTimestamp(transaction, "time")
var currencyId interface{} = this.SafeString(transaction, "asset")
var code interface{} = this.SafeCurrencyCode(currencyId, currency)
var address interface{} = this.SafeString(transaction, "info")
var amount interface{} = this.SafeNumber(transaction, "amount")
var status interface{} = this.ParseTransactionStatus(this.SafeString(transaction, "status"))
var statusProp interface{} = this.SafeString(transaction, "status-prop")
var isOnHoldDeposit interface{} = IsEqual(statusProp, "on-hold")
var isCancellationRequest interface{} = IsEqual(statusProp, "cancel-pending")
var isOnHoldWithdrawal interface{} = IsEqual(statusProp, "onhold")
if IsTrue(IsTrue(IsTrue(isOnHoldDeposit) || IsTrue(isCancellationRequest)) || IsTrue(isOnHoldWithdrawal)) {
status = "pending"
}
var typeVar interface{} = this.SafeString(transaction, "type") // injected from the outside
var feeCost interface{} = this.SafeNumber(transaction, "fee")
if IsTrue(IsEqual(feeCost, nil)) {
if IsTrue(IsEqual(typeVar, "deposit")) {
feeCost = 0
}
}
return map[string]interface{} {
"info": transaction,
"id": id,
"currency": code,
"amount": amount,
"network": this.ParseNetwork(this.SafeString(transaction, "network")),
"address": address,
"addressTo": nil,
"addressFrom": nil,
"tag": nil,
"tagTo": nil,
"tagFrom": nil,
"status": status,
"type": typeVar,
"updated": nil,
"txid": txid,
"timestamp": timestamp,
"datetime": this.Iso8601(timestamp),
"comment": nil,
"internal": nil,
"fee": map[string]interface{} {
"currency": code,
"cost": feeCost,
},
}
}
func (this *kraken) ParseTransactionsByType(typeVar interface{}, transactions interface{}, optionalArgs ...interface{}) interface{} {
code := GetArg(optionalArgs, 0, nil)
_ = code
since := GetArg(optionalArgs, 1, nil)
_ = since
limit := GetArg(optionalArgs, 2, nil)
_ = limit
var result interface{} = []interface{}{}
for i := 0; IsLessThan(i, GetArrayLength(transactions)); i++ {
var transaction interface{} = this.ParseTransaction(this.Extend(map[string]interface{} {
"type": typeVar,
}, GetValue(transactions, i)))
AppendToArray(&result,transaction)
}
return this.FilterByCurrencySinceLimit(result, code, since, limit)
}
/**
* @method
* @name kraken#fetchDeposits
* @description fetch all deposits made to an account
* @see https://docs.kraken.com/rest/#tag/Funding/operation/getStatusRecentDeposits
* @param {string} code unified currency code
* @param {int} [since] the earliest time in ms to fetch deposits for
* @param {int} [limit] the maximum number of deposits structures to retrieve
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {int} [params.until] timestamp in ms of the latest transaction entry
* @param {int} [params.end] timestamp in seconds of the latest transaction entry
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
*/
func (this *kraken) FetchDeposits(optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
// https://www.kraken.com/en-us/help/api#deposit-status
code := GetArg(optionalArgs, 0, nil)
_ = code
since := GetArg(optionalArgs, 1, nil)
_ = since
limit := GetArg(optionalArgs, 2, nil)
_ = limit
params := GetArg(optionalArgs, 3, map[string]interface{} {})
_ = params
retRes28428 := (<-this.LoadMarkets())
PanicOnError(retRes28428)
var request interface{} = map[string]interface{} {}
if IsTrue(!IsEqual(code, nil)) {
var currency interface{} = this.Currency(code)
AddElementToObject(request, "asset", GetValue(currency, "id"))
}
if IsTrue(!IsEqual(since, nil)) {
var sinceString interface{} = this.NumberToString(since)
AddElementToObject(request, "start", Precise.StringDiv(sinceString, "1000"))
}
var until interface{} = this.SafeStringN(params, []interface{}{"until", "till"})
if IsTrue(!IsEqual(until, nil)) {
params = this.Omit(params, []interface{}{"until", "till"})
var untilDivided interface{} = Precise.StringDiv(until, "1000")
AddElementToObject(request, "end", Precise.StringAdd(untilDivided, "1"))
}
response:= (<-this.PrivatePostDepositStatus(this.Extend(request, params)))
PanicOnError(response)
//
// { error: [],
// "result": [ { "method": "Ether (Hex)",
// "aclass": "currency",
// "asset": "XETH",
// "refid": "Q2CANKL-LBFVEE-U4Y2WQ",
// "txid": "0x57fd704dab1a73c20e24c8696099b695d596924b401b261513cfdab23…",
// "info": "0x615f9ba7a9575b0ab4d571b2b36b1b324bd83290",
// "amount": "7.9999257900",
// "fee": "0.0000000000",
// "time": 1529223212,
// "status": "Success" } ] }
//
ch <- this.ParseTransactionsByType("deposit", GetValue(response, "result"), code, since, limit)
return nil
}()
return ch
}
/**
* @method
* @name kraken#fetchTime
* @description fetches the current integer timestamp in milliseconds from the exchange server
* @see https://docs.kraken.com/rest/#tag/Spot-Market-Data/operation/getServerTime
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {int} the current integer timestamp in milliseconds from the exchange server
*/
func (this *kraken) FetchTime(optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
// https://www.kraken.com/en-us/features/api#get-server-time
params := GetArg(optionalArgs, 0, map[string]interface{} {})
_ = params
response:= (<-this.PublicGetTime(params))
PanicOnError(response)
//
// {
// "error": [],
// "result": {
// "unixtime": 1591502873,
// "rfc1123": "Sun, 7 Jun 20 04:07:53 +0000"
// }
// }
//
var result interface{} = this.SafeValue(response, "result", map[string]interface{} {})
ch <- this.SafeTimestamp(result, "unixtime")
return nil
}()
return ch
}
/**
* @method
* @name kraken#fetchWithdrawals
* @description fetch all withdrawals made from an account
* @see https://docs.kraken.com/rest/#tag/Funding/operation/getStatusRecentWithdrawals
* @param {string} code unified currency code
* @param {int} [since] the earliest time in ms to fetch withdrawals for
* @param {int} [limit] the maximum number of withdrawals structures to retrieve
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @param {int} [params.until] timestamp in ms of the latest transaction entry
* @param {int} [params.end] timestamp in seconds of the latest transaction entry
* @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times
* @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure}
*/
func (this *kraken) FetchWithdrawals(optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
code := GetArg(optionalArgs, 0, nil)
_ = code
since := GetArg(optionalArgs, 1, nil)
_ = since
limit := GetArg(optionalArgs, 2, nil)
_ = limit
params := GetArg(optionalArgs, 3, map[string]interface{} {})
_ = params
retRes29148 := (<-this.LoadMarkets())
PanicOnError(retRes29148)
var paginate interface{} = false
paginateparamsVariable := this.HandleOptionAndParams(params, "fetchWithdrawals", "paginate");
paginate = GetValue(paginateparamsVariable,0);
params = GetValue(paginateparamsVariable,1)
if IsTrue(paginate) {
AddElementToObject(params, "cursor", true)
retRes291919 := (<-this.FetchPaginatedCallCursor("fetchWithdrawals", code, since, limit, params, "next_cursor", "cursor"))
PanicOnError(retRes291919)
ch <- retRes291919
return nil
}
var request interface{} = map[string]interface{} {}
if IsTrue(!IsEqual(code, nil)) {
var currency interface{} = this.Currency(code)
AddElementToObject(request, "asset", GetValue(currency, "id"))
}
if IsTrue(!IsEqual(since, nil)) {
var sinceString interface{} = this.NumberToString(since)
AddElementToObject(request, "start", Precise.StringDiv(sinceString, "1000"))
}
var until interface{} = this.SafeStringN(params, []interface{}{"until", "till"})
if IsTrue(!IsEqual(until, nil)) {
params = this.Omit(params, []interface{}{"until", "till"})
var untilDivided interface{} = Precise.StringDiv(until, "1000")
AddElementToObject(request, "end", Precise.StringAdd(untilDivided, "1"))
}
response:= (<-this.PrivatePostWithdrawStatus(this.Extend(request, params)))
PanicOnError(response)
//
// with no pagination
// { error: [],
// "result": [ { "method": "Ether",
// "aclass": "currency",
// "asset": "XETH",
// "refid": "A2BF34S-O7LBNQ-UE4Y4O",
// "txid": "0x298c83c7b0904d8400ef43e1c9e2287b518f7ea3d838822d53f704a1565c274d",
// "info": "0x7cb275a5e07ba943fee972e165d80daa67cb2dd0",
// "amount": "9.9950000000",
// "fee": "0.0050000000",
// "time": 1530481750,
// "status": "Success" } ] }
// with pagination
// {
// "error":[],
// "result":{
// "withdrawals":[
// {
// "method":"Tether USD (TRC20)",
// "aclass":"currency",
// "asset":"USDT",
// "refid":"BSNFZU2-MEFN4G-J3NEZV",
// "txid":"1c7a642fb7387bbc2c6a2c509fd1ae146937f4cf793b4079a4f0715e3a02615a",
// "info":"TQmdxSuC16EhFg8FZWtYgrfFRosoRF7bCp",
// "amount":"1996.50000000",
// "fee":"2.50000000",
// "time":1669126657,
// "status":"Success",
// "key":"poloniex",
// "network":"Tron"
// },
// ...
// ],
// "next_cursor":"HgAAAAAAAABGVFRSd3k1LVF4Y0JQY05Gd0xRY0NxenFndHpybkwBAQH2AwEBAAAAAQAAAAAAAAABAAAAAAAZAAAAAAAAAA=="
// }
// }
//
var rawWithdrawals interface{} = nil
var result interface{} = this.SafeValue(response, "result")
if !IsTrue(IsArray(result)) {
rawWithdrawals = this.AddPaginationCursorToResult(result)
} else {
rawWithdrawals = result
}
ch <- this.ParseTransactionsByType("withdrawal", rawWithdrawals, code, since, limit)
return nil
}()
return ch
}
func (this *kraken) AddPaginationCursorToResult(result interface{}) interface{} {
var cursor interface{} = this.SafeString(result, "next_cursor")
var data interface{} = this.SafeValue(result, "withdrawals")
var dataLength interface{} = GetArrayLength(data)
if IsTrue(IsTrue(!IsEqual(cursor, nil)) && IsTrue(IsGreaterThan(dataLength, 0))) {
var last interface{} = GetValue(data, Subtract(dataLength, 1))
AddElementToObject(last, "next_cursor", cursor)
AddElementToObject(data, Subtract(dataLength, 1), last)
}
return data
}
/**
* @method
* @name kraken#createDepositAddress
* @description create a currency deposit address
* @see https://docs.kraken.com/rest/#tag/Funding/operation/getDepositAddresses
* @param {string} code unified currency code of the currency for the deposit address
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
*/
func (this *kraken) CreateDepositAddress(code interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
params := GetArg(optionalArgs, 0, map[string]interface{} {})
_ = params
var request interface{} = map[string]interface{} {
"new": "true",
}
retRes301015 := (<-this.FetchDepositAddress(code, this.Extend(request, params)))
PanicOnError(retRes301015)
ch <- retRes301015
return nil
}()
return ch
}
/**
* @method
* @name kraken#fetchDepositMethods
* @description fetch deposit methods for a currency associated with this account
* @see https://docs.kraken.com/rest/#tag/Funding/operation/getDepositMethods
* @param {string} code unified currency code
* @param {object} [params] extra parameters specific to the kraken api endpoint
* @returns {object} of deposit methods
*/
func (this *kraken) FetchDepositMethods(code interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
params := GetArg(optionalArgs, 0, map[string]interface{} {})
_ = params
retRes30238 := (<-this.LoadMarkets())
PanicOnError(retRes30238)
var currency interface{} = this.Currency(code)
var request interface{} = map[string]interface{} {
"asset": GetValue(currency, "id"),
}
response:= (<-this.PrivatePostDepositMethods(this.Extend(request, params)))
PanicOnError(response)
//
// {
// "error":[],
// "result":[
// {"method":"Ether (Hex)","limit":false,"gen-address":true}
// ]
// }
//
// {
// "error":[],
// "result":[
// {"method":"Tether USD (ERC20)","limit":false,"address-setup-fee":"0.00000000","gen-address":true},
// {"method":"Tether USD (TRC20)","limit":false,"address-setup-fee":"0.00000000","gen-address":true}
// ]
// }
//
// {
// "error":[],
// "result":[
// {"method":"Bitcoin","limit":false,"fee":"0.0000000000","gen-address":true}
// ]
// }
//
ch <- this.SafeValue(response, "result")
return nil
}()
return ch
}
/**
* @method
* @name kraken#fetchDepositAddress
* @description fetch the deposit address for a currency associated with this account
* @see https://docs.kraken.com/rest/#tag/Funding/operation/getDepositAddresses
* @param {string} code unified currency code
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure}
*/
func (this *kraken) FetchDepositAddress(code interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
params := GetArg(optionalArgs, 0, map[string]interface{} {})
_ = params
retRes30658 := (<-this.LoadMarkets())
PanicOnError(retRes30658)
var currency interface{} = this.Currency(code)
var network interface{} = this.SafeStringUpper(params, "network")
var networks interface{} = this.SafeValue(this.Options, "networks", map[string]interface{} {})
network = this.SafeString(networks, network, network) // support ETH > ERC20 aliases
params = this.Omit(params, "network")
if IsTrue(IsTrue((IsEqual(code, "USDT"))) && IsTrue((IsEqual(network, "TRC20")))) {
code = Add(Add(code, "-"), network)
}
var defaultDepositMethods interface{} = this.SafeValue(this.Options, "depositMethods", map[string]interface{} {})
var defaultDepositMethod interface{} = this.SafeString(defaultDepositMethods, code)
var depositMethod interface{} = this.SafeString(params, "method", defaultDepositMethod)
// if the user has specified an exchange-specific method in params
// we pass it as is, otherwise we take the 'network' unified param
if IsTrue(IsEqual(depositMethod, nil)) {
depositMethods:= (<-this.FetchDepositMethods(code))
PanicOnError(depositMethods)
if IsTrue(!IsEqual(network, nil)) {
// find best matching deposit method, or fallback to the first one
for i := 0; IsLessThan(i, GetArrayLength(depositMethods)); i++ {
var entry interface{} = this.SafeString(GetValue(depositMethods, i), "method")
if IsTrue(IsGreaterThanOrEqual(GetIndexOf(entry, network), 0)) {
depositMethod = entry
break
}
}
}
// if depositMethod was not specified, fallback to the first available deposit method
if IsTrue(IsEqual(depositMethod, nil)) {
var firstDepositMethod interface{} = this.SafeValue(depositMethods, 0, map[string]interface{} {})
depositMethod = this.SafeString(firstDepositMethod, "method")
}
}
var request interface{} = map[string]interface{} {
"asset": GetValue(currency, "id"),
"method": depositMethod,
}
response:= (<-this.PrivatePostDepositAddresses(this.Extend(request, params)))
PanicOnError(response)
//
// {
// "error":[],
// "result":[
// {"address":"0x77b5051f97efa9cc52c9ad5b023a53fc15c200d3","expiretm":"0"}
// ]
// }
//
var result interface{} = this.SafeValue(response, "result", []interface{}{})
var firstResult interface{} = this.SafeValue(result, 0, map[string]interface{} {})
if IsTrue(IsEqual(firstResult, nil)) {
panic(InvalidAddress(Add(Add(this.Id, " privatePostDepositAddresses() returned no addresses for "), code)))
}
ch <- this.ParseDepositAddress(firstResult, currency)
return nil
}()
return ch
}
func (this *kraken) ParseDepositAddress(depositAddress interface{}, optionalArgs ...interface{}) interface{} {
//
// {
// "address":"0x77b5051f97efa9cc52c9ad5b023a53fc15c200d3",
// "expiretm":"0"
// }
//
currency := GetArg(optionalArgs, 0, nil)
_ = currency
var address interface{} = this.SafeString(depositAddress, "address")
var tag interface{} = this.SafeString(depositAddress, "tag")
currency = this.SafeCurrency(nil, currency)
var code interface{} = GetValue(currency, "code")
this.CheckAddress(address)
return map[string]interface{} {
"info": depositAddress,
"currency": code,
"network": nil,
"address": address,
"tag": tag,
}
}
/**
* @method
* @name kraken#withdraw
* @description make a withdrawal
* @see https://docs.kraken.com/rest/#tag/Funding/operation/withdrawFunds
* @param {string} code unified currency code
* @param {float} amount the amount to withdraw
* @param {string} address the address to withdraw to
* @param {string} tag
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object} a [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure}
*/
func (this *kraken) Withdraw(code interface{}, amount interface{}, address interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
tag := GetArg(optionalArgs, 0, nil)
_ = tag
params := GetArg(optionalArgs, 1, map[string]interface{} {})
_ = params
tagparamsVariable := this.HandleWithdrawTagAndParams(tag, params);
tag = GetValue(tagparamsVariable,0);
params = GetValue(tagparamsVariable,1)
this.CheckAddress(address)
if IsTrue(InOp(params, "key")) {
retRes315512 := (<-this.LoadMarkets())
PanicOnError(retRes315512)
var currency interface{} = this.Currency(code)
var request interface{} = map[string]interface{} {
"asset": GetValue(currency, "id"),
"amount": amount,
"address": address,
}
response:= (<-this.PrivatePostWithdraw(this.Extend(request, params)))
PanicOnError(response)
//
// {
// "error": [],
// "result": {
// "refid": "AGBSO6T-UFMTTQ-I7KGS6"
// }
// }
//
var result interface{} = this.SafeDict(response, "result", map[string]interface{} {})
ch <- this.ParseTransaction(result, currency)
return nil
}
panic(ExchangeError(Add(this.Id, " withdraw() requires a \\'key\\' parameter (withdrawal key name, as set up on your account)")))
}()
return ch
}
/**
* @method
* @name kraken#fetchPositions
* @description fetch all open positions
* @see https://docs.kraken.com/rest/#tag/Account-Data/operation/getOpenPositions
* @param {string[]} [symbols] not used by kraken fetchPositions ()
* @param {object} [params] extra parameters specific to the exchange API endpoint
* @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure}
*/
func (this *kraken) FetchPositions(optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
symbols := GetArg(optionalArgs, 0, nil)
_ = symbols
params := GetArg(optionalArgs, 1, map[string]interface{} {})
_ = params
retRes31878 := (<-this.LoadMarkets())
PanicOnError(retRes31878)
var request interface{} = map[string]interface{} {
"docalcs": "true",
"consolidation": "market",
}
response:= (<-this.PrivatePostOpenPositions(this.Extend(request, params)))
PanicOnError(response)
//
// no consolidation
//
// {
// "error": [],
// "result": {
// 'TGUFMY-FLESJ-VYIX3J': {
// "ordertxid": "O3LRNU-ZKDG5-XNCDFR",
// "posstatus": "open",
// "pair": "ETHUSDT",
// "time": 1611557231.4584,
// "type": "buy",
// "ordertype": "market",
// "cost": "28.49800",
// "fee": "0.07979",
// "vol": "0.02000000",
// "vol_closed": "0.00000000",
// "margin": "14.24900",
// "terms": "0.0200% per 4 hours",
// "rollovertm": "1611571631",
// "misc": "",
// "oflags": ""
// }
// }
// }
//
// consolidation by market
//
// {
// "error": [],
// "result": [
// {
// "pair": "ETHUSDT",
// "positions": "1",
// "type": "buy",
// "leverage": "2.00000",
// "cost": "28.49800",
// "fee": "0.07979",
// "vol": "0.02000000",
// "vol_closed": "0.00000000",
// "margin": "14.24900"
// }
// ]
// }
//
symbols = this.MarketSymbols(symbols)
var result interface{} = this.SafeList(response, "result")
var results interface{} = this.ParsePositions(result, symbols)
ch <- this.FilterByArrayPositions(results, "symbol", symbols, false)
return nil
}()
return ch
}
func (this *kraken) ParsePosition(position interface{}, optionalArgs ...interface{}) interface{} {
//
// {
// "pair": "ETHUSDT",
// "positions": "1",
// "type": "buy",
// "leverage": "2.00000",
// "cost": "28.49800",
// "fee": "0.07979",
// "vol": "0.02000000",
// "vol_closed": "0.00000000",
// "margin": "14.24900"
// }
//
market := GetArg(optionalArgs, 0, nil)
_ = market
var marketId interface{} = this.SafeString(position, "pair")
var rawSide interface{} = this.SafeString(position, "type")
var side interface{} = Ternary(IsTrue((IsEqual(rawSide, "buy"))), "long", "short")
return this.SafePosition(map[string]interface{} {
"info": position,
"id": nil,
"symbol": this.SafeSymbol(marketId, market),
"notional": nil,
"marginMode": nil,
"liquidationPrice": nil,
"entryPrice": nil,
"unrealizedPnl": this.SafeNumber(position, "net"),
"realizedPnl": nil,
"percentage": nil,
"contracts": this.SafeNumber(position, "vol"),
"contractSize": nil,
"markPrice": nil,
"lastPrice": nil,
"side": side,
"hedged": nil,
"timestamp": nil,
"datetime": nil,
"lastUpdateTimestamp": nil,
"maintenanceMargin": nil,
"maintenanceMarginPercentage": nil,
"collateral": nil,
"initialMargin": this.SafeNumber(position, "margin"),
"initialMarginPercentage": nil,
"leverage": this.SafeNumber(position, "leverage"),
"marginRatio": nil,
"stopLossPrice": nil,
"takeProfitPrice": nil,
})
}
func (this *kraken) ParseAccountType(account interface{}) interface{} {
var accountByType interface{} = map[string]interface{} {
"spot": "Spot Wallet",
"swap": "Futures Wallet",
"future": "Futures Wallet",
}
return this.SafeString(accountByType, account, account)
}
/**
* @method
* @name kraken#transferOut
* @description transfer from spot wallet to futures wallet
* @see https://docs.kraken.com/rest/#tag/User-Funding/operation/walletTransfer
* @param {str} code Unified currency code
* @param {float} amount Size of the transfer
* @param {dict} [params] Exchange specific parameters
* @returns a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
*/
func (this *kraken) TransferOut(code interface{}, amount interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
params := GetArg(optionalArgs, 0, map[string]interface{} {})
_ = params
retRes331415 := (<-this.Transfer(code, amount, "spot", "swap", params))
PanicOnError(retRes331415)
ch <- retRes331415
return nil
}()
return ch
}
/**
* @method
* @name kraken#transfer
* @see https://docs.kraken.com/rest/#tag/User-Funding/operation/walletTransfer
* @description transfers currencies between sub-accounts (only spot->swap direction is supported)
* @param {string} code Unified currency code
* @param {float} amount Size of the transfer
* @param {string} fromAccount 'spot' or 'Spot Wallet'
* @param {string} toAccount 'swap' or 'Futures Wallet'
* @param {object} [params] Exchange specific parameters
* @returns a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure}
*/
func (this *kraken) Transfer(code interface{}, amount interface{}, fromAccount interface{}, toAccount interface{}, optionalArgs ...interface{}) <- chan interface{} {
ch := make(chan interface{})
go func() interface{} {
defer close(ch)
defer ReturnPanicError(ch)
params := GetArg(optionalArgs, 0, map[string]interface{} {})
_ = params
retRes33308 := (<-this.LoadMarkets())
PanicOnError(retRes33308)
var currency interface{} = this.Currency(code)
fromAccount = this.ParseAccountType(fromAccount)
toAccount = this.ParseAccountType(toAccount)
var request interface{} = map[string]interface{} {
"amount": this.CurrencyToPrecision(code, amount),
"from": fromAccount,
"to": toAccount,
"asset": GetValue(currency, "id"),
}
if IsTrue(!IsEqual(fromAccount, "Spot Wallet")) {
panic(BadRequest(Add(Add(Add(Add(Add(this.Id, " transfer cannot transfer from "), fromAccount), " to "), toAccount), ". Use krakenfutures instead to transfer from the futures account.")))
}
response:= (<-this.PrivatePostWalletTransfer(this.Extend(request, params)))
PanicOnError(response)
//
// {
// "error":[
// ],
// "result":{
// "refid":"BOIUSIF-M7DLMN-UXZ3P5"
// }
// }
//
var transfer interface{} = this.ParseTransfer(response, currency)
ch <- this.Extend(transfer, map[string]interface{} {
"amount": amount,
"fromAccount": fromAccount,
"toAccount": toAccount,
})
return nil
}()
return ch
}
func (this *kraken) ParseTransfer(transfer interface{}, optionalArgs ...interface{}) interface{} {
//
// transfer
//
// {
// "error":[
// ],
// "result":{
// "refid":"BOIUSIF-M7DLMN-UXZ3P5"
// }
// }
//
currency := GetArg(optionalArgs, 0, nil)
_ = currency
var result interface{} = this.SafeValue(transfer, "result", map[string]interface{} {})
var refid interface{} = this.SafeString(result, "refid")
return map[string]interface{} {
"info": transfer,
"id": refid,
"timestamp": nil,
"datetime": nil,
"currency": this.SafeString(currency, "code"),
"amount": nil,
"fromAccount": nil,
"toAccount": nil,
"status": "sucess",
}
}
func (this *kraken) Sign(path interface{}, optionalArgs ...interface{}) interface{} {
api := GetArg(optionalArgs, 0, "public")
_ = api
method := GetArg(optionalArgs, 1, "GET")
_ = method
params := GetArg(optionalArgs, 2, map[string]interface{} {})
_ = params
headers := GetArg(optionalArgs, 3, nil)
_ = headers
body := GetArg(optionalArgs, 4, nil)
_ = body
var url interface{} = Add(Add(Add(Add(Add("/", this.Version), "/"), api), "/"), path)
if IsTrue(IsEqual(api, "public")) {
if IsTrue(GetArrayLength(ObjectKeys(params))) {
// urlencodeNested is used to address https://github.com/ccxt/ccxt/issues/12872
url = Add(url, Add("?", this.UrlencodeNested(params)))
}
} else if IsTrue(IsEqual(api, "private")) {
var price interface{} = this.SafeString(params, "price")
var isTriggerPercent interface{} = false
if IsTrue(!IsEqual(price, nil)) {
isTriggerPercent = Ternary(IsTrue((EndsWith(price, "%"))), true, false)
}
var isCancelOrderBatch interface{} = (IsEqual(path, "CancelOrderBatch"))
this.CheckRequiredCredentials()
var nonce interface{} = ToString(this.Nonce())
// urlencodeNested is used to address https://github.com/ccxt/ccxt/issues/12872
if IsTrue(IsTrue(isCancelOrderBatch) || IsTrue(isTriggerPercent)) {
body = this.Json(this.Extend(map[string]interface{} {
"nonce": nonce,
}, params))
} else {
body = this.UrlencodeNested(this.Extend(map[string]interface{} {
"nonce": nonce,
}, params))
}
var auth interface{} = this.Encode(Add(nonce, body))
var hash interface{} = this.Hash(auth, sha256, "binary")
var binary interface{} = this.Encode(url)
var binhash interface{} = this.BinaryConcat(binary, hash)
var secret interface{} = this.Base64ToBinary(this.Secret)
var signature interface{} = this.Hmac(binhash, secret, sha512, "base64")
headers = map[string]interface{} {
"API-Key": this.ApiKey,
"API-Sign": signature,
}
if IsTrue(IsTrue(isCancelOrderBatch) || IsTrue(isTriggerPercent)) {
AddElementToObject(headers, "Content-Type", "application/json")
} else {
AddElementToObject(headers, "Content-Type", "application/x-www-form-urlencoded")
}
} else {
url = Add("/", path)
}
url = Add(GetValue(GetValue(this.Urls, "api"), api), url)
return map[string]interface{} {
"url": url,
"method": method,
"body": body,
"headers": headers,
}
}
func (this *kraken) Nonce() interface{} {
return Subtract(this.Milliseconds(), GetValue(this.Options, "timeDifference"))
}
func (this *kraken) HandleErrors(code interface{}, reason interface{}, url interface{}, method interface{}, headers interface{}, body interface{}, response interface{}, requestHeaders interface{}, requestBody interface{}) interface{} {
if IsTrue(IsEqual(code, 520)) {
panic(ExchangeNotAvailable(Add(Add(Add(Add(this.Id, " "), ToString(code)), " "), reason)))
}
if IsTrue(IsEqual(response, nil)) {
return nil
}
if IsTrue(IsEqual(GetValue(body, 0), "{")) {
if IsTrue(!IsString(response)) {
if IsTrue(InOp(response, "error")) {
var numErrors interface{} = GetArrayLength(GetValue(response, "error"))
if IsTrue(numErrors) {
var message interface{} = Add(Add(this.Id, " "), body)
for i := 0; IsLessThan(i, GetArrayLength(GetValue(response, "error"))); i++ {
var error interface{} = GetValue(GetValue(response, "error"), i)
this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), error, message)
this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "broad"), error, message)
}
panic(ExchangeError(message))
}
}
}
}
return nil
}
func (this *kraken) Init(userConfig map[string]interface{}) {
this.Exchange = Exchange{}
this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this)
this.Exchange.DerivedExchange = this
}