Feature: Implement funding rates, futures and coin margin (exchange API coverage) (#530)

* ALMOST THERE

* more api wips

* more api thingz

* testing n more api wipz

* more apiz

* more wips

* what is goin on

* more wips

* whip n testing

* testing

* testing

no keys

* remove log

* kraken is broken

ugh

* still broken

* fixing auth funcs + usdtm api docs

* wip

* api stuffs

* whip

* more wips

* whip

* more wip

* api wip n testing

* wip

* wip

* unsaved

* wip n testing

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* wip

* whip

* wrapper authenticated functions

* adding asset type and fixing dependencies

* wip

* binance auth wrapper start

* wrapper functionality

* wip

* wip

* wip

* wrapper cancel functions

* order submission for wrappers

* wip

* more error fixing and nits

* websocket beginning n error fix

* wip

* WOW

* glorious n shazzy nits

* useless nits

* wip

* fixing things

* merge stuffs

* crapveyor

* crapveyor rebuild

* probably broke more things than he fixed

* rm lns n other thangs

* hope

* please

* stop it

* done

* ofcourse

* rm vb

* fix lbank

* appveyor please

* float lev

* DONT ASK RYAN FOR HELP EVER

* wip

* wip

* endpoint upgrades continued

* path upgrade

* NeeeNeeeNeeeNeeeNING

* fix stuffs

* fixing time issue

* fixing broken funcs

* glorious nits

* shaz changes

* fixing errors for fundmon

* more error fixing for fundmon

* test running past 30s

* basic changes

* THX AGAIN SHAZBERT

* path system upgrade

* config upgrade

* unsaved stuffs

* broken wip config upgrade

* path system upgrade contd.

* path system upgrade contd

* path upgrade ready for review

* testing verbose removed

* linter stuffs

* appveyor stuffs

* appveyor stuff

* fixed?

* bugfix

* wip

* broken stuff

* fix test

* wierd hack fix

* appveyor pls stop

* error found

* more useless nits

* bitmex err

* broken wip

* broken wip path upgrade change to uint32

* changed url lookups to uint

* WOW

* ready4review

* config fixed HOPEFULLY

* config fix and glorious changes

* efficient way of getting orders and open orders

* binance wrapper logic fixing

* testing, adding tests and fixing lot of errrrrs

* merge master

* appveyor stuffs

* appveyor stuffs

* fmt

* test

* octalLiteral issue fix?

* octalLiteral fix?

* rm vb

* prnt ln to restart

* adding testz

* test fixzzz

* READY FOR REVIEW

* Actually ready now

* FORMATTING

* addressing shazzy n glorious nits

* crapveyor

* rm vb

* small change

* fixing err

* shazbert nits

* review changes

* requested changes

* more requested changes

* noo

* last nit fixes

* restart appveyor

* improving test cov

* Update .golangci.yml

* shazbert changes

* moving pair formatting

* format pair update wip

* path upgrade complete

* error fix

* appveyor linters

* more linters

* remove testexch

* more formatting changes

* changes

* shazbert changes

* checking older requested changes to ensure completion

* wip

* fixing broken code

* error fix

* all fixed

* additional changes

* more changes

* remove commented code

* ftx margin api

* appveyor fixes

* more appveyor issues + test addition

* more appveyor issues + test addition

* remove unnecessary

* testing

* testing, fixing okex api, error fix

* git merge fix

* go sum

* glorious changes and error fix

* rm vb

* more glorious changes and go mod tidy

* fixed now

* okex testing upgrade

* old config migration and batch fetching fix

* added test

* glorious requested changes WIP

* tested and fixed

* go fmted

* go fmt and test fix

* additional funcs and tests for fundingRates

* OKEX tested and fixed

* appveyor fixes

* ineff assign

* 1 glorious change

* error fix

* typo

* shazbert changes

* glorious code changes and path fixing huobi WIP

* adding assetType to accountinfo functions

* fixing panic

* panic fix and updating account info wrappers WIP

* updateaccountinfo updated

* testing WIP binance USDT n Coin Margined and Kraken Futures

* auth functions tested and fixed

* added test

* config reverted

* shazbert and glorious changes

* shazbert and glorious changes

* latest changes and portfolio update

* go fmt change:

* remove commented codes

* improved error checking

* index out of range fix

* rm ln

* critical nit

* glorious latest changes

* appveyor changes

* shazbert change

* easier readability

* latest glorious changes

* shadow dec

* assetstore updated

* last change

* another last change

* merge changes

* go mod tidy

* thrasher requested changes wip

* improving struct layouts

* appveyor go fmt

* remove unnecessary code

* shazbert changes

* small change

* oopsie

* tidy

* configtest reverted

* error fix

* oopsie

* for what

* test patch fix

* insecurities

* fixing tests

* fix config
This commit is contained in:
Adam
2021-02-12 16:19:18 +11:00
committed by GitHub
parent e9bd2ad4d8
commit 504c2fad6d
169 changed files with 227754 additions and 31776 deletions

View File

@@ -1,10 +1,12 @@
package bitfinex
import (
"bytes"
"context"
"encoding/json"
"errors"
"fmt"
"io"
"net/http"
"net/url"
"strconv"
@@ -60,17 +62,23 @@ const (
bitfinexLeaderboard = "rankings"
// Version 2 API endpoints
bitfinexAPIVersion2 = "/v2/"
bitfinexPlatformStatus = "platform/status"
bitfinexTickerBatch = "tickers"
bitfinexTicker = "ticker/"
bitfinexTrades = "trades/"
bitfinexOrderbook = "book/"
bitfinexStatistics = "stats1/"
bitfinexCandles = "candles/trade"
bitfinexKeyPermissions = "key_info"
bitfinexMarginInfo = "margin_infos"
bitfinexDepositMethod = "conf/pub:map:currency:label"
bitfinexAPIVersion2 = "/v2/"
bitfinexV2MarginFunding = "calc/trade/avg?"
bitfinexV2Balances = "auth/r/wallets"
bitfinexV2AccountInfo = "auth/r/info/user"
bitfinexV2FundingInfo = "auth/r/info/funding/%s"
bitfinexDerivativeData = "status/deriv?"
bitfinexPlatformStatus = "platform/status"
bitfinexTickerBatch = "tickers"
bitfinexTicker = "ticker/"
bitfinexTrades = "trades/"
bitfinexOrderbook = "book/"
bitfinexStatistics = "stats1/"
bitfinexCandles = "candles/trade"
bitfinexKeyPermissions = "key_info"
bitfinexMarginInfo = "margin_infos"
bitfinexDepositMethod = "conf/pub:map:currency:label"
bitfinexMarginPairs = "conf/pub:list:pair:margin"
// Bitfinex platform status values
// When the platform is marked in maintenance mode bots should stop trading
@@ -91,9 +99,9 @@ type Bitfinex struct {
// GetPlatformStatus returns the Bifinex platform status
func (b *Bitfinex) GetPlatformStatus() (int, error) {
var response []int
err := b.SendHTTPRequest(b.API.Endpoints.URL+
err := b.SendHTTPRequest(exchange.RestSpot,
bitfinexAPIVersion2+
bitfinexPlatformStatus,
bitfinexPlatformStatus,
&response,
platformStatus)
if err != nil {
@@ -110,16 +118,271 @@ func (b *Bitfinex) GetPlatformStatus() (int, error) {
return -1, fmt.Errorf("unexpected platform status value %d", response[0])
}
// GetV2MarginFunding gets borrowing rates for margin trading
func (b *Bitfinex) GetV2MarginFunding(symbol, amount string, period int32) (MarginV2FundingData, error) {
var resp []interface{}
var response MarginV2FundingData
params := make(map[string]interface{})
params["symbol"] = symbol
params["period"] = period
params["amount"] = amount
err := b.SendAuthenticatedHTTPRequestV2(exchange.RestSpot, http.MethodPost,
bitfinexV2MarginFunding,
params,
&resp,
getAccountFees)
if err != nil {
return response, err
}
if len(resp) != 2 {
return response, errors.New("invalid data received")
}
avgRate, ok := resp[0].(float64)
if !ok {
return response, errors.New("failed type assertion for rate")
}
avgAmount, ok := resp[1].(float64)
if !ok {
return response, errors.New("failed type assertion for amount")
}
response.Symbol = symbol
response.RateAverage = avgRate
response.AmountAverage = avgAmount
return response, nil
}
// GetV2FundingInfo gets funding info for margin pairs
func (b *Bitfinex) GetV2FundingInfo(key string) (MarginFundingDataV2, error) {
var resp []interface{}
var response MarginFundingDataV2
err := b.SendAuthenticatedHTTPRequestV2(exchange.RestSpot, http.MethodPost,
fmt.Sprintf(bitfinexV2FundingInfo, key),
nil,
&resp,
getAccountFees)
if err != nil {
return response, err
}
if len(resp) != 3 {
return response, errors.New("invalid data received")
}
sym, ok := resp[0].(string)
if !ok {
return response, errors.New("failed type assertion for sym")
}
symbol, ok := resp[1].(string)
if !ok {
return response, errors.New("failed type assertion for symbol")
}
fundingData, ok := resp[2].([]interface{})
if !ok {
return response, errors.New("failed type assertion for fundingData")
}
response.Sym = sym
response.Symbol = symbol
if len(fundingData) < 4 {
return response, errors.New("invalid length of fundingData")
}
for x := 0; x < 3; x++ {
_, ok := fundingData[x].(float64)
if !ok {
return response, fmt.Errorf("type conversion failed for x = %d", x)
}
}
response.Data.YieldLoan = fundingData[0].(float64)
response.Data.YieldLend = fundingData[1].(float64)
response.Data.DurationLoan = fundingData[2].(float64)
response.Data.DurationLend = fundingData[3].(float64)
return response, nil
}
// GetAccountInfoV2 gets V2 account data
func (b *Bitfinex) GetAccountInfoV2() (AccountV2Data, error) {
var resp AccountV2Data
var data []interface{}
err := b.SendAuthenticatedHTTPRequestV2(exchange.RestSpot, http.MethodPost,
bitfinexV2AccountInfo,
nil,
&data,
getAccountFees)
if err != nil {
return resp, err
}
if len(data) < 8 {
return resp, errors.New("invalid length of data")
}
var ok bool
var tempString string
var tempFloat float64
if tempFloat, ok = data[0].(float64); !ok {
return resp, errors.New("type assertion failed for id, check for api updates")
}
resp.ID = int64(tempFloat)
if tempString, ok = data[1].(string); !ok {
return resp, errors.New("type assertion failed for email, check for api updates")
}
resp.Email = tempString
if tempString, ok = data[2].(string); !ok {
return resp, errors.New("type assertion failed for username, check for api updates")
}
resp.Username = tempString
if tempFloat, ok = data[3].(float64); !ok {
return resp, errors.New("type assertion failed for accountcreate, check for api updates")
}
resp.MTSAccountCreate = int64(tempFloat)
if tempFloat, ok = data[4].(float64); !ok {
return resp, errors.New("type assertion failed for verified, check for api updates")
}
resp.Verified = int64(tempFloat)
if tempString, ok = data[7].(string); !ok {
return resp, errors.New("type assertion failed for timezone, check for api updates")
}
resp.Timezone = tempString
return resp, nil
}
// GetV2Balances gets v2 balances
func (b *Bitfinex) GetV2Balances() ([]WalletDataV2, error) {
var resp []WalletDataV2
var data [][4]interface{}
err := b.SendAuthenticatedHTTPRequestV2(exchange.RestSpot, http.MethodPost,
bitfinexV2Balances,
nil,
&data,
getAccountFees)
if err != nil {
return resp, err
}
for x := range data {
wType, ok := data[x][0].(string)
if !ok {
return resp, errors.New("type assertion failed for walletType, check for api updates")
}
curr, ok := data[x][1].(string)
if !ok {
return resp, errors.New("type assertion failed for currency, check for api updates")
}
bal, ok := data[x][2].(float64)
if !ok {
return resp, errors.New("type assertion failed for balance, check for api updates")
}
unsettledInterest, ok := data[x][3].(float64)
if !ok {
return resp, errors.New("type assertion failed for unsettledInterest, check for api updates")
}
resp = append(resp, WalletDataV2{
WalletType: wType,
Currency: curr,
Balance: bal,
UnsettledInterest: unsettledInterest,
})
}
return resp, nil
}
// GetMarginPairs gets pairs that allow margin trading
func (b *Bitfinex) GetMarginPairs() ([]string, error) {
var resp [][]string
path := bitfinexAPIVersion2 + bitfinexMarginPairs
err := b.SendHTTPRequest(exchange.RestSpot, path, &resp, status)
if err != nil {
return nil, err
}
if len(resp) != 1 {
return nil, errors.New("invalid response")
}
return resp[0], nil
}
// GetDerivativeData gets data for the queried derivative
func (b *Bitfinex) GetDerivativeData(keys, startTime, endTime string, sort, limit int64) (DerivativeDataResponse, error) {
var result [][19]interface{}
var response DerivativeDataResponse
params := url.Values{}
params.Set("keys", keys)
if startTime != "" {
params.Set("start", startTime)
}
if endTime != "" {
params.Set("end", endTime)
}
if sort != 0 {
params.Set("sort", strconv.FormatInt(sort, 10))
}
if limit != 0 {
params.Set("limit", strconv.FormatInt(limit, 10))
}
path := bitfinexAPIVersion2 + bitfinexDerivativeData +
params.Encode()
err := b.SendHTTPRequest(exchange.RestSpot, path, &result, status)
if err != nil {
return response, err
}
if len(result) < 1 {
return response, errors.New("invalid response, array length too small, check api docs for updates")
}
if len(result[0]) < 19 {
return response, errors.New("invalid response, array length too small, check api docs for updates")
}
var floatData float64
var stringData string
var ok bool
if stringData, ok = result[0][0].(string); !ok {
return response, errors.New("type assertion failed, check for api updates")
}
response.Key = stringData
if floatData, ok = result[0][1].(float64); !ok {
return response, errors.New("type assertion failed, check for api updates")
}
response.MTS = floatData
if floatData, ok = result[0][3].(float64); !ok {
return response, errors.New("type assertion failed, check for api updates")
}
response.DerivPrice = floatData
if floatData, ok = result[0][4].(float64); !ok {
return response, errors.New("type assertion failed, check for api updates")
}
response.SpotPrice = floatData
if floatData, ok = result[0][6].(float64); !ok {
return response, errors.New("type assertion failed, check for api updates")
}
response.InsuranceFundBalance = floatData
if floatData, ok = result[0][8].(float64); !ok {
return response, errors.New("type assertion failed, check for api updates")
}
response.NextFundingEventTS = floatData
if floatData, ok = result[0][9].(float64); !ok {
return response, errors.New("type assertion failed, check for api updates")
}
response.NextFundingAccured = floatData
if floatData, ok = result[0][10].(float64); !ok {
return response, errors.New("type assertion failed, check for api updates")
}
response.NextFundingStep = floatData
if floatData, ok = result[0][12].(float64); !ok {
return response, errors.New("type assertion failed, check for api updates")
}
response.CurrentFunding = floatData
if floatData, ok = result[0][15].(float64); !ok {
return response, errors.New("type assertion failed, check for api updates")
}
response.MarkPrice = floatData
if floatData, ok = result[0][18].(float64); !ok {
return response, errors.New("type assertion failed, check for api updates")
}
response.OpenInterest = floatData
return response, nil
}
// GetTickerBatch returns all supported ticker information
func (b *Bitfinex) GetTickerBatch() (map[string]Ticker, error) {
var response [][]interface{}
path := b.API.Endpoints.URL +
bitfinexAPIVersion2 +
bitfinexTickerBatch +
path := bitfinexAPIVersion2 + bitfinexTickerBatch +
"?symbols=ALL"
err := b.SendHTTPRequest(path, &response, tickerBatch)
err := b.SendHTTPRequest(exchange.RestSpot, path, &response, tickerBatch)
if err != nil {
return nil, err
}
@@ -165,12 +428,9 @@ func (b *Bitfinex) GetTickerBatch() (map[string]Ticker, error) {
func (b *Bitfinex) GetTicker(symbol string) (Ticker, error) {
var response []interface{}
path := b.API.Endpoints.URL +
bitfinexAPIVersion2 +
bitfinexTicker +
symbol
path := bitfinexAPIVersion2 + bitfinexTicker + symbol
err := b.SendHTTPRequest(path, &response, tickerFunction)
err := b.SendHTTPRequest(exchange.RestSpot, path, &response, tickerFunction)
if err != nil {
return Ticker{}, err
}
@@ -232,16 +492,10 @@ func (b *Bitfinex) GetTrades(currencyPair string, limit, timestampStart, timesta
}
v.Set("sort", sortVal)
path := b.API.Endpoints.URL +
bitfinexAPIVersion2 +
bitfinexTrades +
currencyPair +
"/hist" +
"?" +
v.Encode()
path := bitfinexAPIVersion2 + bitfinexTrades + currencyPair + "/hist" + "?" + v.Encode()
var resp [][]interface{}
err := b.SendHTTPRequest(path, &resp, tradeRateLimit)
err := b.SendHTTPRequest(exchange.RestSpot, path, &resp, tradeRateLimit)
if err != nil {
return nil, err
}
@@ -290,17 +544,10 @@ func (b *Bitfinex) GetOrderbook(symbol, precision string, limit int64) (Orderboo
if limit > 0 {
u.Set("len", strconv.FormatInt(limit, 10))
}
path := b.API.Endpoints.URL +
bitfinexAPIVersion2 +
bitfinexOrderbook +
symbol +
"/" +
precision +
"?" +
u.Encode()
path := bitfinexAPIVersion2 + bitfinexOrderbook + symbol + "/" + precision + "?" + u.Encode()
var response [][]interface{}
err := b.SendHTTPRequest(path, &response, orderbookFunction)
err := b.SendHTTPRequest(exchange.RestSpot, path, &response, orderbookFunction)
if err != nil {
return Orderbook{}, err
}
@@ -371,8 +618,8 @@ func (b *Bitfinex) GetOrderbook(symbol, precision string, limit int64) (Orderboo
// GetStats returns various statistics about the requested pair
func (b *Bitfinex) GetStats(symbol string) ([]Stat, error) {
var response []Stat
path := b.API.Endpoints.URL + bitfinexAPIVersion + bitfinexStats + symbol
return response, b.SendHTTPRequest(path, &response, statsV1)
path := bitfinexAPIVersion + bitfinexStats + symbol
return response, b.SendHTTPRequest(exchange.RestSpot, path, &response, statsV1)
}
// GetFundingBook the entire margin funding book for both bids and asks sides
@@ -382,9 +629,9 @@ func (b *Bitfinex) GetStats(symbol string) ([]Stat, error) {
// conversion to full V2 API update is done.
func (b *Bitfinex) GetFundingBook(symbol string) (FundingBook, error) {
response := FundingBook{}
path := b.API.Endpoints.URL + bitfinexAPIVersion + bitfinexLendbook + symbol
path := bitfinexAPIVersion + bitfinexLendbook + symbol
if err := b.SendHTTPRequest(path, &response, fundingbook); err != nil {
if err := b.SendHTTPRequest(exchange.RestSpot, path, &response, fundingbook); err != nil {
return response, err
}
@@ -397,12 +644,11 @@ func (b *Bitfinex) GetFundingBook(symbol string) (FundingBook, error) {
// Symbol - example "USD"
func (b *Bitfinex) GetLends(symbol string, values url.Values) ([]Lends, error) {
var response []Lends
path := common.EncodeURLValues(b.API.Endpoints.URL+
bitfinexAPIVersion+
path := common.EncodeURLValues(bitfinexAPIVersion+
bitfinexLends+
symbol,
values)
return response, b.SendHTTPRequest(path, &response, lends)
return response, b.SendHTTPRequest(exchange.RestSpot, path, &response, lends)
}
// GetCandles returns candle chart data
@@ -415,8 +661,7 @@ func (b *Bitfinex) GetCandles(symbol, timeFrame string, start, end int64, limit
fundingPeriod = ":p30"
}
var path = b.API.Endpoints.URL +
bitfinexAPIVersion2 +
var path = bitfinexAPIVersion2 +
bitfinexCandles +
":" +
timeFrame +
@@ -444,7 +689,7 @@ func (b *Bitfinex) GetCandles(symbol, timeFrame string, start, end int64, limit
}
var response [][]interface{}
err := b.SendHTTPRequest(path, &response, candle)
err := b.SendHTTPRequest(exchange.RestSpot, path, &response, candle)
if err != nil {
return nil, err
}
@@ -467,7 +712,7 @@ func (b *Bitfinex) GetCandles(symbol, timeFrame string, start, end int64, limit
path += "/last"
var response []interface{}
err := b.SendHTTPRequest(path, &response, candle)
err := b.SendHTTPRequest(exchange.RestSpot, path, &response, candle)
if err != nil {
return nil, err
}
@@ -528,7 +773,7 @@ func (b *Bitfinex) GetLeaderboard(key, timeframe, symbol string, sort, limit int
return nil, errors.New("invalid leaderboard key")
}
path := fmt.Sprintf("%s/%s:%s:%s/hist", b.API.Endpoints.URL+bitfinexAPIVersion2+bitfinexLeaderboard,
path := fmt.Sprintf("%s/%s:%s:%s/hist", bitfinexAPIVersion2+bitfinexLeaderboard,
key,
timeframe,
symbol)
@@ -547,7 +792,7 @@ func (b *Bitfinex) GetLeaderboard(key, timeframe, symbol string, sort, limit int
}
path = common.EncodeURLValues(path, vals)
var resp []interface{}
if err := b.SendHTTPRequest(path, &resp, leaderBoardReqRate); err != nil {
if err := b.SendHTTPRequest(exchange.RestSpot, path, &resp, leaderBoardReqRate); err != nil {
return nil, err
}
@@ -587,7 +832,7 @@ func (b *Bitfinex) GetForeignExchangeRate() error {
// GetAccountFees returns information about your account trading fees
func (b *Bitfinex) GetAccountFees() ([]AccountInfo, error) {
var responses []AccountInfo
return responses, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return responses, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexAccountInfo,
nil,
&responses,
@@ -597,7 +842,7 @@ func (b *Bitfinex) GetAccountFees() ([]AccountInfo, error) {
// GetWithdrawalFees - Gets all fee rates for withdrawals
func (b *Bitfinex) GetWithdrawalFees() (AccountFees, error) {
response := AccountFees{}
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexAccountFees,
nil,
&response,
@@ -609,7 +854,7 @@ func (b *Bitfinex) GetWithdrawalFees() (AccountFees, error) {
func (b *Bitfinex) GetAccountSummary() (AccountSummary, error) {
response := AccountSummary{}
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexAccountSummary,
nil,
&response,
@@ -635,7 +880,7 @@ func (b *Bitfinex) NewDeposit(method, walletName string, renew int) (DepositResp
req["wallet_name"] = walletName
req["renew"] = renew
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexDeposit,
req,
&response,
@@ -646,7 +891,7 @@ func (b *Bitfinex) NewDeposit(method, walletName string, renew int) (DepositResp
// this request.
func (b *Bitfinex) GetKeyPermissions() (KeyPermissions, error) {
response := KeyPermissions{}
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexKeyPermissions,
nil,
&response,
@@ -656,7 +901,7 @@ func (b *Bitfinex) GetKeyPermissions() (KeyPermissions, error) {
// GetMarginInfo shows your trading wallet information for margin trading
func (b *Bitfinex) GetMarginInfo() ([]MarginInfo, error) {
var response []MarginInfo
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexMarginInfo,
nil,
&response,
@@ -666,7 +911,7 @@ func (b *Bitfinex) GetMarginInfo() ([]MarginInfo, error) {
// GetAccountBalance returns full wallet balance information
func (b *Bitfinex) GetAccountBalance() ([]Balance, error) {
var response []Balance
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexBalances,
nil,
&response,
@@ -686,7 +931,7 @@ func (b *Bitfinex) WalletTransfer(amount float64, currency, walletFrom, walletTo
req["walletfrom"] = walletFrom
req["walletto"] = walletTo
err := b.SendAuthenticatedHTTPRequest(http.MethodPost,
err := b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexTransfer,
req,
&response,
@@ -714,7 +959,7 @@ func (b *Bitfinex) WithdrawCryptocurrency(wallet, address, paymentID string, amo
req["payment_id"] = paymentID
}
err := b.SendAuthenticatedHTTPRequest(http.MethodPost,
err := b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexWithdrawal,
req,
&response,
@@ -759,7 +1004,7 @@ func (b *Bitfinex) WithdrawFIAT(withdrawalType, walletType string, withdrawReque
req["intermediary_bank_swift"] = withdrawRequest.Fiat.IntermediarySwiftCode
}
err := b.SendAuthenticatedHTTPRequest(http.MethodPost,
err := b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexWithdrawal,
req,
&response,
@@ -794,7 +1039,7 @@ func (b *Bitfinex) NewOrder(currencyPair, orderType string, amount, price float6
req["side"] = order.Buy.Lower()
}
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexOrderNew,
req,
&response,
@@ -807,7 +1052,7 @@ func (b *Bitfinex) NewOrderMulti(orders []PlaceOrder) (OrderMultiResponse, error
req := make(map[string]interface{})
req["orders"] = orders
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexOrderNewMulti,
req,
&response,
@@ -820,7 +1065,7 @@ func (b *Bitfinex) CancelExistingOrder(orderID int64) (Order, error) {
req := make(map[string]interface{})
req["order_id"] = orderID
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexOrderCancel,
req,
&response,
@@ -833,7 +1078,7 @@ func (b *Bitfinex) CancelMultipleOrders(orderIDs []int64) (string, error) {
req := make(map[string]interface{})
req["order_ids"] = orderIDs
return response.Result, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response.Result, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexOrderCancelMulti,
req,
nil,
@@ -844,7 +1089,7 @@ func (b *Bitfinex) CancelMultipleOrders(orderIDs []int64) (string, error) {
func (b *Bitfinex) CancelAllExistingOrders() (string, error) {
response := GenericResponse{}
return response.Result, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response.Result, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexOrderCancelAll,
nil,
nil,
@@ -869,7 +1114,7 @@ func (b *Bitfinex) ReplaceOrder(orderID int64, symbol string, amount, price floa
req["side"] = order.Sell.Lower()
}
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexOrderCancelReplace,
req,
&response,
@@ -882,7 +1127,7 @@ func (b *Bitfinex) GetOrderStatus(orderID int64) (Order, error) {
req := make(map[string]interface{})
req["order_id"] = orderID
return orderStatus, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return orderStatus, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexOrderStatus,
req,
&orderStatus,
@@ -895,7 +1140,7 @@ func (b *Bitfinex) GetInactiveOrders() ([]Order, error) {
req := make(map[string]interface{})
req["limit"] = "100"
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexInactiveOrders,
req,
&response,
@@ -905,7 +1150,7 @@ func (b *Bitfinex) GetInactiveOrders() ([]Order, error) {
// GetOpenOrders returns all active orders and statuses
func (b *Bitfinex) GetOpenOrders() ([]Order, error) {
var response []Order
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexOrders,
nil,
&response,
@@ -916,7 +1161,7 @@ func (b *Bitfinex) GetOpenOrders() ([]Order, error) {
func (b *Bitfinex) GetActivePositions() ([]Position, error) {
var response []Position
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexPositions,
nil,
&response,
@@ -929,7 +1174,7 @@ func (b *Bitfinex) ClaimPosition(positionID int) (Position, error) {
req := make(map[string]interface{})
req["position_id"] = positionID
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexClaimPosition,
nil,
nil,
@@ -955,7 +1200,7 @@ func (b *Bitfinex) GetBalanceHistory(symbol string, timeSince, timeUntil time.Ti
req["wallet"] = wallet
}
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexHistory,
req,
&response,
@@ -981,7 +1226,7 @@ func (b *Bitfinex) GetMovementHistory(symbol, method string, timeSince, timeUnti
req["limit"] = limit
}
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexHistoryMovements,
req,
&response,
@@ -1005,7 +1250,7 @@ func (b *Bitfinex) GetTradeHistory(currencyPair string, timestamp, until time.Ti
req["reverse"] = reverse
}
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexTradeHistory,
req,
&response,
@@ -1022,7 +1267,7 @@ func (b *Bitfinex) NewOffer(symbol string, amount, rate float64, period int64, d
req["period"] = period
req["direction"] = direction
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexOfferNew,
req,
&response,
@@ -1035,7 +1280,7 @@ func (b *Bitfinex) CancelOffer(offerID int64) (Offer, error) {
req := make(map[string]interface{})
req["offer_id"] = offerID
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexOfferCancel,
req,
&response,
@@ -1049,7 +1294,7 @@ func (b *Bitfinex) GetOfferStatus(offerID int64) (Offer, error) {
req := make(map[string]interface{})
req["offer_id"] = offerID
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexOrderStatus,
req,
&response,
@@ -1060,7 +1305,7 @@ func (b *Bitfinex) GetOfferStatus(offerID int64) (Offer, error) {
func (b *Bitfinex) GetActiveCredits() ([]Offer, error) {
var response []Offer
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexActiveCredits,
nil,
&response,
@@ -1071,7 +1316,7 @@ func (b *Bitfinex) GetActiveCredits() ([]Offer, error) {
func (b *Bitfinex) GetActiveOffers() ([]Offer, error) {
var response []Offer
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexOffers,
nil,
&response,
@@ -1082,7 +1327,7 @@ func (b *Bitfinex) GetActiveOffers() ([]Offer, error) {
func (b *Bitfinex) GetActiveMarginFunding() ([]MarginFunds, error) {
var response []MarginFunds
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexMarginActiveFunds,
nil,
&response,
@@ -1094,7 +1339,7 @@ func (b *Bitfinex) GetActiveMarginFunding() ([]MarginFunds, error) {
func (b *Bitfinex) GetUnusedMarginFunds() ([]MarginFunds, error) {
var response []MarginFunds
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexMarginUnusedFunds,
nil,
&response,
@@ -1106,7 +1351,7 @@ func (b *Bitfinex) GetUnusedMarginFunds() ([]MarginFunds, error) {
func (b *Bitfinex) GetMarginTotalTakenFunds() ([]MarginTotalTakenFunds, error) {
var response []MarginTotalTakenFunds
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexMarginTotalFunds,
nil,
&response,
@@ -1119,7 +1364,7 @@ func (b *Bitfinex) CloseMarginFunding(swapID int64) (Offer, error) {
req := make(map[string]interface{})
req["swap_id"] = swapID
return response, b.SendAuthenticatedHTTPRequest(http.MethodPost,
return response, b.SendAuthenticatedHTTPRequest(exchange.RestSpot, http.MethodPost,
bitfinexMarginClose,
req,
&response,
@@ -1127,10 +1372,14 @@ func (b *Bitfinex) CloseMarginFunding(swapID int64) (Offer, error) {
}
// SendHTTPRequest sends an unauthenticated request
func (b *Bitfinex) SendHTTPRequest(path string, result interface{}, e request.EndpointLimit) error {
func (b *Bitfinex) SendHTTPRequest(ep exchange.URL, path string, result interface{}, e request.EndpointLimit) error {
endpoint, err := b.API.Endpoints.GetURL(ep)
if err != nil {
return err
}
return b.SendPayload(context.Background(), &request.Item{
Method: http.MethodGet,
Path: path,
Path: endpoint + path,
Result: result,
Verbose: b.Verbose,
HTTPDebugging: b.HTTPDebugging,
@@ -1140,12 +1389,17 @@ func (b *Bitfinex) SendHTTPRequest(path string, result interface{}, e request.En
// SendAuthenticatedHTTPRequest sends an autheticated http request and json
// unmarshals result to a supplied variable
func (b *Bitfinex) SendAuthenticatedHTTPRequest(method, path string, params map[string]interface{}, result interface{}, endpoint request.EndpointLimit) error {
func (b *Bitfinex) SendAuthenticatedHTTPRequest(ep exchange.URL, method, path string, params map[string]interface{}, result interface{}, endpoint request.EndpointLimit) error {
if !b.AllowAuthenticatedRequest() {
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet,
b.Name)
}
ePoint, err := b.API.Endpoints.GetURL(ep)
if err != nil {
return err
}
n := b.Requester.GetNonce(true)
req := make(map[string]interface{})
@@ -1175,7 +1429,7 @@ func (b *Bitfinex) SendAuthenticatedHTTPRequest(method, path string, params map[
return b.SendPayload(context.Background(), &request.Item{
Method: method,
Path: b.API.Endpoints.URL + bitfinexAPIVersion + path,
Path: ePoint + bitfinexAPIVersion + path,
Headers: headers,
Result: result,
AuthRequest: true,
@@ -1186,6 +1440,58 @@ func (b *Bitfinex) SendAuthenticatedHTTPRequest(method, path string, params map[
Endpoint: endpoint})
}
// SendAuthenticatedHTTPRequestV2 sends an autheticated http request and json
// unmarshals result to a supplied variable
func (b *Bitfinex) SendAuthenticatedHTTPRequestV2(ep exchange.URL, method, path string, params map[string]interface{}, result interface{}, endpoint request.EndpointLimit) error {
if !b.AllowAuthenticatedRequest() {
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet,
b.Name)
}
ePoint, err := b.API.Endpoints.GetURL(ep)
if err != nil {
return err
}
var body io.Reader
var payload []byte
if len(params) != 0 {
payload, err = json.Marshal(params)
if err != nil {
return err
}
body = bytes.NewBuffer(payload)
}
// This is done in a weird way because bitfinex doesn't accept unixnano
n := strconv.FormatInt(int64(b.Requester.GetNonce(false))*1e9, 10)
headers := make(map[string]string)
headers["Content-Type"] = "application/json"
headers["Accept"] = "application/json"
headers["bfx-apikey"] = b.API.Credentials.Key
headers["bfx-nonce"] = n
strPath := "/api" + bitfinexAPIVersion2 + path + string(payload)
signStr := strPath + n
hmac := crypto.GetHMAC(
crypto.HashSHA512_384,
[]byte(signStr),
[]byte(b.API.Credentials.Secret),
)
headers["bfx-signature"] = crypto.HexEncodeToString(hmac)
return b.SendPayload(context.Background(), &request.Item{
Method: method,
Path: ePoint + bitfinexAPIVersion2 + path,
Headers: headers,
Body: body,
Result: result,
AuthRequest: true,
NonceEnabled: true,
Verbose: b.Verbose,
HTTPDebugging: b.HTTPDebugging,
HTTPRecording: b.HTTPRecording,
Endpoint: endpoint,
})
}
// GetFee returns an estimate of fee based on type of transaction
func (b *Bitfinex) GetFee(feeBuilder *exchange.FeeBuilder) (float64, error) {
var fee float64
@@ -1343,9 +1649,8 @@ func (b *Bitfinex) ConvertSymbolToDepositMethod(c currency.Code) (string, error)
func (b *Bitfinex) PopulateAcceptableMethods() error {
if len(AcceptableMethods) == 0 {
var response [][][2]string
err := b.SendHTTPRequest(b.API.Endpoints.URL+
bitfinexAPIVersion2+
bitfinexDepositMethod,
err := b.SendHTTPRequest(exchange.RestSpot,
bitfinexAPIVersion2+bitfinexDepositMethod,
&response,
configs)
if err != nil {

View File

@@ -61,6 +61,64 @@ func TestMain(m *testing.M) {
os.Exit(m.Run())
}
func TestGetV2MarginFunding(t *testing.T) {
if !areTestAPIKeysSet() {
t.SkipNow()
}
_, err := b.GetV2MarginFunding("fUSD", "2", 2)
if err != nil {
t.Error(err)
}
}
func TestGetAccountInfoV2(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.SkipNow()
}
_, err := b.GetAccountInfoV2()
if err != nil {
t.Error(err)
}
}
func TestGetV2FundingInfo(t *testing.T) {
if !areTestAPIKeysSet() {
t.SkipNow()
}
_, err := b.GetV2FundingInfo("fUSD")
if err != nil {
t.Error(err)
}
}
func TestGetV2Balances(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.SkipNow()
}
_, err := b.GetV2Balances()
if err != nil {
t.Error(err)
}
}
func TestGetDerivativeData(t *testing.T) {
t.Parallel()
_, err := b.GetDerivativeData("tBTCF0:USTF0", "", "", 0, 0)
if err != nil {
t.Error(err)
}
}
func TestGetMarginPairs(t *testing.T) {
t.Parallel()
_, err := b.GetMarginPairs()
if err != nil {
t.Error(err)
}
}
func TestAppendOptionalDelimiter(t *testing.T) {
t.Parallel()
curr1, err := currency.NewPairFromString("BTCUSD")
@@ -222,7 +280,7 @@ func TestGetAccountFees(t *testing.T) {
}
t.Parallel()
_, err := b.UpdateAccountInfo()
_, err := b.UpdateAccountInfo(asset.Spot)
if err != nil {
t.Error("GetAccountInfo error", err)
}
@@ -233,7 +291,6 @@ func TestGetWithdrawalFee(t *testing.T) {
t.SkipNow()
}
t.Parallel()
_, err := b.GetWithdrawalFees()
if err != nil {
t.Error("GetAccountInfo error", err)
@@ -315,7 +372,7 @@ func TestGetAccountInfo(t *testing.T) {
}
t.Parallel()
_, err := b.FetchAccountInfo()
_, err := b.FetchAccountInfo(asset.Spot)
if err != nil {
t.Error(err)
}
@@ -487,7 +544,6 @@ func TestGetBalanceHistory(t *testing.T) {
t.SkipNow()
}
t.Parallel()
_, err := b.GetBalanceHistory("USD", time.Time{}, time.Time{}, 1, "deposit")
if err == nil {
t.Error("GetBalanceHistory() Expected error")
@@ -511,7 +567,6 @@ func TestGetTradeHistory(t *testing.T) {
t.SkipNow()
}
t.Parallel()
_, err := b.GetTradeHistory("BTCUSD", time.Time{}, time.Time{}, 1, 0)
if err == nil {
t.Error("GetTradeHistory() Expected error")
@@ -734,7 +789,8 @@ func TestFormatWithdrawPermissions(t *testing.T) {
func TestGetActiveOrders(t *testing.T) {
t.Parallel()
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
Type: order.AnyType,
AssetType: asset.Spot,
}
_, err := b.GetActiveOrders(&getOrdersRequest)
@@ -748,7 +804,8 @@ func TestGetActiveOrders(t *testing.T) {
func TestGetOrderHistory(t *testing.T) {
t.Parallel()
var getOrdersRequest = order.GetOrdersRequest{
Type: order.AnyType,
Type: order.AnyType,
AssetType: asset.Spot,
}
_, err := b.GetOrderHistory(&getOrdersRequest)
@@ -1470,7 +1527,7 @@ func TestGetHistoricTrades(t *testing.T) {
}
// longer term test
_, err = b.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Hour*24*100), time.Now().Add(-time.Hour*24*99))
_, err = b.GetHistoricTrades(currencyPair, asset.Spot, time.Now().Add(-time.Hour*100), time.Now().Add(-time.Hour*99))
if err != nil {
t.Error(err)
}

View File

@@ -6,6 +6,24 @@ import (
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
)
// AccountV2Data stores account v2 data
type AccountV2Data struct {
ID int64
Email string
Username string
MTSAccountCreate int64
Verified int64
Timezone string
}
// WalletDataV2 stores wallet data for v2
type WalletDataV2 struct {
WalletType string
Currency string
Balance float64
UnsettledInterest float64
}
// AcceptedOrderType defines the accepted market types, exchange strings denote non-contract order types.
var AcceptedOrderType = []string{"market", "limit", "stop", "trailing-stop",
"fill-or-kill", "exchange market", "exchange limit", "exchange stop",
@@ -18,6 +36,42 @@ var AcceptedWalletNames = []string{"trading", "exchange", "deposit", "margin",
// AcceptableMethods defines a map of currency codes to methods
var AcceptableMethods = make(map[string]string)
// MarginV2FundingData stores margin funding data
type MarginV2FundingData struct {
Symbol string
RateAverage float64
AmountAverage float64
}
// MarginFundingDataV2 stores margin funding data
type MarginFundingDataV2 struct {
Sym string
Symbol string
Data struct {
YieldLoan float64
YieldLend float64
DurationLoan float64
DurationLend float64
}
}
// MarginFundingData stores data for margin funding
type MarginFundingData struct {
ID int64
Symbol string
MTSCreated int64
MTSUpdated int64
Amount float64
AmountOrig float64
OrderType string
OfferStatus string
Active string
Rate float64
Period float64
Notify bool
Renew bool
}
// Ticker holds ticker information
type Ticker struct {
FlashReturnRate float64
@@ -36,6 +90,21 @@ type Ticker struct {
FFRAmountAvailable float64
}
// DerivativeDataResponse stores data for queried derivative
type DerivativeDataResponse struct {
Key string
MTS float64
DerivPrice float64
SpotPrice float64
MarkPrice float64
InsuranceFundBalance float64
NextFundingEventTS float64
NextFundingAccured float64
NextFundingStep float64
CurrentFunding float64
OpenInterest float64
}
// Stat holds individual statistics from exchange
type Stat struct {
Period int64 `json:"period"`

View File

@@ -163,10 +163,14 @@ func (b *Bitfinex) SetDefaults() {
b.Requester = request.New(b.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(SetRateLimit()))
b.API.Endpoints.URLDefault = bitfinexAPIURLBase
b.API.Endpoints.URL = b.API.Endpoints.URLDefault
b.API.Endpoints.WebsocketURL = publicBitfinexWebsocketEndpoint
b.API.Endpoints = b.NewEndpoints()
err = b.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{
exchange.RestSpot: bitfinexAPIURLBase,
exchange.WebsocketSpot: publicBitfinexWebsocketEndpoint,
})
if err != nil {
log.Errorln(log.ExchangeSys, err)
}
b.Websocket = stream.New()
b.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit
b.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout
@@ -184,6 +188,10 @@ func (b *Bitfinex) Setup(exch *config.ExchangeConfig) error {
if err != nil {
return err
}
wsEndpoint, err := b.API.Endpoints.GetURL(exchange.WebsocketSpot)
if err != nil {
return err
}
err = b.Websocket.Setup(&stream.WebsocketSetup{
Enabled: exch.Features.Enabled.Websocket,
@@ -192,7 +200,7 @@ func (b *Bitfinex) Setup(exch *config.ExchangeConfig) error {
WebsocketTimeout: exch.WebsocketTrafficTimeout,
DefaultURL: publicBitfinexWebsocketEndpoint,
ExchangeName: exch.Name,
RunningURL: exch.API.Endpoints.WebsocketURL,
RunningURL: wsEndpoint,
Connector: b.WsConnect,
Subscriber: b.Subscribe,
UnSubscriber: b.Unsubscribe,
@@ -398,17 +406,19 @@ func (b *Bitfinex) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orde
if err != nil {
return o, err
}
if assetType != asset.Spot && assetType != asset.Margin && assetType != asset.MarginFunding {
return o, fmt.Errorf("assetType not supported: %v", assetType)
}
b.appendOptionalDelimiter(&fPair)
var prefix = "t"
if assetType == asset.MarginFunding {
prefix = "f"
}
orderbookNew, err := b.GetOrderbook(prefix+fPair.String(), "R0", 100)
var orderbookNew Orderbook
orderbookNew, err = b.GetOrderbook(prefix+fPair.String(), "R0", 100)
if err != nil {
return o, err
return nil, err
}
if assetType == asset.MarginFunding {
o.IsFundingRate = true
for x := range orderbookNew.Asks {
@@ -443,18 +453,16 @@ func (b *Bitfinex) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orde
})
}
}
err = o.Process()
if err != nil {
return nil, err
}
return orderbook.Get(b.Name, fPair, assetType)
}
// UpdateAccountInfo retrieves balances for all enabled currencies on the
// Bitfinex exchange
func (b *Bitfinex) UpdateAccountInfo() (account.Holdings, error) {
func (b *Bitfinex) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) {
var response account.Holdings
response.Exchange = b.Name
@@ -494,10 +502,10 @@ func (b *Bitfinex) UpdateAccountInfo() (account.Holdings, error) {
}
// FetchAccountInfo retrieves balances for all enabled currencies
func (b *Bitfinex) FetchAccountInfo() (account.Holdings, error) {
acc, err := account.GetHoldings(b.Name)
func (b *Bitfinex) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) {
acc, err := account.GetHoldings(b.Name, assetType)
if err != nil {
return b.UpdateAccountInfo()
return b.UpdateAccountInfo(assetType)
}
return acc, nil
@@ -945,8 +953,8 @@ func (b *Bitfinex) appendOptionalDelimiter(p *currency.Pair) {
// ValidateCredentials validates current credentials used for wrapper
// functionality
func (b *Bitfinex) ValidateCredentials() error {
_, err := b.UpdateAccountInfo()
func (b *Bitfinex) ValidateCredentials(assetType asset.Item) error {
_, err := b.UpdateAccountInfo(assetType)
return b.CheckTransientError(err)
}