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

2840 lines
116 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 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
}