mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-06-02 23:16:51 +00:00
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:
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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"`
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user