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 bitfinex struct { Exchange } func NewBitfinexCore() bitfinex { p := bitfinex{} setDefaults(&p) return p } func (this *bitfinex) Describe() interface{} { return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} { "id": "bitfinex", "name": "Bitfinex", "countries": []interface{}{"VG"}, "version": "v2", "certified": false, "pro": true, "has": map[string]interface{} { "CORS": nil, "spot": true, "margin": true, "swap": true, "future": false, "option": false, "addMargin": false, "borrowCrossMargin": false, "borrowIsolatedMargin": false, "cancelAllOrders": true, "cancelOrder": true, "cancelOrders": true, "createDepositAddress": true, "createLimitOrder": true, "createMarketOrder": true, "createOrder": true, "createPostOnlyOrder": true, "createReduceOnlyOrder": true, "createStopLimitOrder": true, "createStopMarketOrder": true, "createStopOrder": true, "createTrailingAmountOrder": true, "createTrailingPercentOrder": false, "createTriggerOrder": true, "editOrder": true, "fetchBalance": true, "fetchBorrowInterest": false, "fetchBorrowRate": false, "fetchBorrowRateHistories": false, "fetchBorrowRateHistory": false, "fetchBorrowRates": false, "fetchBorrowRatesPerSymbol": false, "fetchClosedOrder": true, "fetchClosedOrders": true, "fetchCrossBorrowRate": false, "fetchCrossBorrowRates": false, "fetchCurrencies": true, "fetchDepositAddress": true, "fetchDepositAddresses": false, "fetchDepositAddressesByNetwork": false, "fetchDepositsWithdrawals": true, "fetchFundingHistory": false, "fetchFundingRate": "emulated", "fetchFundingRateHistory": true, "fetchFundingRates": true, "fetchIndexOHLCV": false, "fetchIsolatedBorrowRate": false, "fetchIsolatedBorrowRates": false, "fetchLedger": true, "fetchLeverage": false, "fetchLeverageTiers": false, "fetchLiquidations": true, "fetchMarginMode": false, "fetchMarketLeverageTiers": false, "fetchMarkOHLCV": false, "fetchMyTrades": true, "fetchOHLCV": true, "fetchOpenInterest": true, "fetchOpenInterestHistory": true, "fetchOpenInterests": true, "fetchOpenOrder": true, "fetchOpenOrders": true, "fetchOrder": true, "fetchOrderBook": true, "fetchOrderBooks": false, "fetchOrderTrades": true, "fetchPosition": false, "fetchPositionMode": false, "fetchPositions": true, "fetchPremiumIndexOHLCV": false, "fetchStatus": true, "fetchTickers": true, "fetchTime": false, "fetchTradingFee": false, "fetchTradingFees": true, "fetchTransactionFees": nil, "fetchTransactions": "emulated", "reduceMargin": false, "repayCrossMargin": false, "repayIsolatedMargin": false, "setLeverage": false, "setMargin": true, "setMarginMode": false, "setPositionMode": false, "signIn": false, "transfer": true, "withdraw": true, }, "timeframes": map[string]interface{} { "1m": "1m", "5m": "5m", "15m": "15m", "30m": "30m", "1h": "1h", "3h": "3h", "4h": "4h", "6h": "6h", "12h": "12h", "1d": "1D", "1w": "7D", "2w": "14D", "1M": "1M", }, "rateLimit": 250, "urls": map[string]interface{} { "logo": "https://github.com/user-attachments/assets/4a8e947f-ab46-481a-a8ae-8b20e9b03178", "api": map[string]interface{} { "v1": "https://api.bitfinex.com", "public": "https://api-pub.bitfinex.com", "private": "https://api.bitfinex.com", }, "www": "https://www.bitfinex.com", "doc": []interface{}{"https://docs.bitfinex.com/v2/docs/", "https://github.com/bitfinexcom/bitfinex-api-node"}, "fees": "https://www.bitfinex.com/fees", }, "api": map[string]interface{} { "public": map[string]interface{} { "get": map[string]interface{} { "conf/{config}": 2.7, "conf/pub:{action}:{object}": 2.7, "conf/pub:{action}:{object}:{detail}": 2.7, "conf/pub:map:{object}": 2.7, "conf/pub:map:{object}:{detail}": 2.7, "conf/pub:map:currency:{detail}": 2.7, "conf/pub:map:currency:sym": 2.7, "conf/pub:map:currency:label": 2.7, "conf/pub:map:currency:unit": 2.7, "conf/pub:map:currency:undl": 2.7, "conf/pub:map:currency:pool": 2.7, "conf/pub:map:currency:explorer": 2.7, "conf/pub:map:currency:tx:fee": 2.7, "conf/pub:map:tx:method": 2.7, "conf/pub:list:{object}": 2.7, "conf/pub:list:{object}:{detail}": 2.7, "conf/pub:list:currency": 2.7, "conf/pub:list:pair:exchange": 2.7, "conf/pub:list:pair:margin": 2.7, "conf/pub:list:pair:futures": 2.7, "conf/pub:list:competitions": 2.7, "conf/pub:info:{object}": 2.7, "conf/pub:info:{object}:{detail}": 2.7, "conf/pub:info:pair": 2.7, "conf/pub:info:pair:futures": 2.7, "conf/pub:info:tx:status": 2.7, "conf/pub:fees": 2.7, "platform/status": 8, "tickers": 2.7, "ticker/{symbol}": 2.7, "tickers/hist": 2.7, "trades/{symbol}/hist": 2.7, "book/{symbol}/{precision}": 1, "book/{symbol}/P0": 1, "book/{symbol}/P1": 1, "book/{symbol}/P2": 1, "book/{symbol}/P3": 1, "book/{symbol}/R0": 1, "stats1/{key}:{size}:{symbol}:{side}/{section}": 2.7, "stats1/{key}:{size}:{symbol}:{side}/last": 2.7, "stats1/{key}:{size}:{symbol}:{side}/hist": 2.7, "stats1/{key}:{size}:{symbol}/{section}": 2.7, "stats1/{key}:{size}:{symbol}/last": 2.7, "stats1/{key}:{size}:{symbol}/hist": 2.7, "stats1/{key}:{size}:{symbol}:long/last": 2.7, "stats1/{key}:{size}:{symbol}:long/hist": 2.7, "stats1/{key}:{size}:{symbol}:short/last": 2.7, "stats1/{key}:{size}:{symbol}:short/hist": 2.7, "candles/trade:{timeframe}:{symbol}:{period}/{section}": 2.7, "candles/trade:{timeframe}:{symbol}/{section}": 2.7, "candles/trade:{timeframe}:{symbol}/last": 2.7, "candles/trade:{timeframe}:{symbol}/hist": 2.7, "status/{type}": 2.7, "status/deriv": 2.7, "status/deriv/{symbol}/hist": 2.7, "liquidations/hist": 80, "rankings/{key}:{timeframe}:{symbol}/{section}": 2.7, "rankings/{key}:{timeframe}:{symbol}/hist": 2.7, "pulse/hist": 2.7, "pulse/profile/{nickname}": 2.7, "funding/stats/{symbol}/hist": 10, "ext/vasps": 1, }, "post": map[string]interface{} { "calc/trade/avg": 2.7, "calc/fx": 2.7, }, }, "private": map[string]interface{} { "post": map[string]interface{} { "auth/r/wallets": 2.7, "auth/r/wallets/hist": 2.7, "auth/r/orders": 2.7, "auth/r/orders/{symbol}": 2.7, "auth/w/order/submit": 2.7, "auth/w/order/update": 2.7, "auth/w/order/cancel": 2.7, "auth/w/order/multi": 2.7, "auth/w/order/cancel/multi": 2.7, "auth/r/orders/{symbol}/hist": 2.7, "auth/r/orders/hist": 2.7, "auth/r/order/{symbol}:{id}/trades": 2.7, "auth/r/trades/{symbol}/hist": 2.7, "auth/r/trades/hist": 2.7, "auth/r/ledgers/{currency}/hist": 2.7, "auth/r/ledgers/hist": 2.7, "auth/r/info/margin/{key}": 2.7, "auth/r/info/margin/base": 2.7, "auth/r/info/margin/sym_all": 2.7, "auth/r/positions": 2.7, "auth/w/position/claim": 2.7, "auth/w/position/increase:": 2.7, "auth/r/position/increase/info": 2.7, "auth/r/positions/hist": 2.7, "auth/r/positions/audit": 2.7, "auth/r/positions/snap": 2.7, "auth/w/deriv/collateral/set": 2.7, "auth/w/deriv/collateral/limits": 2.7, "auth/r/funding/offers": 2.7, "auth/r/funding/offers/{symbol}": 2.7, "auth/w/funding/offer/submit": 2.7, "auth/w/funding/offer/cancel": 2.7, "auth/w/funding/offer/cancel/all": 2.7, "auth/w/funding/close": 2.7, "auth/w/funding/auto": 2.7, "auth/w/funding/keep": 2.7, "auth/r/funding/offers/{symbol}/hist": 2.7, "auth/r/funding/offers/hist": 2.7, "auth/r/funding/loans": 2.7, "auth/r/funding/loans/hist": 2.7, "auth/r/funding/loans/{symbol}": 2.7, "auth/r/funding/loans/{symbol}/hist": 2.7, "auth/r/funding/credits": 2.7, "auth/r/funding/credits/hist": 2.7, "auth/r/funding/credits/{symbol}": 2.7, "auth/r/funding/credits/{symbol}/hist": 2.7, "auth/r/funding/trades/{symbol}/hist": 2.7, "auth/r/funding/trades/hist": 2.7, "auth/r/info/funding/{key}": 2.7, "auth/r/info/user": 2.7, "auth/r/summary": 2.7, "auth/r/logins/hist": 2.7, "auth/r/permissions": 2.7, "auth/w/token": 2.7, "auth/r/audit/hist": 2.7, "auth/w/transfer": 2.7, "auth/w/deposit/address": 24, "auth/w/deposit/invoice": 24, "auth/w/withdraw": 24, "auth/r/movements/{currency}/hist": 2.7, "auth/r/movements/hist": 2.7, "auth/r/alerts": 5.34, "auth/w/alert/set": 2.7, "auth/w/alert/price:{symbol}:{price}/del": 2.7, "auth/w/alert/{type}:{symbol}:{price}/del": 2.7, "auth/calc/order/avail": 2.7, "auth/w/settings/set": 2.7, "auth/r/settings": 2.7, "auth/w/settings/del": 2.7, "auth/r/pulse/hist": 2.7, "auth/w/pulse/add": 16, "auth/w/pulse/del": 2.7, }, }, }, "fees": map[string]interface{} { "trading": map[string]interface{} { "feeSide": "get", "percentage": true, "tierBased": true, "maker": this.ParseNumber("0.001"), "taker": this.ParseNumber("0.002"), "tiers": map[string]interface{} { "taker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.002")}, []interface{}{this.ParseNumber("500000"), this.ParseNumber("0.002")}, []interface{}{this.ParseNumber("1000000"), this.ParseNumber("0.002")}, []interface{}{this.ParseNumber("2500000"), this.ParseNumber("0.002")}, []interface{}{this.ParseNumber("5000000"), this.ParseNumber("0.002")}, []interface{}{this.ParseNumber("7500000"), this.ParseNumber("0.002")}, []interface{}{this.ParseNumber("10000000"), this.ParseNumber("0.0018")}, []interface{}{this.ParseNumber("15000000"), this.ParseNumber("0.0016")}, []interface{}{this.ParseNumber("20000000"), this.ParseNumber("0.0014")}, []interface{}{this.ParseNumber("25000000"), this.ParseNumber("0.0012")}, []interface{}{this.ParseNumber("30000000"), this.ParseNumber("0.001")}}, "maker": []interface{}{[]interface{}{this.ParseNumber("0"), this.ParseNumber("0.001")}, []interface{}{this.ParseNumber("500000"), this.ParseNumber("0.0008")}, []interface{}{this.ParseNumber("1000000"), this.ParseNumber("0.0006")}, []interface{}{this.ParseNumber("2500000"), this.ParseNumber("0.0004")}, []interface{}{this.ParseNumber("5000000"), this.ParseNumber("0.0002")}, []interface{}{this.ParseNumber("7500000"), this.ParseNumber("0")}, []interface{}{this.ParseNumber("10000000"), this.ParseNumber("0")}, []interface{}{this.ParseNumber("15000000"), this.ParseNumber("0")}, []interface{}{this.ParseNumber("20000000"), this.ParseNumber("0")}, []interface{}{this.ParseNumber("25000000"), this.ParseNumber("0")}, []interface{}{this.ParseNumber("30000000"), this.ParseNumber("0")}}, }, }, "funding": map[string]interface{} { "withdraw": map[string]interface{} {}, }, }, "precisionMode": SIGNIFICANT_DIGITS, "options": map[string]interface{} { "precision": "R0", "exchangeTypes": map[string]interface{} { "MARKET": "market", "EXCHANGE MARKET": "market", "LIMIT": "limit", "EXCHANGE LIMIT": "limit", "EXCHANGE STOP": "market", "EXCHANGE FOK": "limit", "EXCHANGE STOP LIMIT": "limit", "EXCHANGE IOC": "limit", }, "orderTypes": map[string]interface{} { "market": "EXCHANGE MARKET", "limit": "EXCHANGE LIMIT", }, "fiat": map[string]interface{} { "USD": "USD", "EUR": "EUR", "JPY": "JPY", "GBP": "GBP", "CHN": "CHN", }, "v2AccountsByType": map[string]interface{} { "spot": "exchange", "exchange": "exchange", "funding": "funding", "margin": "margin", "derivatives": "margin", "future": "margin", "swap": "margin", }, "withdraw": map[string]interface{} { "includeFee": false, }, "networks": map[string]interface{} { "BTC": "BITCOIN", "LTC": "LITECOIN", "ERC20": "ETHEREUM", "OMNI": "TETHERUSO", "LIQUID": "TETHERUSL", "TRC20": "TETHERUSX", "EOS": "TETHERUSS", "AVAX": "TETHERUSDTAVAX", "SOL": "TETHERUSDTSOL", "ALGO": "TETHERUSDTALG", "BCH": "TETHERUSDTBCH", "KSM": "TETHERUSDTKSM", "DVF": "TETHERUSDTDVF", "OMG": "TETHERUSDTOMG", }, "networksById": map[string]interface{} { "TETHERUSE": "ERC20", }, }, "features": map[string]interface{} { "default": map[string]interface{} { "sandbox": false, "createOrder": map[string]interface{} { "marginMode": true, "triggerPrice": true, "triggerPriceType": nil, "triggerDirection": false, "stopLossPrice": true, "takeProfitPrice": true, "attachedStopLossTakeProfit": nil, "timeInForce": map[string]interface{} { "IOC": true, "FOK": true, "PO": true, "GTD": false, }, "hedged": false, "trailing": true, "leverage": true, "marketBuyRequiresPrice": false, "marketBuyByCost": true, "selfTradePrevention": false, "iceberg": false, }, "createOrders": map[string]interface{} { "max": 75, }, "fetchMyTrades": map[string]interface{} { "marginMode": false, "limit": 2500, "daysBack": nil, "untilDays": 100000, "symbolRequired": false, }, "fetchOrder": map[string]interface{} { "marginMode": false, "trigger": false, "trailing": false, "symbolRequired": false, }, "fetchOpenOrders": map[string]interface{} { "marginMode": false, "limit": nil, "trigger": false, "trailing": false, "symbolRequired": false, }, "fetchOrders": nil, "fetchClosedOrders": map[string]interface{} { "marginMode": false, "limit": nil, "daysBack": nil, "daysBackCanceled": nil, "untilDays": 100000, "trigger": false, "trailing": false, "symbolRequired": false, }, "fetchOHLCV": map[string]interface{} { "limit": 10000, }, }, "spot": map[string]interface{} { "extends": "default", }, "swap": map[string]interface{} { "linear": map[string]interface{} { "extends": "default", }, "inverse": nil, }, "future": map[string]interface{} { "linear": nil, "inverse": nil, }, }, "exceptions": map[string]interface{} { "exact": map[string]interface{} { "11010": RateLimitExceeded, "10001": PermissionDenied, "10020": BadRequest, "10100": AuthenticationError, "10114": InvalidNonce, "20060": OnMaintenance, "temporarily_unavailable": ExchangeNotAvailable, }, "broad": map[string]interface{} { "available balance is only": InsufficientFunds, "not enough exchange balance": InsufficientFunds, "Order not found": OrderNotFound, "symbol: invalid": BadSymbol, }, }, "commonCurrencies": map[string]interface{} { "UST": "USDT", "EUTF0": "EURT", "USTF0": "USDT", "ALG": "ALGO", "AMP": "AMPL", "ATO": "ATOM", "BCHABC": "XEC", "BCHN": "BCH", "DAT": "DATA", "DOG": "MDOGE", "DSH": "DASH", "EDO": "PNT", "EUS": "EURS", "EUT": "EURT", "HTX": "HT", "IDX": "ID", "IOT": "IOTA", "IQX": "IQ", "LUNA": "LUNC", "LUNA2": "LUNA", "MNA": "MANA", "ORS": "ORS Group", "PAS": "PASS", "QSH": "QASH", "QTM": "QTUM", "RBT": "RBTC", "SNG": "SNGLS", "STJ": "STORJ", "TERRAUST": "USTC", "TSD": "TUSD", "YGG": "YEED", "YYW": "YOYOW", "UDC": "USDC", "VSY": "VSYS", "WAX": "WAXP", "XCH": "XCHF", "ZBT": "ZB", }, }) } func (this *bitfinex) IsFiat(code interface{}) interface{} { return (InOp(GetValue(this.Options, "fiat"), code)) } func (this *bitfinex) GetCurrencyId(code interface{}) interface{} { return Add("f", code) } func (this *bitfinex) GetCurrencyName(code interface{}) interface{} { // temporary fix for transpiler recognition, even though this is in parent class if IsTrue(InOp(GetValue(this.Options, "currencyNames"), code)) { return GetValue(GetValue(this.Options, "currencyNames"), code) } panic(NotSupported(Add(Add(Add(this.Id, " "), code), " not supported for withdrawal"))) } func (this *bitfinex) AmountToPrecision(symbol interface{}, amount interface{}) interface{} { // https://docs.bitfinex.com/docs/introduction#amount-precision // The amount field allows up to 8 decimals. // Anything exceeding this will be rounded to the 8th decimal. symbol = this.SafeSymbol(symbol) return this.DecimalToPrecision(amount, TRUNCATE, GetValue(GetValue(GetValue(this.Markets, symbol), "precision"), "amount"), DECIMAL_PLACES) } func (this *bitfinex) PriceToPrecision(symbol interface{}, price interface{}) interface{} { symbol = this.SafeSymbol(symbol) price = this.DecimalToPrecision(price, ROUND, GetValue(GetValue(GetValue(this.Markets, symbol), "precision"), "price"), this.PrecisionMode) // https://docs.bitfinex.com/docs/introduction#price-precision // The precision level of all trading prices is based on significant figures. // All pairs on Bitfinex use up to 5 significant digits and up to 8 decimals (e.g. 1.2345, 123.45, 1234.5, 0.00012345). // Prices submit with a precision larger than 5 will be cut by the API. return this.DecimalToPrecision(price, TRUNCATE, 8, DECIMAL_PLACES) } /** * @method * @name bitfinex#fetchStatus * @description the latest known information on the availability of the exchange API * @see https://docs.bitfinex.com/reference/rest-public-platform-status * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} a [status structure]{@link https://docs.ccxt.com/#/?id=exchange-status-structure} */ func (this *bitfinex) FetchStatus(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) // // [1] // operative // [0] // maintenance // params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params response:= (<-this.PublicGetPlatformStatus(params)) PanicOnError(response) var statusRaw interface{} = this.SafeString(response, 0) ch <- map[string]interface{} { "status": this.SafeString(map[string]interface{} { "0": "maintenance", "1": "ok", }, statusRaw, statusRaw), "updated": nil, "eta": nil, "url": nil, "info": response, } return nil }() return ch } /** * @method * @name bitfinex#fetchMarkets * @description retrieves data on all markets for bitfinex * @see https://docs.bitfinex.com/reference/rest-public-conf * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ func (this *bitfinex) 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 var spotMarketsInfoPromise interface{} = this.PublicGetConfPubInfoPair(params) var futuresMarketsInfoPromise interface{} = this.PublicGetConfPubInfoPairFutures(params) var marginIdsPromise interface{} = this.PublicGetConfPubListPairMargin(params) spotMarketsInfofuturesMarketsInfomarginIdsVariable := (<-promiseAll([]interface{}{spotMarketsInfoPromise, futuresMarketsInfoPromise, marginIdsPromise})); spotMarketsInfo := GetValue(spotMarketsInfofuturesMarketsInfomarginIdsVariable,0); futuresMarketsInfo := GetValue(spotMarketsInfofuturesMarketsInfomarginIdsVariable,1); marginIds := GetValue(spotMarketsInfofuturesMarketsInfomarginIdsVariable,2) spotMarketsInfo = this.SafeList(spotMarketsInfo, 0, []interface{}{}) futuresMarketsInfo = this.SafeList(futuresMarketsInfo, 0, []interface{}{}) var markets interface{} = this.ArrayConcat(spotMarketsInfo, futuresMarketsInfo) marginIds = this.SafeValue(marginIds, 0, []interface{}{}) // // [ // "1INCH:USD", // [ // null, // null, // null, // "2.0", // "100000.0", // null, // null, // null, // null, // null, // null, // null // ] // ] // var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(markets)); i++ { var pair interface{} = GetValue(markets, i) var id interface{} = this.SafeStringUpper(pair, 0) var market interface{} = this.SafeValue(pair, 1, map[string]interface{} {}) var spot interface{} = true if IsTrue(IsGreaterThanOrEqual(GetIndexOf(id, "F0"), 0)) { spot = false } var swap interface{} = !IsTrue(spot) var baseId interface{} = nil var quoteId interface{} = nil if IsTrue(IsGreaterThanOrEqual(GetIndexOf(id, ":"), 0)) { var parts interface{} = Split(id, ":") baseId = GetValue(parts, 0) quoteId = GetValue(parts, 1) } else { baseId = Slice(id, 0, 3) quoteId = Slice(id, 3, 6) } var base interface{} = this.SafeCurrencyCode(baseId) var quote interface{} = this.SafeCurrencyCode(quoteId) var splitBase interface{} = Split(base, "F0") var splitQuote interface{} = Split(quote, "F0") base = this.SafeString(splitBase, 0) quote = this.SafeString(splitQuote, 0) var symbol interface{} = Add(Add(base, "/"), quote) baseId = this.GetCurrencyId(baseId) quoteId = this.GetCurrencyId(quoteId) var settle interface{} = nil var settleId interface{} = nil if IsTrue(swap) { settle = quote settleId = quote symbol = Add(Add(symbol, ":"), settle) } var minOrderSizeString interface{} = this.SafeString(market, 3) var maxOrderSizeString interface{} = this.SafeString(market, 4) var margin interface{} = false if IsTrue(IsTrue(spot) && IsTrue(this.InArray(id, marginIds))) { margin = true } AppendToArray(&result,map[string]interface{} { "id": Add("t", id), "symbol": symbol, "base": base, "quote": quote, "settle": settle, "baseId": baseId, "quoteId": quoteId, "settleId": settleId, "type": Ternary(IsTrue(spot), "spot", "swap"), "spot": spot, "margin": margin, "swap": swap, "future": false, "option": false, "active": true, "contract": swap, "linear": Ternary(IsTrue(swap), true, nil), "inverse": Ternary(IsTrue(swap), false, nil), "contractSize": Ternary(IsTrue(swap), this.ParseNumber("1"), nil), "expiry": nil, "expiryDatetime": nil, "strike": nil, "optionType": nil, "precision": map[string]interface{} { "amount": ParseInt("8"), "price": ParseInt("5"), }, "limits": map[string]interface{} { "leverage": map[string]interface{} { "min": nil, "max": nil, }, "amount": map[string]interface{} { "min": this.ParseNumber(minOrderSizeString), "max": this.ParseNumber(maxOrderSizeString), }, "price": map[string]interface{} { "min": this.ParseNumber("1e-8"), "max": nil, }, "cost": map[string]interface{} { "min": nil, "max": nil, }, }, "created": nil, "info": market, }) } ch <- result return nil }() return ch } /** * @method * @name bitfinex#fetchCurrencies * @description fetches all available currencies on an exchange * @see https://docs.bitfinex.com/reference/rest-public-conf * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an associative dictionary of currencies */ func (this *bitfinex) 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 var labels interface{} = []interface{}{"pub:list:currency", "pub:map:currency:sym", "pub:map:currency:label", "pub:map:currency:unit", "pub:map:currency:undl", "pub:map:currency:pool", "pub:map:currency:explorer", "pub:map:currency:tx:fee", "pub:map:tx:method"} var config interface{} = Join(labels, ",") var request interface{} = map[string]interface{} { "config": config, } response:= (<-this.PublicGetConfConfig(this.Extend(request, params))) PanicOnError(response) // // [ // // a list of symbols // ["AAA","ABS","ADA"], // // // sym // // maps symbols to their API symbols, BAB > BCH // [ // [ "BAB", "BCH" ], // [ "CNHT", "CNHt" ], // [ "DSH", "DASH" ], // [ "IOT", "IOTA" ], // [ "LES", "LEO-EOS" ], // [ "LET", "LEO-ERC20" ], // [ "STJ", "STORJ" ], // [ "TSD", "TUSD" ], // [ "UDC", "USDC" ], // [ "USK", "USDK" ], // [ "UST", "USDt" ], // [ "USTF0", "USDt0" ], // [ "XCH", "XCHF" ], // [ "YYW", "YOYOW" ], // // ... // ], // // label // // verbose friendly names, BNT > Bancor // [ // [ "BAB", "Bitcoin Cash" ], // [ "BCH", "Bitcoin Cash" ], // [ "LEO", "Unus Sed LEO" ], // [ "LES", "Unus Sed LEO (EOS)" ], // [ "LET", "Unus Sed LEO (ERC20)" ], // // ... // ], // // unit // // maps symbols to unit of measure where applicable // [ // [ "IOT", "Mi|MegaIOTA" ], // ], // // undl // // maps derivatives symbols to their underlying currency // [ // [ "USTF0", "UST" ], // [ "BTCF0", "BTC" ], // [ "ETHF0", "ETH" ], // ], // // pool // // maps symbols to underlying network/protocol they operate on // [ // [ 'SAN', 'ETH' ], [ 'OMG', 'ETH' ], [ 'AVT', 'ETH' ], [ "EDO", "ETH" ], // [ 'ESS', 'ETH' ], [ 'ATD', 'EOS' ], [ 'ADD', 'EOS' ], [ "MTO", "EOS" ], // [ 'PNK', 'ETH' ], [ 'BAB', 'BCH' ], [ 'WLO', 'XLM' ], [ "VLD", "ETH" ], // [ 'BTT', 'TRX' ], [ 'IMP', 'ETH' ], [ 'SCR', 'ETH' ], [ "GNO", "ETH" ], // // ... // ], // // explorer // // maps symbols to their recognised block explorer URLs // [ // [ // "AIO", // [ // "https://mainnet.aion.network", // "https://mainnet.aion.network/#/account/VAL", // "https://mainnet.aion.network/#/transaction/VAL" // ] // ], // // ... // ], // // fee // // maps currencies to their withdrawal fees // [ // ["AAA",[0,0]], // ["ABS",[0,131.3]], // ["ADA",[0,0.3]], // ], // ] // var indexed interface{} = map[string]interface{} { "sym": this.IndexBy(this.SafeValue(response, 1, []interface{}{}), 0), "label": this.IndexBy(this.SafeValue(response, 2, []interface{}{}), 0), "unit": this.IndexBy(this.SafeValue(response, 3, []interface{}{}), 0), "undl": this.IndexBy(this.SafeValue(response, 4, []interface{}{}), 0), "pool": this.IndexBy(this.SafeValue(response, 5, []interface{}{}), 0), "explorer": this.IndexBy(this.SafeValue(response, 6, []interface{}{}), 0), "fees": this.IndexBy(this.SafeValue(response, 7, []interface{}{}), 0), } var ids interface{} = this.SafeValue(response, 0, []interface{}{}) var result interface{} = map[string]interface{} {} for i := 0; IsLessThan(i, GetArrayLength(ids)); i++ { var id interface{} = GetValue(ids, i) if IsTrue(IsGreaterThanOrEqual(GetIndexOf(id, "F0"), 0)) { continue } var code interface{} = this.SafeCurrencyCode(id) var label interface{} = this.SafeValue(GetValue(indexed, "label"), id, []interface{}{}) var name interface{} = this.SafeString(label, 1) var pool interface{} = this.SafeValue(GetValue(indexed, "pool"), id, []interface{}{}) var rawType interface{} = this.SafeString(pool, 1) var isCryptoCoin interface{} = IsTrue((!IsEqual(rawType, nil))) || IsTrue((InOp(GetValue(indexed, "explorer"), id))) // "hacky" solution var typeVar interface{} = nil if IsTrue(isCryptoCoin) { typeVar = "crypto" } var feeValues interface{} = this.SafeValue(GetValue(indexed, "fees"), id, []interface{}{}) var fees interface{} = this.SafeValue(feeValues, 1, []interface{}{}) var fee interface{} = this.SafeNumber(fees, 1) var undl interface{} = this.SafeValue(GetValue(indexed, "undl"), id, []interface{}{}) var precision interface{} = "8" // default precision, todo: fix "magic constants" var fid interface{} = Add("f", id) AddElementToObject(result, code, map[string]interface{} { "id": fid, "uppercaseId": id, "code": code, "info": []interface{}{id, label, pool, feeValues, undl}, "type": typeVar, "name": name, "active": true, "deposit": nil, "withdraw": nil, "fee": fee, "precision": ParseInt(precision), "limits": map[string]interface{} { "amount": map[string]interface{} { "min": this.ParseNumber(this.ParsePrecision(precision)), "max": nil, }, "withdraw": map[string]interface{} { "min": fee, "max": nil, }, }, "networks": map[string]interface{} {}, }) var networks interface{} = map[string]interface{} {} var currencyNetworks interface{} = this.SafeValue(response, 8, []interface{}{}) var cleanId interface{} = Replace(id, "F0", "") for j := 0; IsLessThan(j, GetArrayLength(currencyNetworks)); j++ { var pair interface{} = GetValue(currencyNetworks, j) var networkId interface{} = this.SafeString(pair, 0) var currencyId interface{} = this.SafeString(this.SafeValue(pair, 1, []interface{}{}), 0) if IsTrue(IsEqual(currencyId, cleanId)) { var network interface{} = this.NetworkIdToCode(networkId) AddElementToObject(networks, network, map[string]interface{} { "info": networkId, "id": ToLower(networkId), "network": networkId, "active": nil, "deposit": nil, "withdraw": nil, "fee": nil, "precision": nil, "limits": map[string]interface{} { "withdraw": map[string]interface{} { "min": nil, "max": nil, }, }, }) } } var keysNetworks interface{} = ObjectKeys(networks) var networksLength interface{} = GetArrayLength(keysNetworks) if IsTrue(IsGreaterThan(networksLength, 0)) { AddElementToObject(GetValue(result, code), "networks", networks) } } ch <- result return nil }() return ch } /** * @method * @name bitfinex#fetchBalance * @description query for balance and get the amount of funds available for trading or funds locked in orders * @see https://docs.bitfinex.com/reference/rest-auth-wallets * @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 *bitfinex) FetchBalance(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) // this api call does not return the 'used' amount - use the v1 version instead (which also returns zero balances) // there is a difference between this and the v1 api, namely trading wallet is called margin in v2 params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes9378 := (<-this.LoadMarkets()) PanicOnError(retRes9378) var accountsByType interface{} = this.SafeValue(this.Options, "v2AccountsByType", map[string]interface{} {}) var requestedType interface{} = this.SafeString(params, "type", "exchange") var accountType interface{} = this.SafeString(accountsByType, requestedType, requestedType) if IsTrue(IsEqual(accountType, nil)) { var keys interface{} = ObjectKeys(accountsByType) panic(ExchangeError(Add(Add(this.Id, " fetchBalance() type parameter must be one of "), Join(keys, ", ")))) } var isDerivative interface{} = IsEqual(requestedType, "derivatives") var query interface{} = this.Omit(params, "type") response:= (<-this.PrivatePostAuthRWallets(query)) PanicOnError(response) var result interface{} = map[string]interface{} { "info": response, } for i := 0; IsLessThan(i, GetArrayLength(response)); i++ { var balance interface{} = GetValue(response, i) var account interface{} = this.Account() var interest interface{} = this.SafeString(balance, 3) if IsTrue(!IsEqual(interest, "0")) { AddElementToObject(account, "debt", interest) } var typeVar interface{} = this.SafeString(balance, 0) var currencyId interface{} = this.SafeStringLower(balance, 1, "") var start interface{} = Subtract(GetLength(currencyId), 2) var isDerivativeCode interface{} = IsEqual(Slice(currencyId, start, nil), "f0") // this will only filter the derivative codes if the requestedType is 'derivatives' var derivativeCondition interface{} = (!IsTrue(isDerivative) || IsTrue(isDerivativeCode)) if IsTrue(IsTrue((IsEqual(accountType, typeVar))) && IsTrue(derivativeCondition)) { var code interface{} = this.SafeCurrencyCode(currencyId) AddElementToObject(account, "total", this.SafeString(balance, 2)) AddElementToObject(account, "free", this.SafeString(balance, 4)) AddElementToObject(result, code, account) } } ch <- this.SafeBalance(result) return nil }() return ch } /** * @method * @name bitfinex#transfer * @description transfer currency internally between wallets on the same account * @see https://docs.bitfinex.com/reference/rest-auth-transfer * @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 *bitfinex) 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) // transferring between derivatives wallet and regular wallet is not documented in their API // however we support it in CCXT (from just looking at web inspector) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes9878 := (<-this.LoadMarkets()) PanicOnError(retRes9878) var accountsByType interface{} = this.SafeValue(this.Options, "v2AccountsByType", map[string]interface{} {}) var fromId interface{} = this.SafeString(accountsByType, fromAccount) if IsTrue(IsEqual(fromId, nil)) { var keys interface{} = ObjectKeys(accountsByType) panic(ArgumentsRequired(Add(Add(this.Id, " transfer() fromAccount must be one of "), Join(keys, ", ")))) } var toId interface{} = this.SafeString(accountsByType, toAccount) if IsTrue(IsEqual(toId, nil)) { var keys interface{} = ObjectKeys(accountsByType) panic(ArgumentsRequired(Add(Add(this.Id, " transfer() toAccount must be one of "), Join(keys, ", ")))) } var currency interface{} = this.Currency(code) var fromCurrencyId interface{} = this.ConvertDerivativesId(currency, fromAccount) var toCurrencyId interface{} = this.ConvertDerivativesId(currency, toAccount) var requestedAmount interface{} = this.CurrencyToPrecision(code, amount) // this request is slightly different from v1 fromAccount -> from var request interface{} = map[string]interface{} { "amount": requestedAmount, "currency": fromCurrencyId, "currency_to": toCurrencyId, "from": fromId, "to": toId, } response:= (<-this.PrivatePostAuthWTransfer(this.Extend(request, params))) PanicOnError(response) // // [ // 1616451183763, // "acc_tf", // null, // null, // [ // 1616451183763, // "exchange", // "margin", // null, // "UST", // "UST", // null, // 1 // ], // null, // "SUCCESS", // "1.0 Tether USDt transfered from Exchange to Margin" // ] // var error interface{} = this.SafeString(response, 0) if IsTrue(IsEqual(error, "error")) { var message interface{} = this.SafeString(response, 2, "") // same message as in v1 this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), message, Add(Add(this.Id, " "), message)) panic(ExchangeError(Add(Add(this.Id, " "), message))) } ch <- this.ParseTransfer(map[string]interface{} { "result": response, }, currency) return nil }() return ch } func (this *bitfinex) ParseTransfer(transfer interface{}, optionalArgs ...interface{}) interface{} { // // transfer // // [ // 1616451183763, // "acc_tf", // null, // null, // [ // 1616451183763, // "exchange", // "margin", // null, // "UST", // "UST", // null, // 1 // ], // null, // "SUCCESS", // "1.0 Tether USDt transfered from Exchange to Margin" // ] // currency := GetArg(optionalArgs, 0, nil) _ = currency var result interface{} = this.SafeList(transfer, "result") var timestamp interface{} = this.SafeInteger(result, 0) var info interface{} = this.SafeValue(result, 4) var fromAccount interface{} = this.SafeString(info, 1) var toAccount interface{} = this.SafeString(info, 2) var currencyId interface{} = this.SafeString(info, 5) var status interface{} = this.SafeString(result, 6) return map[string]interface{} { "id": nil, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "status": this.ParseTransferStatus(status), "amount": this.SafeNumber(info, 7), "currency": this.SafeCurrencyCode(currencyId, currency), "fromAccount": fromAccount, "toAccount": toAccount, "info": result, } } func (this *bitfinex) ParseTransferStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "SUCCESS": "ok", "ERROR": "failed", "FAILURE": "failed", } return this.SafeString(statuses, status, status) } func (this *bitfinex) ConvertDerivativesId(currency interface{}, typeVar interface{}) interface{} { // there is a difference between this and the v1 api, namely trading wallet is called margin in v2 // { // "id": "fUSTF0", // "code": "USTF0", // "info": [ 'USTF0', [], [], [], [ "USTF0", "UST" ] ], var info interface{} = this.SafeValue(currency, "info") var transferId interface{} = this.SafeString(info, 0) var underlying interface{} = this.SafeValue(info, 4, []interface{}{}) var currencyId interface{} = nil if IsTrue(IsEqual(typeVar, "derivatives")) { currencyId = this.SafeString(underlying, 0, transferId) var start interface{} = Subtract(GetArrayLength(currencyId), 2) var isDerivativeCode interface{} = IsEqual(Slice(currencyId, start, nil), "F0") if !IsTrue(isDerivativeCode) { currencyId = Add(currencyId, "F0") } } else if IsTrue(!IsEqual(typeVar, "margin")) { currencyId = this.SafeString(underlying, 1, transferId) } else { currencyId = transferId } return currencyId } /** * @method * @name bitfinex#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @see https://docs.bitfinex.com/reference/rest-public-book * @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, bitfinex only allows 1, 25, or 100 * @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 *bitfinex) 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 retRes11328 := (<-this.LoadMarkets()) PanicOnError(retRes11328) var precision interface{} = this.SafeValue(this.Options, "precision", "R0") var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), "precision": precision, } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "len", limit) } var fullRequest interface{} = this.Extend(request, params) orderbook:= (<-this.PublicGetBookSymbolPrecision(fullRequest)) PanicOnError(orderbook) var timestamp interface{} = this.Milliseconds() var result interface{} = map[string]interface{} { "symbol": GetValue(market, "symbol"), "bids": []interface{}{}, "asks": []interface{}{}, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "nonce": nil, } var priceIndex interface{} = Ternary(IsTrue((IsEqual(GetValue(fullRequest, "precision"), "R0"))), 1, 0) for i := 0; IsLessThan(i, GetArrayLength(orderbook)); i++ { var order interface{} = GetValue(orderbook, i) var price interface{} = this.SafeNumber(order, priceIndex) var signedAmount interface{} = this.SafeString(order, 2) var amount interface{} = Precise.StringAbs(signedAmount) var side interface{} = Ternary(IsTrue(Precise.StringGt(signedAmount, "0")), "bids", "asks") var resultSide interface{} = GetValue(result, side) AppendToArray(&resultSide,[]interface{}{price, this.ParseNumber(amount)}) } AddElementToObject(result, "bids", this.SortBy(GetValue(result, "bids"), 0, true)) AddElementToObject(result, "asks", this.SortBy(GetValue(result, "asks"), 0)) ch <- result return nil }() return ch } func (this *bitfinex) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} { // // on trading pairs (ex. tBTCUSD) // // { // 'result': [ // SYMBOL, // BID, // BID_SIZE, // ASK, // ASK_SIZE, // DAILY_CHANGE, // DAILY_CHANGE_RELATIVE, // LAST_PRICE, // VOLUME, // HIGH, // LOW // ] // } // // // on funding currencies (ex. fUSD) // // { // 'result': [ // SYMBOL, // FRR, // BID, // BID_PERIOD, // BID_SIZE, // ASK, // ASK_PERIOD, // ASK_SIZE, // DAILY_CHANGE, // DAILY_CHANGE_RELATIVE, // LAST_PRICE, // VOLUME, // HIGH, // LOW, // _PLACEHOLDER, // _PLACEHOLDER, // FRR_AMOUNT_AVAILABLE // ] // } // market := GetArg(optionalArgs, 0, nil) _ = market var result interface{} = this.SafeList(ticker, "result") var symbol interface{} = this.SafeSymbol(nil, market) var length interface{} = GetArrayLength(result) var last interface{} = this.SafeString(result, Subtract(length, 4)) var percentage interface{} = this.SafeString(result, Subtract(length, 5)) return this.SafeTicker(map[string]interface{} { "symbol": symbol, "timestamp": nil, "datetime": nil, "high": this.SafeString(result, Subtract(length, 2)), "low": this.SafeString(result, Subtract(length, 1)), "bid": this.SafeString(result, Subtract(length, 10)), "bidVolume": this.SafeString(result, Subtract(length, 9)), "ask": this.SafeString(result, Subtract(length, 8)), "askVolume": this.SafeString(result, Subtract(length, 7)), "vwap": nil, "open": nil, "close": last, "last": last, "previousClose": nil, "change": this.SafeString(result, Subtract(length, 6)), "percentage": Precise.StringMul(percentage, "100"), "average": nil, "baseVolume": this.SafeString(result, Subtract(length, 3)), "quoteVolume": nil, "info": result, }, market) } /** * @method * @name bitfinex#fetchTickers * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market * @see https://docs.bitfinex.com/reference/rest-public-tickers * @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 *bitfinex) 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 retRes12528 := (<-this.LoadMarkets()) PanicOnError(retRes12528) symbols = this.MarketSymbols(symbols) var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(symbols, nil)) { var ids interface{} = this.MarketIds(symbols) AddElementToObject(request, "symbols", Join(ids, ",")) } else { AddElementToObject(request, "symbols", "ALL") } tickers:= (<-this.PublicGetTickers(this.Extend(request, params))) PanicOnError(tickers) // // [ // // on trading pairs (ex. tBTCUSD) // [ // SYMBOL, // BID, // BID_SIZE, // ASK, // ASK_SIZE, // DAILY_CHANGE, // DAILY_CHANGE_RELATIVE, // LAST_PRICE, // VOLUME, // HIGH, // LOW // ], // // on funding currencies (ex. fUSD) // [ // SYMBOL, // FRR, // BID, // BID_PERIOD, // BID_SIZE, // ASK, // ASK_PERIOD, // ASK_SIZE, // DAILY_CHANGE, // DAILY_CHANGE_RELATIVE, // LAST_PRICE, // VOLUME, // HIGH, // LOW, // _PLACEHOLDER, // _PLACEHOLDER, // FRR_AMOUNT_AVAILABLE // ], // ... // ] // var result interface{} = map[string]interface{} {} for i := 0; IsLessThan(i, GetArrayLength(tickers)); i++ { var ticker interface{} = GetValue(tickers, i) var marketId interface{} = this.SafeString(ticker, 0) var market interface{} = this.SafeMarket(marketId) var symbol interface{} = GetValue(market, "symbol") AddElementToObject(result, symbol, this.ParseTicker(map[string]interface{} { "result": ticker, }, market)) } ch <- this.FilterByArrayTickers(result, "symbol", symbols) return nil }() return ch } /** * @method * @name bitfinex#fetchTicker * @description fetches a price ticker, a statistical calculation with the information calculated over the past 24 hours for a specific market * @see https://docs.bitfinex.com/reference/rest-public-ticker * @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 *bitfinex) 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 retRes13228 := (<-this.LoadMarkets()) PanicOnError(retRes13228) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } ticker:= (<-this.PublicGetTickerSymbol(this.Extend(request, params))) PanicOnError(ticker) var result interface{} = map[string]interface{} { "result": ticker, } ch <- this.ParseTicker(result, market) return nil }() return ch } func (this *bitfinex) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} { // // fetchTrades (public) // // [ // ID, // MTS, // timestamp // AMOUNT, // PRICE // ] // // fetchMyTrades (private) // // [ // ID, // PAIR, // MTS_CREATE, // ORDER_ID, // EXEC_AMOUNT, // EXEC_PRICE, // ORDER_TYPE, // ORDER_PRICE, // MAKER, // FEE, // FEE_CURRENCY, // ... // ] // market := GetArg(optionalArgs, 0, nil) _ = market var tradeList interface{} = this.SafeList(trade, "result", []interface{}{}) var tradeLength interface{} = GetArrayLength(tradeList) var isPrivate interface{} = (IsGreaterThan(tradeLength, 5)) var id interface{} = this.SafeString(tradeList, 0) var amountIndex interface{} = Ternary(IsTrue(isPrivate), 4, 2) var side interface{} = nil var amountString interface{} = this.SafeString(tradeList, amountIndex) var priceIndex interface{} = Ternary(IsTrue(isPrivate), 5, 3) var priceString interface{} = this.SafeString(tradeList, priceIndex) if IsTrue(IsEqual(GetValue(amountString, 0), "-")) { side = "sell" amountString = Precise.StringAbs(amountString) } else { side = "buy" } var orderId interface{} = nil var takerOrMaker interface{} = nil var typeVar interface{} = nil var fee interface{} = nil var symbol interface{} = this.SafeSymbol(nil, market) var timestampIndex interface{} = Ternary(IsTrue(isPrivate), 2, 1) var timestamp interface{} = this.SafeInteger(tradeList, timestampIndex) if IsTrue(isPrivate) { var marketId interface{} = GetValue(tradeList, 1) symbol = this.SafeSymbol(marketId) orderId = this.SafeString(tradeList, 3) var maker interface{} = this.SafeInteger(tradeList, 8) takerOrMaker = Ternary(IsTrue((IsEqual(maker, 1))), "maker", "taker") var feeCostString interface{} = this.SafeString(tradeList, 9) feeCostString = Precise.StringNeg(feeCostString) var feeCurrencyId interface{} = this.SafeString(tradeList, 10) var feeCurrency interface{} = this.SafeCurrencyCode(feeCurrencyId) fee = map[string]interface{} { "cost": feeCostString, "currency": feeCurrency, } var orderType interface{} = GetValue(tradeList, 6) typeVar = this.SafeString(GetValue(this.Options, "exchangeTypes"), orderType) } return this.SafeTrade(map[string]interface{} { "id": id, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "symbol": symbol, "order": orderId, "side": side, "type": typeVar, "takerOrMaker": takerOrMaker, "price": priceString, "amount": amountString, "cost": nil, "fee": fee, "info": tradeList, }, market) } /** * @method * @name bitfinex#fetchTrades * @description get the list of most recent trades for a particular symbol * @see https://docs.bitfinex.com/reference/rest-public-trades * @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, default 120, max 10000 * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @param {int} [params.until] the latest time in ms to fetch entries for * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades} */ func (this *bitfinex) 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 retRes14308 := (<-this.LoadMarkets()) PanicOnError(retRes14308) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchTrades", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes143419 := (<-this.FetchPaginatedCallDynamic("fetchTrades", symbol, since, limit, params, 10000)) PanicOnError(retRes143419) ch <- retRes143419 return nil } var market interface{} = this.Market(symbol) var sort interface{} = "-1" var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start", since) sort = "1" } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", mathMin(limit, 10000)) // default 120, max 10000 } AddElementToObject(request, "sort", sort) requestparamsVariable := this.HandleUntilOption("end", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) response:= (<-this.PublicGetTradesSymbolHist(this.Extend(request, params))) PanicOnError(response) // // [ // [ // ID, // MTS, // timestamp // AMOUNT, // PRICE // ] // ] // var trades interface{} = this.SortBy(response, 1) var tradesList interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(trades)); i++ { AppendToArray(&tradesList,map[string]interface{} { "result": GetValue(trades, i), }) // convert to array of dicts to match parseOrder signature } ch <- this.ParseTrades(tradesList, market, nil, limit) return nil }() return ch } /** * @method * @name bitfinex#fetchOHLCV * @description fetches historical candlestick data containing the open, high, low, and close price, and the volume of a market * @see https://docs.bitfinex.com/reference/rest-public-candles * @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, default 100 max 10000 * @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 * @param {int} [params.until] timestamp in ms of the latest candle to fetch * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) */ func (this *bitfinex) 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, 100) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes14848 := (<-this.LoadMarkets()) PanicOnError(retRes14848) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOHLCV", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes148819 := (<-this.FetchPaginatedCallDeterministic("fetchOHLCV", symbol, since, limit, timeframe, params, 10000)) PanicOnError(retRes148819) ch <- retRes148819 return nil } var market interface{} = this.Market(symbol) if IsTrue(IsEqual(limit, nil)) { limit = 10000 } else { limit = mathMin(limit, 10000) } var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), "timeframe": this.SafeString(this.Timeframes, timeframe, timeframe), "sort": 1, "limit": limit, } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start", since) } requestparamsVariable := this.HandleUntilOption("end", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) response:= (<-this.PublicGetCandlesTradeTimeframeSymbolHist(this.Extend(request, params))) PanicOnError(response) // // [ // [1591503840000,0.025069,0.025068,0.025069,0.025068,1.97828998], // [1591504500000,0.025065,0.025065,0.025065,0.025065,1.0164], // [1591504620000,0.025062,0.025062,0.025062,0.025062,0.5], // ] // ch <- this.ParseOHLCVs(response, market, timeframe, since, limit) return nil }() return ch } func (this *bitfinex) ParseOHLCV(ohlcv interface{}, optionalArgs ...interface{}) interface{} { // // [ // 1457539800000, // 0.02594, // 0.02594, // 0.02594, // 0.02594, // 0.1 // ] // market := GetArg(optionalArgs, 0, nil) _ = market return []interface{}{this.SafeInteger(ohlcv, 0), this.SafeNumber(ohlcv, 1), this.SafeNumber(ohlcv, 3), this.SafeNumber(ohlcv, 4), this.SafeNumber(ohlcv, 2), this.SafeNumber(ohlcv, 5)} } func (this *bitfinex) ParseOrderStatus(status interface{}) interface{} { if IsTrue(IsEqual(status, nil)) { return status } var parts interface{} = Split(status, " ") var state interface{} = this.SafeString(parts, 0) var statuses interface{} = map[string]interface{} { "ACTIVE": "open", "PARTIALLY": "open", "EXECUTED": "closed", "CANCELED": "canceled", "INSUFFICIENT": "canceled", "POSTONLY CANCELED": "canceled", "RSN_DUST": "rejected", "RSN_PAUSE": "rejected", "IOC CANCELED": "canceled", "FILLORKILL CANCELED": "canceled", } return this.SafeString(statuses, state, status) } func (this *bitfinex) ParseOrderFlags(flags interface{}) interface{} { // flags can be added to each other... var flagValues interface{} = map[string]interface{} { "1024": []interface{}{"reduceOnly"}, "4096": []interface{}{"postOnly"}, "5120": []interface{}{"reduceOnly", "postOnly"}, } return this.SafeValue(flagValues, flags, nil) } func (this *bitfinex) ParseTimeInForce(orderType interface{}) interface{} { var orderTypes interface{} = map[string]interface{} { "EXCHANGE IOC": "IOC", "EXCHANGE FOK": "FOK", "IOC": "IOC", "FOK": "FOK", } return this.SafeString(orderTypes, orderType, "GTC") } func (this *bitfinex) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} { market := GetArg(optionalArgs, 0, nil) _ = market var orderList interface{} = this.SafeList(order, "result") var id interface{} = this.SafeString(orderList, 0) var marketId interface{} = this.SafeString(orderList, 3) var symbol interface{} = this.SafeSymbol(marketId) // https://github.com/ccxt/ccxt/issues/6686 // const timestamp = this.safeTimestamp (orderObject, 5); var timestamp interface{} = this.SafeInteger(orderList, 5) var remaining interface{} = Precise.StringAbs(this.SafeString(orderList, 6)) var signedAmount interface{} = this.SafeString(orderList, 7) var amount interface{} = Precise.StringAbs(signedAmount) var side interface{} = Ternary(IsTrue(Precise.StringLt(signedAmount, "0")), "sell", "buy") var orderType interface{} = this.SafeString(orderList, 8) var typeVar interface{} = this.SafeString(this.SafeValue(this.Options, "exchangeTypes"), orderType) var timeInForce interface{} = this.ParseTimeInForce(orderType) var rawFlags interface{} = this.SafeString(orderList, 12) var flags interface{} = this.ParseOrderFlags(rawFlags) var postOnly interface{} = false if IsTrue(!IsEqual(flags, nil)) { for i := 0; IsLessThan(i, GetArrayLength(flags)); i++ { if IsTrue(IsEqual(GetValue(flags, i), "postOnly")) { postOnly = true } } } var price interface{} = this.SafeString(orderList, 16) var triggerPrice interface{} = nil if IsTrue(IsTrue((IsEqual(orderType, "EXCHANGE STOP"))) || IsTrue((IsEqual(orderType, "EXCHANGE STOP LIMIT")))) { price = nil triggerPrice = this.SafeString(orderList, 16) if IsTrue(IsEqual(orderType, "EXCHANGE STOP LIMIT")) { price = this.SafeString(orderList, 19) } } var status interface{} = nil var statusString interface{} = this.SafeString(orderList, 13) if IsTrue(!IsEqual(statusString, nil)) { var parts interface{} = Split(statusString, " @ ") status = this.ParseOrderStatus(this.SafeString(parts, 0)) } var average interface{} = this.SafeString(orderList, 17) var clientOrderId interface{} = this.SafeString(orderList, 2) return this.SafeOrder(map[string]interface{} { "info": orderList, "id": id, "clientOrderId": clientOrderId, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "lastTradeTimestamp": nil, "symbol": symbol, "type": typeVar, "timeInForce": timeInForce, "postOnly": postOnly, "side": side, "price": price, "triggerPrice": triggerPrice, "amount": amount, "cost": nil, "average": average, "filled": nil, "remaining": remaining, "status": status, "fee": nil, "trades": nil, }, market) } func (this *bitfinex) CreateOrderRequest(symbol interface{}, typeVar interface{}, side interface{}, amount interface{}, optionalArgs ...interface{}) interface{} { /** * @method * @ignore * @name bitfinex#createOrderRequest * @description helper function to build an order request * @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 you want to trade in units of the base currency * @param {float} [price] the price of the order, in units of the quote currency, ignored in market orders * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {float} [params.triggerPrice] The price at which a trigger order is triggered at * @param {string} [params.timeInForce] "GTC", "IOC", "FOK", or "PO" * @param {bool} [params.postOnly] * @param {bool} [params.reduceOnly] Ensures that the executed order does not flip the opened position. * @param {int} [params.flags] additional order parameters: 4096 (Post Only), 1024 (Reduce Only), 16384 (OCO), 64 (Hidden), 512 (Close), 524288 (No Var Rates) * @param {int} [params.lev] leverage for a derivative order, supported by derivative symbol orders only. The value should be between 1 and 100 inclusive. * @param {string} [params.price_traling] The trailing price for a trailing stop order * @param {string} [params.price_aux_limit] Order price for stop limit orders * @param {string} [params.price_oco_stop] OCO stop price * @returns {object} an [order structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#order-structure} */ price := GetArg(optionalArgs, 0, nil) _ = price params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params var market interface{} = this.Market(symbol) var amountString interface{} = this.AmountToPrecision(symbol, amount) amountString = Ternary(IsTrue((IsEqual(side, "buy"))), amountString, Precise.StringNeg(amountString)) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), "amount": amountString, } var triggerPrice interface{} = this.SafeString2(params, "stopPrice", "triggerPrice") var trailingAmount interface{} = this.SafeString(params, "trailingAmount") var timeInForce interface{} = this.SafeString(params, "timeInForce") var postOnlyParam interface{} = this.SafeBool(params, "postOnly", false) var reduceOnly interface{} = this.SafeBool(params, "reduceOnly", false) var clientOrderId interface{} = this.SafeValue2(params, "cid", "clientOrderId") var orderType interface{} = ToUpper(typeVar) if IsTrue(!IsEqual(trailingAmount, nil)) { orderType = "TRAILING STOP" AddElementToObject(request, "price_trailing", trailingAmount) } else if IsTrue(!IsEqual(triggerPrice, nil)) { // request['price'] is taken as triggerPrice for stop orders AddElementToObject(request, "price", this.PriceToPrecision(symbol, triggerPrice)) if IsTrue(IsEqual(typeVar, "limit")) { orderType = "STOP LIMIT" AddElementToObject(request, "price_aux_limit", this.PriceToPrecision(symbol, price)) } else { orderType = "STOP" } } var ioc interface{} = (IsEqual(timeInForce, "IOC")) var fok interface{} = (IsEqual(timeInForce, "FOK")) var postOnly interface{} = (IsTrue(postOnlyParam) || IsTrue((IsEqual(timeInForce, "PO")))) if IsTrue(IsTrue((IsTrue(ioc) || IsTrue(fok))) && IsTrue((IsEqual(price, nil)))) { panic(InvalidOrder(Add(this.Id, " createOrder() requires a price argument with IOC and FOK orders"))) } if IsTrue(IsTrue((IsTrue(ioc) || IsTrue(fok))) && IsTrue((IsEqual(typeVar, "market")))) { panic(InvalidOrder(Add(this.Id, " createOrder() does not allow market IOC and FOK orders"))) } if IsTrue(IsTrue((!IsEqual(typeVar, "market"))) && IsTrue((IsEqual(triggerPrice, nil)))) { AddElementToObject(request, "price", this.PriceToPrecision(symbol, price)) } if IsTrue(ioc) { orderType = "IOC" } else if IsTrue(fok) { orderType = "FOK" } var marginMode interface{} = nil marginModeparamsVariable := this.HandleMarginModeAndParams("createOrder", params); marginMode = GetValue(marginModeparamsVariable,0); params = GetValue(marginModeparamsVariable,1) if IsTrue(IsTrue(GetValue(market, "spot")) && IsTrue((IsEqual(marginMode, nil)))) { // The EXCHANGE prefix is only required for non margin spot markets orderType = Add("EXCHANGE ", orderType) } AddElementToObject(request, "type", orderType) // flag values may be summed to combine flags var flags interface{} = 0 if IsTrue(postOnly) { flags = this.Sum(flags, 4096) } if IsTrue(reduceOnly) { flags = this.Sum(flags, 1024) } if IsTrue(!IsEqual(flags, 0)) { AddElementToObject(request, "flags", flags) } if IsTrue(!IsEqual(clientOrderId, nil)) { AddElementToObject(request, "cid", clientOrderId) } params = this.Omit(params, []interface{}{"triggerPrice", "stopPrice", "timeInForce", "postOnly", "reduceOnly", "trailingAmount", "clientOrderId"}) return this.Extend(request, params) } /** * @method * @name bitfinex#createOrder * @description create an order on the exchange * @see https://docs.bitfinex.com/reference/rest-auth-submit-order * @param {string} symbol unified CCXT market symbol * @param {string} type 'limit' or 'market' * @param {string} side 'buy' or 'sell' * @param {float} amount the amount of currency to trade * @param {float} [price] price of the order * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {float} [params.triggerPrice] the price that triggers a trigger order * @param {string} [params.timeInForce] "GTC", "IOC", "FOK", or "PO" * @param {boolean} [params.postOnly] set to true if you want to make a post only order * @param {boolean} [params.reduceOnly] indicates that the order is to reduce the size of a position * @param {int} [params.flags] additional order parameters: 4096 (Post Only), 1024 (Reduce Only), 16384 (OCO), 64 (Hidden), 512 (Close), 524288 (No Var Rates) * @param {int} [params.lev] leverage for a derivative order, supported by derivative symbol orders only. The value should be between 1 and 100 inclusive. * @param {string} [params.price_aux_limit] order price for stop limit orders * @param {string} [params.price_oco_stop] OCO stop price * @param {string} [params.trailingAmount] *swap only* the quote amount to trail away from the current market price * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *bitfinex) 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 retRes17658 := (<-this.LoadMarkets()) PanicOnError(retRes17658) var market interface{} = this.Market(symbol) var request interface{} = this.CreateOrderRequest(symbol, typeVar, side, amount, price, params) response:= (<-this.PrivatePostAuthWOrderSubmit(request)) PanicOnError(response) // // [ // 1653325121, // Timestamp in milliseconds // "on-req", // Purpose of notification ('on-req', 'oc-req', "uca", 'fon-req', "foc-req") // null, // unique ID of the message // null, // [ // [ // 95412102131, // Order ID // null, // Group ID // 1653325121798, // Client Order ID // "tDOGE:UST", // Market ID // 1653325121798, // Millisecond timestamp of creation // 1653325121798, // Millisecond timestamp of update // -10, // Amount (Positive means buy, negative means sell) // -10, // Original amount // "EXCHANGE LIMIT", // Type of the order: LIMIT, EXCHANGE LIMIT, MARKET, EXCHANGE MARKET, STOP, EXCHANGE STOP, STOP LIMIT, EXCHANGE STOP LIMIT, TRAILING STOP, EXCHANGE TRAILING STOP, FOK, EXCHANGE FOK, IOC, EXCHANGE IOC. // null, // Previous order type (stop-limit orders are converted to limit orders so for them previous type is always STOP) // null, // Millisecond timestamp of Time-In-Force: automatic order cancellation // null, // _PLACEHOLDER // 4096, // Flags, see parseOrderFlags() // "ACTIVE", // Order Status, see parseOrderStatus() // null, // _PLACEHOLDER // null, // _PLACEHOLDER // 0.071, // Price (Stop Price for stop-limit orders, Limit Price for limit orders) // 0, // Average Price // 0, // Trailing Price // 0, // Auxiliary Limit price (for STOP LIMIT) // null, // _PLACEHOLDER // null, // _PLACEHOLDER // null, // _PLACEHOLDER // 0, // Hidden (0 if false, 1 if true) // 0, // Placed ID (If another order caused this order to be placed (OCO) this will be that other order's ID) // null, // _PLACEHOLDER // null, // _PLACEHOLDER // null, // _PLACEHOLDER // "API>BFX", // Routing, indicates origin of action: BFX, ETHFX, API>BFX, API>ETHFX // null, // _PLACEHOLDER // null, // _PLACEHOLDER // {"$F7":1} // additional meta information about the order ( $F7 = IS_POST_ONLY (0 if false, 1 if true), $F33 = Leverage (int)) // ] // ], // null, // CODE (work in progress) // "SUCCESS", // Status of the request // "Submitting 1 orders." // Message // ] // var status interface{} = this.SafeString(response, 6) if IsTrue(!IsEqual(status, "SUCCESS")) { var errorCode interface{} = GetValue(response, 5) var errorText interface{} = GetValue(response, 7) panic(ExchangeError(Add(Add(Add(Add(Add(Add(Add(this.Id, " "), GetValue(response, 6)), ": "), errorText), " (#"), errorCode), ")"))) } var orders interface{} = this.SafeList(response, 4, []interface{}{}) var order interface{} = this.SafeList(orders, 0) var newOrder interface{} = map[string]interface{} { "result": order, } ch <- this.ParseOrder(newOrder, market) return nil }() return ch } /** * @method * @name bitfinex#createOrders * @description create a list of trade orders * @see https://docs.bitfinex.com/reference/rest-auth-order-multi * @param {Array} orders list of orders to create, each object should contain the parameters required by createOrder, namely symbol, type, side, amount, price and params * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *bitfinex) CreateOrders(orders 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 retRes18388 := (<-this.LoadMarkets()) PanicOnError(retRes18388) var ordersRequests interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(orders)); i++ { var rawOrder interface{} = GetValue(orders, i) var symbol interface{} = this.SafeString(rawOrder, "symbol") var typeVar interface{} = this.SafeString(rawOrder, "type") var side interface{} = this.SafeString(rawOrder, "side") var amount interface{} = this.SafeNumber(rawOrder, "amount") var price interface{} = this.SafeNumber(rawOrder, "price") var orderParams interface{} = this.SafeDict(rawOrder, "params", map[string]interface{} {}) var orderRequest interface{} = this.CreateOrderRequest(symbol, typeVar, side, amount, price, orderParams) AppendToArray(&ordersRequests,[]interface{}{"on", orderRequest}) } var request interface{} = map[string]interface{} { "ops": ordersRequests, } response:= (<-this.PrivatePostAuthWOrderMulti(request)) PanicOnError(response) // // [ // 1706762515553, // "ox_multi-req", // null, // null, // [ // [ // 1706762515, // "on-req", // null, // null, // [ // [139567428547,null,1706762515551,"tBTCUST",1706762515551,1706762515551,0.0001,0.0001,"EXCHANGE LIMIT",null,null,null,0,"ACTIVE",null,null,35000,0,0,0,null,null,null,0,0,null,null,null,"API>BFX",null,null,{}] // ], // null, // "SUCCESS", // "Submitting 1 orders." // ], // ], // null, // "SUCCESS", // "Submitting 2 order operations." // ] // var results interface{} = []interface{}{} var data interface{} = this.SafeList(response, 4, []interface{}{}) for i := 0; IsLessThan(i, GetArrayLength(data)); i++ { var entry interface{} = GetValue(data, i) var individualOrder interface{} = GetValue(entry, 4) AppendToArray(&results,map[string]interface{} { "result": GetValue(individualOrder, 0), }) } ch <- this.ParseOrders(results) return nil }() return ch } /** * @method * @name bitfinex#cancelAllOrders * @description cancel all open orders * @see https://docs.bitfinex.com/reference/rest-auth-cancel-orders-multiple * @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 *bitfinex) 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 retRes19008 := (<-this.LoadMarkets()) PanicOnError(retRes19008) var request interface{} = map[string]interface{} { "all": 1, } response:= (<-this.PrivatePostAuthWOrderCancelMulti(this.Extend(request, params))) PanicOnError(response) var orders interface{} = this.SafeList(response, 4, []interface{}{}) var ordersList interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(orders)); i++ { AppendToArray(&ordersList,map[string]interface{} { "result": GetValue(orders, i), }) } ch <- this.ParseOrders(ordersList) return nil }() return ch } /** * @method * @name bitfinex#cancelOrder * @description cancels an open order * @see https://docs.bitfinex.com/reference/rest-auth-cancel-order * @param {string} id order id * @param {string} symbol Not used by bitfinex cancelOrder () * @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 *bitfinex) 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 retRes19248 := (<-this.LoadMarkets()) PanicOnError(retRes19248) var cid interface{} = this.SafeValue2(params, "cid", "clientOrderId") // client order id var request interface{} = nil var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } if IsTrue(!IsEqual(cid, nil)) { var cidDate interface{} = this.SafeValue(params, "cidDate") // client order id date if IsTrue(IsEqual(cidDate, nil)) { panic(InvalidOrder(Add(this.Id, " canceling an order by clientOrderId (\\'cid\\') requires both \\'cid\\' and \\'cid_date\\' (\\'YYYY-MM-DD\\')"))) } request = map[string]interface{} { "cid": cid, "cid_date": cidDate, } params = this.Omit(params, []interface{}{"cid", "clientOrderId"}) } else { request = map[string]interface{} { "id": ParseInt(id), } } response:= (<-this.PrivatePostAuthWOrderCancel(this.Extend(request, params))) PanicOnError(response) var order interface{} = this.SafeValue(response, 4) var newOrder interface{} = map[string]interface{} { "result": order, } ch <- this.ParseOrder(newOrder, market) return nil }() return ch } /** * @method * @name bitfinex#cancelOrders * @description cancel multiple orders at the same time * @see https://docs.bitfinex.com/reference/rest-auth-cancel-orders-multiple * @param {string[]} ids order ids * @param {string} symbol unified market symbol, default is undefined * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an array of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *bitfinex) CancelOrders(ids interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes19638 := (<-this.LoadMarkets()) PanicOnError(retRes19638) for i := 0; IsLessThan(i, GetArrayLength(ids)); i++ { AddElementToObject(ids, i, this.ParseToNumeric(GetValue(ids, i))) } var request interface{} = map[string]interface{} { "id": ids, } var market interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) } response:= (<-this.PrivatePostAuthWOrderCancelMulti(this.Extend(request, params))) PanicOnError(response) // // [ // 1706740198811, // "oc_multi-req", // null, // null, // [ // [ // 139530205057, // null, // 1706740132275, // "tBTCF0:USTF0", // 1706740132276, // 1706740132276, // 0.0001, // 0.0001, // "LIMIT", // null, // null, // null, // 0, // "ACTIVE", // null, // null, // 39000, // 0, // 0, // 0, // null, // null, // null, // 0, // 0, // null, // null, // null, // "API>BFX", // null, // null, // { // "lev": 10, // "$F33": 10 // } // ], // ], // null, // "SUCCESS", // "Submitting 2 order cancellations." // ] // var orders interface{} = this.SafeList(response, 4, []interface{}{}) var ordersList interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(orders)); i++ { AppendToArray(&ordersList,map[string]interface{} { "result": GetValue(orders, i), }) } ch <- this.ParseOrders(ordersList, market) return nil }() return ch } /** * @method * @name bitfinex#fetchOpenOrder * @description fetch an open order by it's id * @see https://docs.bitfinex.com/reference/rest-auth-retrieve-orders * @see https://docs.bitfinex.com/reference/rest-auth-retrieve-orders-by-symbol * @param {string} id order id * @param {string} symbol unified market symbol, default is undefined * @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 *bitfinex) FetchOpenOrder(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 var request interface{} = map[string]interface{} { "id": []interface{}{ParseInt(id)}, } orders:= (<-this.FetchOpenOrders(symbol, nil, nil, this.Extend(request, params))) PanicOnError(orders) var order interface{} = this.SafeValue(orders, 0) if IsTrue(IsEqual(order, nil)) { panic(OrderNotFound(Add(Add(Add(this.Id, " order "), id), " not found"))) } ch <- order return nil }() return ch } /** * @method * @name bitfinex#fetchClosedOrder * @description fetch an open order by it's id * @see https://docs.bitfinex.com/reference/rest-auth-retrieve-orders * @see https://docs.bitfinex.com/reference/rest-auth-retrieve-orders-by-symbol * @param {string} id order id * @param {string} symbol unified market symbol, default is undefined * @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 *bitfinex) FetchClosedOrder(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 var request interface{} = map[string]interface{} { "id": []interface{}{ParseInt(id)}, } orders:= (<-this.FetchClosedOrders(symbol, nil, nil, this.Extend(request, params))) PanicOnError(orders) var order interface{} = this.SafeValue(orders, 0) if IsTrue(IsEqual(order, nil)) { panic(OrderNotFound(Add(Add(Add(this.Id, " order "), id), " not found"))) } ch <- order return nil }() return ch } /** * @method * @name bitfinex#fetchOpenOrders * @description fetch all unfilled currently open orders * @see https://docs.bitfinex.com/reference/rest-auth-retrieve-orders * @see https://docs.bitfinex.com/reference/rest-auth-retrieve-orders-by-symbol * @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 *bitfinex) 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 retRes20928 := (<-this.LoadMarkets()) PanicOnError(retRes20928) var request interface{} = map[string]interface{} {} var market interface{} = nil var response interface{} = nil if IsTrue(IsEqual(symbol, nil)) { response = (<-this.PrivatePostAuthROrders(this.Extend(request, params))) PanicOnError(response) } else { market = this.Market(symbol) AddElementToObject(request, "symbol", GetValue(market, "id")) response = (<-this.PrivatePostAuthROrdersSymbol(this.Extend(request, params))) PanicOnError(response) } // // [ // [ // 95408916206, // Order ID // null, // Group Order ID // 1653322349926, // Client Order ID // "tDOGE:UST", // Market ID // 1653322349926, // Created Timestamp in milliseconds // 1653322349927, // Updated Timestamp in milliseconds // -10, // Amount remaining (Positive means buy, negative means sell) // -10, // Original amount // "EXCHANGE LIMIT", // Order type // null, // Previous Order Type // null, // _PLACEHOLDER // null, // _PLACEHOLDER // 0, // Flags, see parseOrderFlags() // "ACTIVE", // Order Status, see parseOrderStatus() // null, // _PLACEHOLDER // null, // _PLACEHOLDER // 0.11, // Price // 0, // Average Price // 0, // Trailing Price // 0, // Auxiliary Limit price (for STOP LIMIT) // null, // _PLACEHOLDER // null, // _PLACEHOLDER // null, // _PLACEHOLDER // 0, // Hidden (0 if false, 1 if true) // 0, // Placed ID (If another order caused this order to be placed (OCO) this will be that other order's ID) // null, // _PLACEHOLDER // null, // _PLACEHOLDER // null, // _PLACEHOLDER // "API>BFX", // Routing, indicates origin of action: BFX, ETHFX, API>BFX, API>ETHFX // null, // _PLACEHOLDER // null, // _PLACEHOLDER // {"$F7":1} // additional meta information about the order ( $F7 = IS_POST_ONLY (0 if false, 1 if true), $F33 = Leverage (int)) // ], // ] // var ordersList interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(response)); i++ { AppendToArray(&ordersList,map[string]interface{} { "result": GetValue(response, i), }) } ch <- this.ParseOrders(ordersList, market, since, limit) return nil }() return ch } /** * @method * @name bitfinex#fetchClosedOrders * @description fetches information on multiple closed orders made by the user * @see https://docs.bitfinex.com/reference/rest-auth-retrieve-orders * @see https://docs.bitfinex.com/reference/rest-auth-retrieve-orders-by-symbol * @param {string} symbol unified market symbol of the market orders were made in * @param {int} [since] the earliest time in ms to fetch orders for * @param {int} [limit] the maximum number of order structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] the latest time in ms to fetch entries for * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [availble parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *bitfinex) FetchClosedOrders(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) // returns the most recent closed or canceled orders up to circa two weeks ago 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 retRes21648 := (<-this.LoadMarkets()) PanicOnError(retRes21648) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchClosedOrders", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes216819 := (<-this.FetchPaginatedCallDynamic("fetchClosedOrders", symbol, since, limit, params)) PanicOnError(retRes216819) ch <- retRes216819 return nil } var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) // default 25, max 2500 } requestparamsVariable := this.HandleUntilOption("end", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) var market interface{} = nil var response interface{} = nil if IsTrue(IsEqual(symbol, nil)) { response = (<-this.PrivatePostAuthROrdersHist(this.Extend(request, params))) PanicOnError(response) } else { market = this.Market(symbol) AddElementToObject(request, "symbol", GetValue(market, "id")) response = (<-this.PrivatePostAuthROrdersSymbolHist(this.Extend(request, params))) PanicOnError(response) } // // [ // [ // 95412102131, // Order ID // null, // Group Order ID // 1653325121798, // Client Order ID // "tDOGE:UST", // Market ID // 1653325122000, // Created Timestamp in milliseconds // 1653325122000, // Updated Timestamp in milliseconds // -10, // Amount remaining (Positive means buy, negative means sell) // -10, // Original amount // "EXCHANGE LIMIT", // Order type // null, // Previous Order Type // null, // Millisecond timestamp of Time-In-Force: automatic order cancellation // null, // _PLACEHOLDER // "4096", // Flags, see parseOrderFlags() // "POSTONLY CANCELED", // Order Status, see parseOrderStatus() // null, // _PLACEHOLDER // null, // _PLACEHOLDER // 0.071, // Price // 0, // Average Price // 0, // Trailing Price // 0, // Auxiliary Limit price (for STOP LIMIT) // null, // _PLACEHOLDER // null, // _PLACEHOLDER // null, // _PLACEHOLDER // 0, // Notify (0 if false, 1 if true) // 0, // Hidden (0 if false, 1 if true) // null, // Placed ID (If another order caused this order to be placed (OCO) this will be that other order's ID) // null, // _PLACEHOLDER // null, // _PLACEHOLDER // "API>BFX", // Routing, indicates origin of action: BFX, ETHFX, API>BFX, API>ETHFX // null, // _PLACEHOLDER // null, // _PLACEHOLDER // {"_$F7":1} // additional meta information about the order ( _$F7 = IS_POST_ONLY (0 if false, 1 if true), _$F33 = Leverage (int)) // ] // ] // var ordersList interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(response)); i++ { AppendToArray(&ordersList,map[string]interface{} { "result": GetValue(response, i), }) } ch <- this.ParseOrders(ordersList, market, since, limit) return nil }() return ch } /** * @method * @name bitfinex#fetchOrderTrades * @description fetch all the trades made from a single order * @see https://docs.bitfinex.com/reference/rest-auth-order-trades * @param {string} id order id * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch trades for * @param {int} [limit] the maximum number of trades to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=trade-structure} */ func (this *bitfinex) FetchOrderTrades(id interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchOrderTrades() requires a symbol argument"))) } retRes22488 := (<-this.LoadMarkets()) PanicOnError(retRes22488) var market interface{} = this.Market(symbol) var orderId interface{} = ParseInt(id) var request interface{} = map[string]interface{} { "id": orderId, "symbol": GetValue(market, "id"), } // valid for trades upto 10 days old response:= (<-this.PrivatePostAuthROrderSymbolIdTrades(this.Extend(request, params))) PanicOnError(response) var tradesList interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(response)); i++ { AppendToArray(&tradesList,map[string]interface{} { "result": GetValue(response, i), }) // convert to array of dicts to match parseOrder signature } ch <- this.ParseTrades(tradesList, market, since, limit) return nil }() return ch } /** * @method * @name bitfinex#fetchMyTrades * @description fetch all trades made by the user * @see https://docs.bitfinex.com/reference/rest-auth-trades * @see https://docs.bitfinex.com/reference/rest-auth-trades-by-symbol * @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 *bitfinex) 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 retRes22778 := (<-this.LoadMarkets()) PanicOnError(retRes22778) var market interface{} = nil var request interface{} = map[string]interface{} { "end": this.Milliseconds(), } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) // default 25, max 1000 } var response interface{} = nil if IsTrue(!IsEqual(symbol, nil)) { market = this.Market(symbol) AddElementToObject(request, "symbol", GetValue(market, "id")) response = (<-this.PrivatePostAuthRTradesSymbolHist(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivatePostAuthRTradesHist(this.Extend(request, params))) PanicOnError(response) } var tradesList interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(response)); i++ { AppendToArray(&tradesList,map[string]interface{} { "result": GetValue(response, i), }) // convert to array of dicts to match parseOrder signature } ch <- this.ParseTrades(tradesList, market, since, limit) return nil }() return ch } /** * @method * @name bitfinex#createDepositAddress * @description create a currency deposit address * @see https://docs.bitfinex.com/reference/rest-auth-deposit-address * @param {string} code unified currency code of the currency for the deposit address * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an [address structure]{@link https://docs.ccxt.com/#/?id=address-structure} */ func (this *bitfinex) CreateDepositAddress(code interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes23138 := (<-this.LoadMarkets()) PanicOnError(retRes23138) var request interface{} = map[string]interface{} { "op_renew": 1, } retRes231715 := (<-this.FetchDepositAddress(code, this.Extend(request, params))) PanicOnError(retRes231715) ch <- retRes231715 return nil }() return ch } /** * @method * @name bitfinex#fetchDepositAddress * @description fetch the deposit address for a currency associated with this account * @see https://docs.bitfinex.com/reference/rest-auth-deposit-address * @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 *bitfinex) 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 retRes23308 := (<-this.LoadMarkets()) PanicOnError(retRes23308) var currency interface{} = this.Currency(code) // if not provided explicitly we will try to match using the currency name var network interface{} = this.SafeString(params, "network", code) var currencyNetworks interface{} = this.SafeValue(currency, "networks", map[string]interface{} {}) var currencyNetwork interface{} = this.SafeValue(currencyNetworks, network) var networkId interface{} = this.SafeString(currencyNetwork, "id") if IsTrue(IsEqual(networkId, nil)) { panic(ArgumentsRequired(Add(Add(Add(this.Id, " fetchDepositAddress() could not find a network for \\'"), code), "\\'. You can specify it by providing the \\'network\\' value inside params"))) } var wallet interface{} = this.SafeString(params, "wallet", "exchange") // 'exchange', 'margin', 'funding' and also old labels 'exchange', 'trading', 'deposit', respectively params = this.Omit(params, "network", "wallet") var request interface{} = map[string]interface{} { "method": networkId, "wallet": wallet, "op_renew": 0, } response:= (<-this.PrivatePostAuthWDepositAddress(this.Extend(request, params))) PanicOnError(response) // // [ // 1582269616687, // MTS Millisecond Time Stamp of the update // "acc_dep", // TYPE Purpose of notification "acc_dep" for account deposit // null, // MESSAGE_ID unique ID of the message // null, // not documented // [ // null, // PLACEHOLDER // "BITCOIN", // METHOD Method of deposit // "BTC", // CURRENCY_CODE Currency code of new address // null, // PLACEHOLDER // "1BC9PZqpUmjyEB54uggn8TFKj49zSDYzqG", // ADDRESS // null, // POOL_ADDRESS // ], // null, // CODE null or integer work in progress // "SUCCESS", // STATUS Status of the notification, SUCCESS, ERROR, FAILURE // "success", // TEXT Text of the notification // ] // var result interface{} = this.SafeValue(response, 4, []interface{}{}) var poolAddress interface{} = this.SafeString(result, 5) var address interface{} = Ternary(IsTrue((IsEqual(poolAddress, nil))), this.SafeString(result, 4), poolAddress) var tag interface{} = Ternary(IsTrue((IsEqual(poolAddress, nil))), nil, this.SafeString(result, 4)) this.CheckAddress(address) ch <- map[string]interface{} { "currency": code, "address": address, "tag": tag, "network": nil, "info": response, } return nil }() return ch } func (this *bitfinex) ParseTransactionStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "SUCCESS": "ok", "COMPLETED": "ok", "ERROR": "failed", "FAILURE": "failed", "CANCELED": "canceled", "PENDING APPROVAL": "pending", "PENDING": "pending", "PENDING REVIEW": "pending", "PENDING CANCELLATION": "pending", "SENDING": "pending", "USER APPROVED": "pending", } return this.SafeString(statuses, status, status) } func (this *bitfinex) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} { // // withdraw // // [ // 1582271520931, // MTS Millisecond Time Stamp of the update // "acc_wd-req", // TYPE Purpose of notification "acc_wd-req" account withdrawal request // null, // MESSAGE_ID unique ID of the message // null, // not documented // [ // 0, // WITHDRAWAL_ID Unique Withdrawal ID // null, // PLACEHOLDER // "bitcoin", // METHOD Method of withdrawal // null, // PAYMENT_ID Payment ID if relevant // "exchange", // WALLET Sending wallet // 1, // AMOUNT Amount of Withdrawal less fee // null, // PLACEHOLDER // null, // PLACEHOLDER // 0.0004, // WITHDRAWAL_FEE Fee on withdrawal // ], // null, // CODE null or integer Work in progress // "SUCCESS", // STATUS Status of the notification, it may vary over time SUCCESS, ERROR, FAILURE // "Invalid bitcoin address (abcdef)", // TEXT Text of the notification // ] // // fetchDepositsWithdrawals // // [ // 13293039, // ID // "ETH", // CURRENCY // "ETHEREUM", // CURRENCY_NAME // null, // null, // 1574175052000, // MTS_STARTED // 1574181326000, // MTS_UPDATED // null, // null, // "CANCELED", // STATUS // null, // null, // -0.24, // AMOUNT, negative for withdrawals // -0.00135, // FEES // null, // null, // "0x38110e0Fc932CB2BE...........", // DESTINATION_ADDRESS // null, // null, // null, // "0x523ec8945500.....................................", // TRANSACTION_ID // "Purchase of 100 pizzas", // WITHDRAW_TRANSACTION_NOTE, might also be: null // ] // currency := GetArg(optionalArgs, 0, nil) _ = currency var transactionLength interface{} = GetArrayLength(transaction) var timestamp interface{} = nil var updated interface{} = nil var code interface{} = nil var amount interface{} = nil var id interface{} = nil var status interface{} = nil var tag interface{} = nil var typeVar interface{} = nil var feeCost interface{} = nil var txid interface{} = nil var addressTo interface{} = nil var network interface{} = nil var comment interface{} = nil if IsTrue(IsEqual(transactionLength, 8)) { var data interface{} = this.SafeValue(transaction, 4, []interface{}{}) timestamp = this.SafeInteger(transaction, 0) if IsTrue(!IsEqual(currency, nil)) { code = GetValue(currency, "code") } feeCost = this.SafeString(data, 8) if IsTrue(!IsEqual(feeCost, nil)) { feeCost = Precise.StringAbs(feeCost) } amount = this.SafeNumber(data, 5) id = this.SafeInteger(data, 0) status = "ok" if IsTrue(IsEqual(id, 0)) { id = nil status = "failed" } tag = this.SafeString(data, 3) typeVar = "withdrawal" var networkId interface{} = this.SafeString(data, 2) network = this.NetworkIdToCode(ToUpper(networkId)) // withdraw returns in lowercase } else if IsTrue(IsEqual(transactionLength, 22)) { id = this.SafeString(transaction, 0) var currencyId interface{} = this.SafeString(transaction, 1) code = this.SafeCurrencyCode(currencyId, currency) var networkId interface{} = this.SafeString(transaction, 2) network = this.NetworkIdToCode(networkId) timestamp = this.SafeInteger(transaction, 5) updated = this.SafeInteger(transaction, 6) status = this.ParseTransactionStatus(this.SafeString(transaction, 9)) var signedAmount interface{} = this.SafeString(transaction, 12) amount = Precise.StringAbs(signedAmount) if IsTrue(!IsEqual(signedAmount, nil)) { if IsTrue(Precise.StringLt(signedAmount, "0")) { typeVar = "withdrawal" } else { typeVar = "deposit" } } feeCost = this.SafeString(transaction, 13) if IsTrue(!IsEqual(feeCost, nil)) { feeCost = Precise.StringAbs(feeCost) } addressTo = this.SafeString(transaction, 16) txid = this.SafeString(transaction, 20) comment = this.SafeString(transaction, 21) } return map[string]interface{} { "info": transaction, "id": id, "txid": txid, "type": typeVar, "currency": code, "network": network, "amount": this.ParseNumber(amount), "status": status, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "address": addressTo, "addressFrom": nil, "addressTo": addressTo, "tag": tag, "tagFrom": nil, "tagTo": tag, "updated": updated, "comment": comment, "internal": nil, "fee": map[string]interface{} { "currency": code, "cost": this.ParseNumber(feeCost), "rate": nil, }, } } /** * @method * @name bitfinex#fetchTradingFees * @description fetch the trading fees for multiple markets * @see https://docs.bitfinex.com/reference/rest-auth-summary * @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 *bitfinex) 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 retRes25488 := (<-this.LoadMarkets()) PanicOnError(retRes25488) response:= (<-this.PrivatePostAuthRSummary(params)) PanicOnError(response) // // Response Spec: // [ // PLACEHOLDER, // PLACEHOLDER, // PLACEHOLDER, // PLACEHOLDER, // [ // [ // MAKER_FEE, // MAKER_FEE, // MAKER_FEE, // PLACEHOLDER, // PLACEHOLDER, // DERIV_REBATE // ], // [ // TAKER_FEE_TO_CRYPTO, // TAKER_FEE_TO_STABLE, // TAKER_FEE_TO_FIAT, // PLACEHOLDER, // PLACEHOLDER, // DERIV_TAKER_FEE // ] // ], // PLACEHOLDER, // PLACEHOLDER, // PLACEHOLDER, // PLACEHOLDER, // { // LEO_LEV, // LEO_AMOUNT_AVG // } // ] // // Example response: // // [ // null, // null, // null, // null, // [ // [ 0.001, 0.001, 0.001, null, null, 0.0002 ], // [ 0.002, 0.002, 0.002, null, null, 0.00065 ] // ], // [ // [ // { // "curr": "Total (USD)", // "vol": "0", // "vol_safe": "0", // "vol_maker": "0", // "vol_BFX": "0", // "vol_BFX_safe": "0", // "vol_BFX_maker": "0" // } // ], // {}, // 0 // ], // [ null, {}, 0 ], // null, // null, // { leo_lev: "0", leo_amount_avg: "0" } // ] // var result interface{} = map[string]interface{} {} var fiat interface{} = this.SafeValue(this.Options, "fiat", map[string]interface{} {}) var feeData interface{} = this.SafeValue(response, 4, []interface{}{}) var makerData interface{} = this.SafeValue(feeData, 0, []interface{}{}) var takerData interface{} = this.SafeValue(feeData, 1, []interface{}{}) var makerFee interface{} = this.SafeNumber(makerData, 0) var makerFeeFiat interface{} = this.SafeNumber(makerData, 2) var makerFeeDeriv interface{} = this.SafeNumber(makerData, 5) var takerFee interface{} = this.SafeNumber(takerData, 0) var takerFeeFiat interface{} = this.SafeNumber(takerData, 2) var takerFeeDeriv interface{} = this.SafeNumber(takerData, 5) for i := 0; IsLessThan(i, GetArrayLength(this.Symbols)); i++ { var symbol interface{} = GetValue(this.Symbols, i) var market interface{} = this.Market(symbol) var fee interface{} = map[string]interface{} { "info": response, "symbol": symbol, "percentage": true, "tierBased": true, } if IsTrue(InOp(fiat, GetValue(market, "quote"))) { AddElementToObject(fee, "maker", makerFeeFiat) AddElementToObject(fee, "taker", takerFeeFiat) } else if IsTrue(GetValue(market, "contract")) { AddElementToObject(fee, "maker", makerFeeDeriv) AddElementToObject(fee, "taker", takerFeeDeriv) } else { AddElementToObject(fee, "maker", makerFee) AddElementToObject(fee, "taker", takerFee) } AddElementToObject(result, symbol, fee) } ch <- result return nil }() return ch } /** * @method * @name bitfinex#fetchDepositsWithdrawals * @description fetch history of deposits and withdrawals * @see https://docs.bitfinex.com/reference/movement-info * @see https://docs.bitfinex.com/reference/rest-auth-movements * @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 *bitfinex) 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 retRes26658 := (<-this.LoadMarkets()) PanicOnError(retRes26658) var currency interface{} = nil var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) // max 1000 } var response interface{} = nil if IsTrue(!IsEqual(code, nil)) { currency = this.Currency(code) AddElementToObject(request, "currency", GetValue(currency, "uppercaseId")) response = (<-this.PrivatePostAuthRMovementsCurrencyHist(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivatePostAuthRMovementsHist(this.Extend(request, params))) PanicOnError(response) } // // [ // [ // 13293039, // ID // "ETH", // CURRENCY // "ETHEREUM", // CURRENCY_NAME // null, // null, // 1574175052000, // MTS_STARTED // 1574181326000, // MTS_UPDATED // null, // null, // "CANCELED", // STATUS // null, // null, // -0.24, // AMOUNT, negative for withdrawals // -0.00135, // FEES // null, // null, // "0x38110e0Fc932CB2BE...........", // DESTINATION_ADDRESS // null, // null, // null, // "0x523ec8945500.....................................", // TRANSACTION_ID // "Purchase of 100 pizzas", // WITHDRAW_TRANSACTION_NOTE, might also be: null // ] // ] // ch <- this.ParseTransactions(response, currency, since, limit) return nil }() return ch } /** * @method * @name bitfinex#withdraw * @description make a withdrawal * @see https://docs.bitfinex.com/reference/rest-auth-withdraw * @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 *bitfinex) Withdraw(code interface{}, amount interface{}, address interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) tag := GetArg(optionalArgs, 0, nil) _ = tag params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params this.CheckAddress(address) retRes27278 := (<-this.LoadMarkets()) PanicOnError(retRes27278) var currency interface{} = this.Currency(code) // if not provided explicitly we will try to match using the currency name var network interface{} = this.SafeString(params, "network", code) params = this.Omit(params, "network") var currencyNetworks interface{} = this.SafeValue(currency, "networks", map[string]interface{} {}) var currencyNetwork interface{} = this.SafeValue(currencyNetworks, network) var networkId interface{} = this.SafeString(currencyNetwork, "id") if IsTrue(IsEqual(networkId, nil)) { panic(ArgumentsRequired(Add(Add(Add(this.Id, " withdraw() could not find a network for \\'"), code), "\\'. You can specify it by providing the \\'network\\' value inside params"))) } var wallet interface{} = this.SafeString(params, "wallet", "exchange") // 'exchange', 'margin', 'funding' and also old labels 'exchange', 'trading', 'deposit', respectively params = this.Omit(params, "network", "wallet") var request interface{} = map[string]interface{} { "method": networkId, "wallet": wallet, "amount": this.NumberToString(amount), "address": address, } if IsTrue(!IsEqual(tag, nil)) { AddElementToObject(request, "payment_id", tag) } var withdrawOptions interface{} = this.SafeValue(this.Options, "withdraw", map[string]interface{} {}) var includeFee interface{} = this.SafeBool(withdrawOptions, "includeFee", false) if IsTrue(includeFee) { AddElementToObject(request, "fee_deduct", 1) } response:= (<-this.PrivatePostAuthWWithdraw(this.Extend(request, params))) PanicOnError(response) // // [ // 1582271520931, // MTS Millisecond Time Stamp of the update // "acc_wd-req", // TYPE Purpose of notification "acc_wd-req" account withdrawal request // null, // MESSAGE_ID unique ID of the message // null, // not documented // [ // 0, // WITHDRAWAL_ID Unique Withdrawal ID // null, // PLACEHOLDER // "bitcoin", // METHOD Method of withdrawal // null, // PAYMENT_ID Payment ID if relevant // "exchange", // WALLET Sending wallet // 1, // AMOUNT Amount of Withdrawal less fee // null, // PLACEHOLDER // null, // PLACEHOLDER // 0.0004, // WITHDRAWAL_FEE Fee on withdrawal // ], // null, // CODE null or integer Work in progress // "SUCCESS", // STATUS Status of the notification, it may vary over time SUCCESS, ERROR, FAILURE // "Invalid bitcoin address (abcdef)", // TEXT Text of the notification // ] // // in case of failure: // // [ // "error", // 10001, // "Momentary balance check. Please wait few seconds and try the transfer again." // ] // var statusMessage interface{} = this.SafeString(response, 0) if IsTrue(IsEqual(statusMessage, "error")) { var feedback interface{} = Add(Add(this.Id, " "), response) var message interface{} = this.SafeString(response, 2, "") // same message as in v1 this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), message, feedback) this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), message, feedback) panic(ExchangeError(feedback)) } var text interface{} = this.SafeString(response, 7) if IsTrue(!IsEqual(text, "success")) { this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), text, text) } ch <- this.ParseTransaction(response, currency) return nil }() return ch } /** * @method * @name bitfinex#fetchPositions * @description fetch all open positions * @see https://docs.bitfinex.com/reference/rest-auth-positions * @param {string[]|undefined} symbols list of unified market symbols * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [position structure]{@link https://docs.ccxt.com/#/?id=position-structure} */ func (this *bitfinex) FetchPositions(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbols := GetArg(optionalArgs, 0, nil) _ = symbols params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes28118 := (<-this.LoadMarkets()) PanicOnError(retRes28118) symbols = this.MarketSymbols(symbols) response:= (<-this.PrivatePostAuthRPositions(params)) PanicOnError(response) // // [ // [ // "tBTCUSD", // SYMBOL // "ACTIVE", // STATUS // 0.0195, // AMOUNT // 8565.0267019, // BASE_PRICE // 0, // MARGIN_FUNDING // 0, // MARGIN_FUNDING_TYPE // -0.33455568705000516, // PL // -0.0003117550117425625, // PL_PERC // 7045.876419249083, // PRICE_LIQ // 3.0673001895895604, // LEVERAGE // null, // _PLACEHOLDER // 142355652, // POSITION_ID // 1574002216000, // MTS_CREATE // 1574002216000, // MTS_UPDATE // null, // _PLACEHOLDER // 0, // TYPE // null, // _PLACEHOLDER // 0, // COLLATERAL // 0, // COLLATERAL_MIN // // META // { // "reason":"TRADE", // "order_id":34271018124, // "liq_stage":null, // "trade_price":"8565.0267019", // "trade_amount":"0.0195", // "order_id_oppo":34277498022 // } // ] // ] // var positionsList interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(response)); i++ { AppendToArray(&positionsList,map[string]interface{} { "result": GetValue(response, i), }) } ch <- this.ParsePositions(positionsList, symbols) return nil }() return ch } func (this *bitfinex) ParsePosition(position interface{}, optionalArgs ...interface{}) interface{} { // // [ // "tBTCUSD", // SYMBOL // "ACTIVE", // STATUS // 0.0195, // AMOUNT // 8565.0267019, // BASE_PRICE // 0, // MARGIN_FUNDING // 0, // MARGIN_FUNDING_TYPE // -0.33455568705000516, // PL // -0.0003117550117425625, // PL_PERC // 7045.876419249083, // PRICE_LIQ // 3.0673001895895604, // LEVERAGE // null, // _PLACEHOLDER // 142355652, // POSITION_ID // 1574002216000, // MTS_CREATE // 1574002216000, // MTS_UPDATE // null, // _PLACEHOLDER // 0, // TYPE // null, // _PLACEHOLDER // 0, // COLLATERAL // 0, // COLLATERAL_MIN // // META // { // "reason": "TRADE", // "order_id": 34271018124, // "liq_stage": null, // "trade_price": "8565.0267019", // "trade_amount": "0.0195", // "order_id_oppo": 34277498022 // } // ] // market := GetArg(optionalArgs, 0, nil) _ = market var positionList interface{} = this.SafeList(position, "result") var marketId interface{} = this.SafeString(positionList, 0) var amount interface{} = this.SafeString(positionList, 2) var timestamp interface{} = this.SafeInteger(positionList, 12) var meta interface{} = this.SafeString(positionList, 19) var tradePrice interface{} = this.SafeString(meta, "trade_price") var tradeAmount interface{} = this.SafeString(meta, "trade_amount") return this.SafePosition(map[string]interface{} { "info": positionList, "id": this.SafeString(positionList, 11), "symbol": this.SafeSymbol(marketId, market), "notional": this.ParseNumber(amount), "marginMode": "isolated", "liquidationPrice": this.SafeNumber(positionList, 8), "entryPrice": this.SafeNumber(positionList, 3), "unrealizedPnl": this.SafeNumber(positionList, 6), "percentage": this.SafeNumber(positionList, 7), "contracts": nil, "contractSize": nil, "markPrice": nil, "lastPrice": nil, "side": Ternary(IsTrue(Precise.StringGt(amount, "0")), "long", "short"), "hedged": nil, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "lastUpdateTimestamp": this.SafeInteger(positionList, 13), "maintenanceMargin": this.SafeNumber(positionList, 18), "maintenanceMarginPercentage": nil, "collateral": this.SafeNumber(positionList, 17), "initialMargin": this.ParseNumber(Precise.StringMul(tradeAmount, tradePrice)), "initialMarginPercentage": nil, "leverage": this.SafeNumber(positionList, 9), "marginRatio": nil, "stopLossPrice": nil, "takeProfitPrice": nil, }) } func (this *bitfinex) Nonce() interface{} { return this.Milliseconds() } func (this *bitfinex) 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 request interface{} = Add("/", this.ImplodeParams(path, params)) var query interface{} = this.Omit(params, this.ExtractParams(path)) if IsTrue(IsEqual(api, "v1")) { request = Add(api, request) } else { request = Add(this.Version, request) } var url interface{} = Add(Add(GetValue(GetValue(this.Urls, "api"), api), "/"), request) if IsTrue(IsEqual(api, "public")) { if IsTrue(GetArrayLength(ObjectKeys(query))) { url = Add(url, Add("?", this.Urlencode(query))) } } if IsTrue(IsEqual(api, "private")) { this.CheckRequiredCredentials() var nonce interface{} = ToString(this.Nonce()) body = this.Json(query) var auth interface{} = Add(Add(Add("/api/", request), nonce), body) var signature interface{} = this.Hmac(this.Encode(auth), this.Encode(this.Secret), sha384) headers = map[string]interface{} { "bfx-nonce": nonce, "bfx-apikey": this.ApiKey, "bfx-signature": signature, "Content-Type": "application/json", } } return map[string]interface{} { "url": url, "method": method, "body": body, "headers": headers, } } func (this *bitfinex) HandleErrors(statusCode interface{}, statusText interface{}, url interface{}, method interface{}, headers interface{}, body interface{}, response interface{}, requestHeaders interface{}, requestBody interface{}) interface{} { // ["error", 11010, "ratelimit: error"] if IsTrue(!IsEqual(response, nil)) { if !IsTrue(IsArray(response)) { var message interface{} = this.SafeString2(response, "message", "error") var feedback interface{} = Add(Add(this.Id, " "), body) this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), message, feedback) this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), message, feedback) panic(ExchangeError(Add(Add(this.Id, " "), body))) } } else if IsTrue(IsEqual(response, "")) { panic(ExchangeError(Add(this.Id, " returned empty response"))) } if IsTrue(IsEqual(statusCode, 429)) { panic(RateLimitExceeded(Add(Add(this.Id, " "), body))) } if IsTrue(IsEqual(statusCode, 500)) { // See https://docs.bitfinex.com/docs/abbreviations-glossary#section-errorinfo-codes var errorCode interface{} = this.SafeString(response, 1, "") var errorText interface{} = this.SafeString(response, 2, "") var feedback interface{} = Add(Add(this.Id, " "), errorText) this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), errorText, feedback) this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), errorCode, feedback) this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), errorText, feedback) panic(ExchangeError(Add(Add(Add(Add(Add(this.Id, " "), errorText), " (#"), errorCode), ")"))) } return response } func (this *bitfinex) ParseLedgerEntryType(typeVar interface{}) interface{} { if IsTrue(IsEqual(typeVar, nil)) { return nil } else if IsTrue(IsTrue(IsGreaterThanOrEqual(GetIndexOf(typeVar, "fee"), 0)) || IsTrue(IsGreaterThanOrEqual(GetIndexOf(typeVar, "charged"), 0))) { return "fee" } else if IsTrue(IsGreaterThanOrEqual(GetIndexOf(typeVar, "rebate"), 0)) { return "rebate" } else if IsTrue(IsTrue(IsGreaterThanOrEqual(GetIndexOf(typeVar, "deposit"), 0)) || IsTrue(IsGreaterThanOrEqual(GetIndexOf(typeVar, "withdrawal"), 0))) { return "transaction" } else if IsTrue(IsGreaterThanOrEqual(GetIndexOf(typeVar, "transfer"), 0)) { return "transfer" } else if IsTrue(IsGreaterThanOrEqual(GetIndexOf(typeVar, "payment"), 0)) { return "payout" } else if IsTrue(IsTrue(IsGreaterThanOrEqual(GetIndexOf(typeVar, "exchange"), 0)) || IsTrue(IsGreaterThanOrEqual(GetIndexOf(typeVar, "position"), 0))) { return "trade" } else { return typeVar } } func (this *bitfinex) ParseLedgerEntry(item interface{}, optionalArgs ...interface{}) interface{} { // // [ // [ // 2531822314, // ID: Ledger identifier // "USD", // CURRENCY: The symbol of the currency (ex. "BTC") // null, // PLACEHOLDER // 1573521810000, // MTS: Timestamp in milliseconds // null, // PLACEHOLDER // 0.01644445, // AMOUNT: Amount of funds moved // 0, // BALANCE: New balance // null, // PLACEHOLDER // "Settlement @ 185.79 on wallet margin" // DESCRIPTION: Description of ledger transaction // ] // ] // currency := GetArg(optionalArgs, 0, nil) _ = currency var itemList interface{} = this.SafeList(item, "result", []interface{}{}) var typeVar interface{} = nil var id interface{} = this.SafeString(itemList, 0) var currencyId interface{} = this.SafeString(itemList, 1) var code interface{} = this.SafeCurrencyCode(currencyId, currency) currency = this.SafeCurrency(currencyId, currency) var timestamp interface{} = this.SafeInteger(itemList, 3) var amount interface{} = this.SafeNumber(itemList, 5) var after interface{} = this.SafeNumber(itemList, 6) var description interface{} = this.SafeString(itemList, 8) if IsTrue(!IsEqual(description, nil)) { var parts interface{} = Split(description, " @ ") var first interface{} = this.SafeStringLower(parts, 0) typeVar = this.ParseLedgerEntryType(first) } return this.SafeLedgerEntry(map[string]interface{} { "info": item, "id": id, "direction": nil, "account": nil, "referenceId": id, "referenceAccount": nil, "type": typeVar, "currency": code, "amount": amount, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "before": nil, "after": after, "status": nil, "fee": nil, }, currency) } /** * @method * @name bitfinex#fetchLedger * @description fetch the history of changes, actions done by the user or operations that altered the balance of the user * @see https://docs.bitfinex.com/reference/rest-auth-ledgers * @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, max is 2500 * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] timestamp in ms of the latest ledger entry * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {object} a [ledger structure]{@link https://docs.ccxt.com/#/?id=ledger} */ func (this *bitfinex) 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 retRes30738 := (<-this.LoadMarkets()) PanicOnError(retRes30738) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchLedger", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes307719 := (<-this.FetchPaginatedCallDynamic("fetchLedger", code, since, limit, params, 2500)) PanicOnError(retRes307719) ch <- retRes307719 return nil } var currency interface{} = nil var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } requestparamsVariable := this.HandleUntilOption("end", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) var response interface{} = nil if IsTrue(!IsEqual(code, nil)) { currency = this.Currency(code) AddElementToObject(request, "currency", GetValue(currency, "uppercaseId")) response = (<-this.PrivatePostAuthRLedgersCurrencyHist(this.Extend(request, params))) PanicOnError(response) } else { response = (<-this.PrivatePostAuthRLedgersHist(this.Extend(request, params))) PanicOnError(response) } // // [ // [ // 2531822314, // ID: Ledger identifier // "USD", // CURRENCY: The symbol of the currency (ex. "BTC") // null, // PLACEHOLDER // 1573521810000, // MTS: Timestamp in milliseconds // null, // PLACEHOLDER // 0.01644445, // AMOUNT: Amount of funds moved // 0, // BALANCE: New balance // null, // PLACEHOLDER // "Settlement @ 185.79 on wallet margin" // DESCRIPTION: Description of ledger transaction // ] // ] // var ledgerObjects interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(response)); i++ { var item interface{} = GetValue(response, i) AppendToArray(&ledgerObjects,map[string]interface{} { "result": item, }) } ch <- this.ParseLedger(ledgerObjects, currency, since, limit) return nil }() return ch } /** * @method * @name bitfinex#fetchFundingRates * @description fetch the current funding rate for multiple symbols * @see https://docs.bitfinex.com/reference/rest-public-derivatives-status * @param {string[]} symbols list of unified market symbols * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [funding rate structures]{@link https://docs.ccxt.com/#/?id=funding-rate-structure} */ func (this *bitfinex) FetchFundingRates(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 if IsTrue(IsEqual(symbols, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchFundingRates() requires a symbols argument"))) } retRes31328 := (<-this.LoadMarkets()) PanicOnError(retRes31328) var marketIds interface{} = this.MarketIds(symbols) var request interface{} = map[string]interface{} { "keys": Join(marketIds, ","), } response:= (<-this.PublicGetStatusDeriv(this.Extend(request, params))) PanicOnError(response) // // [ // [ // "tBTCF0:USTF0", // 1691165059000, // null, // 29297.851276225, // 29277.5, // null, // 36950860.76010306, // null, // 1691193600000, // 0.00000527, // 82, // null, // 0.00014548, // null, // null, // 29278.8925, // null, // null, // 9636.07644994, // null, // null, // null, // 0.0005, // 0.0025 // ] // ] // ch <- this.ParseFundingRates(response, symbols) return nil }() return ch } /** * @method * @name bitfinex#fetchFundingRateHistory * @description fetches historical funding rate prices * @see https://docs.bitfinex.com/reference/rest-public-derivatives-status-history * @param {string} symbol unified market symbol * @param {int} [since] timestamp in ms of the earliest funding rate entry * @param {int} [limit] max number of funding rate entrys to return * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] timestamp in ms of the latest funding rate * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {object} a [funding rate structure]{@link https://docs.ccxt.com/#/?id=funding-rate-structure} */ func (this *bitfinex) FetchFundingRateHistory(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 if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchFundingRateHistory() requires a symbol argument"))) } retRes31888 := (<-this.LoadMarkets()) PanicOnError(retRes31888) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchFundingRateHistory", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes319219 := (<-this.FetchPaginatedCallDeterministic("fetchFundingRateHistory", symbol, since, limit, "8h", params, 5000)) PanicOnError(retRes319219) ch <- retRes319219 return nil } var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start", since) } requestparamsVariable := this.HandleUntilOption("end", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) response:= (<-this.PublicGetStatusDerivSymbolHist(this.Extend(request, params))) PanicOnError(response) // // [ // [ // "tBTCF0:USTF0", // 1691165059000, // null, // 29297.851276225, // 29277.5, // null, // 36950860.76010306, // null, // 1691193600000, // 0.00000527, // 82, // null, // 0.00014548, // null, // null, // 29278.8925, // null, // null, // 9636.07644994, // null, // null, // null, // 0.0005, // 0.0025 // ] // ] // var rates interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(response)); i++ { var fr interface{} = GetValue(response, i) var rate interface{} = this.ParseFundingRateHistory(fr, market) AppendToArray(&rates,rate) } var reversedArray interface{} = []interface{}{} var rawRates interface{} = this.FilterBySymbolSinceLimit(rates, symbol, since, limit) var ratesLength interface{} = GetArrayLength(rawRates) for i := 0; IsLessThan(i, ratesLength); i++ { var index interface{} = Subtract(Subtract(ratesLength, i), 1) var valueAtIndex interface{} = GetValue(rawRates, index) AppendToArray(&reversedArray,valueAtIndex) } ch <- reversedArray return nil }() return ch } func (this *bitfinex) ParseFundingRate(contract interface{}, optionalArgs ...interface{}) interface{} { // // [ // "tBTCF0:USTF0", // 1691165059000, // null, // 29297.851276225, // 29277.5, // null, // 36950860.76010306, // null, // 1691193600000, // 0.00000527, // 82, // null, // 0.00014548, // null, // null, // 29278.8925, // null, // null, // 9636.07644994, // null, // null, // null, // 0.0005, // 0.0025 // ] // market := GetArg(optionalArgs, 0, nil) _ = market var marketId interface{} = this.SafeString(contract, 0) var timestamp interface{} = this.SafeInteger(contract, 1) var nextFundingTimestamp interface{} = this.SafeInteger(contract, 8) return map[string]interface{} { "info": contract, "symbol": this.SafeSymbol(marketId, market), "markPrice": this.SafeNumber(contract, 15), "indexPrice": this.SafeNumber(contract, 3), "interestRate": nil, "estimatedSettlePrice": nil, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "fundingRate": this.SafeNumber(contract, 12), "fundingTimestamp": nil, "fundingDatetime": nil, "nextFundingRate": this.SafeNumber(contract, 9), "nextFundingTimestamp": nextFundingTimestamp, "nextFundingDatetime": this.Iso8601(nextFundingTimestamp), "previousFundingRate": nil, "previousFundingTimestamp": nil, "previousFundingDatetime": nil, "interval": nil, } } func (this *bitfinex) ParseFundingRateHistory(contract interface{}, optionalArgs ...interface{}) interface{} { // // [ // 1691165494000, // null, // 29278.95838065, // 29260.5, // null, // 36950860.76010305, // null, // 1691193600000, // 0.00001449, // 222, // null, // 0.00014548, // null, // null, // 29260.005, // null, // null, // 9635.86484562, // null, // null, // null, // 0.0005, // 0.0025 // ] // market := GetArg(optionalArgs, 0, nil) _ = market var timestamp interface{} = this.SafeInteger(contract, 0) var nextFundingTimestamp interface{} = this.SafeInteger(contract, 7) return map[string]interface{} { "info": contract, "symbol": this.SafeSymbol(nil, market), "markPrice": this.SafeNumber(contract, 14), "indexPrice": this.SafeNumber(contract, 2), "interestRate": nil, "estimatedSettlePrice": nil, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "fundingRate": this.SafeNumber(contract, 11), "fundingTimestamp": nil, "fundingDatetime": nil, "nextFundingRate": this.SafeNumber(contract, 8), "nextFundingTimestamp": nextFundingTimestamp, "nextFundingDatetime": this.Iso8601(nextFundingTimestamp), "previousFundingRate": nil, "previousFundingTimestamp": nil, "previousFundingDatetime": nil, } } /** * @method * @name bitfinex#fetchOpenInterests * @description Retrieves the open interest for a list of symbols * @see https://docs.bitfinex.com/reference/rest-public-derivatives-status * @param {string[]} [symbols] a list of unified CCXT market symbols * @param {object} [params] exchange specific parameters * @returns {object[]} a list of [open interest structures]{@link https://docs.ccxt.com/#/?id=open-interest-structure} */ func (this *bitfinex) FetchOpenInterests(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 retRes33658 := (<-this.LoadMarkets()) PanicOnError(retRes33658) symbols = this.MarketSymbols(symbols) var marketIds interface{} = []interface{}{"ALL"} if IsTrue(!IsEqual(symbols, nil)) { marketIds = this.MarketIds(symbols) } var request interface{} = map[string]interface{} { "keys": Join(marketIds, ","), } response:= (<-this.PublicGetStatusDeriv(this.Extend(request, params))) PanicOnError(response) // // [ // [ // "tXRPF0:USTF0", // market id // 1706256986000, // millisecond timestamp // null, // 0.512705, // derivative mid price // 0.512395, // underlying spot mid price // null, // 37671483.04, // insurance fund balance // null, // 1706284800000, // timestamp of next funding // 0.00002353, // accrued funding for next period // 317, // next funding step // null, // 0, // current funding // null, // null, // 0.5123016, // mark price // null, // null, // 2233562.03115, // open interest in contracts // null, // null, // null, // 0.0005, // average spread without funding payment // 0.0025 // funding payment cap // ] // ] // ch <- this.ParseOpenInterests(response, symbols) return nil }() return ch } /** * @method * @name bitfinex#fetchOpenInterest * @description retrieves the open interest of a contract trading pair * @see https://docs.bitfinex.com/reference/rest-public-derivatives-status * @param {string} symbol unified CCXT market symbol * @param {object} [params] exchange specific parameters * @returns {object} an [open interest structure]{@link https://docs.ccxt.com/#/?id=open-interest-structure} */ func (this *bitfinex) FetchOpenInterest(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 retRes34188 := (<-this.LoadMarkets()) PanicOnError(retRes34188) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "keys": GetValue(market, "id"), } response:= (<-this.PublicGetStatusDeriv(this.Extend(request, params))) PanicOnError(response) // // [ // [ // "tXRPF0:USTF0", // market id // 1706256986000, // millisecond timestamp // null, // 0.512705, // derivative mid price // 0.512395, // underlying spot mid price // null, // 37671483.04, // insurance fund balance // null, // 1706284800000, // timestamp of next funding // 0.00002353, // accrued funding for next period // 317, // next funding step // null, // 0, // current funding // null, // null, // 0.5123016, // mark price // null, // null, // 2233562.03115, // open interest in contracts // null, // null, // null, // 0.0005, // average spread without funding payment // 0.0025 // funding payment cap // ] // ] // var oi interface{} = this.SafeList(response, 0) ch <- this.ParseOpenInterest(oi, market) return nil }() return ch } /** * @method * @name bitfinex#fetchOpenInterestHistory * @description retrieves the open interest history of a currency * @see https://docs.bitfinex.com/reference/rest-public-derivatives-status-history * @param {string} symbol unified CCXT market symbol * @param {string} timeframe the time period of each row of data, not used by bitfinex * @param {int} [since] the time in ms of the earliest record to retrieve as a unix timestamp * @param {int} [limit] the number of records in the response * @param {object} [params] exchange specific parameters * @param {int} [params.until] the time in ms of the latest record to retrieve as a unix timestamp * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns An array of [open interest structures]{@link https://docs.ccxt.com/#/?id=open-interest-structure} */ func (this *bitfinex) FetchOpenInterestHistory(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 retRes34738 := (<-this.LoadMarkets()) PanicOnError(retRes34738) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchOpenInterestHistory", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes347719 := (<-this.FetchPaginatedCallDeterministic("fetchOpenInterestHistory", symbol, since, limit, "8h", params, 5000)) PanicOnError(retRes347719) ch <- retRes347719 return nil } var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } requestparamsVariable := this.HandleUntilOption("end", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) response:= (<-this.PublicGetStatusDerivSymbolHist(this.Extend(request, params))) PanicOnError(response) // // [ // [ // 1706295191000, // timestamp // null, // 42152.425382, // derivative mid price // 42133, // spot mid price // null, // 37671589.7853521, // insurance fund balance // null, // 1706313600000, // timestamp of next funding // 0.00018734, // accrued funding for next period // 3343, // next funding step // null, // 0.00007587, // current funding // null, // null, // 42134.1, // mark price // null, // null, // 5775.20348804, // open interest number of contracts // null, // null, // null, // 0.0005, // average spread without funding payment // 0.0025 // funding payment cap // ], // ] // ch <- this.ParseOpenInterestsHistory(response, market, since, limit) return nil }() return ch } func (this *bitfinex) ParseOpenInterest(interest interface{}, optionalArgs ...interface{}) interface{} { // // fetchOpenInterest: // // [ // "tXRPF0:USTF0", // market id // 1706256986000, // millisecond timestamp // null, // 0.512705, // derivative mid price // 0.512395, // underlying spot mid price // null, // 37671483.04, // insurance fund balance // null, // 1706284800000, // timestamp of next funding // 0.00002353, // accrued funding for next period // 317, // next funding step // null, // 0, // current funding // null, // null, // 0.5123016, // mark price // null, // null, // 2233562.03115, // open interest in contracts // null, // null, // null, // 0.0005, // average spread without funding payment // 0.0025 // funding payment cap // ] // // fetchOpenInterestHistory: // // [ // 1706295191000, // timestamp // null, // 42152.425382, // derivative mid price // 42133, // spot mid price // null, // 37671589.7853521, // insurance fund balance // null, // 1706313600000, // timestamp of next funding // 0.00018734, // accrued funding for next period // 3343, // next funding step // null, // 0.00007587, // current funding // null, // null, // 42134.1, // mark price // null, // null, // 5775.20348804, // open interest number of contracts // null, // null, // null, // 0.0005, // average spread without funding payment // 0.0025 // funding payment cap // ] // market := GetArg(optionalArgs, 0, nil) _ = market var interestLength interface{} = GetArrayLength(interest) var openInterestIndex interface{} = Ternary(IsTrue((IsEqual(interestLength, 23))), 17, 18) var timestamp interface{} = this.SafeInteger(interest, 1) var marketId interface{} = this.SafeString(interest, 0) return this.SafeOpenInterest(map[string]interface{} { "symbol": this.SafeSymbol(marketId, market, nil, "swap"), "openInterestAmount": this.SafeNumber(interest, openInterestIndex), "openInterestValue": nil, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "info": interest, }, market) } /** * @method * @name bitfinex#fetchLiquidations * @description retrieves the public liquidations of a trading pair * @see https://docs.bitfinex.com/reference/rest-public-liquidations * @param {string} symbol unified CCXT market symbol * @param {int} [since] the earliest time in ms to fetch liquidations for * @param {int} [limit] the maximum number of liquidation structures to retrieve * @param {object} [params] exchange specific parameters * @param {int} [params.until] timestamp in ms of the latest liquidation * @param {boolean} [params.paginate] default false, when true will automatically paginate by calling this endpoint multiple times. See in the docs all the [available parameters](https://github.com/ccxt/ccxt/wiki/Manual#pagination-params) * @returns {object} an array of [liquidation structures]{@link https://docs.ccxt.com/#/?id=liquidation-structure} */ func (this *bitfinex) FetchLiquidations(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 retRes36108 := (<-this.LoadMarkets()) PanicOnError(retRes36108) var paginate interface{} = false paginateparamsVariable := this.HandleOptionAndParams(params, "fetchLiquidations", "paginate"); paginate = GetValue(paginateparamsVariable,0); params = GetValue(paginateparamsVariable,1) if IsTrue(paginate) { retRes361419 := (<-this.FetchPaginatedCallDeterministic("fetchLiquidations", symbol, since, limit, "8h", params, 500)) PanicOnError(retRes361419) ch <- retRes361419 return nil } var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start", since) } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } requestparamsVariable := this.HandleUntilOption("end", request, params); request = GetValue(requestparamsVariable,0); params = GetValue(requestparamsVariable,1) response:= (<-this.PublicGetLiquidationsHist(this.Extend(request, params))) PanicOnError(response) // // [ // [ // [ // "pos", // 171085137, // 1706395919788, // null, // "tAVAXF0:USTF0", // -8, // 32.868, // null, // 1, // 1, // null, // 33.255 // ] // ], // ] // ch <- this.ParseLiquidations(response, market, since, limit) return nil }() return ch } func (this *bitfinex) ParseLiquidation(liquidation interface{}, optionalArgs ...interface{}) interface{} { // // [ // [ // "pos", // 171085137, // position id // 1706395919788, // timestamp // null, // "tAVAXF0:USTF0", // market id // -8, // amount in contracts // 32.868, // base price // null, // 1, // 1, // null, // 33.255 // acquired price // ] // ] // market := GetArg(optionalArgs, 0, nil) _ = market var entry interface{} = GetValue(liquidation, 0) var timestamp interface{} = this.SafeInteger(entry, 2) var marketId interface{} = this.SafeString(entry, 4) var contracts interface{} = Precise.StringAbs(this.SafeString(entry, 5)) var contractSize interface{} = this.SafeString(market, "contractSize") var baseValue interface{} = Precise.StringMul(contracts, contractSize) var price interface{} = this.SafeString(entry, 11) return this.SafeLiquidation(map[string]interface{} { "info": entry, "symbol": this.SafeSymbol(marketId, market, nil, "contract"), "contracts": this.ParseNumber(contracts), "contractSize": this.ParseNumber(contractSize), "price": this.ParseNumber(price), "baseValue": this.ParseNumber(baseValue), "quoteValue": this.ParseNumber(Precise.StringMul(baseValue, price)), "timestamp": timestamp, "datetime": this.Iso8601(timestamp), }) } /** * @method * @name bitfinex#setMargin * @description either adds or reduces margin in a swap position in order to set the margin to a specific value * @see https://docs.bitfinex.com/reference/rest-auth-deriv-pos-collateral-set * @param {string} symbol unified market symbol of the market to set margin in * @param {float} amount the amount to set the margin to * @param {object} [params] parameters specific to the exchange API endpoint * @returns {object} A [margin structure]{@link https://github.com/ccxt/ccxt/wiki/Manual#add-margin-structure} */ func (this *bitfinex) SetMargin(symbol interface{}, amount interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes36998 := (<-this.LoadMarkets()) PanicOnError(retRes36998) var market interface{} = this.Market(symbol) if !IsTrue(GetValue(market, "swap")) { panic(NotSupported(Add(this.Id, " setMargin() only support swap markets"))) } var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), "collateral": this.ParseToNumeric(amount), } response:= (<-this.PrivatePostAuthWDerivCollateralSet(this.Extend(request, params))) PanicOnError(response) // // [ // [ // 1 // ] // ] // var data interface{} = this.SafeValue(response, 0) ch <- this.ParseMarginModification(data, market) return nil }() return ch } func (this *bitfinex) ParseMarginModification(data interface{}, optionalArgs ...interface{}) interface{} { // // setMargin // // [ // [ // 1 // ] // ] // market := GetArg(optionalArgs, 0, nil) _ = market var marginStatusRaw interface{} = GetValue(data, 0) var marginStatus interface{} = Ternary(IsTrue((IsEqual(marginStatusRaw, 1))), "ok", "failed") return map[string]interface{} { "info": data, "symbol": GetValue(market, "symbol"), "type": nil, "marginMode": "isolated", "amount": nil, "total": nil, "code": nil, "status": marginStatus, "timestamp": nil, "datetime": nil, } } /** * @method * @name bitfinex#fetchOrder * @description fetches information on an order made by the user * @see https://docs.bitfinex.com/reference/rest-auth-retrieve-orders * @see https://docs.bitfinex.com/reference/rest-auth-retrieve-orders-by-symbol * @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 *bitfinex) 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 retRes37588 := (<-this.LoadMarkets()) PanicOnError(retRes37588) var request interface{} = map[string]interface{} { "id": []interface{}{this.ParseToNumeric(id)}, } var market interface{} = nil var response interface{} = nil if IsTrue(IsEqual(symbol, nil)) { response = (<-this.PrivatePostAuthROrders(this.Extend(request, params))) PanicOnError(response) } else { market = this.Market(symbol) AddElementToObject(request, "symbol", GetValue(market, "id")) response = (<-this.PrivatePostAuthROrdersSymbol(this.Extend(request, params))) PanicOnError(response) } // // [ // [ // 139658969116, // null, // 1706843908637, // "tBTCUST", // 1706843908637, // 1706843908638, // 0.0001, // 0.0001, // "EXCHANGE LIMIT", // null, // null, // null, // 0, // "ACTIVE", // null, // null, // 35000, // 0, // 0, // 0, // null, // null, // null, // 0, // 0, // null, // null, // null, // "API>BFX", // null, // null, // {} // ] // ] // var order interface{} = this.SafeList(response, 0) var newOrder interface{} = map[string]interface{} { "result": order, } ch <- this.ParseOrder(newOrder, market) return nil }() return ch } /** * @method * @name bitfinex#editOrder * @description edit a trade order * @see https://docs.bitfinex.com/reference/rest-auth-update-order * @param {string} id edit order id * @param {string} symbol unified symbol of the market to edit an order in * @param {string} type 'market' or 'limit' * @param {string} side 'buy' or 'sell' * @param {float} amount how much you want to trade in units of the base currency * @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {float} [params.triggerPrice] the price that triggers a trigger order * @param {boolean} [params.postOnly] set to true if you want to make a post only order * @param {boolean} [params.reduceOnly] indicates that the order is to reduce the size of a position * @param {int} [params.flags] additional order parameters: 4096 (Post Only), 1024 (Reduce Only), 16384 (OCO), 64 (Hidden), 512 (Close), 524288 (No Var Rates) * @param {int} [params.leverage] leverage for a derivative order, supported by derivative symbol orders only, the value should be between 1 and 100 inclusive * @param {int} [params.clientOrderId] a unique client order id for the order * @param {float} [params.trailingAmount] *swap only* the quote amount to trail away from the current market price * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *bitfinex) EditOrder(id interface{}, symbol interface{}, typeVar interface{}, side interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) amount := GetArg(optionalArgs, 0, nil) _ = amount price := GetArg(optionalArgs, 1, nil) _ = price params := GetArg(optionalArgs, 2, map[string]interface{} {}) _ = params retRes38368 := (<-this.LoadMarkets()) PanicOnError(retRes38368) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "id": this.ParseToNumeric(id), } if IsTrue(!IsEqual(amount, nil)) { var amountString interface{} = this.AmountToPrecision(symbol, amount) amountString = Ternary(IsTrue((IsEqual(side, "buy"))), amountString, Precise.StringNeg(amountString)) AddElementToObject(request, "amount", amountString) } var triggerPrice interface{} = this.SafeString2(params, "stopPrice", "triggerPrice") var trailingAmount interface{} = this.SafeString(params, "trailingAmount") var timeInForce interface{} = this.SafeString(params, "timeInForce") var postOnlyParam interface{} = this.SafeBool(params, "postOnly", false) var reduceOnly interface{} = this.SafeBool(params, "reduceOnly", false) var clientOrderId interface{} = this.SafeInteger2(params, "cid", "clientOrderId") if IsTrue(!IsEqual(trailingAmount, nil)) { AddElementToObject(request, "price_trailing", trailingAmount) } else if IsTrue(!IsEqual(triggerPrice, nil)) { // request['price'] is taken as triggerPrice for stop orders AddElementToObject(request, "price", this.PriceToPrecision(symbol, triggerPrice)) if IsTrue(IsEqual(typeVar, "limit")) { AddElementToObject(request, "price_aux_limit", this.PriceToPrecision(symbol, price)) } } var postOnly interface{} = (IsTrue(postOnlyParam) || IsTrue((IsEqual(timeInForce, "PO")))) if IsTrue(IsTrue((!IsEqual(typeVar, "market"))) && IsTrue((IsEqual(triggerPrice, nil)))) { AddElementToObject(request, "price", this.PriceToPrecision(symbol, price)) } // flag values may be summed to combine flags var flags interface{} = 0 if IsTrue(postOnly) { flags = this.Sum(flags, 4096) } if IsTrue(reduceOnly) { flags = this.Sum(flags, 1024) } if IsTrue(!IsEqual(flags, 0)) { AddElementToObject(request, "flags", flags) } if IsTrue(!IsEqual(clientOrderId, nil)) { AddElementToObject(request, "cid", clientOrderId) } var leverage interface{} = this.SafeInteger2(params, "leverage", "lev") if IsTrue(!IsEqual(leverage, nil)) { AddElementToObject(request, "lev", leverage) } params = this.Omit(params, []interface{}{"triggerPrice", "stopPrice", "timeInForce", "postOnly", "reduceOnly", "trailingAmount", "clientOrderId", "leverage"}) response:= (<-this.PrivatePostAuthWOrderUpdate(this.Extend(request, params))) PanicOnError(response) // // [ // 1706845376402, // "ou-req", // null, // null, // [ // 139658969116, // null, // 1706843908637, // "tBTCUST", // 1706843908637, // 1706843908638, // 0.0002, // 0.0002, // "EXCHANGE LIMIT", // null, // null, // null, // 0, // "ACTIVE", // null, // null, // 35000, // 0, // 0, // 0, // null, // null, // null, // 0, // 0, // null, // null, // null, // "API>BFX", // null, // null, // {} // ], // null, // "SUCCESS", // "Submitting update to exchange limit buy order for 0.0002 BTC." // ] // var status interface{} = this.SafeString(response, 6) if IsTrue(!IsEqual(status, "SUCCESS")) { var errorCode interface{} = GetValue(response, 5) var errorText interface{} = GetValue(response, 7) panic(ExchangeError(Add(Add(Add(Add(Add(Add(Add(this.Id, " "), GetValue(response, 6)), ": "), errorText), " (#"), errorCode), ")"))) } var order interface{} = this.SafeList(response, 4, []interface{}{}) var newOrder interface{} = map[string]interface{} { "result": order, } ch <- this.ParseOrder(newOrder, market) return nil }() return ch } func (this *bitfinex) Init(userConfig map[string]interface{}) { this.Exchange = Exchange{} this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this) this.Exchange.DerivedExchange = this }