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

@@ -36,7 +36,7 @@ const (
getFutures = "/futures"
getFuture = "/futures/"
getFutureStats = "/futures/%s/stats"
getFundingRates = "/funding_rates"
getFundingRates = "/funding_rates?"
getIndexWeights = "/indexes/%s/weights"
getAllWalletBalances = "/wallet/all_balances"
@@ -90,6 +90,17 @@ const (
getOTCQuoteStatus = "/otc/quotes/"
acceptOTCQuote = "/otc/quotes/%s/accept"
// Margin Endpoints
marginBorrowRates = "/spot_margin/borrow_rates"
maringLendingRates = "/spot_margin/lending_rates"
dailyBorrowedAmounts = "/spot_margin/borrow_summary"
marginMarketInfo = "/spot_margin/market_info?market=%s"
marginBorrowHistory = "/spot_margin/borrow_history"
marginLendHistory = "/spot_margin/lending_history"
marginLendingOffers = "/spot_margin/offers"
marginLendingInfo = "/spot_margin/lending_info"
submitLendingOrder = "/spot_margin/offers"
// Other Consts
trailingStopOrderType = "trailingStop"
takeProfitOrderType = "takeProfit"
@@ -106,7 +117,7 @@ func (f *FTX) GetMarkets() ([]MarketData, error) {
resp := struct {
Data []MarketData `json:"result"`
}{}
return resp.Data, f.SendHTTPRequest(ftxAPIURL+getMarkets, &resp)
return resp.Data, f.SendHTTPRequest(exchange.RestSpot, getMarkets, &resp)
}
// GetMarket gets market data for a provided asset type
@@ -114,7 +125,7 @@ func (f *FTX) GetMarket(marketName string) (MarketData, error) {
resp := struct {
Data MarketData `json:"result"`
}{}
return resp.Data, f.SendHTTPRequest(ftxAPIURL+getMarket+marketName,
return resp.Data, f.SendHTTPRequest(exchange.RestSpot, getMarket+marketName,
&resp)
}
@@ -131,7 +142,7 @@ func (f *FTX) GetOrderbook(marketName string, depth int64) (OrderbookData, error
}
var resp OrderbookData
err := f.SendHTTPRequest(fmt.Sprintf(ftxAPIURL+getOrderbook, marketName, strDepth), &result)
err := f.SendHTTPRequest(exchange.RestSpot, fmt.Sprintf(getOrderbook, marketName, strDepth), &result)
if err != nil {
return resp, err
}
@@ -166,7 +177,7 @@ func (f *FTX) GetTrades(marketName string, startTime, endTime, limit int64) ([]T
params.Set("start_time", strconv.FormatInt(startTime, 10))
params.Set("end_time", strconv.FormatInt(endTime, 10))
}
return resp.Data, f.SendHTTPRequest(fmt.Sprintf(ftxAPIURL+getTrades, marketName)+params.Encode(),
return resp.Data, f.SendHTTPRequest(exchange.RestSpot, fmt.Sprintf(getTrades, marketName)+params.Encode(),
&resp)
}
@@ -187,7 +198,7 @@ func (f *FTX) GetHistoricalData(marketName, timeInterval, limit string, startTim
params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10))
params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10))
}
return resp.Data, f.SendHTTPRequest(fmt.Sprintf(ftxAPIURL+getHistoricalData, marketName)+params.Encode(), &resp)
return resp.Data, f.SendHTTPRequest(exchange.RestSpot, fmt.Sprintf(getHistoricalData, marketName)+params.Encode(), &resp)
}
// GetFutures gets data on futures
@@ -195,7 +206,7 @@ func (f *FTX) GetFutures() ([]FuturesData, error) {
resp := struct {
Data []FuturesData `json:"result"`
}{}
return resp.Data, f.SendHTTPRequest(ftxAPIURL+getFutures, &resp)
return resp.Data, f.SendHTTPRequest(exchange.RestSpot, getFutures, &resp)
}
// GetFuture gets data on a given future
@@ -203,7 +214,7 @@ func (f *FTX) GetFuture(futureName string) (FuturesData, error) {
resp := struct {
Data FuturesData `json:"result"`
}{}
return resp.Data, f.SendHTTPRequest(ftxAPIURL+getFuture+futureName, &resp)
return resp.Data, f.SendHTTPRequest(exchange.RestSpot, getFuture+futureName, &resp)
}
// GetFutureStats gets data on a given future's stats
@@ -211,28 +222,43 @@ func (f *FTX) GetFutureStats(futureName string) (FutureStatsData, error) {
resp := struct {
Data FutureStatsData `json:"result"`
}{}
return resp.Data, f.SendHTTPRequest(fmt.Sprintf(ftxAPIURL+getFutureStats, futureName), &resp)
return resp.Data, f.SendHTTPRequest(exchange.RestSpot, fmt.Sprintf(getFutureStats, futureName), &resp)
}
// GetFundingRates gets data on funding rates
func (f *FTX) GetFundingRates() ([]FundingRatesData, error) {
func (f *FTX) GetFundingRates(startTime, endTime time.Time, future string) ([]FundingRatesData, error) {
resp := struct {
Data []FundingRatesData `json:"result"`
}{}
return resp.Data, f.SendHTTPRequest(ftxAPIURL+getFundingRates, &resp)
params := url.Values{}
if !startTime.IsZero() && !endTime.IsZero() {
if startTime.After(endTime) {
return resp.Data, errors.New("startTime cannot be after endTime")
}
params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10))
params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10))
}
if future != "" {
params.Set("future", future)
}
return resp.Data, f.SendHTTPRequest(exchange.RestSpot, getFundingRates+params.Encode(), &resp)
}
// GetIndexWeights gets index weights
func (f *FTX) GetIndexWeights(index string) (IndexWeights, error) {
var resp IndexWeights
return resp, f.SendHTTPRequest(ftxAPIURL+fmt.Sprintf(getIndexWeights, index), &resp)
return resp, f.SendHTTPRequest(exchange.RestSpot, fmt.Sprintf(getIndexWeights, index), &resp)
}
// SendHTTPRequest sends an unauthenticated HTTP request
func (f *FTX) SendHTTPRequest(path string, result interface{}) error {
func (f *FTX) SendHTTPRequest(ep exchange.URL, path string, result interface{}) error {
endpoint, err := f.API.Endpoints.GetURL(ep)
if err != nil {
return err
}
return f.SendPayload(context.Background(), &request.Item{
Method: http.MethodGet,
Path: path,
Path: endpoint + path,
Result: result,
Verbose: f.Verbose,
HTTPDebugging: f.HTTPDebugging,
@@ -240,12 +266,86 @@ func (f *FTX) SendHTTPRequest(path string, result interface{}) error {
})
}
// GetMarginBorrowRates gets borrowing rates for margin trading
func (f *FTX) GetMarginBorrowRates() ([]MarginFundingData, error) {
r := struct {
Data []MarginFundingData `json:"result"`
}{}
return r.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, marginBorrowRates, nil, &r)
}
// GetMarginLendingRates gets lending rates for margin trading
func (f *FTX) GetMarginLendingRates() ([]MarginFundingData, error) {
r := struct {
Data []MarginFundingData `json:"result"`
}{}
return r.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, maringLendingRates, nil, &r)
}
// MarginDailyBorrowedAmounts gets daily borrowed amounts for margin
func (f *FTX) MarginDailyBorrowedAmounts() ([]MarginMarketInfo, error) {
r := struct {
Data []MarginMarketInfo `json:"result"`
}{}
return r.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, dailyBorrowedAmounts, nil, &r)
}
// GetMarginMarketInfo gets margin market data
func (f *FTX) GetMarginMarketInfo(market string) ([]MarginMarketInfo, error) {
r := struct {
Data []MarginMarketInfo `json:"result"`
}{}
return r.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, fmt.Sprintf(marginMarketInfo, market), nil, &r)
}
// GetMarginBorrowHistory gets margin borrowing history
func (f *FTX) GetMarginBorrowHistory() ([]MarginTransactionHistoryData, error) {
r := struct {
Data []MarginTransactionHistoryData `json:"result"`
}{}
return r.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, marginBorrowHistory, nil, &r)
}
// GetMarginLendingHistory gets margin lending history
func (f *FTX) GetMarginLendingHistory() ([]MarginTransactionHistoryData, error) {
r := struct {
Data []MarginTransactionHistoryData `json:"result"`
}{}
return r.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, marginLendHistory, nil, &r)
}
// GetMarginLendingOffers gets margin lending offers
func (f *FTX) GetMarginLendingOffers() ([]LendingOffersData, error) {
r := struct {
Data []LendingOffersData `json:"result"`
}{}
return r.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, marginLendingOffers, nil, &r)
}
// GetLendingInfo gets margin lending info
func (f *FTX) GetLendingInfo() ([]LendingInfoData, error) {
r := struct {
Data []LendingInfoData `json:"result"`
}{}
return r.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, marginLendingInfo, nil, &r)
}
// SubmitLendingOffer submits an offer for margin lending
func (f *FTX) SubmitLendingOffer(coin string, size, rate float64) (interface{}, error) {
var resp interface{}
req := make(map[string]interface{})
req["coin"] = coin
req["size"] = size
req["rate"] = rate
return resp, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, marginLendingInfo, req, &resp)
}
// GetAccountInfo gets account info
func (f *FTX) GetAccountInfo() (AccountInfoData, error) {
resp := struct {
Data AccountInfoData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getAccountInfo, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getAccountInfo, nil, &resp)
}
// GetPositions gets the users positions
@@ -253,14 +353,14 @@ func (f *FTX) GetPositions() ([]PositionData, error) {
resp := struct {
Data []PositionData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getPositions, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getPositions, nil, &resp)
}
// ChangeAccountLeverage changes default leverage used by account
func (f *FTX) ChangeAccountLeverage(leverage float64) error {
req := make(map[string]interface{})
req["leverage"] = leverage
return f.SendAuthHTTPRequest(http.MethodPost, setLeverage, req, nil)
return f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, setLeverage, req, nil)
}
// GetCoins gets coins' data in the account wallet
@@ -268,7 +368,7 @@ func (f *FTX) GetCoins() ([]WalletCoinsData, error) {
resp := struct {
Data []WalletCoinsData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getCoins, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getCoins, nil, &resp)
}
// GetBalances gets balances of the account
@@ -276,7 +376,7 @@ func (f *FTX) GetBalances() ([]BalancesData, error) {
resp := struct {
Data []BalancesData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getBalances, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getBalances, nil, &resp)
}
// GetAllWalletBalances gets all wallets' balances
@@ -284,7 +384,7 @@ func (f *FTX) GetAllWalletBalances() (AllWalletAccountData, error) {
resp := struct {
Data AllWalletAccountData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getAllWalletBalances, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getAllWalletBalances, nil, &resp)
}
// FetchDepositAddress gets deposit address for a given coin
@@ -292,7 +392,7 @@ func (f *FTX) FetchDepositAddress(coin string) (DepositData, error) {
resp := struct {
Data DepositData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getDepositAddress+coin, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getDepositAddress+coin, nil, &resp)
}
// FetchDepositHistory gets deposit history
@@ -300,7 +400,7 @@ func (f *FTX) FetchDepositHistory() ([]TransactionData, error) {
resp := struct {
Data []TransactionData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getDepositHistory, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getDepositHistory, nil, &resp)
}
// FetchWithdrawalHistory gets withdrawal history
@@ -308,7 +408,7 @@ func (f *FTX) FetchWithdrawalHistory() ([]TransactionData, error) {
resp := struct {
Data []TransactionData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getWithdrawalHistory, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getWithdrawalHistory, nil, &resp)
}
// Withdraw sends a withdrawal request
@@ -329,7 +429,7 @@ func (f *FTX) Withdraw(coin, address, tag, password, code string, size float64)
resp := struct {
Data TransactionData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodPost, withdrawRequest, req, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, withdrawRequest, req, &resp)
}
// GetOpenOrders gets open orders
@@ -341,7 +441,7 @@ func (f *FTX) GetOpenOrders(marketName string) ([]OrderData, error) {
resp := struct {
Data []OrderData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getOpenOrders+params.Encode(), nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOpenOrders+params.Encode(), nil, &resp)
}
// FetchOrderHistory gets order history
@@ -363,7 +463,7 @@ func (f *FTX) FetchOrderHistory(marketName string, startTime, endTime time.Time,
if limit != "" {
params.Set("limit", limit)
}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getOrderHistory+params.Encode(), nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOrderHistory+params.Encode(), nil, &resp)
}
// GetOpenTriggerOrders gets trigger orders that are currently open
@@ -378,7 +478,7 @@ func (f *FTX) GetOpenTriggerOrders(marketName, orderType string) ([]TriggerOrder
resp := struct {
Data []TriggerOrderData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getOpenTriggerOrders+params.Encode(), nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOpenTriggerOrders+params.Encode(), nil, &resp)
}
// GetTriggerOrderTriggers gets trigger orders that are currently open
@@ -386,7 +486,7 @@ func (f *FTX) GetTriggerOrderTriggers(orderID string) ([]TriggerData, error) {
resp := struct {
Data []TriggerData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, fmt.Sprintf(getTriggerOrderTriggers, orderID), nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, fmt.Sprintf(getTriggerOrderTriggers, orderID), nil, &resp)
}
// GetTriggerOrderHistory gets trigger orders that are currently open
@@ -414,7 +514,7 @@ func (f *FTX) GetTriggerOrderHistory(marketName string, startTime, endTime time.
if limit != "" {
params.Set("limit", limit)
}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getTriggerOrderHistory+params.Encode(), nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getTriggerOrderHistory+params.Encode(), nil, &resp)
}
// Order places an order
@@ -440,7 +540,7 @@ func (f *FTX) Order(marketName, side, orderType, reduceOnly, ioc, postOnly, clie
resp := struct {
Data OrderData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodPost, placeOrder, req, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, placeOrder, req, &resp)
}
// TriggerOrder places an order
@@ -470,7 +570,7 @@ func (f *FTX) TriggerOrder(marketName, side, orderType, reduceOnly, retryUntilFi
resp := struct {
Data TriggerOrderData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodPost, placeTriggerOrder, req, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, placeTriggerOrder, req, &resp)
}
// ModifyPlacedOrder modifies a placed order
@@ -484,7 +584,7 @@ func (f *FTX) ModifyPlacedOrder(orderID, clientID string, price, size float64) (
resp := struct {
Data OrderData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodPost, fmt.Sprintf(modifyOrder, orderID), req, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, fmt.Sprintf(modifyOrder, orderID), req, &resp)
}
// ModifyOrderByClientID modifies a placed order via clientOrderID
@@ -498,7 +598,7 @@ func (f *FTX) ModifyOrderByClientID(clientOrderID, clientID string, price, size
resp := struct {
Data OrderData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodPost, fmt.Sprintf(modifyOrderByClientID, clientOrderID), req, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, fmt.Sprintf(modifyOrderByClientID, clientOrderID), req, &resp)
}
// ModifyTriggerOrder modifies an existing trigger order
@@ -520,7 +620,7 @@ func (f *FTX) ModifyTriggerOrder(orderID, orderType string, size, triggerPrice,
resp := struct {
Data TriggerOrderData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodPost, fmt.Sprintf(modifyTriggerOrder, orderID), req, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, fmt.Sprintf(modifyTriggerOrder, orderID), req, &resp)
}
// GetOrderStatus gets the order status of a given orderID
@@ -528,7 +628,7 @@ func (f *FTX) GetOrderStatus(orderID string) (OrderData, error) {
resp := struct {
Data OrderData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getOrderStatus+orderID, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOrderStatus+orderID, nil, &resp)
}
// GetOrderStatusByClientID gets the order status of a given clientOrderID
@@ -536,7 +636,7 @@ func (f *FTX) GetOrderStatusByClientID(clientOrderID string) (OrderData, error)
resp := struct {
Data OrderData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getOrderStatusByClientID+clientOrderID, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOrderStatusByClientID+clientOrderID, nil, &resp)
}
// DeleteOrder deletes an order
@@ -545,7 +645,7 @@ func (f *FTX) DeleteOrder(orderID string) (string, error) {
Result string `json:"result"`
Success bool `json:"success"`
}{}
if err := f.SendAuthHTTPRequest(http.MethodDelete, deleteOrder+orderID, nil, &resp); err != nil {
if err := f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodDelete, deleteOrder+orderID, nil, &resp); err != nil {
return "", err
}
if !resp.Success {
@@ -561,7 +661,7 @@ func (f *FTX) DeleteOrderByClientID(clientID string) (string, error) {
Success bool `json:"success"`
}{}
if err := f.SendAuthHTTPRequest(http.MethodDelete, deleteOrderByClientID+clientID, nil, &resp); err != nil {
if err := f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodDelete, deleteOrderByClientID+clientID, nil, &resp); err != nil {
return "", err
}
if !resp.Success {
@@ -577,7 +677,7 @@ func (f *FTX) DeleteTriggerOrder(orderID string) (string, error) {
Success bool `json:"success"`
}{}
if err := f.SendAuthHTTPRequest(http.MethodDelete, cancelTriggerOrder+orderID, nil, &resp); err != nil {
if err := f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodDelete, cancelTriggerOrder+orderID, nil, &resp); err != nil {
return "", err
}
if !resp.Success {
@@ -605,7 +705,7 @@ func (f *FTX) GetFills(market, limit string, startTime, endTime time.Time) ([]Fi
params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10))
params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10))
}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getFills+params.Encode(), nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getFills+params.Encode(), nil, &resp)
}
// GetFundingPayments gets funding payments
@@ -624,7 +724,7 @@ func (f *FTX) GetFundingPayments(startTime, endTime time.Time, future string) ([
if future != "" {
params.Set("future", future)
}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getFundingPayments+params.Encode(), nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getFundingPayments+params.Encode(), nil, &resp)
}
// ListLeveragedTokens lists leveraged tokens
@@ -632,7 +732,7 @@ func (f *FTX) ListLeveragedTokens() ([]LeveragedTokensData, error) {
resp := struct {
Data []LeveragedTokensData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getLeveragedTokens, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getLeveragedTokens, nil, &resp)
}
// GetTokenInfo gets token info
@@ -640,7 +740,7 @@ func (f *FTX) GetTokenInfo(tokenName string) ([]LeveragedTokensData, error) {
resp := struct {
Data []LeveragedTokensData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getTokenInfo+tokenName, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getTokenInfo+tokenName, nil, &resp)
}
// ListLTBalances gets leveraged tokens' balances
@@ -648,7 +748,7 @@ func (f *FTX) ListLTBalances() ([]LTBalanceData, error) {
resp := struct {
Data []LTBalanceData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getLTBalances, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getLTBalances, nil, &resp)
}
// ListLTCreations lists the leveraged tokens' creation requests
@@ -656,7 +756,7 @@ func (f *FTX) ListLTCreations() ([]LTCreationData, error) {
resp := struct {
Data []LTCreationData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getLTCreations, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getLTCreations, nil, &resp)
}
// RequestLTCreation sends a request to create a leveraged token
@@ -666,7 +766,7 @@ func (f *FTX) RequestLTCreation(tokenName string, size float64) (RequestTokenCre
resp := struct {
Data RequestTokenCreationData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodPost, fmt.Sprintf(requestLTCreation, tokenName), req, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, fmt.Sprintf(requestLTCreation, tokenName), req, &resp)
}
// ListLTRedemptions lists the leveraged tokens' redemption requests
@@ -674,7 +774,7 @@ func (f *FTX) ListLTRedemptions() ([]LTRedemptionData, error) {
resp := struct {
Data []LTRedemptionData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getLTRedemptions, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getLTRedemptions, nil, &resp)
}
// RequestLTRedemption sends a request to redeem a leveraged token
@@ -684,7 +784,7 @@ func (f *FTX) RequestLTRedemption(tokenName string, size float64) (LTRedemptionR
resp := struct {
Data LTRedemptionRequestData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodPost, fmt.Sprintf(requestLTRedemption, tokenName), req, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, fmt.Sprintf(requestLTRedemption, tokenName), req, &resp)
}
// GetQuoteRequests gets a list of quote requests
@@ -692,7 +792,7 @@ func (f *FTX) GetQuoteRequests() ([]QuoteRequestData, error) {
resp := struct {
Data []QuoteRequestData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getListQuotes, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getListQuotes, nil, &resp)
}
// GetYourQuoteRequests gets a list of your quote requests
@@ -700,7 +800,7 @@ func (f *FTX) GetYourQuoteRequests() ([]PersonalQuotesData, error) {
resp := struct {
Data []PersonalQuotesData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getMyQuotesRequests, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getMyQuotesRequests, nil, &resp)
}
// CreateQuoteRequest sends a request to create a quote
@@ -725,7 +825,7 @@ func (f *FTX) CreateQuoteRequest(underlying, optionType, side string, expiry int
resp := struct {
Data CreateQuoteRequestData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodPost, createQuoteRequest, req, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, createQuoteRequest, req, &resp)
}
// DeleteQuote sends request to cancel a quote
@@ -733,13 +833,13 @@ func (f *FTX) DeleteQuote(requestID string) (CancelQuoteRequestData, error) {
resp := struct {
Data CancelQuoteRequestData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodDelete, deleteQuote+requestID, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodDelete, deleteQuote+requestID, nil, &resp)
}
// GetQuotesForYourQuote gets a list of quotes for your quote
func (f *FTX) GetQuotesForYourQuote(requestID string) (QuoteForQuoteData, error) {
var resp QuoteForQuoteData
return resp, f.SendAuthHTTPRequest(http.MethodGet, fmt.Sprintf(endpointQuote, requestID), nil, &resp)
return resp, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, fmt.Sprintf(endpointQuote, requestID), nil, &resp)
}
// MakeQuote makes a quote for a quote
@@ -749,7 +849,7 @@ func (f *FTX) MakeQuote(requestID, price string) ([]QuoteForQuoteData, error) {
resp := struct {
Data []QuoteForQuoteData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodPost, fmt.Sprintf(endpointQuote, requestID), nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, fmt.Sprintf(endpointQuote, requestID), nil, &resp)
}
// MyQuotes gets a list of my quotes for quotes
@@ -757,7 +857,7 @@ func (f *FTX) MyQuotes() ([]QuoteForQuoteData, error) {
resp := struct {
Data []QuoteForQuoteData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getMyQuotes, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getMyQuotes, nil, &resp)
}
// DeleteMyQuote deletes my quote for quotes
@@ -765,7 +865,7 @@ func (f *FTX) DeleteMyQuote(quoteID string) ([]QuoteForQuoteData, error) {
resp := struct {
Data []QuoteForQuoteData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodDelete, deleteMyQuote+quoteID, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodDelete, deleteMyQuote+quoteID, nil, &resp)
}
// AcceptQuote accepts the quote for quote
@@ -773,7 +873,7 @@ func (f *FTX) AcceptQuote(quoteID string) ([]QuoteForQuoteData, error) {
resp := struct {
Data []QuoteForQuoteData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodPost, fmt.Sprintf(acceptQuote, quoteID), nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, fmt.Sprintf(acceptQuote, quoteID), nil, &resp)
}
// GetAccountOptionsInfo gets account's options' info
@@ -781,7 +881,7 @@ func (f *FTX) GetAccountOptionsInfo() (AccountOptionsInfoData, error) {
resp := struct {
Data AccountOptionsInfoData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getOptionsInfo, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOptionsInfo, nil, &resp)
}
// GetOptionsPositions gets options' positions
@@ -789,7 +889,7 @@ func (f *FTX) GetOptionsPositions() ([]OptionsPositionsData, error) {
resp := struct {
Data []OptionsPositionsData `json:"result"`
}{}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getOptionsPositions, nil, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOptionsPositions, nil, &resp)
}
// GetPublicOptionsTrades gets options' trades from public
@@ -808,7 +908,7 @@ func (f *FTX) GetPublicOptionsTrades(startTime, endTime time.Time, limit string)
if limit != "" {
req["limit"] = limit
}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getPublicOptionsTrades, req, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getPublicOptionsTrades, req, &resp)
}
// GetOptionsFills gets fills data for options
@@ -827,15 +927,18 @@ func (f *FTX) GetOptionsFills(startTime, endTime time.Time, limit string) ([]Opt
if limit != "" {
req["limit"] = limit
}
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getOptionsFills, req, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOptionsFills, req, &resp)
}
// SendAuthHTTPRequest sends an authenticated request
func (f *FTX) SendAuthHTTPRequest(method, path string, data, result interface{}) error {
func (f *FTX) SendAuthHTTPRequest(ep exchange.URL, method, path string, data, result interface{}) error {
endpoint, err := f.API.Endpoints.GetURL(ep)
if err != nil {
return err
}
ts := strconv.FormatInt(time.Now().UnixNano()/1000000, 10)
var body io.Reader
var hmac, payload []byte
var err error
if data != nil {
payload, err = json.Marshal(data)
if err != nil {
@@ -855,7 +958,7 @@ func (f *FTX) SendAuthHTTPRequest(method, path string, data, result interface{})
headers["Content-Type"] = "application/json"
return f.SendPayload(context.Background(), &request.Item{
Method: method,
Path: ftxAPIURL + path,
Path: endpoint + path,
Headers: headers,
Body: body,
Result: result,
@@ -947,7 +1050,7 @@ func (f *FTX) RequestForQuotes(base, quote string, amount float64) (RequestQuote
req["fromCoin"] = base
req["toCoin"] = quote
req["size"] = amount
return resp.Data, f.SendAuthHTTPRequest(http.MethodPost, requestOTCQuote, req, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, requestOTCQuote, req, &resp)
}
// GetOTCQuoteStatus gets quote status of a quote
@@ -957,10 +1060,10 @@ func (f *FTX) GetOTCQuoteStatus(marketName, quoteID string) ([]QuoteStatusData,
}{}
params := url.Values{}
params.Set("market", marketName)
return resp.Data, f.SendAuthHTTPRequest(http.MethodGet, getOTCQuoteStatus+quoteID, params, &resp)
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOTCQuoteStatus+quoteID, params, &resp)
}
// AcceptOTCQuote requests for otc quotes
func (f *FTX) AcceptOTCQuote(quoteID string) error {
return f.SendAuthHTTPRequest(http.MethodPost, fmt.Sprintf(acceptOTCQuote, quoteID), nil, nil)
return f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, fmt.Sprintf(acceptOTCQuote, quoteID), nil, nil)
}

View File

@@ -147,7 +147,7 @@ func TestGetFutureStats(t *testing.T) {
func TestGetFundingRates(t *testing.T) {
t.Parallel()
_, err := f.GetFundingRates()
_, err := f.GetFundingRates(time.Now().Add(-time.Hour), time.Now(), "BTC-PERP")
if err != nil {
t.Error(err)
}
@@ -175,6 +175,28 @@ func TestGetPositions(t *testing.T) {
}
}
func TestGetBalances(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip()
}
_, err := f.GetBalances()
if err != nil {
t.Error(err)
}
}
func TestGetAllWalletBalances(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip()
}
_, err := f.GetAllWalletBalances()
if err != nil {
t.Error(err)
}
}
func TestChangeAccountLeverage(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() || !canManipulateRealOrders {
@@ -197,23 +219,100 @@ func TestGetCoins(t *testing.T) {
}
}
func TestGetBalances(t *testing.T) {
func TestGetMarginBorrowRates(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip()
}
_, err := f.GetBalances()
_, err := f.GetMarginBorrowRates()
if err != nil {
t.Error(err)
}
}
func TestGetAllWalletBalances(t *testing.T) {
func TestGetMarginLendingRates(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip()
}
_, err := f.GetAllWalletBalances()
_, err := f.GetMarginLendingRates()
if err != nil {
t.Error(err)
}
}
func TestMarginDailyBorrowedAmounts(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip()
}
_, err := f.MarginDailyBorrowedAmounts()
if err != nil {
t.Error(err)
}
}
func TestGetMarginMarketInfo(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip()
}
_, err := f.GetMarginMarketInfo("BTC_USD")
if err != nil {
t.Error(err)
}
}
func TestGetMarginBorrowHistory(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip()
}
_, err := f.GetMarginBorrowHistory()
if err != nil {
t.Error(err)
}
}
func TestGetMarginLendingHistory(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip()
}
_, err := f.GetMarginLendingHistory()
if err != nil {
t.Error(err)
}
}
func TestGetMarginLendingOffers(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip()
}
_, err := f.GetMarginLendingOffers()
if err != nil {
t.Error(err)
}
}
func TestGetLendingInfo(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() {
t.Skip()
}
_, err := f.GetLendingInfo()
if err != nil {
t.Error(err)
}
}
func TestSubmitLendingOffer(t *testing.T) {
t.Parallel()
if !areTestAPIKeysSet() || !canManipulateRealOrders {
t.Skip()
}
_, err := f.SubmitLendingOffer("btc", 0.1, 500)
if err != nil {
t.Error(err)
}
@@ -727,6 +826,7 @@ func TestGetActiveOrders(t *testing.T) {
var orderReq order.GetOrdersRequest
cp := currency.NewPairWithDelimiter(currency.BTC.String(), currency.USDT.String(), "/")
orderReq.Pairs = append(orderReq.Pairs, cp)
orderReq.AssetType = asset.Spot
_, err := f.GetActiveOrders(&orderReq)
if err != nil {
t.Fatal(err)
@@ -741,6 +841,7 @@ func TestGetOrderHistory(t *testing.T) {
var orderReq order.GetOrdersRequest
cp := currency.NewPairWithDelimiter(currency.BTC.String(), currency.USDT.String(), "/")
orderReq.Pairs = append(orderReq.Pairs, cp)
orderReq.AssetType = asset.Spot
_, err := f.GetOrderHistory(&orderReq)
if err != nil {
t.Fatal(err)
@@ -752,7 +853,7 @@ func TestUpdateAccountHoldings(t *testing.T) {
if !areTestAPIKeysSet() {
t.Skip("API keys required but not set, skipping test")
}
_, err := f.UpdateAccountInfo()
_, err := f.UpdateAccountInfo(asset.Spot)
if err != nil {
t.Error(err)
}
@@ -763,7 +864,7 @@ func TestFetchAccountInfo(t *testing.T) {
if !areTestAPIKeysSet() {
t.Skip("API keys required but not set, skipping test")
}
_, err := f.FetchAccountInfo()
_, err := f.FetchAccountInfo(asset.Spot)
if err != nil {
t.Error(err)
}

View File

@@ -7,6 +7,47 @@ import (
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
)
// MarginFundingData stores borrowing/lending data for margin trading
type MarginFundingData struct {
Coin string `json:"coin"`
Estimate float64 `json:"estimate"`
Previous float64 `json:"previous"`
}
// MarginMarketInfo stores margin market info
type MarginMarketInfo struct {
Coin string `json:"coin"`
Borrowed float64 `json:"borrowed"`
Free float64 `json:"free"`
EstimatedRate float64 `json:"estimatedRate"`
PreviousRate float64 `json:"previousRate"`
}
// MarginTransactionHistoryData stores margin borrowing/lending history
type MarginTransactionHistoryData struct {
Coin string `json:"coin"`
Cost float64 `json:"cost"`
Rate float64 `json:"rate"`
Size float64 `json:"size"`
Time time.Time `json:"time"`
}
// LendingOffersData stores data for lending offers
type LendingOffersData struct {
Coin string `json:"coin"`
Rate float64 `json:"rate"`
Size float64 `json:"size"`
}
// LendingInfoData stores margin lending info
type LendingInfoData struct {
Coin string `json:"coin"`
Lendable float64 `json:"lendable"`
Locked float64 `json:"locked"`
MinRate float64 `json:"minRate"`
Offered float64 `json:"offered"`
}
// MarketData stores market data
type MarketData struct {
Name string `json:"name"`

View File

@@ -142,9 +142,14 @@ func (f *FTX) SetDefaults() {
f.Requester = request.New(f.Name,
common.NewHTTPClientWithTimeout(exchange.DefaultHTTPTimeout),
request.WithLimiter(request.NewBasicRateLimit(ratePeriod, rateLimit)))
f.API.Endpoints.URLDefault = ftxAPIURL
f.API.Endpoints.URL = f.API.Endpoints.URLDefault
f.API.Endpoints = f.NewEndpoints()
err = f.API.Endpoints.SetDefaultEndpoints(map[exchange.URL]string{
exchange.RestSpot: ftxAPIURL,
exchange.WebsocketSpot: ftxWSURL,
})
if err != nil {
log.Errorln(log.ExchangeSys, err)
}
f.Websocket = stream.New()
f.WebsocketResponseMaxLimit = exchange.DefaultWebsocketResponseMaxLimit
f.WebsocketResponseCheckTimeout = exchange.DefaultWebsocketResponseCheckTimeout
@@ -163,6 +168,11 @@ func (f *FTX) Setup(exch *config.ExchangeConfig) error {
return err
}
wsEndpoint, err := f.API.Endpoints.GetURL(exchange.WebsocketSpot)
if err != nil {
return err
}
err = f.Websocket.Setup(&stream.WebsocketSetup{
Enabled: exch.Features.Enabled.Websocket,
Verbose: exch.Verbose,
@@ -170,7 +180,7 @@ func (f *FTX) Setup(exch *config.ExchangeConfig) error {
WebsocketTimeout: exch.WebsocketTrafficTimeout,
DefaultURL: ftxWSURL,
ExchangeName: exch.Name,
RunningURL: exch.API.Endpoints.WebsocketURL,
RunningURL: wsEndpoint,
Connector: f.WsConnect,
Subscriber: f.Subscribe,
UnSubscriber: f.Unsubscribe,
@@ -365,7 +375,7 @@ func (f *FTX) UpdateOrderbook(p currency.Pair, assetType asset.Item) (*orderbook
}
// UpdateAccountInfo retrieves balances for all enabled currencies
func (f *FTX) UpdateAccountInfo() (account.Holdings, error) {
func (f *FTX) UpdateAccountInfo(assetType asset.Item) (account.Holdings, error) {
var resp account.Holdings
data, err := f.GetBalances()
if err != nil {
@@ -393,10 +403,10 @@ func (f *FTX) UpdateAccountInfo() (account.Holdings, error) {
}
// FetchAccountInfo retrieves balances for all enabled currencies
func (f *FTX) FetchAccountInfo() (account.Holdings, error) {
acc, err := account.GetHoldings(f.Name)
func (f *FTX) FetchAccountInfo(assetType asset.Item) (account.Holdings, error) {
acc, err := account.GetHoldings(f.Name, assetType)
if err != nil {
return f.UpdateAccountInfo()
return f.UpdateAccountInfo(assetType)
}
return acc, nil
@@ -651,6 +661,8 @@ func (s *OrderData) GetCompatible(f *FTX) (OrderVars, error) {
resp.Side = order.Buy
case order.Sell.Lower():
resp.Side = order.Sell
default:
resp.Side = order.UnknownSide
}
switch s.Status {
case strings.ToLower(order.New.String()):
@@ -667,6 +679,8 @@ func (s *OrderData) GetCompatible(f *FTX) (OrderVars, error) {
if s.FilledSize == s.Size {
resp.Status = order.Filled
}
default:
resp.Status = order.AnyStatus
}
var feeBuilder exchange.FeeBuilder
feeBuilder.PurchasePrice = s.AvgFillPrice
@@ -991,8 +1005,8 @@ func (f *FTX) AuthenticateWebsocket() error {
// ValidateCredentials validates current credentials used for wrapper
// functionality
func (f *FTX) ValidateCredentials() error {
_, err := f.UpdateAccountInfo()
func (f *FTX) ValidateCredentials(assetType asset.Item) error {
_, err := f.UpdateAccountInfo(assetType)
return f.CheckTransientError(err)
}