mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-31 07:26:44 +00:00
FTX: Various bug fixes (#631)
* FTX: Various bug fixes * ImPrOvE CaSe SenSitVity * Shazbert nitterinos * "Rm newline" * Switch from API specified timestamp values to valid FTTBTC ones for auth requests * Move comment to specific test
This commit is contained in:
@@ -13,6 +13,7 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-corp/gocryptotrader/common"
|
||||
"github.com/thrasher-corp/gocryptotrader/common/crypto"
|
||||
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/order"
|
||||
@@ -31,12 +32,12 @@ const (
|
||||
getMarkets = "/markets"
|
||||
getMarket = "/markets/"
|
||||
getOrderbook = "/markets/%s/orderbook?depth=%s"
|
||||
getTrades = "/markets/%s/trades?"
|
||||
getHistoricalData = "/markets/%s/candles?"
|
||||
getTrades = "/markets/%s/trades"
|
||||
getHistoricalData = "/markets/%s/candles"
|
||||
getFutures = "/futures"
|
||||
getFuture = "/futures/"
|
||||
getFutureStats = "/futures/%s/stats"
|
||||
getFundingRates = "/funding_rates?"
|
||||
getFundingRates = "/funding_rates"
|
||||
getIndexWeights = "/indexes/%s/weights"
|
||||
getAllWalletBalances = "/wallet/all_balances"
|
||||
|
||||
@@ -50,11 +51,11 @@ const (
|
||||
getDepositHistory = "/wallet/deposits"
|
||||
getWithdrawalHistory = "/wallet/withdrawals"
|
||||
withdrawRequest = "/wallet/withdrawals"
|
||||
getOpenOrders = "/orders?"
|
||||
getOrderHistory = "/orders/history?"
|
||||
getOpenTriggerOrders = "/conditional_orders?"
|
||||
getOpenOrders = "/orders"
|
||||
getOrderHistory = "/orders/history"
|
||||
getOpenTriggerOrders = "/conditional_orders"
|
||||
getTriggerOrderTriggers = "/conditional_orders/%s/triggers"
|
||||
getTriggerOrderHistory = "/conditional_orders/history?"
|
||||
getTriggerOrderHistory = "/conditional_orders/history"
|
||||
placeOrder = "/orders"
|
||||
placeTriggerOrder = "/conditional_orders"
|
||||
modifyOrder = "/orders/%s/modify"
|
||||
@@ -65,8 +66,8 @@ const (
|
||||
deleteOrder = "/orders/"
|
||||
deleteOrderByClientID = "/orders/by_client_id/"
|
||||
cancelTriggerOrder = "/conditional_orders/"
|
||||
getFills = "/fills?"
|
||||
getFundingPayments = "/funding_payments?"
|
||||
getFills = "/fills"
|
||||
getFundingPayments = "/funding_payments"
|
||||
getLeveragedTokens = "/lt/tokens"
|
||||
getTokenInfo = "/lt/"
|
||||
getLTBalances = "/lt/balances"
|
||||
@@ -92,7 +93,7 @@ const (
|
||||
|
||||
// Margin Endpoints
|
||||
marginBorrowRates = "/spot_margin/borrow_rates"
|
||||
maringLendingRates = "/spot_margin/lending_rates"
|
||||
marginLendingRates = "/spot_margin/lending_rates"
|
||||
dailyBorrowedAmounts = "/spot_margin/borrow_summary"
|
||||
marginMarketInfo = "/spot_margin/market_info?market=%s"
|
||||
marginBorrowHistory = "/spot_margin/borrow_history"
|
||||
@@ -112,6 +113,10 @@ const (
|
||||
rateLimit = 30
|
||||
)
|
||||
|
||||
var (
|
||||
errStartTimeCannotBeAfterEndTime = errors.New("start timestamp cannot be after end timestamp")
|
||||
)
|
||||
|
||||
// GetMarkets gets market data
|
||||
func (f *FTX) GetMarkets() ([]MarketData, error) {
|
||||
resp := struct {
|
||||
@@ -164,28 +169,38 @@ func (f *FTX) GetOrderbook(marketName string, depth int64) (OrderbookData, error
|
||||
|
||||
// GetTrades gets trades based on the conditions specified
|
||||
func (f *FTX) GetTrades(marketName string, startTime, endTime, limit int64) ([]TradeData, error) {
|
||||
strLimit := strconv.FormatInt(limit, 10)
|
||||
if marketName == "" {
|
||||
return nil, errors.New("a market pair must be specified")
|
||||
}
|
||||
|
||||
params := url.Values{}
|
||||
params.Set("limit", strLimit)
|
||||
resp := struct {
|
||||
Data []TradeData `json:"result"`
|
||||
}{}
|
||||
if limit != 0 {
|
||||
params.Set("limit", strconv.FormatInt(limit, 10))
|
||||
}
|
||||
if startTime > 0 && endTime > 0 {
|
||||
if startTime >= (endTime) {
|
||||
return resp.Data, errors.New("startTime cannot be after endTime")
|
||||
return nil, errStartTimeCannotBeAfterEndTime
|
||||
}
|
||||
params.Set("start_time", strconv.FormatInt(startTime, 10))
|
||||
params.Set("end_time", strconv.FormatInt(endTime, 10))
|
||||
}
|
||||
return resp.Data, f.SendHTTPRequest(exchange.RestSpot, fmt.Sprintf(getTrades, marketName)+params.Encode(),
|
||||
&resp)
|
||||
resp := struct {
|
||||
Data []TradeData `json:"result"`
|
||||
}{}
|
||||
endpoint := common.EncodeURLValues(fmt.Sprintf(getTrades, marketName), params)
|
||||
return resp.Data, f.SendHTTPRequest(exchange.RestSpot, endpoint, &resp)
|
||||
}
|
||||
|
||||
// GetHistoricalData gets historical OHLCV data for a given market pair
|
||||
func (f *FTX) GetHistoricalData(marketName, timeInterval, limit string, startTime, endTime time.Time) ([]OHLCVData, error) {
|
||||
resp := struct {
|
||||
Data []OHLCVData `json:"result"`
|
||||
}{}
|
||||
if marketName == "" {
|
||||
return nil, errors.New("a market pair must be specified")
|
||||
}
|
||||
|
||||
if timeInterval == "" {
|
||||
return nil, errors.New("a time interval must be specified")
|
||||
}
|
||||
|
||||
params := url.Values{}
|
||||
params.Set("resolution", timeInterval)
|
||||
if limit != "" {
|
||||
@@ -193,12 +208,16 @@ func (f *FTX) GetHistoricalData(marketName, timeInterval, limit string, startTim
|
||||
}
|
||||
if !startTime.IsZero() && !endTime.IsZero() {
|
||||
if startTime.After(endTime) {
|
||||
return resp.Data, errors.New("startTime cannot be after endTime")
|
||||
return nil, errStartTimeCannotBeAfterEndTime
|
||||
}
|
||||
params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10))
|
||||
params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10))
|
||||
}
|
||||
return resp.Data, f.SendHTTPRequest(exchange.RestSpot, fmt.Sprintf(getHistoricalData, marketName)+params.Encode(), &resp)
|
||||
resp := struct {
|
||||
Data []OHLCVData `json:"result"`
|
||||
}{}
|
||||
endpoint := common.EncodeURLValues(fmt.Sprintf(getHistoricalData, marketName), params)
|
||||
return resp.Data, f.SendHTTPRequest(exchange.RestSpot, endpoint, &resp)
|
||||
}
|
||||
|
||||
// GetFutures gets data on futures
|
||||
@@ -233,7 +252,7 @@ func (f *FTX) GetFundingRates(startTime, endTime time.Time, future string) ([]Fu
|
||||
params := url.Values{}
|
||||
if !startTime.IsZero() && !endTime.IsZero() {
|
||||
if startTime.After(endTime) {
|
||||
return resp.Data, errors.New("startTime cannot be after endTime")
|
||||
return resp.Data, errStartTimeCannotBeAfterEndTime
|
||||
}
|
||||
params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10))
|
||||
params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10))
|
||||
@@ -241,7 +260,8 @@ func (f *FTX) GetFundingRates(startTime, endTime time.Time, future string) ([]Fu
|
||||
if future != "" {
|
||||
params.Set("future", future)
|
||||
}
|
||||
return resp.Data, f.SendHTTPRequest(exchange.RestSpot, getFundingRates+params.Encode(), &resp)
|
||||
endpoint := common.EncodeURLValues(getFundingRates, params)
|
||||
return resp.Data, f.SendHTTPRequest(exchange.RestSpot, endpoint, &resp)
|
||||
}
|
||||
|
||||
// GetIndexWeights gets index weights
|
||||
@@ -279,15 +299,15 @@ func (f *FTX) GetMarginLendingRates() ([]MarginFundingData, error) {
|
||||
r := struct {
|
||||
Data []MarginFundingData `json:"result"`
|
||||
}{}
|
||||
return r.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, maringLendingRates, nil, &r)
|
||||
return r.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, marginLendingRates, nil, &r)
|
||||
}
|
||||
|
||||
// MarginDailyBorrowedAmounts gets daily borrowed amounts for margin
|
||||
func (f *FTX) MarginDailyBorrowedAmounts() ([]MarginMarketInfo, error) {
|
||||
func (f *FTX) MarginDailyBorrowedAmounts() ([]MarginDailyBorrowStats, error) {
|
||||
r := struct {
|
||||
Data []MarginMarketInfo `json:"result"`
|
||||
Data []MarginDailyBorrowStats `json:"result"`
|
||||
}{}
|
||||
return r.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, dailyBorrowedAmounts, nil, &r)
|
||||
return r.Data, f.SendHTTPRequest(exchange.RestSpot, dailyBorrowedAmounts, &r)
|
||||
}
|
||||
|
||||
// GetMarginMarketInfo gets margin market data
|
||||
@@ -331,13 +351,24 @@ func (f *FTX) GetLendingInfo() ([]LendingInfoData, error) {
|
||||
}
|
||||
|
||||
// SubmitLendingOffer submits an offer for margin lending
|
||||
func (f *FTX) SubmitLendingOffer(coin string, size, rate float64) (interface{}, error) {
|
||||
var resp interface{}
|
||||
func (f *FTX) SubmitLendingOffer(coin string, size, rate float64) error {
|
||||
resp := struct {
|
||||
Result string `json:"result"`
|
||||
Success bool `json:"success"`
|
||||
}{}
|
||||
req := make(map[string]interface{})
|
||||
req["coin"] = coin
|
||||
req["coin"] = strings.ToUpper(coin)
|
||||
req["size"] = size
|
||||
req["rate"] = rate
|
||||
return resp, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, marginLendingInfo, req, &resp)
|
||||
|
||||
if err := f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, marginLendingOffers, req, &resp); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !resp.Success {
|
||||
return errors.New(resp.Result)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAccountInfo gets account info
|
||||
@@ -392,7 +423,7 @@ func (f *FTX) FetchDepositAddress(coin string) (DepositData, error) {
|
||||
resp := struct {
|
||||
Data DepositData `json:"result"`
|
||||
}{}
|
||||
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getDepositAddress+coin, nil, &resp)
|
||||
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getDepositAddress+strings.ToUpper(coin), nil, &resp)
|
||||
}
|
||||
|
||||
// FetchDepositHistory gets deposit history
|
||||
@@ -414,7 +445,7 @@ func (f *FTX) FetchWithdrawalHistory() ([]TransactionData, error) {
|
||||
// Withdraw sends a withdrawal request
|
||||
func (f *FTX) Withdraw(coin, address, tag, password, code string, size float64) (TransactionData, error) {
|
||||
req := make(map[string]interface{})
|
||||
req["coin"] = coin
|
||||
req["coin"] = strings.ToUpper(coin)
|
||||
req["address"] = address
|
||||
req["size"] = size
|
||||
if code != "" {
|
||||
@@ -441,7 +472,8 @@ func (f *FTX) GetOpenOrders(marketName string) ([]OrderData, error) {
|
||||
resp := struct {
|
||||
Data []OrderData `json:"result"`
|
||||
}{}
|
||||
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOpenOrders+params.Encode(), nil, &resp)
|
||||
endpoint := common.EncodeURLValues(getOpenOrders, params)
|
||||
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, endpoint, nil, &resp)
|
||||
}
|
||||
|
||||
// FetchOrderHistory gets order history
|
||||
@@ -455,7 +487,7 @@ func (f *FTX) FetchOrderHistory(marketName string, startTime, endTime time.Time,
|
||||
}
|
||||
if !startTime.IsZero() && !endTime.IsZero() {
|
||||
if startTime.After(endTime) {
|
||||
return resp.Data, errors.New("startTime cannot be after endTime")
|
||||
return resp.Data, errStartTimeCannotBeAfterEndTime
|
||||
}
|
||||
params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10))
|
||||
params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10))
|
||||
@@ -463,7 +495,8 @@ func (f *FTX) FetchOrderHistory(marketName string, startTime, endTime time.Time,
|
||||
if limit != "" {
|
||||
params.Set("limit", limit)
|
||||
}
|
||||
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOrderHistory+params.Encode(), nil, &resp)
|
||||
endpoint := common.EncodeURLValues(getOrderHistory, params)
|
||||
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, endpoint, nil, &resp)
|
||||
}
|
||||
|
||||
// GetOpenTriggerOrders gets trigger orders that are currently open
|
||||
@@ -478,7 +511,8 @@ func (f *FTX) GetOpenTriggerOrders(marketName, orderType string) ([]TriggerOrder
|
||||
resp := struct {
|
||||
Data []TriggerOrderData `json:"result"`
|
||||
}{}
|
||||
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getOpenTriggerOrders+params.Encode(), nil, &resp)
|
||||
endpoint := common.EncodeURLValues(getOpenTriggerOrders, params)
|
||||
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, endpoint, nil, &resp)
|
||||
}
|
||||
|
||||
// GetTriggerOrderTriggers gets trigger orders that are currently open
|
||||
@@ -491,16 +525,13 @@ func (f *FTX) GetTriggerOrderTriggers(orderID string) ([]TriggerData, error) {
|
||||
|
||||
// GetTriggerOrderHistory gets trigger orders that are currently open
|
||||
func (f *FTX) GetTriggerOrderHistory(marketName string, startTime, endTime time.Time, side, orderType, limit string) ([]TriggerOrderData, error) {
|
||||
resp := struct {
|
||||
Data []TriggerOrderData `json:"result"`
|
||||
}{}
|
||||
params := url.Values{}
|
||||
if marketName != "" {
|
||||
params.Set("market", marketName)
|
||||
}
|
||||
if !startTime.IsZero() && !endTime.IsZero() {
|
||||
if startTime.After(endTime) {
|
||||
return resp.Data, errors.New("startTime cannot be after endTime")
|
||||
return nil, errStartTimeCannotBeAfterEndTime
|
||||
}
|
||||
params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10))
|
||||
params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10))
|
||||
@@ -514,7 +545,11 @@ func (f *FTX) GetTriggerOrderHistory(marketName string, startTime, endTime time.
|
||||
if limit != "" {
|
||||
params.Set("limit", limit)
|
||||
}
|
||||
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getTriggerOrderHistory+params.Encode(), nil, &resp)
|
||||
resp := struct {
|
||||
Data []TriggerOrderData `json:"result"`
|
||||
}{}
|
||||
endpoint := common.EncodeURLValues(getTriggerOrderHistory, params)
|
||||
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, endpoint, nil, &resp)
|
||||
}
|
||||
|
||||
// Order places an order
|
||||
@@ -700,12 +735,13 @@ func (f *FTX) GetFills(market, limit string, startTime, endTime time.Time) ([]Fi
|
||||
}
|
||||
if !startTime.IsZero() && !endTime.IsZero() {
|
||||
if startTime.After(endTime) {
|
||||
return resp.Data, errors.New("startTime cannot be after endTime")
|
||||
return resp.Data, errStartTimeCannotBeAfterEndTime
|
||||
}
|
||||
params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10))
|
||||
params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10))
|
||||
}
|
||||
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getFills+params.Encode(), nil, &resp)
|
||||
endpoint := common.EncodeURLValues(getFills, params)
|
||||
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, endpoint, nil, &resp)
|
||||
}
|
||||
|
||||
// GetFundingPayments gets funding payments
|
||||
@@ -716,7 +752,7 @@ func (f *FTX) GetFundingPayments(startTime, endTime time.Time, future string) ([
|
||||
params := url.Values{}
|
||||
if !startTime.IsZero() && !endTime.IsZero() {
|
||||
if startTime.After(endTime) {
|
||||
return resp.Data, errors.New("startTime cannot be after endTime")
|
||||
return resp.Data, errStartTimeCannotBeAfterEndTime
|
||||
}
|
||||
params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10))
|
||||
params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10))
|
||||
@@ -724,7 +760,8 @@ func (f *FTX) GetFundingPayments(startTime, endTime time.Time, future string) ([
|
||||
if future != "" {
|
||||
params.Set("future", future)
|
||||
}
|
||||
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getFundingPayments+params.Encode(), nil, &resp)
|
||||
endpoint := common.EncodeURLValues(getFundingPayments, params)
|
||||
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, endpoint, nil, &resp)
|
||||
}
|
||||
|
||||
// ListLeveragedTokens lists leveraged tokens
|
||||
@@ -806,7 +843,7 @@ func (f *FTX) GetYourQuoteRequests() ([]PersonalQuotesData, error) {
|
||||
// CreateQuoteRequest sends a request to create a quote
|
||||
func (f *FTX) CreateQuoteRequest(underlying, optionType, side string, expiry int64, requestExpiry string, strike, size, limitPrice, counterParyID float64, hideLimitPrice bool) (CreateQuoteRequestData, error) {
|
||||
req := make(map[string]interface{})
|
||||
req["underlying"] = underlying
|
||||
req["underlying"] = strings.ToUpper(underlying)
|
||||
req["type"] = optionType
|
||||
req["side"] = side
|
||||
req["strike"] = strike
|
||||
@@ -894,21 +931,22 @@ func (f *FTX) GetOptionsPositions() ([]OptionsPositionsData, error) {
|
||||
|
||||
// GetPublicOptionsTrades gets options' trades from public
|
||||
func (f *FTX) GetPublicOptionsTrades(startTime, endTime time.Time, limit string) ([]OptionsTradesData, error) {
|
||||
params := url.Values{}
|
||||
if !startTime.IsZero() && !endTime.IsZero() {
|
||||
if startTime.After(endTime) {
|
||||
return nil, errStartTimeCannotBeAfterEndTime
|
||||
}
|
||||
params.Set("start_time", strconv.FormatInt(startTime.Unix(), 10))
|
||||
params.Set("end_time", strconv.FormatInt(endTime.Unix(), 10))
|
||||
}
|
||||
if limit != "" {
|
||||
params.Set("limit", limit)
|
||||
}
|
||||
resp := struct {
|
||||
Data []OptionsTradesData `json:"result"`
|
||||
}{}
|
||||
req := make(map[string]interface{})
|
||||
if !startTime.IsZero() && !endTime.IsZero() {
|
||||
req["start_time"] = strconv.FormatInt(startTime.Unix(), 10)
|
||||
req["end_time"] = strconv.FormatInt(endTime.Unix(), 10)
|
||||
if startTime.After(endTime) {
|
||||
return resp.Data, errors.New("startTime cannot be after endTime")
|
||||
}
|
||||
}
|
||||
if limit != "" {
|
||||
req["limit"] = limit
|
||||
}
|
||||
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodGet, getPublicOptionsTrades, req, &resp)
|
||||
endpoint := common.EncodeURLValues(getPublicOptionsTrades, params)
|
||||
return resp.Data, f.SendHTTPRequest(exchange.RestSpot, endpoint, &resp)
|
||||
}
|
||||
|
||||
// GetOptionsFills gets fills data for options
|
||||
@@ -921,7 +959,7 @@ func (f *FTX) GetOptionsFills(startTime, endTime time.Time, limit string) ([]Opt
|
||||
req["start_time"] = strconv.FormatInt(startTime.Unix(), 10)
|
||||
req["end_time"] = strconv.FormatInt(endTime.Unix(), 10)
|
||||
if startTime.After(endTime) {
|
||||
return resp.Data, errors.New("startTime cannot be after endTime")
|
||||
return resp.Data, errStartTimeCannotBeAfterEndTime
|
||||
}
|
||||
}
|
||||
if limit != "" {
|
||||
@@ -1047,8 +1085,8 @@ func (f *FTX) RequestForQuotes(base, quote string, amount float64) (RequestQuote
|
||||
Data RequestQuoteData `json:"result"`
|
||||
}{}
|
||||
req := make(map[string]interface{})
|
||||
req["fromCoin"] = base
|
||||
req["toCoin"] = quote
|
||||
req["fromCoin"] = strings.ToUpper(base)
|
||||
req["toCoin"] = strings.ToUpper(quote)
|
||||
req["size"] = amount
|
||||
return resp.Data, f.SendAuthHTTPRequest(exchange.RestSpot, http.MethodPost, requestOTCQuote, req, &resp)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@@ -26,8 +25,14 @@ const (
|
||||
canManipulateRealOrders = false
|
||||
spotPair = "FTT/BTC"
|
||||
futuresPair = "DOGE-PERP"
|
||||
testToken = "ADAMOON"
|
||||
btcusd = "BTC/USD"
|
||||
testLeverageToken = "ADAMOON"
|
||||
|
||||
validFTTBTCStartTime = 1565445600 // Sat Aug 10 2019 14:00:00 GMT+0000
|
||||
validFTTBTCEndTime = 1565532000 // Sat Aug 10 2019 14:00:00 GMT+0000
|
||||
invalidFTTBTCStartTime = 1559881511 // Fri Jun 07 2019 04:25:11 GMT+0000
|
||||
invalidFTTBTCEndTime = 1559901511 // Fri Jun 07 2019 09:58:31 GMT+0000
|
||||
authStartTime = validFTTBTCStartTime // Adjust these to test auth requests
|
||||
authEndTime = validFTTBTCEndTime
|
||||
)
|
||||
|
||||
var f FTX
|
||||
@@ -91,34 +96,71 @@ func TestGetOrderbook(t *testing.T) {
|
||||
|
||||
func TestGetTrades(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := f.GetTrades(spotPair, 0, 0, 200)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = f.GetTrades(spotPair, 0, 0, 5)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = f.GetTrades(spotPair, 1559901511, 1559881511, 5)
|
||||
// test empty market
|
||||
_, err := f.GetTrades("", 0, 0, 200)
|
||||
if err == nil {
|
||||
t.Error("empty market should return an error")
|
||||
}
|
||||
_, err = f.GetTrades(spotPair, validFTTBTCEndTime, validFTTBTCStartTime, 5)
|
||||
if err != errStartTimeCannotBeAfterEndTime {
|
||||
t.Errorf("should have thrown errStartTimeCannotBeAfterEndTime, got %v", err)
|
||||
}
|
||||
// test optional params
|
||||
var trades []TradeData
|
||||
trades, err = f.GetTrades(spotPair, 0, 0, 0)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if len(trades) != 20 {
|
||||
t.Error("default limit should return 20 items")
|
||||
}
|
||||
trades, err = f.GetTrades(spotPair, validFTTBTCStartTime, validFTTBTCEndTime, 5)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if len(trades) != 5 {
|
||||
t.Error("limit of 5 should return 5 items")
|
||||
}
|
||||
trades, err = f.GetTrades(spotPair, invalidFTTBTCStartTime, invalidFTTBTCEndTime, 5)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if len(trades) != 0 {
|
||||
t.Error("invalid time range should return 0 items")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetHistoricalData(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := f.GetHistoricalData(spotPair, "86400", "5", time.Time{}, time.Time{})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = f.GetHistoricalData(spotPair, "86400", "5", time.Unix(1559881511, 0), time.Unix(1559901511, 0))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = f.GetHistoricalData(spotPair, "86400", "5", time.Unix(1559901511, 0), time.Unix(1559881511, 0))
|
||||
// test empty market
|
||||
_, err := f.GetHistoricalData("", "86400", "5", time.Time{}, time.Time{})
|
||||
if err == nil {
|
||||
t.Error("empty market should return an error")
|
||||
}
|
||||
// test empty resolution
|
||||
_, err = f.GetHistoricalData(spotPair, "", "5", time.Time{}, time.Time{})
|
||||
if err == nil {
|
||||
t.Error("empty resolution should return an error")
|
||||
}
|
||||
_, err = f.GetHistoricalData(spotPair, "86400", "5", time.Unix(validFTTBTCEndTime, 0), time.Unix(validFTTBTCStartTime, 0))
|
||||
if err != errStartTimeCannotBeAfterEndTime {
|
||||
t.Errorf("should have thrown errStartTimeCannotBeAfterEndTime, got %v", err)
|
||||
}
|
||||
var o []OHLCVData
|
||||
o, err = f.GetHistoricalData(spotPair, "86400", "5", time.Time{}, time.Time{})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if len(o) != 5 {
|
||||
t.Error("limit of 5 should return 5 items")
|
||||
}
|
||||
o, err = f.GetHistoricalData(spotPair, "86400", "5", time.Unix(invalidFTTBTCStartTime, 0), time.Unix(invalidFTTBTCEndTime, 0))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if len(o) != 0 {
|
||||
t.Error("invalid time range should return 0 items")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetFutures(t *testing.T) {
|
||||
@@ -147,7 +189,12 @@ func TestGetFutureStats(t *testing.T) {
|
||||
|
||||
func TestGetFundingRates(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := f.GetFundingRates(time.Now().Add(-time.Hour), time.Now(), "BTC-PERP")
|
||||
// optional params
|
||||
_, err := f.GetFundingRates(time.Time{}, time.Time{}, "")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = f.GetFundingRates(time.Now().Add(-time.Hour), time.Now(), "BTC-PERP")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -243,9 +290,6 @@ func TestGetMarginLendingRates(t *testing.T) {
|
||||
|
||||
func TestMarginDailyBorrowedAmounts(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip()
|
||||
}
|
||||
_, err := f.MarginDailyBorrowedAmounts()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
@@ -312,8 +356,7 @@ func TestSubmitLendingOffer(t *testing.T) {
|
||||
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
||||
t.Skip()
|
||||
}
|
||||
_, err := f.SubmitLendingOffer("btc", 0.1, 500)
|
||||
if err != nil {
|
||||
if err := f.SubmitLendingOffer("bTc", 0.1, 500); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
@@ -323,7 +366,7 @@ func TestFetchDepositAddress(t *testing.T) {
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip()
|
||||
}
|
||||
_, err := f.FetchDepositAddress("TUSD")
|
||||
_, err := f.FetchDepositAddress("tUsD")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -356,7 +399,7 @@ func TestWithdraw(t *testing.T) {
|
||||
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
||||
t.Skip("skipping test, either api keys or canManipulateRealOrders isnt set correctly")
|
||||
}
|
||||
_, err := f.Withdraw("BTC", core.BitcoinDonationAddress, "", "", "957378", 0.0009)
|
||||
_, err := f.Withdraw("BtC", core.BitcoinDonationAddress, "", "", "957378", 0.0009)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -367,7 +410,11 @@ func TestGetOpenOrders(t *testing.T) {
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip()
|
||||
}
|
||||
_, err := f.GetOpenOrders(spotPair)
|
||||
_, err := f.GetOpenOrders("")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = f.GetOpenOrders(spotPair)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -378,17 +425,17 @@ func TestFetchOrderHistory(t *testing.T) {
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip()
|
||||
}
|
||||
_, err := f.FetchOrderHistory(spotPair, time.Time{}, time.Time{}, "2")
|
||||
_, err := f.FetchOrderHistory("", time.Time{}, time.Time{}, "2")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = f.FetchOrderHistory(spotPair, time.Unix(1559881511, 0), time.Unix(1559901511, 0), "2")
|
||||
_, err = f.FetchOrderHistory(spotPair, time.Unix(authStartTime, 0), time.Unix(authEndTime, 0), "2")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = f.FetchOrderHistory(spotPair, time.Unix(1559901511, 0), time.Unix(1559881511, 0), "2")
|
||||
if err == nil {
|
||||
t.Error(err)
|
||||
_, err = f.FetchOrderHistory(spotPair, time.Unix(authEndTime, 0), time.Unix(authStartTime, 0), "2")
|
||||
if err != errStartTimeCannotBeAfterEndTime {
|
||||
t.Errorf("should have thrown errStartTimeCannotBeAfterEndTime, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -397,7 +444,12 @@ func TestGetOpenTriggerOrders(t *testing.T) {
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip()
|
||||
}
|
||||
_, err := f.GetOpenTriggerOrders(spotPair, "")
|
||||
// optional params
|
||||
_, err := f.GetOpenTriggerOrders("", "")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = f.GetOpenTriggerOrders(spotPair, "")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -419,18 +471,22 @@ func TestGetTriggerOrderHistory(t *testing.T) {
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip()
|
||||
}
|
||||
_, err := f.GetTriggerOrderHistory(spotPair, time.Time{}, time.Time{}, order.Buy.Lower(), "stop", "1")
|
||||
_, err := f.GetTriggerOrderHistory("", time.Time{}, time.Time{}, "", "", "")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = f.GetTriggerOrderHistory(spotPair, time.Unix(1559881511, 0), time.Unix(1559901511, 0), order.Buy.Lower(), "stop", "1")
|
||||
_, err = f.GetTriggerOrderHistory(spotPair, time.Time{}, time.Time{}, order.Buy.Lower(), "stop", "1")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = f.GetTriggerOrderHistory(spotPair, time.Unix(1559901511, 0), time.Unix(1559881511, 0), order.Buy.Lower(), "stop", "1")
|
||||
if err == nil {
|
||||
_, err = f.GetTriggerOrderHistory(spotPair, time.Unix(authStartTime, 0), time.Unix(authEndTime, 0), order.Buy.Lower(), "stop", "1")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = f.GetTriggerOrderHistory(spotPair, time.Unix(authEndTime, 0), time.Unix(authStartTime, 0), order.Buy.Lower(), "stop", "1")
|
||||
if err != errStartTimeCannotBeAfterEndTime {
|
||||
t.Errorf("should have thrown errStartTimeCannotBeAfterEndTime, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestOrder(t *testing.T) {
|
||||
@@ -546,18 +602,23 @@ func TestGetFills(t *testing.T) {
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip()
|
||||
}
|
||||
_, err := f.GetFills(spotPair, "", time.Time{}, time.Time{})
|
||||
// optional params
|
||||
_, err := f.GetFills("", "", time.Time{}, time.Time{})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = f.GetFills(spotPair, "", time.Unix(1559881511, 0), time.Unix(1559901511, 0))
|
||||
_, err = f.GetFills(spotPair, "", time.Time{}, time.Time{})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = f.GetFills(spotPair, "", time.Unix(1559901511, 0), time.Unix(1559881511, 0))
|
||||
if err == nil {
|
||||
_, err = f.GetFills(spotPair, "", time.Unix(authStartTime, 0), time.Unix(authEndTime, 0))
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = f.GetFills(spotPair, "", time.Unix(authEndTime, 0), time.Unix(authStartTime, 0))
|
||||
if err != errStartTimeCannotBeAfterEndTime {
|
||||
t.Errorf("should have thrown errStartTimeCannotBeAfterEndTime, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetFundingPayments(t *testing.T) {
|
||||
@@ -565,14 +626,19 @@ func TestGetFundingPayments(t *testing.T) {
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip()
|
||||
}
|
||||
_, err := f.GetFundingPayments(time.Unix(1559881511, 0), time.Unix(1559901511, 0), "")
|
||||
// optional params
|
||||
_, err := f.GetFundingPayments(time.Time{}, time.Time{}, "")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = f.GetFundingPayments(time.Unix(1559901511, 0), time.Unix(1559881511, 0), "")
|
||||
if err == nil {
|
||||
_, err = f.GetFundingPayments(time.Unix(authStartTime, 0), time.Unix(authEndTime, 0), futuresPair)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = f.GetFundingPayments(time.Unix(authEndTime, 0), time.Unix(authStartTime, 0), futuresPair)
|
||||
if err != errStartTimeCannotBeAfterEndTime {
|
||||
t.Errorf("should have thrown errStartTimeCannotBeAfterEndTime, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestListLeveragedTokens(t *testing.T) {
|
||||
@@ -624,7 +690,7 @@ func TestRequestLTCreation(t *testing.T) {
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip()
|
||||
}
|
||||
_, err := f.RequestLTCreation(testToken, 1)
|
||||
_, err := f.RequestLTCreation(testLeverageToken, 1)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -668,7 +734,7 @@ func TestCreateQuoteRequest(t *testing.T) {
|
||||
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
||||
t.Skip("skipping test, either api keys or canManipulateRealOrders isnt set correctly")
|
||||
}
|
||||
_, err := f.CreateQuoteRequest(strings.ToUpper(currency.BTC.String()), "call", order.Buy.Lower(), 1593140400, "", 10, 10, 5, 0, false)
|
||||
_, err := f.CreateQuoteRequest(currency.BTC.String(), "call", order.Buy.Lower(), 1593140400, "", 10, 10, 5, 0, false)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -764,20 +830,25 @@ func TestGetOptionsPositions(t *testing.T) {
|
||||
|
||||
func TestGetPublicOptionsTrades(t *testing.T) {
|
||||
t.Parallel()
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip()
|
||||
}
|
||||
_, err := f.GetPublicOptionsTrades(time.Time{}, time.Time{}, "5")
|
||||
// test optional params
|
||||
result, err := f.GetPublicOptionsTrades(time.Time{}, time.Time{}, "")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = f.GetPublicOptionsTrades(time.Unix(1559881511, 0), time.Unix(1559901511, 0), "5")
|
||||
if len(result) != 20 {
|
||||
t.Error("default limit should have returned 20 items")
|
||||
}
|
||||
tmNow := time.Now()
|
||||
result, err = f.GetPublicOptionsTrades(tmNow.AddDate(0, 0, -1), tmNow, "5")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = f.GetPublicOptionsTrades(time.Unix(1559901511, 0), time.Unix(1559881511, 0), "5")
|
||||
if err == nil {
|
||||
t.Error(err)
|
||||
if len(result) != 5 {
|
||||
t.Error("limit of 5 should return 5 items")
|
||||
}
|
||||
_, err = f.GetPublicOptionsTrades(time.Unix(validFTTBTCEndTime, 0), time.Unix(validFTTBTCStartTime, 0), "5")
|
||||
if err != errStartTimeCannotBeAfterEndTime {
|
||||
t.Errorf("should have thrown errStartTimeCannotBeAfterEndTime, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -790,13 +861,13 @@ func TestGetOptionsFills(t *testing.T) {
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = f.GetOptionsFills(time.Unix(1559881511, 0), time.Unix(1559901511, 0), "5")
|
||||
_, err = f.GetOptionsFills(time.Unix(authStartTime, 0), time.Unix(authEndTime, 0), "5")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
_, err = f.GetOptionsFills(time.Unix(1559901511, 0), time.Unix(1559881511, 0), "5")
|
||||
if err == nil {
|
||||
t.Error(err)
|
||||
_, err = f.GetOptionsFills(time.Unix(authEndTime, 0), time.Unix(authStartTime, 0), "5")
|
||||
if err != errStartTimeCannotBeAfterEndTime {
|
||||
t.Errorf("should have thrown errStartTimeCannotBeAfterEndTime, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1223,7 +1294,7 @@ func TestGetOTCQuoteStatus(t *testing.T) {
|
||||
if !areTestAPIKeysSet() {
|
||||
t.Skip("API keys required but not set, skipping test")
|
||||
}
|
||||
_, err := f.GetOTCQuoteStatus(btcusd, "1")
|
||||
_, err := f.GetOTCQuoteStatus(spotPair, "1")
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -1234,7 +1305,7 @@ func TestRequestForQuotes(t *testing.T) {
|
||||
if !areTestAPIKeysSet() || !canManipulateRealOrders {
|
||||
t.Skip("skipping test, either api keys or canManipulateRealOrders isnt set correctly")
|
||||
}
|
||||
_, err := f.RequestForQuotes("BTC", "USD", 0.5)
|
||||
_, err := f.RequestForQuotes("BtC", "UsD", 0.5)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
@@ -14,6 +14,12 @@ type MarginFundingData struct {
|
||||
Previous float64 `json:"previous"`
|
||||
}
|
||||
|
||||
// MarginDailyBorrowStats stores the daily borrowed amounts
|
||||
type MarginDailyBorrowStats struct {
|
||||
Coin string `json:"coin"`
|
||||
Size float64 `json:"size"`
|
||||
}
|
||||
|
||||
// MarginMarketInfo stores margin market info
|
||||
type MarginMarketInfo struct {
|
||||
Coin string `json:"coin"`
|
||||
@@ -319,13 +325,13 @@ type FillsData struct {
|
||||
Fee float64 `json:"fee"`
|
||||
FeeRate float64 `json:"feeRate"`
|
||||
Future string `json:"future"`
|
||||
ID string `json:"id"`
|
||||
ID int64 `json:"id"`
|
||||
Liquidity string `json:"liquidity"`
|
||||
Market string `json:"market"`
|
||||
BaseCurrency string `json:"baseCurrency"`
|
||||
QuoteCurrency string `json:"quoteCurrency"`
|
||||
OrderID string `json:"orderID"`
|
||||
TradeID string `json:"tradeID"`
|
||||
OrderID int64 `json:"orderId"`
|
||||
TradeID int64 `json:"tradeId"`
|
||||
Price float64 `json:"price"`
|
||||
Side string `json:"side"`
|
||||
Size float64 `json:"size"`
|
||||
@@ -336,7 +342,7 @@ type FillsData struct {
|
||||
// FundingPaymentsData stores funding payments' data
|
||||
type FundingPaymentsData struct {
|
||||
Future string `json:"future"`
|
||||
ID string `json:"id"`
|
||||
ID int64 `json:"id"`
|
||||
Payment float64 `json:"payment"`
|
||||
Time time.Time `json:"time"`
|
||||
Rate float64 `json:"rate"`
|
||||
@@ -617,8 +623,8 @@ type WsFills struct {
|
||||
ID int64 `json:"id"`
|
||||
Liquidity string `json:"liquidity"`
|
||||
Market string `json:"market"`
|
||||
OrderID int64 `json:"int64"`
|
||||
TradeID int64 `json:"tradeID"`
|
||||
OrderID int64 `json:"orderId"`
|
||||
TradeID int64 `json:"tradeId"`
|
||||
Price float64 `json:"price"`
|
||||
Side string `json:"side"`
|
||||
Size float64 `json:"size"`
|
||||
|
||||
Reference in New Issue
Block a user