ccxt-go/bitfinex.go

4607 lines
204 KiB
Go
Raw Permalink Normal View History

2025-02-28 10:33:20 +08:00
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
}