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