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 bitstamp struct { Exchange } func NewBitstampCore() bitstamp { p := bitstamp{} setDefaults(&p) return p } func (this *bitstamp) Describe() interface{} { return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} { "id": "bitstamp", "name": "Bitstamp", "countries": []interface{}{"GB"}, "rateLimit": 75, "version": "v2", "userAgent": GetValue(this.UserAgents, "chrome"), "pro": true, "has": map[string]interface{} { "CORS": true, "spot": true, "margin": false, "swap": false, "future": false, "option": false, "addMargin": false, "cancelAllOrders": true, "cancelOrder": true, "closeAllPositions": false, "closePosition": false, "createOrder": true, "createReduceOnlyOrder": false, "createStopLimitOrder": false, "createStopMarketOrder": false, "createStopOrder": false, "fetchBalance": true, "fetchBorrowRateHistories": false, "fetchBorrowRateHistory": false, "fetchCrossBorrowRate": false, "fetchCrossBorrowRates": false, "fetchCurrencies": true, "fetchDepositAddress": true, "fetchDepositAddresses": false, "fetchDepositAddressesByNetwork": false, "fetchDepositsWithdrawals": true, "fetchDepositWithdrawFee": "emulated", "fetchDepositWithdrawFees": true, "fetchFundingHistory": false, "fetchFundingRate": false, "fetchFundingRateHistory": false, "fetchFundingRates": false, "fetchIndexOHLCV": false, "fetchIsolatedBorrowRate": false, "fetchIsolatedBorrowRates": false, "fetchLedger": true, "fetchLeverage": false, "fetchMarginMode": false, "fetchMarkets": true, "fetchMarkOHLCV": false, "fetchMyTrades": true, "fetchOHLCV": true, "fetchOpenInterestHistory": false, "fetchOpenOrders": true, "fetchOrder": true, "fetchOrderBook": true, "fetchPosition": false, "fetchPositionHistory": false, "fetchPositionMode": false, "fetchPositions": false, "fetchPositionsForSymbol": false, "fetchPositionsHistory": false, "fetchPositionsRisk": false, "fetchPremiumIndexOHLCV": false, "fetchTicker": true, "fetchTickers": true, "fetchTrades": true, "fetchTradingFee": true, "fetchTradingFees": true, "fetchTransactionFees": true, "fetchTransactions": "emulated", "fetchWithdrawals": true, "reduceMargin": false, "setLeverage": false, "setMarginMode": false, "setPositionMode": false, "transfer": true, "withdraw": true, }, "urls": map[string]interface{} { "logo": "https://github.com/user-attachments/assets/d5480572-1fee-43cb-b900-d38c522d0024", "api": map[string]interface{} { "public": "https://www.bitstamp.net/api", "private": "https://www.bitstamp.net/api", }, "www": "https://www.bitstamp.net", "doc": "https://www.bitstamp.net/api", }, "timeframes": map[string]interface{} { "1m": "60", "3m": "180", "5m": "300", "15m": "900", "30m": "1800", "1h": "3600", "2h": "7200", "4h": "14400", "6h": "21600", "12h": "43200", "1d": "86400", "1w": "259200", }, "requiredCredentials": map[string]interface{} { "apiKey": true, "secret": true, }, "api": map[string]interface{} { "public": map[string]interface{} { "get": map[string]interface{} { "ohlc/{pair}/": 1, "order_book/{pair}/": 1, "ticker/": 1, "ticker_hour/{pair}/": 1, "ticker/{pair}/": 1, "transactions/{pair}/": 1, "trading-pairs-info/": 1, "currencies/": 1, "eur_usd/": 1, "travel_rule/vasps/": 1, }, }, "private": map[string]interface{} { "get": map[string]interface{} { "travel_rule/contacts/": 1, "contacts/{contact_uuid}/": 1, "earn/subscriptions/": 1, "earn/transactions/": 1, }, "post": map[string]interface{} { "account_balances/": 1, "account_balances/{currency}/": 1, "balance/": 1, "balance/{pair}/": 1, "bch_withdrawal/": 1, "bch_address/": 1, "user_transactions/": 1, "user_transactions/{pair}/": 1, "crypto-transactions/": 1, "open_order": 1, "open_orders/all/": 1, "open_orders/{pair}/": 1, "order_status/": 1, "cancel_order/": 1, "cancel_all_orders/": 1, "cancel_all_orders/{pair}/": 1, "buy/{pair}/": 1, "buy/market/{pair}/": 1, "buy/instant/{pair}/": 1, "sell/{pair}/": 1, "sell/market/{pair}/": 1, "sell/instant/{pair}/": 1, "transfer-to-main/": 1, "transfer-from-main/": 1, "my_trading_pairs/": 1, "fees/trading/": 1, "fees/trading/{market_symbol}": 1, "fees/withdrawal/": 1, "fees/withdrawal/{currency}/": 1, "withdrawal-requests/": 1, "withdrawal/open/": 1, "withdrawal/status/": 1, "withdrawal/cancel/": 1, "liquidation_address/new/": 1, "liquidation_address/info/": 1, "btc_unconfirmed/": 1, "websockets_token/": 1, "btc_withdrawal/": 1, "btc_address/": 1, "ripple_withdrawal/": 1, "ripple_address/": 1, "ltc_withdrawal/": 1, "ltc_address/": 1, "eth_withdrawal/": 1, "eth_address/": 1, "xrp_withdrawal/": 1, "xrp_address/": 1, "xlm_withdrawal/": 1, "xlm_address/": 1, "pax_withdrawal/": 1, "pax_address/": 1, "link_withdrawal/": 1, "link_address/": 1, "usdc_withdrawal/": 1, "usdc_address/": 1, "omg_withdrawal/": 1, "omg_address/": 1, "dai_withdrawal/": 1, "dai_address/": 1, "knc_withdrawal/": 1, "knc_address/": 1, "mkr_withdrawal/": 1, "mkr_address/": 1, "zrx_withdrawal/": 1, "zrx_address/": 1, "gusd_withdrawal/": 1, "gusd_address/": 1, "aave_withdrawal/": 1, "aave_address/": 1, "bat_withdrawal/": 1, "bat_address/": 1, "uma_withdrawal/": 1, "uma_address/": 1, "snx_withdrawal/": 1, "snx_address/": 1, "uni_withdrawal/": 1, "uni_address/": 1, "yfi_withdrawal/": 1, "yfi_address/": 1, "audio_withdrawal/": 1, "audio_address/": 1, "crv_withdrawal/": 1, "crv_address/": 1, "algo_withdrawal/": 1, "algo_address/": 1, "comp_withdrawal/": 1, "comp_address/": 1, "grt_withdrawal/": 1, "grt_address/": 1, "usdt_withdrawal/": 1, "usdt_address/": 1, "eurt_withdrawal/": 1, "eurt_address/": 1, "matic_withdrawal/": 1, "matic_address/": 1, "sushi_withdrawal/": 1, "sushi_address/": 1, "chz_withdrawal/": 1, "chz_address/": 1, "enj_withdrawal/": 1, "enj_address/": 1, "alpha_withdrawal/": 1, "alpha_address/": 1, "ftt_withdrawal/": 1, "ftt_address/": 1, "storj_withdrawal/": 1, "storj_address/": 1, "axs_withdrawal/": 1, "axs_address/": 1, "sand_withdrawal/": 1, "sand_address/": 1, "hbar_withdrawal/": 1, "hbar_address/": 1, "rgt_withdrawal/": 1, "rgt_address/": 1, "fet_withdrawal/": 1, "fet_address/": 1, "skl_withdrawal/": 1, "skl_address/": 1, "cel_withdrawal/": 1, "cel_address/": 1, "sxp_withdrawal/": 1, "sxp_address/": 1, "ada_withdrawal/": 1, "ada_address/": 1, "slp_withdrawal/": 1, "slp_address/": 1, "ftm_withdrawal/": 1, "ftm_address/": 1, "perp_withdrawal/": 1, "perp_address/": 1, "dydx_withdrawal/": 1, "dydx_address/": 1, "gala_withdrawal/": 1, "gala_address/": 1, "shib_withdrawal/": 1, "shib_address/": 1, "amp_withdrawal/": 1, "amp_address/": 1, "sgb_withdrawal/": 1, "sgb_address/": 1, "avax_withdrawal/": 1, "avax_address/": 1, "wbtc_withdrawal/": 1, "wbtc_address/": 1, "ctsi_withdrawal/": 1, "ctsi_address/": 1, "cvx_withdrawal/": 1, "cvx_address/": 1, "imx_withdrawal/": 1, "imx_address/": 1, "nexo_withdrawal/": 1, "nexo_address/": 1, "ust_withdrawal/": 1, "ust_address/": 1, "ant_withdrawal/": 1, "ant_address/": 1, "gods_withdrawal/": 1, "gods_address/": 1, "rad_withdrawal/": 1, "rad_address/": 1, "band_withdrawal/": 1, "band_address/": 1, "inj_withdrawal/": 1, "inj_address/": 1, "rly_withdrawal/": 1, "rly_address/": 1, "rndr_withdrawal/": 1, "rndr_address/": 1, "vega_withdrawal/": 1, "vega_address/": 1, "1inch_withdrawal/": 1, "1inch_address/": 1, "ens_withdrawal/": 1, "ens_address/": 1, "mana_withdrawal/": 1, "mana_address/": 1, "lrc_withdrawal/": 1, "lrc_address/": 1, "ape_withdrawal/": 1, "ape_address/": 1, "mpl_withdrawal/": 1, "mpl_address/": 1, "euroc_withdrawal/": 1, "euroc_address/": 1, "sol_withdrawal/": 1, "sol_address/": 1, "dot_withdrawal/": 1, "dot_address/": 1, "near_withdrawal/": 1, "near_address/": 1, "doge_withdrawal/": 1, "doge_address/": 1, "flr_withdrawal/": 1, "flr_address/": 1, "dgld_withdrawal/": 1, "dgld_address/": 1, "ldo_withdrawal/": 1, "ldo_address/": 1, "travel_rule/contacts/": 1, "earn/subscribe/": 1, "earn/subscriptions/setting/": 1, "earn/unsubscribe": 1, "wecan_withdrawal/": 1, "wecan_address/": 1, "trac_withdrawal/": 1, "trac_address/": 1, "eurcv_withdrawal/": 1, "eurcv_address/": 1, "pyusd_withdrawal/": 1, "pyusd_address/": 1, "lmwr_withdrawal/": 1, "lmwr_address/": 1, "pepe_withdrawal/": 1, "pepe_address/": 1, "blur_withdrawal/": 1, "blur_address/": 1, "vext_withdrawal/": 1, "vext_address/": 1, "cspr_withdrawal/": 1, "cspr_address/": 1, "vchf_withdrawal/": 1, "vchf_address/": 1, "veur_withdrawal/": 1, "veur_address/": 1, "truf_withdrawal/": 1, "truf_address/": 1, "wif_withdrawal/": 1, "wif_address/": 1, "smt_withdrawal/": 1, "smt_address/": 1, "sui_withdrawal/": 1, "sui_address/": 1, "jup_withdrawal/": 1, "jup_address/": 1, "ondo_withdrawal/": 1, "ondo_address/": 1, "boba_withdrawal/": 1, "boba_address/": 1, "pyth_withdrawal/": 1, "pyth_address/": 1, }, }, }, "fees": map[string]interface{} { "trading": map[string]interface{} { "tierBased": true, "percentage": true, "taker": this.ParseNumber("0.004"), "maker": this.ParseNumber("0.004"), "tiers": map[string]interface{} { "taker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.004")}, []interface{}{this.ParseNumber("10000"), this.ParseNumber("0.003")}, []interface{}{this.ParseNumber("100000"), this.ParseNumber("0.002")}, []interface{}{this.ParseNumber("500000"), this.ParseNumber("0.0018")}, []interface{}{this.ParseNumber("1500000"), this.ParseNumber("0.0016")}, []interface{}{this.ParseNumber("5000000"), this.ParseNumber("0.0012")}, []interface{}{this.ParseNumber("20000000"), this.ParseNumber("0.001")}, []interface{}{this.ParseNumber("50000000"), this.ParseNumber("0.0008")}, []interface{}{this.ParseNumber("100000000"), this.ParseNumber("0.0006")}, []interface{}{this.ParseNumber("250000000"), this.ParseNumber("0.0005")}, []interface{}{this.ParseNumber("1000000000"), this.ParseNumber("0.0003")}}, "maker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.003")}, []interface{}{this.ParseNumber("10000"), this.ParseNumber("0.002")}, []interface{}{this.ParseNumber("100000"), this.ParseNumber("0.001")}, []interface{}{this.ParseNumber("500000"), this.ParseNumber("0.0008")}, []interface{}{this.ParseNumber("1500000"), this.ParseNumber("0.0006")}, []interface{}{this.ParseNumber("5000000"), this.ParseNumber("0.0003")}, []interface{}{this.ParseNumber("20000000"), this.ParseNumber("0.002")}, []interface{}{this.ParseNumber("50000000"), this.ParseNumber("0.0001")}, []interface{}{this.ParseNumber("100000000"), this.ParseNumber("0")}, []interface{}{this.ParseNumber("250000000"), this.ParseNumber("0")}, []interface{}{this.ParseNumber("1000000000"), this.ParseNumber("0")}}, }, }, "funding": map[string]interface{} { "tierBased": false, "percentage": false, "withdraw": map[string]interface{} {}, "deposit": map[string]interface{} { "BTC": 0, "BCH": 0, "LTC": 0, "ETH": 0, "XRP": 0, "XLM": 0, "PAX": 0, "USD": 7.5, "EUR": 0, }, }, }, "precisionMode": TICK_SIZE, "commonCurrencies": map[string]interface{} { "UST": "USTC", }, "options": map[string]interface{} { "networksById": map[string]interface{} { "bitcoin-cash": "BCH", "bitcoin": "BTC", "ethereum": "ERC20", "litecoin": "LTC", "stellar": "XLM", "xrpl": "XRP", "tron": "TRC20", "algorand": "ALGO", "flare": "FLR", "hedera": "HBAR", "cardana": "ADA", "songbird": "FLR", "avalanche-c-chain": "AVAX", "solana": "SOL", "polkadot": "DOT", "near": "NEAR", "doge": "DOGE", "sui": "SUI", "casper": "CSRP", }, }, "exceptions": map[string]interface{} { "exact": map[string]interface{} { "No permission found": PermissionDenied, "API key not found": AuthenticationError, "IP address not allowed": PermissionDenied, "Invalid nonce": InvalidNonce, "Invalid signature": AuthenticationError, "Authentication failed": AuthenticationError, "Missing key, signature and nonce parameters": AuthenticationError, "Wrong API key format": AuthenticationError, "Your account is frozen": PermissionDenied, "Please update your profile with your FATCA information, before using API.": PermissionDenied, "Order not found.": OrderNotFound, "Price is more than 20% below market price.": InvalidOrder, "Bitstamp.net is under scheduled maintenance. We\\'ll be back soon.": OnMaintenance, "Order could not be placed.": ExchangeNotAvailable, "Invalid offset.": BadRequest, }, "broad": map[string]interface{} { "Minimum order size is": InvalidOrder, "Check your account balance for details.": InsufficientFunds, "Ensure this value has at least": InvalidAddress, "Ensure that there are no more than": InvalidOrder, }, }, "features": map[string]interface{} { "spot": map[string]interface{} { "sandbox": false, "createOrder": map[string]interface{} { "marginMode": false, "triggerPrice": false, "triggerPriceType": nil, "triggerDirection": false, "stopLossPrice": false, "takeProfitPrice": false, "attachedStopLossTakeProfit": nil, "timeInForce": map[string]interface{} { "IOC": true, "FOK": true, "PO": true, "GTD": true, }, "hedged": false, "trailing": false, "leverage": false, "marketBuyByCost": false, "marketBuyRequiresPrice": false, "selfTradePrevention": false, "iceberg": false, }, "createOrders": nil, "fetchMyTrades": map[string]interface{} { "marginMode": false, "limit": 1000, "daysBack": nil, "untilDays": 30, "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": nil, "fetchOHLCV": map[string]interface{} { "limit": 1000, }, }, "swap": map[string]interface{} { "linear": nil, "inverse": nil, }, "future": map[string]interface{} { "linear": nil, "inverse": nil, }, }, }) } /** * @method * @name bitstamp#fetchMarkets * @description retrieves data on all markets for bitstamp * @see https://www.bitstamp.net/api/#tag/Market-info/operation/GetTradingPairsInfo * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ func (this *bitstamp) FetchMarkets(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params response:= (<-this.FetchMarketsFromCache(params)) PanicOnError(response) // // [ // { // "trading": "Enabled", // "base_decimals": 8, // "url_symbol": "btcusd", // "name": "BTC/USD", // "instant_and_market_orders": "Enabled", // "minimum_order": "20.0 USD", // "counter_decimals": 2, // "description": "Bitcoin / U.S. dollar" // } // ] // var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(response)); i++ { var market interface{} = GetValue(response, i) var name interface{} = this.SafeString(market, "name") basequoteVariable := Split(name, "/"); base := GetValue(basequoteVariable,0); quote := GetValue(basequoteVariable,1) var baseId interface{} = ToLower(base) var quoteId interface{} = ToLower(quote) base = this.SafeCurrencyCode(base) quote = this.SafeCurrencyCode(quote) var minimumOrder interface{} = this.SafeString(market, "minimum_order") var parts interface{} = Split(minimumOrder, " ") var status interface{} = this.SafeString(market, "trading") AppendToArray(&result,map[string]interface{} { "id": this.SafeString(market, "url_symbol"), "marketId": Add(Add(baseId, "_"), quoteId), "symbol": Add(Add(base, "/"), quote), "base": base, "quote": quote, "settle": nil, "baseId": baseId, "quoteId": quoteId, "settleId": nil, "type": "spot", "spot": true, "margin": false, "future": false, "swap": false, "option": false, "active": (IsEqual(status, "Enabled")), "contract": false, "linear": nil, "inverse": nil, "contractSize": nil, "expiry": nil, "expiryDatetime": nil, "strike": nil, "optionType": nil, "precision": map[string]interface{} { "amount": this.ParseNumber(this.ParsePrecision(this.SafeString(market, "base_decimals"))), "price": this.ParseNumber(this.ParsePrecision(this.SafeString(market, "counter_decimals"))), }, "limits": map[string]interface{} { "leverage": map[string]interface{} { "min": nil, "max": nil, }, "amount": map[string]interface{} { "min": nil, "max": nil, }, "price": map[string]interface{} { "min": nil, "max": nil, }, "cost": map[string]interface{} { "min": this.SafeNumber(parts, 0), "max": nil, }, }, "created": nil, "info": market, }) } ch <- result return nil }() return ch } func (this *bitstamp) ConstructCurrencyObject(id interface{}, code interface{}, name interface{}, precision interface{}, minCost interface{}, originalPayload interface{}) interface{} { var currencyType interface{} = "crypto" var description interface{} = this.Describe() if IsTrue(this.IsFiat(code)) { currencyType = "fiat" } var tickSize interface{} = this.ParseNumber(this.ParsePrecision(this.NumberToString(precision))) return map[string]interface{} { "id": id, "code": code, "info": originalPayload, "type": currencyType, "name": name, "active": true, "deposit": nil, "withdraw": nil, "fee": this.SafeNumber(GetValue(GetValue(GetValue(description, "fees"), "funding"), "withdraw"), code), "precision": tickSize, "limits": map[string]interface{} { "amount": map[string]interface{} { "min": tickSize, "max": nil, }, "price": map[string]interface{} { "min": tickSize, "max": nil, }, "cost": map[string]interface{} { "min": minCost, "max": nil, }, "withdraw": map[string]interface{} { "min": nil, "max": nil, }, }, "networks": map[string]interface{} {}, } } func (this *bitstamp) FetchMarketsFromCache(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) // this method is now redundant // currencies are now fetched before markets params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params var options interface{} = this.SafeValue(this.Options, "fetchMarkets", map[string]interface{} {}) var timestamp interface{} = this.SafeInteger(options, "timestamp") var expires interface{} = this.SafeInteger(options, "expires", 1000) var now interface{} = this.Milliseconds() if IsTrue(IsTrue((IsEqual(timestamp, nil))) || IsTrue((IsGreaterThan((Subtract(now, timestamp)), expires)))) { response:= (<-this.PublicGetTradingPairsInfo(params)) PanicOnError(response) AddElementToObject(this.Options, "fetchMarkets", this.Extend(options, map[string]interface{} { "response": response, "timestamp": now, })) } ch <- this.SafeValue(GetValue(this.Options, "fetchMarkets"), "response") return nil }() return ch } /** * @method * @name bitstamp#fetchCurrencies * @description fetches all available currencies on an exchange * @see https://www.bitstamp.net/api/#tag/Market-info/operation/GetTradingPairsInfo * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an associative dictionary of currencies */ func (this *bitstamp) 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.FetchMarketsFromCache(params)) PanicOnError(response) // // [ // { // "trading": "Enabled", // "base_decimals": 8, // "url_symbol": "btcusd", // "name": "BTC/USD", // "instant_and_market_orders": "Enabled", // "minimum_order": "20.0 USD", // "counter_decimals": 2, // "description": "Bitcoin / U.S. dollar" // }, // ] // var result interface{} = map[string]interface{} {} for i := 0; IsLessThan(i, GetArrayLength(response)); i++ { var market interface{} = GetValue(response, i) var name interface{} = this.SafeString(market, "name") basequoteVariable := Split(name, "/"); base := GetValue(basequoteVariable,0); quote := GetValue(basequoteVariable,1) var baseId interface{} = ToLower(base) var quoteId interface{} = ToLower(quote) base = this.SafeCurrencyCode(base) quote = this.SafeCurrencyCode(quote) var description interface{} = this.SafeString(market, "description") baseDescriptionquoteDescriptionVariable := Split(description, " / "); baseDescription := GetValue(baseDescriptionquoteDescriptionVariable,0); quoteDescription := GetValue(baseDescriptionquoteDescriptionVariable,1) var minimumOrder interface{} = this.SafeString(market, "minimum_order") var parts interface{} = Split(minimumOrder, " ") var cost interface{} = GetValue(parts, 0) if !IsTrue((InOp(result, base))) { var baseDecimals interface{} = this.SafeInteger(market, "base_decimals") AddElementToObject(result, base, this.ConstructCurrencyObject(baseId, base, baseDescription, baseDecimals, nil, market)) } if !IsTrue((InOp(result, quote))) { var counterDecimals interface{} = this.SafeInteger(market, "counter_decimals") AddElementToObject(result, quote, this.ConstructCurrencyObject(quoteId, quote, quoteDescription, counterDecimals, this.ParseNumber(cost), market)) } } ch <- result return nil }() return ch } /** * @method * @name bitstamp#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @see https://www.bitstamp.net/api/#tag/Order-book/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 *bitstamp) 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 retRes7698 := (<-this.LoadMarkets()) PanicOnError(retRes7698) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "pair": GetValue(market, "id"), } response:= (<-this.PublicGetOrderBookPair(this.Extend(request, params))) PanicOnError(response) // // { // "timestamp": "1583652948", // "microtimestamp": "1583652948955826", // "bids": [ // [ "8750.00", "1.33685271" ], // [ "8749.39", "0.07700000" ], // [ "8746.98", "0.07400000" ], // ] // "asks": [ // [ "8754.10", "1.51995636" ], // [ "8754.71", "1.40000000" ], // [ "8754.72", "2.50000000" ], // ] // } // var microtimestamp interface{} = this.SafeInteger(response, "microtimestamp") var timestamp interface{} = this.ParseToInt(Divide(microtimestamp, 1000)) var orderbook interface{} = this.ParseOrderBook(response, GetValue(market, "symbol"), timestamp) AddElementToObject(orderbook, "nonce", microtimestamp) ch <- orderbook return nil }() return ch } func (this *bitstamp) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} { // // { // "timestamp": "1686068944", // "high": "26252", // "last": "26216", // "bid": "26208", // "vwap": "25681", // "volume": "3563.13819902", // "low": "25350", // "ask": "26211", // "open": "25730", // "open_24": "25895", // "percent_change_24": "1.24", // "pair": "BTC/USD" // } // market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString(ticker, "pair") var symbol interface{} = this.SafeSymbol(marketId, market, nil) var timestamp interface{} = this.SafeTimestamp(ticker, "timestamp") var vwap interface{} = this.SafeString(ticker, "vwap") var baseVolume interface{} = this.SafeString(ticker, "volume") var quoteVolume interface{} = Precise.StringMul(baseVolume, vwap) var last interface{} = this.SafeString(ticker, "last") return this.SafeTicker(map[string]interface{} { "symbol": symbol, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "high": this.SafeString(ticker, "high"), "low": this.SafeString(ticker, "low"), "bid": this.SafeString(ticker, "bid"), "bidVolume": nil, "ask": this.SafeString(ticker, "ask"), "askVolume": nil, "vwap": vwap, "open": this.SafeString(ticker, "open"), "close": last, "last": last, "previousClose": nil, "change": nil, "percentage": nil, "average": nil, "baseVolume": baseVolume, "quoteVolume": quoteVolume, "info": ticker, }, market) } /** * @method * @name bitstamp#fetchTicker * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market * @see https://www.bitstamp.net/api/#tag/Tickers/operation/GetMarketTicker * @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 *bitstamp) 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 retRes8568 := (<-this.LoadMarkets()) PanicOnError(retRes8568) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "pair": GetValue(market, "id"), } ticker:= (<-this.PublicGetTickerPair(this.Extend(request, params))) PanicOnError(ticker) // // { // "timestamp": "1686068944", // "high": "26252", // "last": "26216", // "bid": "26208", // "vwap": "25681", // "volume": "3563.13819902", // "low": "25350", // "ask": "26211", // "open": "25730", // "open_24": "25895", // "percent_change_24": "1.24" // } // ch <- this.ParseTicker(ticker, market) return nil }() return ch } /** * @method * @name bitstamp#fetchTickers * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market * @see https://www.bitstamp.net/api/#tag/Tickers/operation/GetCurrencyPairTickers * @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 *bitstamp) 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 retRes8908 := (<-this.LoadMarkets()) PanicOnError(retRes8908) response:= (<-this.PublicGetTicker(params)) PanicOnError(response) // // { // "timestamp": "1686068944", // "high": "26252", // "last": "26216", // "bid": "26208", // "vwap": "25681", // "volume": "3563.13819902", // "low": "25350", // "ask": "26211", // "open": "25730", // "open_24": "25895", // "percent_change_24": "1.24", // "pair": "BTC/USD" // } // ch <- this.ParseTickers(response, symbols) return nil }() return ch } func (this *bitstamp) GetCurrencyIdFromTransaction(transaction interface{}) interface{} { // // { // "fee": "0.00000000", // "btc_usd": "0.00", // "datetime": XXX, // "usd": 0.0, // "btc": 0.0, // "eth": "0.05000000", // "type": "0", // "id": XXX, // "eur": 0.0 // } // var currencyId interface{} = this.SafeStringLower(transaction, "currency") if IsTrue(!IsEqual(currencyId, nil)) { return currencyId } transaction = this.Omit(transaction, []interface{}{"fee", "price", "datetime", "type", "status", "id"}) var ids interface{} = ObjectKeys(transaction) for i := 0; IsLessThan(i, GetArrayLength(ids)); i++ { var id interface{} = GetValue(ids, i) if IsTrue(IsLessThan(GetIndexOf(id, "_"), 0)) { var value interface{} = this.SafeInteger(transaction, id) if IsTrue(IsTrue((!IsEqual(value, nil))) && IsTrue((!IsEqual(value, 0)))) { return id } } } return nil } func (this *bitstamp) GetMarketFromTrade(trade interface{}) interface{} { trade = this.Omit(trade, []interface{}{"fee", "price", "datetime", "tid", "type", "order_id", "side"}) var currencyIds interface{} = ObjectKeys(trade) var numCurrencyIds interface{} = GetArrayLength(currencyIds) if IsTrue(IsGreaterThan(numCurrencyIds, 2)) { panic(ExchangeError(Add(Add(Add(Add(this.Id, " getMarketFromTrade() too many keys: "), this.Json(currencyIds)), " in the trade: "), this.Json(trade)))) } if IsTrue(IsEqual(numCurrencyIds, 2)) { var marketId interface{} = Add(GetValue(currencyIds, 0), GetValue(currencyIds, 1)) if IsTrue(InOp(this.Markets_by_id, marketId)) { return this.SafeMarket(marketId) } marketId = Add(GetValue(currencyIds, 1), GetValue(currencyIds, 0)) if IsTrue(InOp(this.Markets_by_id, marketId)) { return this.SafeMarket(marketId) } } return nil } func (this *bitstamp) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} { // // fetchTrades (public) // // { // "date": "1637845199", // "tid": "209895701", // "amount": "0.00500000", // "type": "0", // Transaction type: 0 - buy; 1 - sell // "price": "4451.25" // } // // fetchMyTrades, trades returned within fetchOrder (private) // // { // "fee": "0.11128", // "eth_usdt": 4451.25, // "datetime": "2021-11-25 12:59:59.322000", // "usdt": "-22.26", // "order_id": 1429545880227846, // "usd": 0, // "btc": 0, // "eth": "0.00500000", // "type": "2", // Transaction type: 0 - deposit; 1 - withdrawal; 2 - market trade; 14 - sub account transfer; 25 - credited with staked assets; 26 - sent assets to staking; 27 - staking reward; 32 - referral reward; 35 - inter account transfer. // "id": 209895701, // "eur": 0 // } // // from fetchOrder (private) // // { // "fee": "0.11128", // "price": "4451.25000000", // "datetime": "2021-11-25 12:59:59.322000", // "usdt": "22.25625000", // "tid": 209895701, // "eth": "0.00500000", // "type": 2 // Transaction type: 0 - deposit; 1 - withdrawal; 2 - market trade // } // market := GetArg(optionalArgs, 0, nil) _ = market var id interface{} = this.SafeString2(trade, "id", "tid") var symbol interface{} = nil var side interface{} = nil var priceString interface{} = this.SafeString(trade, "price") var amountString interface{} = this.SafeString(trade, "amount") var orderId interface{} = this.SafeString(trade, "order_id") var typeVar interface{} = nil var costString interface{} = this.SafeString(trade, "cost") var rawMarketId interface{} = nil if IsTrue(IsEqual(market, nil)) { var keys interface{} = ObjectKeys(trade) for i := 0; IsLessThan(i, GetArrayLength(keys)); i++ { var currentKey interface{} = GetValue(keys, i) if IsTrue(IsTrue(!IsEqual(currentKey, "order_id")) && IsTrue(IsGreaterThanOrEqual(GetIndexOf(currentKey, "_"), 0))) { rawMarketId = currentKey market = this.SafeMarket(rawMarketId, market, "_") } } } // if the market is still not defined // try to deduce it from used keys if IsTrue(IsEqual(market, nil)) { market = this.GetMarketFromTrade(trade) } var feeCostString interface{} = this.SafeString(trade, "fee") var feeCurrency interface{} = GetValue(market, "quote") var priceId interface{} = Ternary(IsTrue((!IsEqual(rawMarketId, nil))), rawMarketId, GetValue(market, "marketId")) priceString = this.SafeString(trade, priceId, priceString) amountString = this.SafeString(trade, GetValue(market, "baseId"), amountString) costString = this.SafeString(trade, GetValue(market, "quoteId"), costString) symbol = GetValue(market, "symbol") var datetimeString interface{} = this.SafeString2(trade, "date", "datetime") var timestamp interface{} = nil if IsTrue(!IsEqual(datetimeString, nil)) { if IsTrue(IsGreaterThanOrEqual(GetIndexOf(datetimeString, " "), 0)) { // iso8601 timestamp = this.Parse8601(datetimeString) } else { // string unix epoch in seconds timestamp = ParseInt(datetimeString) timestamp = Multiply(timestamp, 1000) } } // if it is a private trade if IsTrue(InOp(trade, "id")) { if IsTrue(!IsEqual(amountString, nil)) { var isAmountNeg interface{} = Precise.StringLt(amountString, "0") if IsTrue(isAmountNeg) { side = "sell" amountString = Precise.StringNeg(amountString) } else { side = "buy" } } } else { side = this.SafeString(trade, "type") if IsTrue(IsEqual(side, "1")) { side = "sell" } else if IsTrue(IsEqual(side, "0")) { side = "buy" } else { side = nil } } if IsTrue(!IsEqual(costString, nil)) { costString = Precise.StringAbs(costString) } var fee interface{} = nil if IsTrue(!IsEqual(feeCostString, nil)) { fee = map[string]interface{} { "cost": feeCostString, "currency": feeCurrency, } } return this.SafeTrade(map[string]interface{} { "id": id, "info": trade, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "symbol": symbol, "order": orderId, "type": typeVar, "side": side, "takerOrMaker": nil, "price": priceString, "amount": amountString, "cost": costString, "fee": fee, }, market) } /** * @method * @name bitstamp#fetchTrades * @description get the list of most recent trades for a particular symbol * @see https://www.bitstamp.net/api/#tag/Transactions-public/operation/GetTransactions * @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 *bitstamp) 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 retRes11218 := (<-this.LoadMarkets()) PanicOnError(retRes11218) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "pair": GetValue(market, "id"), "time": "hour", } response:= (<-this.PublicGetTransactionsPair(this.Extend(request, params))) PanicOnError(response) // // [ // { // "date": "1551814435", // "tid": "83581898", // "price": "0.03532850", // "type": "1", // "amount": "0.85945907" // }, // { // "date": "1551814434", // "tid": "83581896", // "price": "0.03532851", // "type": "1", // "amount": "11.34130961" // }, // ] // ch <- this.ParseTrades(response, market, since, limit) return nil }() return ch } func (this *bitstamp) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} { // // { // "high": "9064.77", // "timestamp": "1593961440", // "volume": "18.49436608", // "low": "9040.87", // "close": "9064.77", // "open": "9040.87" // } // market := GetArg(optionalArgs, 0, nil) _ = market return []interface{}{this.SafeTimestamp(ohlcv, "timestamp"), this.SafeNumber(ohlcv, "open"), this.SafeNumber(ohlcv, "high"), this.SafeNumber(ohlcv, "low"), this.SafeNumber(ohlcv, "close"), this.SafeNumber(ohlcv, "volume")} } /** * @method * @name bitstamp#fetchOHLCV * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @see https://www.bitstamp.net/api/#tag/Market-info/operation/GetOHLCData * @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 * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume */ func (this *bitstamp) 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 retRes11838 := (<-this.LoadMarkets()) PanicOnError(retRes11838) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "pair": GetValue(market, "id"), "step": this.SafeString(this.Timeframes, timeframe, timeframe), } var duration interface{} = this.ParseTimeframe(timeframe) if IsTrue(IsEqual(limit, nil)) { if IsTrue(IsEqual(since, nil)) { AddElementToObject(request, "limit", 1000) // we need to specify an allowed amount of `limit` if no `since` is set and there is no default limit by exchange } else { limit = 1000 var start interface{} = this.ParseToInt(Divide(since, 1000)) AddElementToObject(request, "start", start) AddElementToObject(request, "end", this.Sum(start, Multiply(duration, (Subtract(limit, 1))))) AddElementToObject(request, "limit", limit) } } else { if IsTrue(!IsEqual(since, nil)) { var start interface{} = this.ParseToInt(Divide(since, 1000)) AddElementToObject(request, "start", start) AddElementToObject(request, "end", this.Sum(start, Multiply(duration, (Subtract(limit, 1))))) } AddElementToObject(request, "limit", mathMin(limit, 1000)) // min 1, max 1000 } response:= (<-this.PublicGetOhlcPair(this.Extend(request, params))) PanicOnError(response) // // { // "data": { // "pair": "BTC/USD", // "ohlc": [ // {"high": "9064.77", "timestamp": "1593961440", "volume": "18.49436608", "low": "9040.87", "close": "9064.77", "open": "9040.87"}, // {"high": "9071.59", "timestamp": "1593961500", "volume": "3.48631711", "low": "9058.76", "close": "9061.07", "open": "9064.66"}, // {"high": "9067.33", "timestamp": "1593961560", "volume": "0.04142833", "low": "9061.94", "close": "9061.94", "open": "9067.33"}, // ], // } // } // var data interface{} = this.SafeValue(response, "data", map[string]interface{} {}) var ohlc interface{} = this.SafeList(data, "ohlc", []interface{}{}) ch <- this.ParseOHLCVs(ohlc, market, timeframe, since, limit) return nil }() return ch } func (this *bitstamp) ParseBalance(response interface{}) interface{} { var result interface{} = map[string]interface{} { "info": response, "timestamp": nil, "datetime": nil, } if IsTrue(IsEqual(response, nil)) { response = []interface{}{} } for i := 0; IsLessThan(i, GetArrayLength(response)); i++ { var currencyBalance interface{} = GetValue(response, i) var currencyId interface{} = this.SafeString(currencyBalance, "currency") var currencyCode interface{} = this.SafeCurrencyCode(currencyId) var account interface{} = this.Account() AddElementToObject(account, "free", this.SafeString(currencyBalance, "available")) AddElementToObject(account, "used", this.SafeString(currencyBalance, "reserved")) AddElementToObject(account, "total", this.SafeString(currencyBalance, "total")) AddElementToObject(result, currencyCode, account) } return this.SafeBalance(result) } /** * @method * @name bitstamp#fetchBalance * @description query for balance and get the amount of funds available for trading or funds locked in orders * @see https://www.bitstamp.net/api/#tag/Account-balances/operation/GetAccountBalances * @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 *bitstamp) 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 retRes12578 := (<-this.LoadMarkets()) PanicOnError(retRes12578) response:= (<-this.PrivatePostAccountBalances(params)) PanicOnError(response) // // [ // { // "currency": "usdt", // "total": "7.00000", // "available": "7.00000", // "reserved": "0.00000" // }, // ... // ] // ch <- this.ParseBalance(response) return nil }() return ch } /** * @method * @name bitstamp#fetchTradingFee * @description fetch the trading fees for a market * @see https://www.bitstamp.net/api/#tag/Fees/operation/GetTradingFeesForCurrency * @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 *bitstamp) 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 retRes12838 := (<-this.LoadMarkets()) PanicOnError(retRes12838) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "market_symbol": GetValue(market, "id"), } response:= (<-this.PrivatePostFeesTrading(this.Extend(request, params))) PanicOnError(response) // // [ // { // "currency_pair": "btcusd", // "fees": // { // "maker": "0.15000", // "taker": "0.16000" // }, // "market": "btcusd" // } // ... // ] // var tradingFeesByMarketId interface{} = this.IndexBy(response, "currency_pair") var tradingFee interface{} = this.SafeDict(tradingFeesByMarketId, GetValue(market, "id")) ch <- this.ParseTradingFee(tradingFee, market) return nil }() return ch } func (this *bitstamp) ParseTradingFee(fee interface{}, optionalArgs ...interface{}) interface{} { market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString(fee, "market") var fees interface{} = this.SafeDict(fee, "fees", map[string]interface{} {}) return map[string]interface{} { "info": fee, "symbol": this.SafeSymbol(marketId, market), "maker": this.SafeNumber(fees, "maker"), "taker": this.SafeNumber(fees, "taker"), "percentage": nil, "tierBased": nil, } } func (this *bitstamp) ParseTradingFees(fees interface{}) interface{} { var result interface{} = map[string]interface{} { "info": fees, } var symbols interface{} = this.Symbols for i := 0; IsLessThan(i, GetArrayLength(symbols)); i++ { var symbol interface{} = GetValue(symbols, i) var fee interface{} = this.ParseTradingFee(GetValue(fees, i)) AddElementToObject(result, symbol, fee) } return result } /** * @method * @name bitstamp#fetchTradingFees * @description fetch the trading fees for multiple markets * @see https://www.bitstamp.net/api/#tag/Fees/operation/GetAllTradingFees * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a dictionary of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} indexed by market symbols */ func (this *bitstamp) FetchTradingFees(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 retRes13418 := (<-this.LoadMarkets()) PanicOnError(retRes13418) response:= (<-this.PrivatePostFeesTrading(params)) PanicOnError(response) // // [ // { // "currency_pair": "btcusd", // "fees": // { // "maker": "0.15000", // "taker": "0.16000" // }, // "market": "btcusd" // } // ... // ] // ch <- this.ParseTradingFees(response) return nil }() return ch } /** * @method * @name bitstamp#fetchTransactionFees * @deprecated * @description please use fetchDepositWithdrawFees instead * @see https://www.bitstamp.net/api/#tag/Fees * @param {string[]|undefined} codes list of unified currency codes * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} */ func (this *bitstamp) FetchTransactionFees(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) codes := GetArg(optionalArgs, 0, nil) _ = codes params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes13718 := (<-this.LoadMarkets()) PanicOnError(retRes13718) response:= (<-this.PrivatePostFeesWithdrawal(params)) PanicOnError(response) // // [ // { // "currency": "btc", // "fee": "0.00015000", // "network": "bitcoin" // } // ... // ] // ch <- this.ParseTransactionFees(response) return nil }() return ch } func (this *bitstamp) ParseTransactionFees(response interface{}, optionalArgs ...interface{}) interface{} { codes := GetArg(optionalArgs, 0, nil) _ = codes var result interface{} = map[string]interface{} {} var currencies interface{} = this.IndexBy(response, "currency") var ids interface{} = ObjectKeys(currencies) for i := 0; IsLessThan(i, GetArrayLength(ids)); i++ { var id interface{} = GetValue(ids, i) var fees interface{} = this.SafeValue(response, i, map[string]interface{} {}) var code interface{} = this.SafeCurrencyCode(id) if IsTrue(IsTrue((!IsEqual(codes, nil))) && !IsTrue(this.InArray(code, codes))) { continue } AddElementToObject(result, code, map[string]interface{} { "withdraw_fee": this.SafeNumber(fees, "fee"), "deposit": map[string]interface{} {}, "info": this.SafeDict(currencies, id), }) } return result } /** * @method * @name bitstamp#fetchDepositWithdrawFees * @description fetch deposit and withdraw fees * @see https://www.bitstamp.net/api/#tag/Fees/operation/GetAllWithdrawalFees * @param {string[]|undefined} codes list of unified currency codes * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [fee structures]{@link https://docs.ccxt.com/#/?id=fee-structure} */ func (this *bitstamp) FetchDepositWithdrawFees(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) codes := GetArg(optionalArgs, 0, nil) _ = codes params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes14168 := (<-this.LoadMarkets()) PanicOnError(retRes14168) response:= (<-this.PrivatePostFeesWithdrawal(params)) PanicOnError(response) // // [ // { // "currency": "btc", // "fee": "0.00015000", // "network": "bitcoin" // } // ... // ] // var responseByCurrencyId interface{} = this.GroupBy(response, "currency") ch <- this.ParseDepositWithdrawFees(responseByCurrencyId, codes) return nil }() return ch } func (this *bitstamp) ParseDepositWithdrawFee(fee interface{}, optionalArgs ...interface{}) interface{} { currency := GetArg(optionalArgs, 0, nil) _ = currency var result interface{} = this.DepositWithdrawFee(fee) for j := 0; IsLessThan(j, GetArrayLength(fee)); j++ { var networkEntry interface{} = GetValue(fee, j) var networkId interface{} = this.SafeString(networkEntry, "network") var networkCode interface{} = this.NetworkIdToCode(networkId) var withdrawFee interface{} = this.SafeNumber(networkEntry, "fee") AddElementToObject(result, "withdraw", map[string]interface{} { "fee": withdrawFee, "percentage": nil, }) AddElementToObject(GetValue(result, "networks"), networkCode, map[string]interface{} { "withdraw": map[string]interface{} { "fee": withdrawFee, "percentage": nil, }, "deposit": map[string]interface{} { "fee": nil, "percentage": nil, }, }) } return result } /** * @method * @name bitstamp#createOrder * @description create a trade order * @see https://www.bitstamp.net/api/#tag/Orders/operation/OpenInstantBuyOrder * @see https://www.bitstamp.net/api/#tag/Orders/operation/OpenMarketBuyOrder * @see https://www.bitstamp.net/api/#tag/Orders/operation/OpenLimitBuyOrder * @see https://www.bitstamp.net/api/#tag/Orders/operation/OpenInstantSellOrder * @see https://www.bitstamp.net/api/#tag/Orders/operation/OpenMarketSellOrder * @see https://www.bitstamp.net/api/#tag/Orders/operation/OpenLimitSellOrder * @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 * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *bitstamp) 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 retRes14768 := (<-this.LoadMarkets()) PanicOnError(retRes14768) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "pair": GetValue(market, "id"), "amount": this.AmountToPrecision(symbol, amount), } var clientOrderId interface{} = this.SafeString2(params, "client_order_id", "clientOrderId") if IsTrue(!IsEqual(clientOrderId, nil)) { AddElementToObject(request, "client_order_id", clientOrderId) params = this.Omit(params, []interface{}{"clientOrderId"}) } var response interface{} = nil var capitalizedSide interface{} = this.Capitalize(side) if IsTrue(IsEqual(typeVar, "market")) { if IsTrue(IsEqual(capitalizedSide, "Buy")) { response = (<-this.PrivatePostBuyMarketPair(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivatePostSellMarketPair(this.Extend(request, params))) PanicOnError(response) } } else if IsTrue(IsEqual(typeVar, "instant")) { if IsTrue(IsEqual(capitalizedSide, "Buy")) { response = (<-this.PrivatePostBuyInstantPair(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivatePostSellInstantPair(this.Extend(request, params))) PanicOnError(response) } } else { AddElementToObject(request, "price", this.PriceToPrecision(symbol, price)) if IsTrue(IsEqual(capitalizedSide, "Buy")) { response = (<-this.PrivatePostBuyPair(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivatePostSellPair(this.Extend(request, params))) PanicOnError(response) } } var order interface{} = this.ParseOrder(response, market) AddElementToObject(order, "type", typeVar) ch <- order return nil }() return ch } /** * @method * @name bitstamp#cancelOrder * @description cancels an open order * @see https://www.bitstamp.net/api/#tag/Orders/operation/CancelOrder * @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 * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *bitstamp) 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 retRes15258 := (<-this.LoadMarkets()) PanicOnError(retRes15258) var request interface{} = map[string]interface{} { "id": id, } response:= (<-this.PrivatePostCancelOrder(this.Extend(request, params))) PanicOnError(response) // // { // "id": 1453282316578816, // "amount": "0.02035278", // "price": "2100.45", // "type": 0, // "market": "BTC/USD" // } // ch <- this.ParseOrder(response) return nil }() return ch } /** * @method * @name bitstamp#cancelAllOrders * @description cancel all open orders * @see https://www.bitstamp.net/api/#tag/Orders/operation/CancelAllOrders * @see https://www.bitstamp.net/api/#tag/Orders/operation/CancelOrdersForMarket * @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 *bitstamp) 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 retRes15538 := (<-this.LoadMarkets()) PanicOnError(retRes15538) var market interface{} = nil var request interface{} = map[string]interface{} {} var response interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) AddElementToObject(request, "pair", GetValue(market, "id")) response = (<-this.PrivatePostCancelAllOrdersPair(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivatePostCancelAllOrders(this.Extend(request, params))) PanicOnError(response) } // // { // "canceled": [ // { // "id": 1453282316578816, // "amount": "0.02035278", // "price": "2100.45", // "type": 0, // "currency_pair": "BTC/USD", // "market": "BTC/USD" // } // ], // "success": true // } // var canceled interface{} = this.SafeList(response, "canceled") ch <- this.ParseOrders(canceled) return nil }() return ch } func (this *bitstamp) ParseOrderStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "In Queue": "open", "Open": "open", "Finished": "closed", "Canceled": "canceled", } return this.SafeString(statuses, status, status) } func (this *bitstamp) FetchOrderStatus(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 retRes15948 := (<-this.LoadMarkets()) PanicOnError(retRes15948) var clientOrderId interface{} = this.SafeValue2(params, "client_order_id", "clientOrderId") var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(clientOrderId, nil)) { AddElementToObject(request, "client_order_id", clientOrderId) params = this.Omit(params, []interface{}{"client_order_id", "clientOrderId"}) } else { AddElementToObject(request, "id", id) } response:= (<-this.PrivatePostOrderStatus(this.Extend(request, params))) PanicOnError(response) ch <- this.ParseOrderStatus(this.SafeString(response, "status")) return nil }() return ch } /** * @method * @name bitstamp#fetchOrder * @description fetches information on an order made by the user * @see https://www.bitstamp.net/api/#tag/Orders/operation/GetOrderStatus * @param {string} id the 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 * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *bitstamp) 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 retRes16188 := (<-this.LoadMarkets()) PanicOnError(retRes16188) var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } var clientOrderId interface{} = this.SafeValue2(params, "client_order_id", "clientOrderId") var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(clientOrderId, nil)) { AddElementToObject(request, "client_order_id", clientOrderId) params = this.Omit(params, []interface{}{"client_order_id", "clientOrderId"}) } else { AddElementToObject(request, "id", id) } response:= (<-this.PrivatePostOrderStatus(this.Extend(request, params))) PanicOnError(response) // // { // "status": "Finished", // "id": 1429545880227846, // "amount_remaining": "0.00000000", // "transactions": [ // { // "fee": "0.11128", // "price": "4451.25000000", // "datetime": "2021-11-25 12:59:59.322000", // "usdt": "22.25625000", // "tid": 209895701, // "eth": "0.00500000", // "type": 2 // } // ] // } // ch <- this.ParseOrder(response, market) return nil }() return ch } /** * @method * @name bitstamp#fetchMyTrades * @description fetch all trades made by the user * @see https://www.bitstamp.net/api/#tag/Transactions-private/operation/GetUserTransactions * @see https://www.bitstamp.net/api/#tag/Transactions-private/operation/GetUserTransactionsForMarket * @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 * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure} */ func (this *bitstamp) 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 retRes16668 := (<-this.LoadMarkets()) PanicOnError(retRes16668) var request interface{} = map[string]interface{} {} var method interface{} = "privatePostUserTransactions" var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) AddElementToObject(request, "pair", GetValue(market, "id")) method = Add(method, "Pair") } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.callDynamically(method, this.Extend(request, params))) PanicOnError(response) var result interface{} = this.FilterBy(response, "type", "2") ch <- this.ParseTrades(result, market, since, limit) return nil }() return ch } /** * @method * @name bitstamp#fetchDepositsWithdrawals * @description fetch history of deposits and withdrawals * @see https://www.bitstamp.net/api/#tag/Transactions-private/operation/GetUserTransactions * @param {string} [code] unified currency code for the currency of the deposit/withdrawals, default is undefined * @param {int} [since] timestamp in ms of the earliest deposit/withdrawal, default is undefined * @param {int} [limit] max number of deposit/withdrawals to return, default is undefined * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a list of [transaction structure]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *bitstamp) FetchDepositsWithdrawals(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 retRes16958 := (<-this.LoadMarkets()) PanicOnError(retRes16958) var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.PrivatePostUserTransactions(this.Extend(request, params))) PanicOnError(response) // // [ // { // "fee": "0.00000000", // "btc_usd": "0.00", // "id": 1234567894, // "usd": 0, // "btc": 0, // "datetime": "2018-09-08 09:00:31", // "type": "1", // "xrp": "-20.00000000", // "eur": 0, // }, // { // "fee": "0.00000000", // "btc_usd": "0.00", // "id": 1134567891, // "usd": 0, // "btc": 0, // "datetime": "2018-09-07 18:47:52", // "type": "0", // "xrp": "20.00000000", // "eur": 0, // }, // ] // var currency interface{} = nil if IsTrue(!IsEqual(code, nil)) { currency = this.Currency(code) } var transactions interface{} = this.FilterByArray(response, "type", []interface{}{"0", "1"}, false) ch <- this.ParseTransactions(transactions, currency, since, limit) return nil }() return ch } /** * @method * @name bitstamp#fetchWithdrawals * @description fetch all withdrawals made from an account * @see https://www.bitstamp.net/api/#tag/Withdrawals/operation/GetWithdrawalRequests * @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 * @returns {object[]} a list of [transaction structures]{@link https://docs.ccxt.com/#/?id=transaction-structure} */ func (this *bitstamp) 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 retRes17478 := (<-this.LoadMarkets()) PanicOnError(retRes17478) var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "timedelta", Subtract(this.Milliseconds(), since)) } else { AddElementToObject(request, "timedelta", 50000000) // use max bitstamp approved value } response:= (<-this.PrivatePostWithdrawalRequests(this.Extend(request, params))) PanicOnError(response) // // [ // { // "status": 2, // "datetime": "2018-10-17 10:58:13", // "currency": "BTC", // "amount": "0.29669259", // "address": "aaaaa", // "type": 1, // "id": 111111, // "transaction_id": "xxxx", // }, // { // "status": 2, // "datetime": "2018-10-17 10:55:17", // "currency": "ETH", // "amount": "1.11010664", // "address": "aaaa", // "type": 16, // "id": 222222, // "transaction_id": "xxxxx", // }, // ] // ch <- this.ParseTransactions(response, nil, since, limit) return nil }() return ch } func (this *bitstamp) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} { // // fetchDepositsWithdrawals // // { // "fee": "0.00000000", // "btc_usd": "0.00", // "id": 1234567894, // "usd": 0, // "btc": 0, // "datetime": "2018-09-08 09:00:31", // "type": "1", // "xrp": "-20.00000000", // "eur": 0, // } // // fetchWithdrawals // // { // "status": 2, // "datetime": "2018-10-17 10:58:13", // "currency": "BTC", // "amount": "0.29669259", // "address": "aaaaa", // "type": 1, // "id": 111111, // "transaction_id": "xxxx", // } // // { // "id": 3386432, // "type": 14, // "amount": "863.21332500", // "status": 2, // "address": "rE1sdh25BJQ3qFwngiTBwaq3zPGGYcrjp1?dt=1455", // "currency": "XRP", // "datetime": "2018-01-05 15:27:55", // "transaction_id": "001743B03B0C79BA166A064AC0142917B050347B4CB23BA2AB4B91B3C5608F4C" // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var timestamp interface{} = this.Parse8601(this.SafeString(transaction, "datetime")) var currencyId interface{} = this.GetCurrencyIdFromTransaction(transaction) var code interface{} = this.SafeCurrencyCode(currencyId, currency) var feeCost interface{} = this.SafeString(transaction, "fee") var feeCurrency interface{} = nil var amount interface{} = nil if IsTrue(InOp(transaction, "amount")) { amount = this.SafeString(transaction, "amount") } else if IsTrue(!IsEqual(currency, nil)) { amount = this.SafeString(transaction, GetValue(currency, "id"), amount) feeCurrency = GetValue(currency, "code") } else if IsTrue(IsTrue((!IsEqual(code, nil))) && IsTrue((!IsEqual(currencyId, nil)))) { amount = this.SafeString(transaction, currencyId, amount) feeCurrency = code } if IsTrue(!IsEqual(amount, nil)) { // withdrawals have a negative amount amount = Precise.StringAbs(amount) } var status interface{} = "ok" if IsTrue(InOp(transaction, "status")) { status = this.ParseTransactionStatus(this.SafeString(transaction, "status")) } var typeVar interface{} = nil if IsTrue(InOp(transaction, "type")) { // from fetchDepositsWithdrawals var rawType interface{} = this.SafeString(transaction, "type") if IsTrue(IsEqual(rawType, "0")) { typeVar = "deposit" } else if IsTrue(IsEqual(rawType, "1")) { typeVar = "withdrawal" } } else { // from fetchWithdrawals typeVar = "withdrawal" } var tag interface{} = nil var address interface{} = this.SafeString(transaction, "address") if IsTrue(!IsEqual(address, nil)) { // dt (destination tag) is embedded into the address field var addressParts interface{} = Split(address, "?dt=") var numParts interface{} = GetArrayLength(addressParts) if IsTrue(IsGreaterThan(numParts, 1)) { address = GetValue(addressParts, 0) tag = GetValue(addressParts, 1) } } var fee interface{} = map[string]interface{} { "currency": nil, "cost": nil, "rate": nil, } if IsTrue(!IsEqual(feeCost, nil)) { fee = map[string]interface{} { "currency": feeCurrency, "cost": feeCost, "rate": nil, } } return map[string]interface{} { "info": transaction, "id": this.SafeString(transaction, "id"), "txid": this.SafeString(transaction, "transaction_id"), "type": typeVar, "currency": code, "network": nil, "amount": this.ParseNumber(amount), "status": status, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "address": address, "addressFrom": nil, "addressTo": address, "tag": tag, "tagFrom": nil, "tagTo": tag, "updated": nil, "comment": nil, "internal": nil, "fee": fee, } } func (this *bitstamp) ParseTransactionStatus(status interface{}) interface{} { // // withdrawals: // 0 (open), 1 (in process), 2 (finished), 3 (canceled) or 4 (failed). // var statuses interface{} = map[string]interface{} { "0": "pending", "1": "pending", "2": "ok", "3": "canceled", "4": "failed", } return this.SafeString(statuses, status, status) } func (this *bitstamp) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} { // // from fetch order: // { status: "Finished", // "id": 731693945, // "client_order_id": '', // "transactions": // [ { fee: "0.000019", // "price": "0.00015803", // "datetime": "2018-01-07 10:45:34.132551", // "btc": "0.0079015000000000", // "tid": 42777395, // "type": 2, // "xrp": "50.00000000" } ] } // // partially filled order: // { "id": 468646390, // "client_order_id": "", // "status": "Canceled", // "transactions": [{ // "eth": "0.23000000", // "fee": "0.09", // "tid": 25810126, // "usd": "69.8947000000000000", // "type": 2, // "price": "303.89000000", // "datetime": "2017-11-11 07:22:20.710567" // }]} // // from create order response: // { // "price": "0.00008012", // "client_order_id": '', // "currency_pair": "XRP/BTC", // "datetime": "2019-01-31 21:23:36", // "amount": "15.00000000", // "type": "0", // "id": "2814205012" // } // // cancelOrder // // { // "id": 1453282316578816, // "amount": "0.02035278", // "price": "2100.45", // "type": 0, // "market": "BTC/USD" // } // market := GetArg(optionalArgs, 0, nil) _ = market var id interface{} = this.SafeString(order, "id") var clientOrderId interface{} = this.SafeString(order, "client_order_id") var side interface{} = this.SafeString(order, "type") if IsTrue(!IsEqual(side, nil)) { side = Ternary(IsTrue((IsEqual(side, "1"))), "sell", "buy") } // there is no timestamp from fetchOrder var timestamp interface{} = this.Parse8601(this.SafeString(order, "datetime")) var marketId interface{} = this.SafeStringLower(order, "currency_pair") var symbol interface{} = this.SafeSymbol(marketId, market, "/") var status interface{} = this.ParseOrderStatus(this.SafeString(order, "status")) var amount interface{} = this.SafeString(order, "amount") var transactions interface{} = this.SafeValue(order, "transactions", []interface{}{}) var price interface{} = this.SafeString(order, "price") return this.SafeOrder(map[string]interface{} { "id": id, "clientOrderId": clientOrderId, "datetime": this.Iso8601(timestamp), "timestamp": timestamp, "lastTradeTimestamp": nil, "status": status, "symbol": symbol, "type": nil, "timeInForce": nil, "postOnly": nil, "side": side, "price": price, "triggerPrice": nil, "cost": nil, "amount": amount, "filled": nil, "remaining": nil, "trades": transactions, "fee": nil, "info": order, "average": nil, }, market) } func (this *bitstamp) ParseLedgerEntryType(typeVar interface{}) interface{} { var types interface{} = map[string]interface{} { "0": "transaction", "1": "transaction", "2": "trade", "14": "transfer", } return this.SafeString(types, typeVar, typeVar) } func (this *bitstamp) ParseLedgerEntry(item interface{}, optionalArgs ...interface{}) interface{} { // // [ // { // "fee": "0.00000000", // "btc_usd": "0.00", // "id": 1234567894, // "usd": 0, // "btc": 0, // "datetime": "2018-09-08 09:00:31", // "type": "1", // "xrp": "-20.00000000", // "eur": 0, // }, // { // "fee": "0.00000000", // "btc_usd": "0.00", // "id": 1134567891, // "usd": 0, // "btc": 0, // "datetime": "2018-09-07 18:47:52", // "type": "0", // "xrp": "20.00000000", // "eur": 0, // }, // ] // currency := GetArg(optionalArgs, 0, nil) _ = currency var typeVar interface{} = this.ParseLedgerEntryType(this.SafeString(item, "type")) if IsTrue(IsEqual(typeVar, "trade")) { var parsedTrade interface{} = this.ParseTrade(item) var market interface{} = nil var keys interface{} = ObjectKeys(item) for i := 0; IsLessThan(i, GetArrayLength(keys)); i++ { if IsTrue(IsGreaterThanOrEqual(GetIndexOf(GetValue(keys, i), "_"), 0)) { var marketId interface{} = Replace(GetValue(keys, i), "_", "") market = this.SafeMarket(marketId, market) } } // if the market is still not defined // try to deduce it from used keys if IsTrue(IsEqual(market, nil)) { market = this.GetMarketFromTrade(item) } var direction interface{} = Ternary(IsTrue((IsEqual(GetValue(parsedTrade, "side"), "buy"))), "in", "out") return this.SafeLedgerEntry(map[string]interface{} { "info": item, "id": GetValue(parsedTrade, "id"), "timestamp": GetValue(parsedTrade, "timestamp"), "datetime": GetValue(parsedTrade, "datetime"), "direction": direction, "account": nil, "referenceId": GetValue(parsedTrade, "order"), "referenceAccount": nil, "type": typeVar, "currency": GetValue(market, "base"), "amount": GetValue(parsedTrade, "amount"), "before": nil, "after": nil, "status": "ok", "fee": GetValue(parsedTrade, "fee"), }, currency) } else { var parsedTransaction interface{} = this.ParseTransaction(item, currency) var direction interface{} = nil if IsTrue(InOp(item, "amount")) { var amount interface{} = this.SafeString(item, "amount") direction = Ternary(IsTrue(Precise.StringGt(amount, "0")), "in", "out") } else if IsTrue(IsTrue((InOp(parsedTransaction, "currency"))) && IsTrue(!IsEqual(GetValue(parsedTransaction, "currency"), nil))) { var currencyCode interface{} = this.SafeString(parsedTransaction, "currency") currency = this.Currency(currencyCode) var amount interface{} = this.SafeString(item, GetValue(currency, "id")) direction = Ternary(IsTrue(Precise.StringGt(amount, "0")), "in", "out") } return this.SafeLedgerEntry(map[string]interface{} { "info": item, "id": GetValue(parsedTransaction, "id"), "timestamp": GetValue(parsedTransaction, "timestamp"), "datetime": GetValue(parsedTransaction, "datetime"), "direction": direction, "account": nil, "referenceId": GetValue(parsedTransaction, "txid"), "referenceAccount": nil, "type": typeVar, "currency": GetValue(parsedTransaction, "currency"), "amount": GetValue(parsedTransaction, "amount"), "before": nil, "after": nil, "status": GetValue(parsedTransaction, "status"), "fee": GetValue(parsedTransaction, "fee"), }, currency) } } /** * @method * @name bitstamp#fetchLedger * @description fetch the history of changes, actions done by the user or operations that altered the balance of the user * @see https://www.bitstamp.net/api/#tag/Transactions-private/operation/GetUserTransactions * @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 * @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger} */ func (this *bitstamp) FetchLedger(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 retRes21248 := (<-this.LoadMarkets()) PanicOnError(retRes21248) var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.PrivatePostUserTransactions(this.Extend(request, params))) PanicOnError(response) var currency interface{} = nil if IsTrue(!IsEqual(code, nil)) { currency = this.Currency(code) } ch <- this.ParseLedger(response, currency, since, limit) return nil }() return ch } /** * @method * @name bitstamp#fetchOpenOrders * @description fetch all unfilled currently open orders * @see https://www.bitstamp.net/api/#tag/Orders/operation/GetAllOpenOrders * @see https://www.bitstamp.net/api/#tag/Orders/operation/GetOpenOrdersForMarket * @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 * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *bitstamp) 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 var market interface{} = nil retRes21518 := (<-this.LoadMarkets()) PanicOnError(retRes21518) if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } response:= (<-this.PrivatePostOpenOrdersAll(params)) PanicOnError(response) // // [ // { // "price": "0.00008012", // "currency_pair": "XRP/BTC", // "client_order_id": '', // "datetime": "2019-01-31 21:23:36", // "amount": "15.00000000", // "type": "0", // "id": "2814205012", // } // ] // ch <- this.ParseOrders(response, market, since, limit, map[string]interface{} { "status": "open", "type": "limit", }) return nil }() return ch } func (this *bitstamp) GetCurrencyName(code interface{}) interface{} { /** * @ignore * @method * @param {string} code Unified currency code * @returns {string} lowercase version of code */ return ToLower(code) } func (this *bitstamp) IsFiat(code interface{}) interface{} { return IsTrue(IsTrue(IsEqual(code, "USD")) || IsTrue(IsEqual(code, "EUR"))) || IsTrue(IsEqual(code, "GBP")) } /** * @method * @name bitstamp#fetchDepositAddress * @description fetch the deposit address for a currency associated with this account * @see https://www.bitstamp.net/api/#tag/Deposits/operation/GetCryptoDepositAddress * @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 *bitstamp) 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 if IsTrue(this.IsFiat(code)) { panic(NotSupported(Add(Add(Add(this.Id, " fiat fetchDepositAddress() for "), code), " is not supported!"))) } var name interface{} = this.GetCurrencyName(code) var method interface{} = Add(Add("privatePost", this.Capitalize(name)), "Address") response:= (<-this.callDynamically(method, params)) PanicOnError(response) var address interface{} = this.SafeString(response, "address") var tag interface{} = this.SafeString2(response, "memo_id", "destination_tag") this.CheckAddress(address) ch <- map[string]interface{} { "info": response, "currency": code, "network": nil, "address": address, "tag": tag, } return nil }() return ch } /** * @method * @name bitstamp#withdraw * @description make a withdrawal * @see https://www.bitstamp.net/api/#tag/Withdrawals/operation/RequestFiatWithdrawal * @see https://www.bitstamp.net/api/#tag/Withdrawals/operation/RequestCryptoWithdrawal * @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 *bitstamp) Withdraw(code interface{}, amount interface{}, address interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) // For fiat withdrawals please provide all required additional parameters in the 'params' // Check https://www.bitstamp.net/api/ under 'Open bank withdrawal' for list and description. 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) retRes22348 := (<-this.LoadMarkets()) PanicOnError(retRes22348) this.CheckAddress(address) var request interface{} = map[string]interface{} { "amount": amount, } var currency interface{} = nil var method interface{} = nil if !IsTrue(this.IsFiat(code)) { var name interface{} = this.GetCurrencyName(code) method = Add(Add("privatePost", this.Capitalize(name)), "Withdrawal") if IsTrue(IsEqual(code, "XRP")) { if IsTrue(!IsEqual(tag, nil)) { AddElementToObject(request, "destination_tag", tag) } } else if IsTrue(IsTrue(IsEqual(code, "XLM")) || IsTrue(IsEqual(code, "HBAR"))) { if IsTrue(!IsEqual(tag, nil)) { AddElementToObject(request, "memo_id", tag) } } AddElementToObject(request, "address", address) } else { method = "privatePostWithdrawalOpen" currency = this.Currency(code) AddElementToObject(request, "iban", address) AddElementToObject(request, "account_currency", GetValue(currency, "id")) } response:= (<-this.callDynamically(method, this.Extend(request, params))) PanicOnError(response) ch <- this.ParseTransaction(response, currency) return nil }() return ch } /** * @method * @name bitstamp#transfer * @description transfer currency internally between wallets on the same account * @see https://www.bitstamp.net/api/#tag/Sub-account/operation/TransferFromMainToSub * @see https://www.bitstamp.net/api/#tag/Sub-account/operation/TransferFromSubToMain * @param {string} code unified currency code * @param {float} amount amount to transfer * @param {string} fromAccount account to transfer from * @param {string} toAccount account to transfer to * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [transfer structure]{@link https://docs.ccxt.com/#/?id=transfer-structure} */ func (this *bitstamp) 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 retRes22788 := (<-this.LoadMarkets()) PanicOnError(retRes22788) var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "amount": this.ParseToNumeric(this.CurrencyToPrecision(code, amount)), "currency": ToUpper(GetValue(currency, "id")), } var response interface{} = nil if IsTrue(IsEqual(fromAccount, "main")) { AddElementToObject(request, "subAccount", toAccount) response = (<-this.PrivatePostTransferFromMain(this.Extend(request, params))) PanicOnError(response) } else if IsTrue(IsEqual(toAccount, "main")) { AddElementToObject(request, "subAccount", fromAccount) response = (<-this.PrivatePostTransferToMain(this.Extend(request, params))) PanicOnError(response) } else { panic(BadRequest(Add(this.Id, " transfer() only supports from or to main"))) } // // { status: 'ok' } // var transfer interface{} = this.ParseTransfer(response, currency) AddElementToObject(transfer, "amount", amount) AddElementToObject(transfer, "fromAccount", fromAccount) AddElementToObject(transfer, "toAccount", toAccount) ch <- transfer return nil }() return ch } func (this *bitstamp) ParseTransfer(transfer interface{}, optionalArgs ...interface{}) interface{} { // // { status: 'ok' } // currency := GetArg(optionalArgs, 0, nil) _ = currency var status interface{} = this.SafeString(transfer, "status") return map[string]interface{} { "info": transfer, "id": nil, "timestamp": nil, "datetime": nil, "currency": GetValue(currency, "code"), "amount": nil, "fromAccount": nil, "toAccount": nil, "status": this.ParseTransferStatus(status), } } func (this *bitstamp) ParseTransferStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "ok": "ok", "error": "failed", } return this.SafeString(statuses, status, status) } func (this *bitstamp) Nonce() interface{} { return this.Milliseconds() } func (this *bitstamp) 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(GetValue(GetValue(this.Urls, "api"), api), "/") url = Add(url, Add(this.Version, "/")) url = Add(url, this.ImplodeParams(path, params)) var query interface{} = this.Omit(params, this.ExtractParams(path)) if IsTrue(IsEqual(api, "public")) { if IsTrue(GetArrayLength(ObjectKeys(query))) { url = Add(url, Add("?", this.Urlencode(query))) } } else { this.CheckRequiredCredentials() var xAuth interface{} = Add("BITSTAMP ", this.ApiKey) var xAuthNonce interface{} = this.Uuid() var xAuthTimestamp interface{} = ToString(this.Milliseconds()) var xAuthVersion interface{} = "v2" var contentType interface{} = "" headers = map[string]interface{} { "X-Auth": xAuth, "X-Auth-Nonce": xAuthNonce, "X-Auth-Timestamp": xAuthTimestamp, "X-Auth-Version": xAuthVersion, } if IsTrue(IsEqual(method, "POST")) { if IsTrue(GetArrayLength(ObjectKeys(query))) { body = this.Urlencode(query) contentType = "application/x-www-form-urlencoded" AddElementToObject(headers, "Content-Type", contentType) } else { // sending an empty POST request will trigger // an API0020 error returned by the exchange // therefore for empty requests we send a dummy object // https://github.com/ccxt/ccxt/issues/6846 body = this.Urlencode(map[string]interface{} { "foo": "bar", }) contentType = "application/x-www-form-urlencoded" AddElementToObject(headers, "Content-Type", contentType) } } var authBody interface{} = Ternary(IsTrue(body), body, "") var auth interface{} = Add(Add(Add(Add(Add(Add(Add(xAuth, method), Replace(url, "https://", "")), contentType), xAuthNonce), xAuthTimestamp), xAuthVersion), authBody) var signature interface{} = this.Hmac(this.Encode(auth), this.Encode(this.Secret), sha256) AddElementToObject(headers, "X-Auth-Signature", signature) } return map[string]interface{} { "url": url, "method": method, "body": body, "headers": headers, } } func (this *bitstamp) HandleErrors(httpCode interface{}, reason interface{}, url interface{}, method interface{}, headers interface{}, body interface{}, response interface{}, requestHeaders interface{}, requestBody interface{}) interface{} { if IsTrue(IsEqual(response, nil)) { return nil } // // {"error": "No permission found"} // fetchDepositAddress returns this on apiKeys that don't have the permission required // {"status": "error", "reason": {"__all__": ["Minimum order size is 5.0 EUR."]}} // reuse of a nonce gives: { status: 'error', reason: 'Invalid nonce', code: 'API0004' } // var status interface{} = this.SafeString(response, "status") var error interface{} = this.SafeValue(response, "error") if IsTrue(IsTrue((IsEqual(status, "error"))) || IsTrue((!IsEqual(error, nil)))) { var errors interface{} = []interface{}{} if IsTrue(IsString(error)) { AppendToArray(&errors,error) } else if IsTrue(!IsEqual(error, nil)) { var keys interface{} = ObjectKeys(error) for i := 0; IsLessThan(i, GetArrayLength(keys)); i++ { var key interface{} = GetValue(keys, i) var value interface{} = this.SafeValue(error, key) if IsTrue(IsArray(value)) { errors = this.ArrayConcat(errors, value) } else { AppendToArray(&errors,value) } } } var reasonInner interface{} = this.SafeValue(response, "reason", map[string]interface{} {}) if IsTrue(IsString(reasonInner)) { AppendToArray(&errors,reasonInner) } else { var all interface{} = this.SafeValue(reasonInner, "__all__", []interface{}{}) for i := 0; IsLessThan(i, GetArrayLength(all)); i++ { AppendToArray(&errors,GetValue(all, i)) } } var code interface{} = this.SafeString(response, "code") if IsTrue(IsEqual(code, "API0005")) { panic(AuthenticationError(Add(this.Id, " invalid signature, use the uid for the main account if you have subaccounts"))) } var feedback interface{} = Add(Add(this.Id, " "), body) for i := 0; IsLessThan(i, GetArrayLength(errors)); i++ { var value interface{} = GetValue(errors, i) this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), value, feedback) this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), value, feedback) } panic(ExchangeError(feedback)) } return nil } func (this *bitstamp) Init(userConfig map[string]interface{}) { this.Exchange = Exchange{} this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this) this.Exchange.DerivedExchange = this }