4081 lines
179 KiB
Go
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
|
|
}
|