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