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 bitfinex1 struct { Exchange } func NewBitfinex1Core() bitfinex1 { p := bitfinex1{} setDefaults(&p) return p } func (this *bitfinex1) Describe() interface{} { return this.DeepExtend(this.Exchange.Describe(), map[string]interface{} { "id": "bitfinex1", "name": "Bitfinex", "countries": []interface{}{"VG"}, "version": "v1", "rateLimit": 666.666, "pro": true, "has": map[string]interface{} { "CORS": nil, "spot": true, "margin": nil, "swap": nil, "future": nil, "option": nil, "cancelAllOrders": true, "cancelOrder": true, "createDepositAddress": true, "createOrder": true, "editOrder": true, "fetchBalance": true, "fetchClosedOrders": true, "fetchDepositAddress": true, "fetchDepositAddresses": false, "fetchDepositAddressesByNetwork": false, "fetchDeposits": false, "fetchDepositsWithdrawals": true, "fetchDepositWithdrawFee": "emulated", "fetchDepositWithdrawFees": true, "fetchFundingHistory": false, "fetchFundingRate": false, "fetchFundingRateHistory": false, "fetchFundingRates": false, "fetchIndexOHLCV": false, "fetchLeverageTiers": false, "fetchMarginMode": false, "fetchMarkets": true, "fetchMarkOHLCV": false, "fetchMyTrades": true, "fetchOHLCV": true, "fetchOpenOrders": true, "fetchOrder": true, "fetchOrderBook": true, "fetchPositionMode": false, "fetchPositions": true, "fetchPremiumIndexOHLCV": false, "fetchTicker": true, "fetchTickers": true, "fetchTime": false, "fetchTrades": true, "fetchTradingFee": false, "fetchTradingFees": true, "fetchTransactionFees": true, "fetchTransactions": "emulated", "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", }, "urls": map[string]interface{} { "logo": "https://github.com/user-attachments/assets/9147c6c5-7197-481e-827b-7483672bb0e9", "api": map[string]interface{} { "v2": "https://api-pub.bitfinex.com", "public": "https://api.bitfinex.com", "private": "https://api.bitfinex.com", }, "www": "https://www.bitfinex.com", "referral": "https://www.bitfinex.com/?refcode=P61eYxFL", "doc": []interface{}{"https://docs.bitfinex.com/v1/docs", "https://github.com/bitfinexcom/bitfinex-api-node"}, }, "api": map[string]interface{} { "v2": map[string]interface{} { "get": map[string]interface{} { "platform/status": 3, "tickers": 1, "ticker/{symbol}": 1, "tickers/hist": 1, "trades/{symbol}/hist": 1, "book/{symbol}/{precision}": 0.375, "book/{symbol}/P0": 0.375, "book/{symbol}/P1": 0.375, "book/{symbol}/P2": 0.375, "book/{symbol}/P3": 0.375, "book/{symbol}/R0": 0.375, "stats1/{key}:{size}:{symbol}:{side}/{section}": 1, "stats1/{key}:{size}:{symbol}/{section}": 1, "stats1/{key}:{size}:{symbol}:long/last": 1, "stats1/{key}:{size}:{symbol}:long/hist": 1, "stats1/{key}:{size}:{symbol}:short/last": 1, "stats1/{key}:{size}:{symbol}:short/hist": 1, "candles/trade:{timeframe}:{symbol}/{section}": 1, "candles/trade:{timeframe}:{symbol}/last": 1, "candles/trade:{timeframe}:{symbol}/hist": 1, }, }, "public": map[string]interface{} { "get": map[string]interface{} { "book/{symbol}": 1, "lendbook/{currency}": 6, "lends/{currency}": 3, "pubticker/{symbol}": 3, "stats/{symbol}": 6, "symbols": 18, "symbols_details": 18, "tickers": 1, "trades/{symbol}": 3, }, }, "private": map[string]interface{} { "post": map[string]interface{} { "account_fees": 18, "account_infos": 6, "balances": 9.036, "basket_manage": 6, "credits": 6, "deposit/new": 18, "funding/close": 6, "history": 6, "history/movements": 6, "key_info": 6, "margin_infos": 3, "mytrades": 3, "mytrades_funding": 6, "offer/cancel": 6, "offer/new": 6, "offer/status": 6, "offers": 6, "offers/hist": 90.03, "order/cancel": 0.2, "order/cancel/all": 0.2, "order/cancel/multi": 0.2, "order/cancel/replace": 0.2, "order/new": 0.2, "order/new/multi": 0.2, "order/status": 0.2, "orders": 0.2, "orders/hist": 90.03, "position/claim": 18, "position/close": 18, "positions": 18, "summary": 18, "taken_funds": 6, "total_taken_funds": 6, "transfer": 18, "unused_taken_funds": 6, "withdraw": 18, }, }, }, "fees": map[string]interface{} { "trading": map[string]interface{} { "feeSide": "get", "tierBased": true, "percentage": 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{} { "tierBased": false, "percentage": false, "deposit": map[string]interface{} {}, "withdraw": map[string]interface{} {}, }, }, "commonCurrencies": map[string]interface{} { "ALG": "ALGO", "AMP": "AMPL", "ATO": "ATOM", "BCHABC": "XEC", "BCHN": "BCH", "DAT": "DATA", "DOG": "MDOGE", "DSH": "DASH", "EDO": "PNT", "EUS": "EURS", "EUT": "EURT", "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", "UST": "USDT", "VSY": "VSYS", "WAX": "WAXP", "XCH": "XCHF", "ZBT": "ZB", }, "exceptions": map[string]interface{} { "exact": map[string]interface{} { "temporarily_unavailable": ExchangeNotAvailable, "Order could not be cancelled.": OrderNotFound, "No such order found.": OrderNotFound, "Order price must be positive.": InvalidOrder, "Could not find a key matching the given X-BFX-APIKEY.": AuthenticationError, "Key price should be a decimal number, e.g. \"123.456\"": InvalidOrder, "Key amount should be a decimal number, e.g. \"123.456\"": InvalidOrder, "ERR_RATE_LIMIT": RateLimitExceeded, "Ratelimit": RateLimitExceeded, "Nonce is too small.": InvalidNonce, "No summary found.": ExchangeError, "Cannot evaluate your available balance, please try again": ExchangeNotAvailable, "Unknown symbol": BadSymbol, "Cannot complete transfer. Exchange balance insufficient.": InsufficientFunds, "Momentary balance check. Please wait few seconds and try the transfer again.": ExchangeError, }, "broad": map[string]interface{} { "Invalid X-BFX-SIGNATURE": AuthenticationError, "This API key does not have permission": PermissionDenied, "not enough exchange balance for ": InsufficientFunds, "minimum size for ": InvalidOrder, "Invalid order": InvalidOrder, "The available balance is only": InsufficientFunds, }, }, "precisionMode": SIGNIFICANT_DIGITS, "options": map[string]interface{} { "currencyNames": map[string]interface{} { "AGI": "agi", "AID": "aid", "AIO": "aio", "ANT": "ant", "AVT": "aventus", "BAT": "bat", "BCH": "bab", "BCI": "bci", "BFT": "bft", "BSV": "bsv", "BTC": "bitcoin", "BTG": "bgold", "CFI": "cfi", "COMP": "comp", "DAI": "dai", "DADI": "dad", "DASH": "dash", "DATA": "datacoin", "DTH": "dth", "EDO": "eidoo", "ELF": "elf", "EOS": "eos", "ETC": "ethereumc", "ETH": "ethereum", "ETP": "metaverse", "FUN": "fun", "GNT": "golem", "IOST": "ios", "IOTA": "iota", "LEO": "let", "LINK": "link", "LRC": "lrc", "LTC": "litecoin", "LYM": "lym", "MANA": "mna", "MIT": "mit", "MKR": "mkr", "MTN": "mtn", "NEO": "neo", "ODE": "ode", "OMG": "omisego", "OMNI": "mastercoin", "QASH": "qash", "QTUM": "qtum", "RCN": "rcn", "RDN": "rdn", "REP": "rep", "REQ": "req", "RLC": "rlc", "SAN": "santiment", "SNGLS": "sng", "SNT": "status", "SPANK": "spk", "STORJ": "stj", "TNB": "tnb", "TRX": "trx", "TUSD": "tsd", "USD": "wire", "USDC": "udc", "UTK": "utk", "USDT": "tetheruso", "VEE": "vee", "WAX": "wax", "XLM": "xlm", "XMR": "monero", "XRP": "ripple", "XVG": "xvg", "YOYOW": "yoyow", "ZEC": "zcash", "ZRX": "zrx", "XTZ": "xtz", }, "orderTypes": map[string]interface{} { "limit": "exchange limit", "market": "exchange market", }, "fiat": map[string]interface{} { "USD": "USD", "EUR": "EUR", "JPY": "JPY", "GBP": "GBP", "CNH": "CNH", }, "accountsByType": map[string]interface{} { "spot": "exchange", "margin": "trading", "funding": "deposit", "swap": "trading", }, }, }) } /** * @method * @name bitfinex1#fetchTransactionFees * @deprecated * @description please use fetchDepositWithdrawFees instead * @see https://docs.bitfinex.com/v1/reference/rest-auth-fees * @param {string[]|undefined} codes list of unified currency codes * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [fees structures]{@link https://docs.ccxt.com/#/?id=fee-structure} */ func (this *bitfinex1) FetchTransactionFees(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) codes := GetArg(optionalArgs, 0, nil) _ = codes params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes4158 := (<-this.LoadMarkets()) PanicOnError(retRes4158) var result interface{} = map[string]interface{} {} response:= (<-this.PrivatePostAccountFees(params)) PanicOnError(response) // // { // "withdraw": { // "BTC": "0.0004", // } // } // var fees interface{} = this.SafeDict(response, "withdraw", map[string]interface{} {}) var ids interface{} = ObjectKeys(fees) for i := 0; IsLessThan(i, GetArrayLength(ids)); i++ { var id interface{} = GetValue(ids, i) var code interface{} = this.SafeCurrencyCode(id) if IsTrue(IsTrue((!IsEqual(codes, nil))) && !IsTrue(this.InArray(code, codes))) { continue } AddElementToObject(result, code, map[string]interface{} { "withdraw": this.SafeNumber(fees, id), "deposit": map[string]interface{} {}, "info": this.SafeNumber(fees, id), }) } ch <- result return nil }() return ch } /** * @method * @name bitfinex1#fetchDepositWithdrawFees * @description fetch deposit and withdraw fees * @see https://docs.bitfinex.com/v1/reference/rest-auth-fees * @param {string[]|undefined} codes list of unified currency codes * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} a list of [fees structures]{@link https://docs.ccxt.com/#/?id=fee-structure} */ func (this *bitfinex1) FetchDepositWithdrawFees(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) codes := GetArg(optionalArgs, 0, nil) _ = codes params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params retRes4528 := (<-this.LoadMarkets()) PanicOnError(retRes4528) response:= (<-this.PrivatePostAccountFees(params)) PanicOnError(response) // // { // "withdraw": { // "BTC": "0.0004", // ... // } // } // var withdraw interface{} = this.SafeList(response, "withdraw") ch <- this.ParseDepositWithdrawFees(withdraw, codes) return nil }() return ch } func (this *bitfinex1) ParseDepositWithdrawFee(fee interface{}, optionalArgs ...interface{}) interface{} { // // '0.0004' // currency := GetArg(optionalArgs, 0, nil) _ = currency return map[string]interface{} { "withdraw": map[string]interface{} { "fee": this.ParseNumber(fee), "percentage": nil, }, "deposit": map[string]interface{} { "fee": nil, "percentage": nil, }, "networks": map[string]interface{} {}, "info": fee, } } /** * @method * @name bitfinex1#fetchTradingFees * @description fetch the trading fees for multiple markets * @see https://docs.bitfinex.com/v1/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 *bitfinex1) 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 retRes4938 := (<-this.LoadMarkets()) PanicOnError(retRes4938) response:= (<-this.PrivatePostSummary(params)) PanicOnError(response) // // { // "time": "2022-02-23T16:05:47.659000Z", // "status": { resid_hint: null, login_last: "2022-02-23T16:05:48Z" }, // "is_locked": false, // "leo_lev": "0", // "leo_amount_avg": "0.0", // "trade_vol_30d": [ // { // "curr": "Total (USD)", // "vol": "0.0", // "vol_safe": "0.0", // "vol_maker": "0.0", // "vol_BFX": "0.0", // "vol_BFX_safe": "0.0", // "vol_BFX_maker": "0.0" // } // ], // "fees_funding_30d": {}, // "fees_funding_total_30d": "0", // "fees_trading_30d": {}, // "fees_trading_total_30d": "0", // "rebates_trading_30d": {}, // "rebates_trading_total_30d": "0", // "maker_fee": "0.001", // "taker_fee": "0.002", // "maker_fee_2crypto": "0.001", // "maker_fee_2stablecoin": "0.001", // "maker_fee_2fiat": "0.001", // "maker_fee_2deriv": "0.0002", // "taker_fee_2crypto": "0.002", // "taker_fee_2stablecoin": "0.002", // "taker_fee_2fiat": "0.002", // "taker_fee_2deriv": "0.00065", // "deriv_maker_rebate": "0.0002", // "deriv_taker_fee": "0.00065", // "trade_last": null // } // var result interface{} = map[string]interface{} {} var fiat interface{} = this.SafeDict(this.Options, "fiat", map[string]interface{} {}) var makerFee interface{} = this.SafeNumber(response, "maker_fee") var takerFee interface{} = this.SafeNumber(response, "taker_fee") var makerFee2Fiat interface{} = this.SafeNumber(response, "maker_fee_2fiat") var takerFee2Fiat interface{} = this.SafeNumber(response, "taker_fee_2fiat") var makerFee2Deriv interface{} = this.SafeNumber(response, "maker_fee_2deriv") var takerFee2Deriv interface{} = this.SafeNumber(response, "taker_fee_2deriv") 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", makerFee2Fiat) AddElementToObject(fee, "taker", takerFee2Fiat) } else if IsTrue(GetValue(market, "contract")) { AddElementToObject(fee, "maker", makerFee2Deriv) AddElementToObject(fee, "taker", takerFee2Deriv) } else { AddElementToObject(fee, "maker", makerFee) AddElementToObject(fee, "taker", takerFee) } AddElementToObject(result, symbol, fee) } ch <- result return nil }() return ch } /** * @method * @name bitfinex1#fetchMarkets * @description retrieves data on all markets for bitfinex * @see https://docs.bitfinex.com/v1/reference/rest-public-symbols * @see https://docs.bitfinex.com/v1/reference/rest-public-symbol-details * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object[]} an array of objects representing market data */ func (this *bitfinex1) 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 idsPromise interface{} = this.PublicGetSymbols() // // [ "btcusd", "ltcusd", "ltcbtc" ] // var detailsPromise interface{} = this.PublicGetSymbolsDetails() // // [ // { // "pair":"btcusd", // "price_precision":5, // "initial_margin":"10.0", // "minimum_margin":"5.0", // "maximum_order_size":"2000.0", // "minimum_order_size":"0.0002", // "expiration":"NA", // "margin":true // }, // ] // idsdetailsVariable := (<-promiseAll([]interface{}{idsPromise, detailsPromise})); ids := GetValue(idsdetailsVariable,0); details := GetValue(idsdetailsVariable,1) var result interface{} = []interface{}{} for i := 0; IsLessThan(i, GetArrayLength(details)); i++ { var market interface{} = GetValue(details, i) var id interface{} = this.SafeString(market, "pair") if !IsTrue(this.InArray(id, ids)) { continue } id = ToUpper(id) 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 symbol interface{} = Add(Add(base, "/"), quote) var typeVar interface{} = "spot" if IsTrue(IsGreaterThan(GetIndexOf(id, "F0"), OpNeg(1))) { typeVar = "swap" } AppendToArray(&result,map[string]interface{} { "id": id, "symbol": symbol, "base": base, "quote": quote, "settle": nil, "baseId": baseId, "quoteId": quoteId, "settleId": nil, "type": typeVar, "spot": (IsEqual(typeVar, "spot")), "margin": this.SafeBool(market, "margin"), "swap": (IsEqual(typeVar, "swap")), "future": false, "option": false, "active": true, "contract": (IsEqual(typeVar, "swap")), "linear": nil, "inverse": nil, "contractSize": nil, "expiry": nil, "expiryDatetime": nil, "strike": nil, "optionType": nil, "precision": map[string]interface{} { "amount": ParseInt("8"), "price": this.SafeInteger(market, "price_precision"), }, "limits": map[string]interface{} { "leverage": map[string]interface{} { "min": nil, "max": nil, }, "amount": map[string]interface{} { "min": this.SafeNumber(market, "minimum_order_size"), "max": this.SafeNumber(market, "maximum_order_size"), }, "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 } func (this *bitfinex1) 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 *bitfinex1) 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 bitfinex1#fetchBalance * @description query for balance and get the amount of funds available for trading or funds locked in orders * @see https://docs.bitfinex.com/v1/reference/rest-auth-wallet-balances * @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 *bitfinex1) FetchBalance(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) params := GetArg(optionalArgs, 0, map[string]interface{} {}) _ = params retRes7048 := (<-this.LoadMarkets()) PanicOnError(retRes7048) var accountsByType interface{} = this.SafeDict(this.Options, "accountsByType", 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 query interface{} = this.Omit(params, "type") response:= (<-this.PrivatePostBalances(query)) PanicOnError(response) // [ { type: "deposit", // "currency": "btc", // "amount": "0.00116721", // "available": "0.00116721" }, // { type: "exchange", // "currency": "ust", // "amount": "0.0000002", // "available": "0.0000002" }, // { type: "trading", // "currency": "btc", // "amount": "0.0005", // "available": "0.0005" } ], var result interface{} = map[string]interface{} { "info": response, } var isDerivative interface{} = IsEqual(requestedType, "derivatives") for i := 0; IsLessThan(i, GetArrayLength(response)); i++ { var balance interface{} = GetValue(response, i) var typeVar interface{} = this.SafeString(balance, "type") var currencyId interface{} = this.SafeStringLower(balance, "currency", "") 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) // bitfinex had BCH previously, now it's BAB, but the old // BCH symbol is kept for backward-compatibility // we need a workaround here so that the old BCH balance // would not override the new BAB balance (BAB is unified to BCH) // https://github.com/ccxt/ccxt/issues/4989 if !IsTrue((InOp(result, code))) { var account interface{} = this.Account() AddElementToObject(account, "free", this.SafeString(balance, "available")) AddElementToObject(account, "total", this.SafeString(balance, "amount")) AddElementToObject(result, code, account) } } } ch <- this.SafeBalance(result) return nil }() return ch } /** * @method * @name bitfinex1#transfer * @description transfer currency internally between wallets on the same account * @see https://docs.bitfinex.com/v1/reference/rest-auth-transfer-between-wallets * @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 *bitfinex1) 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 retRes7698 := (<-this.LoadMarkets()) PanicOnError(retRes7698) var accountsByType interface{} = this.SafeDict(this.Options, "accountsByType", map[string]interface{} {}) var fromId interface{} = this.SafeString(accountsByType, fromAccount, fromAccount) var toId interface{} = this.SafeString(accountsByType, toAccount, toAccount) var currency interface{} = this.Currency(code) var fromCurrencyId interface{} = this.ConvertDerivativesId(GetValue(currency, "id"), fromAccount) var toCurrencyId interface{} = this.ConvertDerivativesId(GetValue(currency, "id"), toAccount) var requestedAmount interface{} = this.CurrencyToPrecision(code, amount) var request interface{} = map[string]interface{} { "amount": requestedAmount, "currency": fromCurrencyId, "currency_to": toCurrencyId, "walletfrom": fromId, "walletto": toId, } response:= (<-this.PrivatePostTransfer(this.Extend(request, params))) PanicOnError(response) // // [ // { // "status": "success", // "message": "0.0001 Bitcoin transfered from Margin to Exchange" // } // ] // var result interface{} = this.SafeValue(response, 0) var message interface{} = this.SafeString(result, "message") if IsTrue(IsEqual(message, nil)) { panic(ExchangeError(Add(this.Id, " transfer failed"))) } ch <- this.Extend(this.ParseTransfer(result, currency), map[string]interface{} { "fromAccount": fromAccount, "toAccount": toAccount, "amount": this.ParseNumber(requestedAmount), }) return nil }() return ch } func (this *bitfinex1) ParseTransfer(transfer interface{}, optionalArgs ...interface{}) interface{} { // // { // "status": "success", // "message": "0.0001 Bitcoin transfered from Margin to Exchange" // } // currency := GetArg(optionalArgs, 0, nil) _ = currency return map[string]interface{} { "info": transfer, "id": nil, "timestamp": nil, "datetime": nil, "currency": this.SafeCurrencyCode(nil, currency), "amount": nil, "fromAccount": nil, "toAccount": nil, "status": this.ParseTransferStatus(this.SafeString(transfer, "status")), } } func (this *bitfinex1) ParseTransferStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "SUCCESS": "ok", } return this.SafeString(statuses, status, status) } func (this *bitfinex1) ConvertDerivativesId(currencyId interface{}, typeVar interface{}) interface{} { var start interface{} = Subtract(GetArrayLength(currencyId), 2) var isDerivativeCode interface{} = IsEqual(Slice(currencyId, start, nil), "F0") if IsTrue(IsTrue((IsTrue(IsTrue(!IsEqual(typeVar, "derivatives")) && IsTrue(!IsEqual(typeVar, "trading"))) && IsTrue(!IsEqual(typeVar, "margin")))) && IsTrue(isDerivativeCode)) { currencyId = Slice(currencyId, 0, start) } else if IsTrue(IsTrue(IsEqual(typeVar, "derivatives")) && !IsTrue(isDerivativeCode)) { currencyId = Add(currencyId, "F0") } return currencyId } /** * @method * @name bitfinex1#fetchOrderBook * @description fetches information on open orders with bid (buy) and ask (sell) prices, volumes and other data * @see https://docs.bitfinex.com/v1/reference/rest-public-orderbook * @param {string} symbol unified symbol of the market to fetch the order book for * @param {int} [limit] the maximum amount of order book entries to return * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} A dictionary of [order book structures]{@link https://docs.ccxt.com/#/?id=order-book-structure} indexed by market symbols */ func (this *bitfinex1) 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 retRes8548 := (<-this.LoadMarkets()) PanicOnError(retRes8548) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit_bids", limit) AddElementToObject(request, "limit_asks", limit) } response:= (<-this.PublicGetBookSymbol(this.Extend(request, params))) PanicOnError(response) ch <- this.ParseOrderBook(response, GetValue(market, "symbol"), nil, "bids", "asks", "price", "amount") return nil }() return ch } /** * @method * @name bitfinex1#fetchTickers * @description fetches price tickers for multiple markets, statistical information calculated over the past 24 hours for each market * @param {string[]} [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 *bitfinex1) 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 retRes8768 := (<-this.LoadMarkets()) PanicOnError(retRes8768) symbols = this.MarketSymbols(symbols) response:= (<-this.PublicGetTickers(params)) PanicOnError(response) var result interface{} = map[string]interface{} {} for i := 0; IsLessThan(i, GetArrayLength(response)); i++ { var ticker interface{} = this.ParseTicker(GetValue(response, i)) var symbol interface{} = GetValue(ticker, "symbol") AddElementToObject(result, symbol, ticker) } ch <- this.FilterByArrayTickers(result, "symbol", symbols) return nil }() return ch } /** * @method * @name bitfinex1#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/v1/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 *bitfinex1) 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 retRes8988 := (<-this.LoadMarkets()) PanicOnError(retRes8988) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } ticker:= (<-this.PublicGetPubtickerSymbol(this.Extend(request, params))) PanicOnError(ticker) // // { // mid: '63560.5', // bid: '63560.0', // ask: '63561.0', // last_price: '63547.0', // low: '62812.0', // high: '64480.0', // volume: '517.25634977', // timestamp: '1715102384.9849467' // } // ch <- this.ParseTicker(ticker, market) return nil }() return ch } func (this *bitfinex1) ParseTicker(ticker interface{}, optionalArgs ...interface{}) interface{} { // // { // mid: '63560.5', // bid: '63560.0', // ask: '63561.0', // last_price: '63547.0', // low: '62812.0', // high: '64480.0', // volume: '517.25634977', // timestamp: '1715102384.9849467' // } // market := GetArg(optionalArgs, 0, nil) _ = market var timestamp interface{} = this.SafeTimestamp(ticker, "timestamp") var marketId interface{} = this.SafeString(ticker, "pair") market = this.SafeMarket(marketId, market) var symbol interface{} = GetValue(market, "symbol") var last interface{} = this.SafeString(ticker, "last_price") return this.SafeTicker(map[string]interface{} { "symbol": symbol, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "high": this.SafeString(ticker, "high"), "low": this.SafeString(ticker, "low"), "bid": this.SafeString(ticker, "bid"), "bidVolume": nil, "ask": this.SafeString(ticker, "ask"), "askVolume": nil, "vwap": nil, "open": nil, "close": last, "last": last, "previousClose": nil, "change": nil, "percentage": nil, "average": this.SafeString(ticker, "mid"), "baseVolume": this.SafeString(ticker, "volume"), "quoteVolume": nil, "info": ticker, }, market) } func (this *bitfinex1) ParseTrade(trade interface{}, optionalArgs ...interface{}) interface{} { // // fetchTrades (public) v1 // // { // "timestamp":1637258380, // "tid":894452833, // "price":"0.99941", // "amount":"261.38", // "exchange":"bitfinex", // "type":"sell" // } // // fetchMyTrades (private) v1 // // { // "price":"0.99941", // "amount":"261.38", // "timestamp":"1637258380.0", // "type":"Sell", // "fee_currency":"UST", // "fee_amount":"-0.52245157", // "tid":894452833, // "order_id":78819731373 // } // // { // "price":"0.99958", // "amount":"261.90514", // "timestamp":"1637258238.0", // "type":"Buy", // "fee_currency":"UDC", // "fee_amount":"-0.52381028", // "tid":894452800, // "order_id":78819504838 // } // market := GetArg(optionalArgs, 0, nil) _ = market var id interface{} = this.SafeString(trade, "tid") var timestamp interface{} = this.SafeTimestamp(trade, "timestamp") var typeVar interface{} = nil var side interface{} = this.SafeStringLower(trade, "type") var orderId interface{} = this.SafeString(trade, "order_id") var priceString interface{} = this.SafeString(trade, "price") var amountString interface{} = this.SafeString(trade, "amount") var fee interface{} = nil if IsTrue(InOp(trade, "fee_amount")) { var feeCostString interface{} = Precise.StringNeg(this.SafeString(trade, "fee_amount")) var feeCurrencyId interface{} = this.SafeString(trade, "fee_currency") var feeCurrencyCode interface{} = this.SafeCurrencyCode(feeCurrencyId) fee = map[string]interface{} { "cost": feeCostString, "currency": feeCurrencyCode, } } return this.SafeTrade(map[string]interface{} { "id": id, "info": trade, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "symbol": GetValue(market, "symbol"), "type": typeVar, "order": orderId, "side": side, "takerOrMaker": nil, "price": priceString, "amount": amountString, "cost": nil, "fee": fee, }, market) } /** * @method * @name bitfinex1#fetchTrades * @description get the list of most recent trades for a particular symbol * @see https://docs.bitfinex.com/v1/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 * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {Trade[]} a list of [trade structures]{@link https://docs.ccxt.com/#/?id=public-trades} */ func (this *bitfinex1) 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, 50) _ = limit params := GetArg(optionalArgs, 2, map[string]interface{} {}) _ = params retRes10448 := (<-this.LoadMarkets()) PanicOnError(retRes10448) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), "limit_trades": limit, } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "timestamp", this.ParseToInt(Divide(since, 1000))) } response:= (<-this.PublicGetTradesSymbol(this.Extend(request, params))) PanicOnError(response) // // [ // { // "timestamp": "1694284565", // "tid": "1415415034", // "price": "25862.0", // "amount": "0.00020685", // "exchange": "bitfinex", // "type": "buy" // }, // ] // ch <- this.ParseTrades(response, market, since, limit) return nil }() return ch } /** * @method * @name bitfinex1#fetchMyTrades * @description fetch all trades made by the user * @see https://docs.bitfinex.com/v1/reference/rest-auth-past-trades * @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 *bitfinex1) 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 if IsTrue(IsEqual(symbol, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchMyTrades() requires a symbol argument"))) } retRes10848 := (<-this.LoadMarkets()) PanicOnError(retRes10848) var market interface{} = this.Market(symbol) var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), } if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit_trades", limit) } if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "timestamp", this.ParseToInt(Divide(since, 1000))) } response:= (<-this.PrivatePostMytrades(this.Extend(request, params))) PanicOnError(response) ch <- this.ParseTrades(response, market, since, limit) return nil }() return ch } /** * @method * @name bitfinex1#createOrder * @description create a trade order * @see https://docs.bitfinex.com/v1/reference/rest-auth-new-order * @param {string} symbol unified symbol of the market to create an order in * @param {string} type 'market' or 'limit' * @param {string} side 'buy' or 'sell' * @param {float} amount how much of currency you want to trade in units of base currency * @param {float} [price] the price at which the order is to be fulfilled, in units of the quote currency, ignored in market orders * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} an [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *bitfinex1) 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 retRes11138 := (<-this.LoadMarkets()) PanicOnError(retRes11138) var market interface{} = this.Market(symbol) var postOnly interface{} = this.SafeBool(params, "postOnly", false) typeVar = ToLower(typeVar) params = this.Omit(params, []interface{}{"postOnly"}) if IsTrue(GetValue(market, "spot")) { // although they claim that type needs to be 'exchange limit' or 'exchange market' // in fact that's not the case for swap markets typeVar = this.SafeStringLower(GetValue(this.Options, "orderTypes"), typeVar, typeVar) } var request interface{} = map[string]interface{} { "symbol": GetValue(market, "id"), "side": side, "amount": this.AmountToPrecision(symbol, amount), "type": typeVar, "ocoorder": false, "buy_price_oco": 0, "sell_price_oco": 0, } if IsTrue(IsGreaterThan(GetIndexOf(typeVar, "market"), OpNeg(1))) { AddElementToObject(request, "price", ToString(this.Nonce())) } else { AddElementToObject(request, "price", this.PriceToPrecision(symbol, price)) } if IsTrue(postOnly) { AddElementToObject(request, "is_postonly", true) } response:= (<-this.PrivatePostOrderNew(this.Extend(request, params))) PanicOnError(response) ch <- this.ParseOrder(response, market) return nil }() return ch } func (this *bitfinex1) 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 retRes11458 := (<-this.LoadMarkets()) PanicOnError(retRes11458) var order interface{} = map[string]interface{} { "order_id": ParseInt(id), } if IsTrue(!IsEqual(price, nil)) { AddElementToObject(order, "price", this.PriceToPrecision(symbol, price)) } if IsTrue(!IsEqual(amount, nil)) { AddElementToObject(order, "amount", this.NumberToString(amount)) } if IsTrue(!IsEqual(symbol, nil)) { AddElementToObject(order, "symbol", this.MarketId(symbol)) } if IsTrue(!IsEqual(side, nil)) { AddElementToObject(order, "side", side) } if IsTrue(!IsEqual(typeVar, nil)) { AddElementToObject(order, "type", this.SafeString(GetValue(this.Options, "orderTypes"), typeVar, typeVar)) } response:= (<-this.PrivatePostOrderCancelReplace(this.Extend(order, params))) PanicOnError(response) ch <- this.ParseOrder(response) return nil }() return ch } /** * @method * @name bitfinex1#cancelOrder * @description cancels an open order * @see https://docs.bitfinex.com/v1/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 *bitfinex1) 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 retRes11798 := (<-this.LoadMarkets()) PanicOnError(retRes11798) var request interface{} = map[string]interface{} { "order_id": ParseInt(id), } response:= (<-this.PrivatePostOrderCancel(this.Extend(request, params))) PanicOnError(response) // // { // id: '161236928925', // cid: '1720172026812', // cid_date: '2024-07-05', // gid: null, // symbol: 'adaust', // exchange: 'bitfinex', // price: '0.33', // avg_execution_price: '0.0', // side: 'buy', // type: 'exchange limit', // timestamp: '1720172026.813', // is_live: true, // is_cancelled: false, // is_hidden: false, // oco_order: null, // was_forced: false, // original_amount: '10.0', // remaining_amount: '10.0', // executed_amount: '0.0', // src: 'api', // meta: {} // } // ch <- this.ParseOrder(response) return nil }() return ch } /** * @method * @name bitfinex1#cancelAllOrders * @description cancel all open orders * @see https://docs.bitfinex.com/v1/reference/rest-auth-cancel-all-orders * @param {string} symbol not used by bitfinex cancelAllOrders * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} response from exchange */ func (this *bitfinex1) 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 response:= (<-this.PrivatePostOrderCancelAll(params)) PanicOnError(response) // // { result: 'Submitting 1 order cancellations.' } // ch <- []interface{}{this.SafeOrder(map[string]interface{} { "info": response, })} return nil }() return ch } func (this *bitfinex1) ParseOrder(order interface{}, optionalArgs ...interface{}) interface{} { // // { // "id": 57334010955, // "cid": 1611584840966, // "cid_date": null, // "gid": null, // "symbol": "ltcbtc", // "exchange": null, // "price": "0.0042125", // "avg_execution_price": "0.0042097", // "side": "sell", // "type": "exchange market", // "timestamp": "1611584841.0", // "is_live": false, // "is_cancelled": false, // "is_hidden": 0, // "oco_order": 0, // "was_forced": false, // "original_amount": "0.205176", // "remaining_amount": "0.0", // "executed_amount": "0.205176", // "src": "web" // } // market := GetArg(optionalArgs, 0, nil) _ = market var side interface{} = this.SafeString(order, "side") var open interface{} = this.SafeBool(order, "is_live") var canceled interface{} = this.SafeBool(order, "is_cancelled") var status interface{} = nil if IsTrue(open) { status = "open" } else if IsTrue(canceled) { status = "canceled" } else { status = "closed" } var marketId interface{} = this.SafeStringUpper(order, "symbol") var symbol interface{} = this.SafeSymbol(marketId, market) var orderType interface{} = this.SafeString(order, "type", "") var exchange interface{} = IsGreaterThanOrEqual(GetIndexOf(orderType, "exchange "), 0) if IsTrue(exchange) { var parts interface{} = Split(GetValue(order, "type"), " ") orderType = GetValue(parts, 1) } var timestamp interface{} = this.SafeTimestamp(order, "timestamp") var id interface{} = this.SafeString(order, "id") return this.SafeOrder(map[string]interface{} { "info": order, "id": id, "clientOrderId": nil, "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "lastTradeTimestamp": nil, "symbol": symbol, "type": orderType, "timeInForce": nil, "postOnly": nil, "side": side, "price": this.SafeString(order, "price"), "triggerPrice": nil, "average": this.SafeString(order, "avg_execution_price"), "amount": this.SafeString(order, "original_amount"), "remaining": this.SafeString(order, "remaining_amount"), "filled": this.SafeString(order, "executed_amount"), "status": status, "fee": nil, "cost": nil, "trades": nil, }, market) } /** * @method * @name bitfinex1#fetchOpenOrders * @description fetch all unfilled currently open orders * @see https://docs.bitfinex.com/v1/reference/rest-auth-active-orders * @param {string} symbol unified market symbol * @param {int} [since] the earliest time in ms to fetch open orders for * @param {int} [limit] the maximum number of open orders structures to retrieve * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *bitfinex1) 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 retRes13168 := (<-this.LoadMarkets()) PanicOnError(retRes13168) if IsTrue(!IsEqual(symbol, nil)) { if !IsTrue((InOp(this.Markets, symbol))) { panic(ExchangeError(Add(Add(this.Id, " has no symbol "), symbol))) } } response:= (<-this.PrivatePostOrders(params)) PanicOnError(response) var orders interface{} = this.ParseOrders(response, nil, since, limit) if IsTrue(!IsEqual(symbol, nil)) { orders = this.FilterBy(orders, "symbol", symbol) } ch <- orders return nil }() return ch } /** * @method * @name bitfinex1#fetchClosedOrders * @description fetches information on multiple closed orders made by the user * @see https://docs.bitfinex.com/v1/reference/rest-auth-orders-history * @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 * @returns {Order[]} a list of [order structures]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *bitfinex1) FetchClosedOrders(optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) symbol := GetArg(optionalArgs, 0, nil) _ = symbol since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes13428 := (<-this.LoadMarkets()) PanicOnError(retRes13428) symbol = this.Symbol(symbol) var request interface{} = map[string]interface{} {} if IsTrue(!IsEqual(limit, nil)) { AddElementToObject(request, "limit", limit) } response:= (<-this.PrivatePostOrdersHist(this.Extend(request, params))) PanicOnError(response) var orders interface{} = this.ParseOrders(response, nil, since, limit) if IsTrue(!IsEqual(symbol, nil)) { orders = this.FilterBy(orders, "symbol", symbol) } orders = this.FilterByArray(orders, "status", []interface{}{"closed", "canceled"}, false) ch <- orders return nil }() return ch } /** * @method * @name bitfinex1#fetchOrder * @description fetches information on an order made by the user * @see https://docs.bitfinex.com/v1/reference/rest-auth-order-status * @param {string} id the order id * @param {string} symbol not used by bitfinex fetchOrder * @param {object} [params] extra parameters specific to the exchange API endpoint * @returns {object} An [order structure]{@link https://docs.ccxt.com/#/?id=order-structure} */ func (this *bitfinex1) 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 retRes13688 := (<-this.LoadMarkets()) PanicOnError(retRes13688) var request interface{} = map[string]interface{} { "order_id": ParseInt(id), } response:= (<-this.PrivatePostOrderStatus(this.Extend(request, params))) PanicOnError(response) ch <- this.ParseOrder(response) return nil }() return ch } func (this *bitfinex1) 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)} } /** * @method * @name bitfinex1#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#aggregate-funding-currency-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 * @param {object} [params] extra parameters specific to the exchange API endpoint * @param {int} [params.until] timestamp in ms of the latest candle to fetch * @returns {int[][]} A list of candles ordered as timestamp, open, high, low, close, volume */ func (this *bitfinex1) FetchOHLCV(symbol interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) timeframe := GetArg(optionalArgs, 0, "1m") _ = timeframe since := GetArg(optionalArgs, 1, nil) _ = since limit := GetArg(optionalArgs, 2, nil) _ = limit params := GetArg(optionalArgs, 3, map[string]interface{} {}) _ = params retRes14118 := (<-this.LoadMarkets()) PanicOnError(retRes14118) if IsTrue(IsEqual(limit, nil)) { limit = 100 } else { limit = mathMin(limit, 10000) } var market interface{} = this.Market(symbol) var v2id interface{} = Add("t", GetValue(market, "id")) var request interface{} = map[string]interface{} { "symbol": v2id, "timeframe": this.SafeString(this.Timeframes, timeframe, timeframe), "sort": 1, "limit": limit, } var until interface{} = this.SafeInteger(params, "until") if IsTrue(!IsEqual(since, nil)) { AddElementToObject(request, "start", since) } else if IsTrue(!IsEqual(until, nil)) { var duration interface{} = this.ParseTimeframe(timeframe) AddElementToObject(request, "start", Subtract(until, (Multiply(Multiply((Subtract(limit, 1)), duration), 1000)))) } if IsTrue(!IsEqual(until, nil)) { AddElementToObject(request, "end", until) } params = this.Omit(params, "until") response:= (<-this.V2GetCandlesTradeTimeframeSymbolHist(this.Extend(request, params))) PanicOnError(response) // // [ // [1457539800000,0.02594,0.02594,0.02594,0.02594,0.1], // [1457547300000,0.02577,0.02577,0.02577,0.02577,0.01], // [1457550240000,0.0255,0.0253,0.0255,0.0252,3.2640000000000002], // ] // ch <- this.ParseOHLCVs(response, market, timeframe, since, limit) return nil }() return ch } func (this *bitfinex1) GetCurrencyName(code interface{}) interface{} { // todo rewrite for https://api-pub.bitfinex.com//v2/conf/pub:map:tx:method 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"))) } /** * @method * @name bitfinex1#createDepositAddress * @description create a currency deposit address * @see https://docs.bitfinex.com/v1/reference/rest-auth-deposit * @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 *bitfinex1) 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 retRes14658 := (<-this.LoadMarkets()) PanicOnError(retRes14658) var request interface{} = map[string]interface{} { "renew": 1, } retRes146915 := (<-this.FetchDepositAddress(code, this.Extend(request, params))) PanicOnError(retRes146915) ch <- retRes146915 return nil }() return ch } /** * @method * @name bitfinex1#fetchDepositAddress * @description fetch the deposit address for a currency associated with this account * @see https://docs.bitfinex.com/v1/reference/rest-auth-deposit * @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 *bitfinex1) 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 retRes14828 := (<-this.LoadMarkets()) PanicOnError(retRes14828) // todo rewrite for https://api-pub.bitfinex.com//v2/conf/pub:map:tx:method var name interface{} = this.GetCurrencyName(code) var request interface{} = map[string]interface{} { "method": name, "wallet_name": "exchange", "renew": 0, } response:= (<-this.PrivatePostDepositNew(this.Extend(request, params))) PanicOnError(response) var address interface{} = this.SafeValue(response, "address") var tag interface{} = nil if IsTrue(InOp(response, "address_pool")) { tag = address address = GetValue(response, "address_pool") } this.CheckAddress(address) ch <- map[string]interface{} { "currency": code, "address": address, "tag": tag, "network": nil, "info": response, } return nil }() return ch } /** * @method * @name bitfinex1#fetchDepositsWithdrawals * @description fetch history of deposits and withdrawals * @see https://docs.bitfinex.com/v1/reference/rest-auth-deposit-withdrawal-history * @param {string} code unified currency code for the currency of the deposit/withdrawals * @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 *bitfinex1) 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 retRes15198 := (<-this.LoadMarkets()) PanicOnError(retRes15198) var currencyId interface{} = this.SafeString(params, "currency") var query interface{} = this.Omit(params, "currency") var currency interface{} = nil if IsTrue(IsEqual(currencyId, nil)) { if IsTrue(IsEqual(code, nil)) { panic(ArgumentsRequired(Add(this.Id, " fetchDepositsWithdrawals() requires a currency `code` argument or a `currency` parameter"))) } else { currency = this.Currency(code) currencyId = GetValue(currency, "id") } } AddElementToObject(query, "currency", currencyId) if IsTrue(!IsEqual(since, nil)) { AddElementToObject(query, "since", this.ParseToInt(Divide(since, 1000))) } response:= (<-this.PrivatePostHistoryMovements(this.Extend(query, params))) PanicOnError(response) // // [ // { // "id": 581183, // "txid": 123456, // "currency": "BTC", // "method": "BITCOIN", // "type": "WITHDRAWAL", // "amount": ".01", // "description": "3QXYWgRGX2BPYBpUDBssGbeWEa5zq6snBZ, offchain transfer ", // "address": "3QXYWgRGX2BPYBpUDBssGbeWEa5zq6snBZ", // "status": "COMPLETED", // "timestamp": "1443833327.0", // "timestamp_created": "1443833327.1", // "fee": 0.1, // } // ] // ch <- this.ParseTransactions(response, currency, since, limit) return nil }() return ch } func (this *bitfinex1) ParseTransaction(transaction interface{}, optionalArgs ...interface{}) interface{} { // // crypto // // { // "id": 12042490, // "fee": "-0.02", // "txid": "EA5B5A66000B66855865EFF2494D7C8D1921FCBE996482157EBD749F2C85E13D", // "type": "DEPOSIT", // "amount": "2099.849999", // "method": "RIPPLE", // "status": "COMPLETED", // "address": "2505189261", // "currency": "XRP", // "timestamp": "1551730524.0", // "description": "EA5B5A66000B66855865EFF2494D7C8D1921FCBE996482157EBD749F2C85E13D", // "timestamp_created": "1551730523.0" // } // // fiat // // { // "id": 12725095, // "fee": "-60.0", // "txid": null, // "type": "WITHDRAWAL", // "amount": "9943.0", // "method": "WIRE", // "status": "SENDING", // "address": null, // "currency": "EUR", // "timestamp": "1561802484.0", // "description": "Name: bob, AccountAddress: some address, Account: someaccountno, Bank: bank address, SWIFT: foo, Country: UK, Details of Payment: withdrawal name, Intermediary Bank Name: , Intermediary Bank Address: , Intermediary Bank City: , Intermediary Bank Country: , Intermediary Bank Account: , Intermediary Bank SWIFT: , Fee: -60.0", // "timestamp_created": "1561716066.0" // } // // withdraw // // { // "status": "success", // "message": "Your withdrawal request has been successfully submitted.", // "withdrawal_id": 586829 // } // currency := GetArg(optionalArgs, 0, nil) _ = currency var timestamp interface{} = this.SafeTimestamp(transaction, "timestamp_created") var currencyId interface{} = this.SafeString(transaction, "currency") var code interface{} = this.SafeCurrencyCode(currencyId, currency) var feeCost interface{} = this.SafeString(transaction, "fee") if IsTrue(!IsEqual(feeCost, nil)) { feeCost = Precise.StringAbs(feeCost) } return map[string]interface{} { "info": transaction, "id": this.SafeString2(transaction, "id", "withdrawal_id"), "txid": this.SafeString(transaction, "txid"), "type": this.SafeStringLower(transaction, "type"), "currency": code, "network": nil, "amount": this.SafeNumber(transaction, "amount"), "status": this.ParseTransactionStatus(this.SafeString(transaction, "status")), "timestamp": timestamp, "datetime": this.Iso8601(timestamp), "address": this.SafeString(transaction, "address"), "addressFrom": nil, "addressTo": nil, "tag": this.SafeString(transaction, "description"), "tagFrom": nil, "tagTo": nil, "updated": this.SafeTimestamp(transaction, "timestamp"), "comment": nil, "internal": nil, "fee": map[string]interface{} { "currency": code, "cost": this.ParseNumber(feeCost), "rate": nil, }, } } func (this *bitfinex1) ParseTransactionStatus(status interface{}) interface{} { var statuses interface{} = map[string]interface{} { "SENDING": "pending", "CANCELED": "canceled", "ZEROCONFIRMED": "failed", "COMPLETED": "ok", } return this.SafeString(statuses, status, status) } /** * @method * @name bitfinex1#withdraw * @description make a withdrawal * @see https://docs.bitfinex.com/v1/reference/rest-auth-withdrawal * @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 *bitfinex1) Withdraw(code interface{}, amount interface{}, address interface{}, optionalArgs ...interface{}) <- chan interface{} { ch := make(chan interface{}) go func() interface{} { defer close(ch) defer ReturnPanicError(ch) tag := GetArg(optionalArgs, 0, nil) _ = tag params := GetArg(optionalArgs, 1, map[string]interface{} {}) _ = params tagparamsVariable := this.HandleWithdrawTagAndParams(tag, params); tag = GetValue(tagparamsVariable,0); params = GetValue(tagparamsVariable,1) this.CheckAddress(address) retRes16618 := (<-this.LoadMarkets()) PanicOnError(retRes16618) // todo rewrite for https://api-pub.bitfinex.com//v2/conf/pub:map:tx:method var name interface{} = this.GetCurrencyName(code) var currency interface{} = this.Currency(code) var request interface{} = map[string]interface{} { "withdraw_type": name, "walletselected": "exchange", "amount": this.NumberToString(amount), "address": address, } if IsTrue(!IsEqual(tag, nil)) { AddElementToObject(request, "payment_id", tag) } responses:= (<-this.PrivatePostWithdraw(this.Extend(request, params))) PanicOnError(responses) // // [ // { // "status":"success", // "message":"Your withdrawal request has been successfully submitted.", // "withdrawal_id":586829 // } // ] // var response interface{} = this.SafeDict(responses, 0, map[string]interface{} {}) var id interface{} = this.SafeInteger(response, "withdrawal_id") var message interface{} = this.SafeString(response, "message") var errorMessage interface{} = this.FindBroadlyMatchedKey(GetValue(this.Exceptions, "broad"), message) if IsTrue(IsEqual(id, 0)) { if IsTrue(!IsEqual(errorMessage, nil)) { var ExceptionClass interface{} = GetValue(GetValue(this.Exceptions, "broad"), errorMessage) throwDynamicException(ExceptionClass, Add(Add(this.Id, " "), message));return nil; } panic(ExchangeError(Add(Add(this.Id, " withdraw returned an id of zero: "), this.Json(response)))) } ch <- this.ParseTransaction(response, currency) return nil }() return ch } /** * @method * @name bitfinex1#fetchPositions * @description fetch all open positions * @see https://docs.bitfinex.com/v1/reference/rest-auth-active-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 *bitfinex1) 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 retRes17088 := (<-this.LoadMarkets()) PanicOnError(retRes17088) response:= (<-this.PrivatePostPositions(params)) PanicOnError(response) // // [ // { // "id":943715, // "symbol":"btcusd", // "status":"ACTIVE", // "base":"246.94", // "amount":"1.0", // "timestamp":"1444141857.0", // "swap":"0.0", // "pl":"-2.22042" // } // ] // // todo unify parsePosition/parsePositions ch <- response return nil }() return ch } func (this *bitfinex1) Nonce() interface{} { return this.Microseconds() } func (this *bitfinex1) 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)) if IsTrue(IsEqual(api, "v2")) { request = Add(Add("/", api), request) } else { request = Add(Add("/", this.Version), request) } var query interface{} = this.Omit(params, this.ExtractParams(path)) var url interface{} = Add(GetValue(GetValue(this.Urls, "api"), api), request) if IsTrue(IsTrue((IsEqual(api, "public"))) || IsTrue((IsGreaterThanOrEqual(GetIndexOf(path, "/hist"), 0)))) { if IsTrue(GetArrayLength(ObjectKeys(query))) { var suffix interface{} = Add("?", this.Urlencode(query)) url = Add(url, suffix) request = Add(request, suffix) } } if IsTrue(IsEqual(api, "private")) { this.CheckRequiredCredentials() var nonce interface{} = this.Nonce() query = this.Extend(map[string]interface{} { "nonce": ToString(nonce), "request": request, }, query) body = this.Json(query) var payload interface{} = this.StringToBase64(body) var secret interface{} = this.Encode(this.Secret) var signature interface{} = this.Hmac(this.Encode(payload), secret, sha384) headers = map[string]interface{} { "X-BFX-APIKEY": this.ApiKey, "X-BFX-PAYLOAD": payload, "X-BFX-SIGNATURE": signature, "Content-Type": "application/json", } } return map[string]interface{} { "url": url, "method": method, "body": body, "headers": headers, } } func (this *bitfinex1) HandleErrors(code interface{}, reason interface{}, url interface{}, method interface{}, headers interface{}, body interface{}, response interface{}, requestHeaders interface{}, requestBody interface{}) interface{} { if IsTrue(IsEqual(response, nil)) { return nil } var throwError interface{} = false if IsTrue(IsGreaterThanOrEqual(code, 400)) { if IsTrue(IsEqual(GetValue(body, 0), "{")) { throwError = true } } else { // json response with error, i.e: // [{"status":"error","message":"Momentary balance check. Please wait few seconds and try the transfer again."}] var responseObject interface{} = this.SafeDict(response, 0, map[string]interface{} {}) var status interface{} = this.SafeString(responseObject, "status", "") if IsTrue(IsEqual(status, "error")) { throwError = true } } if IsTrue(throwError) { var feedback interface{} = Add(Add(this.Id, " "), body) var message interface{} = this.SafeString2(response, "message", "error") this.ThrowExactlyMatchedException(GetValue(this.Exceptions, "exact"), message, feedback) this.ThrowBroadlyMatchedException(GetValue(this.Exceptions, "broad"), message, feedback) panic(ExchangeError(feedback)) } return nil } func (this *bitfinex1) Init(userConfig map[string]interface{}) { this.Exchange = Exchange{} this.Exchange.InitParent(userConfig, this.Describe().(map[string]interface{}), this) this.Exchange.DerivedExchange = this }