From dc4144c1c22daccc32c5b20b3d392c69eebf6c9d Mon Sep 17 00:00:00 2001 From: Ryan O'Hara-Reid Date: Sat, 19 Aug 2017 13:30:27 +1000 Subject: [PATCH] Fixed linter issues, increased codecov, fixed general bugs for Bitfinex package --- exchanges/bitfinex/bitfinex.go | 748 ++++--- exchanges/bitfinex/bitfinex_test.go | 1733 ++++------------- exchanges/bitfinex/bitfinex_types.go | 429 ++-- exchanges/bitfinex/bitfinex_websocket.go | 116 +- exchanges/bitfinex/bitfinex_websocket_test.go | 156 +- exchanges/bitfinex/bitfinex_wrapper.go | 16 +- exchanges/bitfinex/bitfinex_wrapper_test.go | 15 - 7 files changed, 1058 insertions(+), 2155 deletions(-) diff --git a/exchanges/bitfinex/bitfinex.go b/exchanges/bitfinex/bitfinex.go index f897fa3f..cf0f77d0 100644 --- a/exchanges/bitfinex/bitfinex.go +++ b/exchanges/bitfinex/bitfinex.go @@ -16,59 +16,74 @@ import ( ) const ( - BITFINEX_API_URL = "https://api.bitfinex.com/v1/" - BITFINEX_API_VERSION = "1" - BITFINEX_TICKER = "pubticker/" - BITFINEX_STATS = "stats/" - BITFINEX_LENDBOOK = "lendbook/" - BITFINEX_ORDERBOOK = "book/" - BITFINEX_TRADES = "trades/" - BITFINEX_LENDS = "lends/" - BITFINEX_SYMBOLS = "symbols/" - BITFINEX_SYMBOLS_DETAILS = "symbols_details/" - BITFINEX_ACCOUNT_INFO = "account_infos" - BITFINEX_DEPOSIT = "deposit/new" - BITFINEX_ORDER_NEW = "order/new" - BITFINEX_ORDER_NEW_MULTI = "order/new/multi" - BITFINEX_ORDER_CANCEL = "order/cancel" - BITFINEX_ORDER_CANCEL_MULTI = "order/cancel/multi" - BITFINEX_ORDER_CANCEL_ALL = "order/cancel/all" - BITFINEX_ORDER_CANCEL_REPLACE = "order/cancel/replace" - BITFINEX_ORDER_STATUS = "order/status" - BITFINEX_ORDERS = "orders" - BITFINEX_POSITIONS = "positions" - BITFINEX_CLAIM_POSITION = "position/claim" - BITFINEX_HISTORY = "history" - BITFINEX_HISTORY_MOVEMENTS = "history/movements" - BITFINEX_TRADE_HISTORY = "mytrades" - BITFINEX_OFFER_NEW = "offer/new" - BITFINEX_OFFER_CANCEL = "offer/cancel" - BITFINEX_OFFER_STATUS = "offer/status" - BITFINEX_OFFERS = "offers" - BITFINEX_MARGIN_ACTIVE_FUNDS = "taken_funds" - BITFINEX_MARGIN_TOTAL_FUNDS = "total_taken_funds" - BITFINEX_MARGIN_CLOSE = "funding/close" - BITFINEX_BALANCES = "balances" - BITFINEX_MARGIN_INFO = "margin_infos" - BITFINEX_TRANSFER = "transfer" - BITFINEX_WITHDRAWAL = "withdrawal" + bitfinexAPIURL = "https://api.bitfinex.com/v1/" + bitfinexAPIVersion = "1" + bitfinexTicker = "pubticker/" + bitfinexStats = "stats/" + bitfinexLendbook = "lendbook/" + bitfinexOrderbook = "book/" + bitfinexTrades = "trades/" + bitfinexKeyPermissions = "key_info" + bitfinexLends = "lends/" + bitfinexSymbols = "symbols/" + bitfinexSymbolsDetails = "symbols_details/" + bitfinexAccountInfo = "account_infos" + bitfinexAccountFees = "account_fees" + bitfinexAccountSummary = "summary" + bitfinexDeposit = "deposit/new" + bitfinexOrderNew = "order/new" + bitfinexOrderNewMulti = "order/new/multi" + bitfinexOrderCancel = "order/cancel" + bitfinexOrderCancelMulti = "order/cancel/multi" + bitfinexOrderCancelAll = "order/cancel/all" + bitfinexOrderCancelReplace = "order/cancel/replace" + bitfinexOrderStatus = "order/status" + bitfinexOrders = "orders" + bitfinexPositions = "positions" + bitfinexClaimPosition = "position/claim" + bitfinexHistory = "history" + bitfinexHistoryMovements = "history/movements" + bitfinexTradeHistory = "mytrades" + bitfinexOfferNew = "offer/new" + bitfinexOfferCancel = "offer/cancel" + bitfinexOfferStatus = "offer/status" + bitfinexOffers = "offers" + bitfinexMarginActiveFunds = "taken_funds" + bitfinexMarginTotalFunds = "total_taken_funds" + bitfinexMarginUnusedFunds = "unused_taken_funds" + bitfinexMarginClose = "funding/close" + bitfinexBalances = "balances" + bitfinexMarginInfo = "margin_infos" + bitfinexTransfer = "transfer" + bitfinexWithdrawal = "withdraw" + bitfinexActiveCredits = "credits" + + // bitfinexMaxRequests if exceeded IP address blocked 10-60 sec, JSON response + // {"error": "ERR_RATE_LIMIT"} + bitfinexMaxRequests = 90 ) +// Bitfinex is the overarching type across the bitfinex package +// Notes: Bitfinex has added a rate limit to the number of REST requests. +// Rate limit policy can vary in a range of 10 to 90 requests per minute +// depending on some factors (e.g. servers load, endpoint, etc.). type Bitfinex struct { exchange.Base WebsocketConn *websocket.Conn - WebsocketSubdChannels map[int]BitfinexWebsocketChanInfo + WebsocketSubdChannels map[int]WebsocketChanInfo } +// SetDefaults sets the basic defaults for bitfinex func (b *Bitfinex) SetDefaults() { b.Name = "Bitfinex" b.Enabled = false b.Verbose = false b.Websocket = false b.RESTPollingDelay = 10 - b.WebsocketSubdChannels = make(map[int]BitfinexWebsocketChanInfo) + b.WebsocketSubdChannels = make(map[int]WebsocketChanInfo) } +// Setup takes in the supplied exchange configuration details and sets params func (b *Bitfinex) Setup(exch config.ExchangeConfig) { if !exch.Enabled { b.SetEnabled(false) @@ -85,199 +100,266 @@ func (b *Bitfinex) Setup(exch config.ExchangeConfig) { } } -func (b *Bitfinex) GetTicker(symbol string, values url.Values) (BitfinexTicker, error) { - path := common.EncodeURLValues(BITFINEX_API_URL+BITFINEX_TICKER+symbol, values) - response := BitfinexTicker{} - err := common.SendHTTPGetRequest(path, true, &response) - if err != nil { - return response, err - } - return response, nil +// GetTicker returns ticker information +func (b *Bitfinex) GetTicker(symbol string, values url.Values) (Ticker, error) { + response := Ticker{} + path := common.EncodeURLValues(bitfinexAPIURL+bitfinexTicker+symbol, values) + + return response, common.SendHTTPGetRequest(path, true, &response) } -func (b *Bitfinex) GetStats(symbol string) ([]BitfinexStats, error) { - response := []BitfinexStats{} - err := common.SendHTTPGetRequest(BITFINEX_API_URL+BITFINEX_STATS+symbol, true, &response) - if err != nil { - return response, err - } - return response, nil +// GetStats returns various statistics about the requested pair +func (b *Bitfinex) GetStats(symbol string) ([]Stat, error) { + response := []Stat{} + path := fmt.Sprint(bitfinexAPIURL + bitfinexStats + symbol) + + return response, common.SendHTTPGetRequest(path, true, &response) } -func (b *Bitfinex) GetLendbook(symbol string, values url.Values) (BitfinexLendbook, error) { +// GetFundingBook the entire margin funding book for both bids and asks sides +// per currency string +// symbol - example "USD" +func (b *Bitfinex) GetFundingBook(symbol string) (FundingBook, error) { + response := FundingBook{} + path := fmt.Sprint(bitfinexAPIURL + bitfinexLendbook + symbol) + + return response, common.SendHTTPGetRequest(path, true, &response) +} + +// GetOrderbook retieves the entire orderbook bid and ask price on a currency +// pair +// CurrencyPair - Example "BTCUSD" +func (b *Bitfinex) GetOrderbook(currencyPair string, values url.Values) (Orderbook, error) { + response := Orderbook{} + path := common.EncodeURLValues( + bitfinexAPIURL+bitfinexOrderbook+currencyPair, + values, + ) + return response, common.SendHTTPGetRequest(path, true, &response) +} + +// GetTrades returns a list of the most recent trades for the given curencyPair +// CurrencyPair - Example "BTCUSD" +func (b *Bitfinex) GetTrades(currencyPair string, values url.Values) ([]TradeStructure, error) { + response := []TradeStructure{} + path := common.EncodeURLValues( + bitfinexAPIURL+bitfinexTrades+currencyPair, + values, + ) + return response, common.SendHTTPGetRequest(path, true, &response) +} + +// GetLendbook returns a list of the most recent funding data for the given +// currency: total amount provided and Flash Return Rate (in % by 365 days) over +// time +// Symbol - example "USD" +func (b *Bitfinex) GetLendbook(symbol string, values url.Values) (Lendbook, error) { + response := Lendbook{} if len(symbol) == 6 { symbol = symbol[:3] } - path := common.EncodeURLValues(BITFINEX_API_URL+BITFINEX_LENDBOOK+symbol, values) - response := BitfinexLendbook{} - err := common.SendHTTPGetRequest(path, true, &response) - if err != nil { - return response, err - } - return response, nil + path := common.EncodeURLValues(bitfinexAPIURL+bitfinexLendbook+symbol, values) + + return response, common.SendHTTPGetRequest(path, true, &response) } -func (b *Bitfinex) GetOrderbook(symbol string, values url.Values) (BitfinexOrderbook, error) { - path := common.EncodeURLValues(BITFINEX_API_URL+BITFINEX_ORDERBOOK+symbol, values) - response := BitfinexOrderbook{} - err := common.SendHTTPGetRequest(path, true, &response) - if err != nil { - return response, err - } - return response, nil -} - -func (b *Bitfinex) GetTrades(symbol string, values url.Values) ([]BitfinexTradeStructure, error) { - path := common.EncodeURLValues(BITFINEX_API_URL+BITFINEX_TRADES+symbol, values) - response := []BitfinexTradeStructure{} - err := common.SendHTTPGetRequest(path, true, &response) - if err != nil { - return nil, err - } - return response, nil -} - -func (b *Bitfinex) GetLends(symbol string, values url.Values) ([]BitfinexLends, error) { - path := common.EncodeURLValues(BITFINEX_API_URL+BITFINEX_LENDS+symbol, values) - response := []BitfinexLends{} - err := common.SendHTTPGetRequest(path, true, &response) - if err != nil { - return nil, err - } - return response, nil +// GetLends returns a list of the most recent funding data for the given +// currency: total amount provided and Flash Return Rate (in % by 365 days) +// over time +// Symbol - example "USD" +func (b *Bitfinex) GetLends(symbol string, values url.Values) ([]Lends, error) { + response := []Lends{} + path := common.EncodeURLValues(bitfinexAPIURL+bitfinexLends+symbol, values) + + return response, common.SendHTTPGetRequest(path, true, &response) } +// GetSymbols returns the avaliable currency pairs on the exchange func (b *Bitfinex) GetSymbols() ([]string, error) { products := []string{} - err := common.SendHTTPGetRequest(BITFINEX_API_URL+BITFINEX_SYMBOLS, true, &products) - if err != nil { - return nil, err - } - return products, nil + path := fmt.Sprint(bitfinexAPIURL + bitfinexSymbols) + + return products, common.SendHTTPGetRequest(path, true, &products) } -func (b *Bitfinex) GetSymbolsDetails() ([]BitfinexSymbolDetails, error) { - response := []BitfinexSymbolDetails{} - err := common.SendHTTPGetRequest(BITFINEX_API_URL+BITFINEX_SYMBOLS_DETAILS, true, &response) - if err != nil { - return nil, err - } - return response, nil +// GetSymbolsDetails a list of valid symbol IDs and the pair details +func (b *Bitfinex) GetSymbolsDetails() ([]SymbolDetails, error) { + response := []SymbolDetails{} + path := fmt.Sprint(bitfinexAPIURL + bitfinexSymbolsDetails) + + return response, common.SendHTTPGetRequest(path, true, &response) } -func (b *Bitfinex) GetAccountInfo() ([]BitfinexAccountInfo, error) { - response := []BitfinexAccountInfo{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_ACCOUNT_INFO, nil, &response) +// GetAccountInfo returns information about your account incl. trading fees +func (b *Bitfinex) GetAccountInfo() ([]AccountInfo, error) { + response := []AccountInfo{} - if err != nil { - return response, err - } - return response, nil + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexAccountInfo, nil, &response) } -func (b *Bitfinex) NewDeposit(method, walletName string, renew int) (BitfinexDepositResponse, error) { +// GetAccountFees - NOT YET IMPLEMENTED +func (b *Bitfinex) GetAccountFees() (AccountFees, error) { + response := AccountFees{} + + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexAccountFees, nil, &response) +} + +// GetAccountSummary returns a 30-day summary of your trading volume and return +// on margin funding +func (b *Bitfinex) GetAccountSummary() (AccountSummary, error) { + response := AccountSummary{} + + return response, + b.SendAuthenticatedHTTPRequest( + "POST", bitfinexAccountSummary, nil, &response, + ) +} + +// NewDeposit returns a new deposit address +// Method - Example methods accepted: “bitcoin”, “litecoin”, “ethereum”, +//“tethers", "ethereumc", "zcash", "monero", "iota", "bcash" +// WalletName - accepted: “trading”, “exchange”, “deposit” +// renew - Default is 0. If set to 1, will return a new unused deposit address +func (b *Bitfinex) NewDeposit(method, walletName string, renew int) (DepositResponse, error) { + response := DepositResponse{} request := make(map[string]interface{}) request["method"] = method request["wallet_name"] = walletName request["renew"] = renew - response := BitfinexDepositResponse{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_DEPOSIT, request, &response) - - if err != nil { - return response, err - } - - return response, nil + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexDeposit, request, &response) } -func (b *Bitfinex) NewOrder(Symbol string, Amount float64, Price float64, Buy bool, Type string, Hidden bool) (BitfinexOrder, error) { - request := make(map[string]interface{}) - request["symbol"] = Symbol - request["amount"] = strconv.FormatFloat(Amount, 'f', -1, 64) - request["price"] = strconv.FormatFloat(Price, 'f', -1, 64) - request["exchange"] = "bitfinex" +// GetKeyPermissions checks the permissions of the key being used to generate +// this request. +func (b *Bitfinex) GetKeyPermissions() (KeyPermissions, error) { + response := KeyPermissions{} - if Buy { + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexKeyPermissions, nil, &response) +} + +// GetMarginInfo shows your trading wallet information for margin trading +func (b *Bitfinex) GetMarginInfo() ([]MarginInfo, error) { + response := []MarginInfo{} + + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexMarginInfo, nil, &response) +} + +// GetAccountBalance returns full wallet balance information +func (b *Bitfinex) GetAccountBalance() ([]Balance, error) { + response := []Balance{} + + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexBalances, nil, &response) +} + +// WalletTransfer move available balances between your wallets +// Amount - Amount to move +// Currency - example "BTC" +// WalletFrom - example "exchange" +// WalletTo - example "deposit" +func (b *Bitfinex) WalletTransfer(amount float64, currency, walletFrom, walletTo string) ([]WalletTransfer, error) { + response := []WalletTransfer{} + request := make(map[string]interface{}) + request["amount"] = amount + request["currency"] = currency + request["walletfrom"] = walletFrom + request["walletTo"] = walletTo + + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexTransfer, request, &response) +} + +// Withdrawal requests a withdrawal from one of your wallets. +// Major Upgrade needed on this function to include all query params +func (b *Bitfinex) Withdrawal(withdrawType, wallet, address string, amount float64) ([]Withdrawal, error) { + response := []Withdrawal{} + request := make(map[string]interface{}) + request["withdrawal_type"] = withdrawType + request["walletselected"] = wallet + request["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) + request["address"] = address + + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexWithdrawal, request, &response) +} + +// NewOrder submits a new order and returns a order information +// Major Upgrade needed on this function to include all query params +func (b *Bitfinex) NewOrder(currencyPair string, amount float64, price float64, buy bool, Type string, hidden bool) (Order, error) { + response := Order{} + request := make(map[string]interface{}) + request["symbol"] = currencyPair + request["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) + request["price"] = strconv.FormatFloat(price, 'f', -1, 64) + request["exchange"] = "bitfinex" + request["type"] = Type + request["is_hidden"] = hidden + + if buy { request["side"] = "buy" } else { request["side"] = "sell" } - request["type"] = Type - //request["is_hidden"] = Hidden - - response := BitfinexOrder{} - - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_ORDER_NEW, request, &response) - - if err != nil { - return response, err - } - - return response, nil + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexOrderNew, request, &response) } -func (b *Bitfinex) NewOrderMulti(orders []BitfinexPlaceOrder) (BitfinexOrderMultiResponse, error) { +// NewOrderMulti allows several new orders at once +func (b *Bitfinex) NewOrderMulti(orders []PlaceOrder) (OrderMultiResponse, error) { + response := OrderMultiResponse{} request := make(map[string]interface{}) request["orders"] = orders - response := BitfinexOrderMultiResponse{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_ORDER_NEW_MULTI, request, &response) - - if err != nil { - return response, err - } - - return response, nil + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexOrderNewMulti, request, &response) } -func (b *Bitfinex) CancelOrder(OrderID int64) (BitfinexOrder, error) { +// CancelOrder cancels a single order +func (b *Bitfinex) CancelOrder(OrderID int64) (Order, error) { + response := Order{} request := make(map[string]interface{}) request["order_id"] = OrderID - response := BitfinexOrder{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_ORDER_CANCEL, request, &response) - - if err != nil { - return response, err - } - - return response, nil + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexOrderCancel, request, &response) } +// CancelMultipleOrders cancels multiple orders func (b *Bitfinex) CancelMultipleOrders(OrderIDs []int64) (string, error) { + response := GenericResponse{} request := make(map[string]interface{}) request["order_ids"] = OrderIDs - response := BitfinexGenericResponse{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_ORDER_CANCEL_MULTI, request, nil) - - if err != nil { - return "", err - } - - return response.Result, nil + return response.Result, + b.SendAuthenticatedHTTPRequest("POST", bitfinexOrderCancelMulti, request, nil) } +// CancelAllOrders cancels all active and open orders func (b *Bitfinex) CancelAllOrders() (string, error) { - response := BitfinexGenericResponse{} - err := b.SendAuthenticatedHTTPRequest("GET", BITFINEX_ORDER_CANCEL_ALL, nil, nil) + response := GenericResponse{} - if err != nil { - return "", err - } - - return response.Result, nil + return response.Result, + b.SendAuthenticatedHTTPRequest("GET", bitfinexOrderCancelAll, nil, nil) } -func (b *Bitfinex) ReplaceOrder(OrderID int64, Symbol string, Amount float64, Price float64, Buy bool, Type string, Hidden bool) (BitfinexOrder, error) { +// ReplaceOrder replaces an older order with a new order +func (b *Bitfinex) ReplaceOrder(OrderID int64, Symbol string, Amount float64, Price float64, Buy bool, Type string, Hidden bool) (Order, error) { + response := Order{} request := make(map[string]interface{}) request["order_id"] = OrderID request["symbol"] = Symbol request["amount"] = strconv.FormatFloat(Amount, 'f', -1, 64) request["price"] = strconv.FormatFloat(Price, 'f', -1, 64) request["exchange"] = "bitfinex" + request["type"] = Type + request["is_hidden"] = Hidden if Buy { request["side"] = "buy" @@ -285,158 +367,116 @@ func (b *Bitfinex) ReplaceOrder(OrderID int64, Symbol string, Amount float64, Pr request["side"] = "sell" } - request["type"] = Type - //request["is_hidden"] = Hidden - - response := BitfinexOrder{} - - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_ORDER_CANCEL_REPLACE, request, &response) - - if err != nil { - return response, err - } - - return response, nil + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexOrderCancelReplace, request, &response) } -func (b *Bitfinex) GetOrderStatus(OrderID int64) (BitfinexOrder, error) { +// GetOrderStatus returns order status information +func (b *Bitfinex) GetOrderStatus(OrderID int64) (Order, error) { + orderStatus := Order{} request := make(map[string]interface{}) request["order_id"] = OrderID - orderStatus := BitfinexOrder{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_ORDER_STATUS, request, &orderStatus) - - if err != nil { - return orderStatus, err - } - - return orderStatus, err + return orderStatus, + b.SendAuthenticatedHTTPRequest("POST", bitfinexOrderStatus, request, &orderStatus) } -func (b *Bitfinex) GetActiveOrders() ([]BitfinexOrder, error) { - response := []BitfinexOrder{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_ORDERS, nil, &response) +// GetActiveOrders returns all active orders and statuses +func (b *Bitfinex) GetActiveOrders() ([]Order, error) { + response := []Order{} - if err != nil { - return nil, err - } - - return response, nil + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexOrders, nil, &response) } -func (b *Bitfinex) GetActivePositions() ([]BitfinexPosition, error) { - response := []BitfinexPosition{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_POSITIONS, nil, &response) +// GetActivePositions returns an array of active positions +func (b *Bitfinex) GetActivePositions() ([]Position, error) { + response := []Position{} - if err != nil { - return nil, err - } - - return response, nil + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexPositions, nil, &response) } -func (b *Bitfinex) ClaimPosition(PositionID int) (BitfinexPosition, error) { +// ClaimPosition allows positions to be claimed +func (b *Bitfinex) ClaimPosition(PositionID int) (Position, error) { + response := Position{} request := make(map[string]interface{}) request["position_id"] = PositionID - response := BitfinexPosition{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_CLAIM_POSITION, nil, nil) - - if err != nil { - return BitfinexPosition{}, err - } - - return response, nil + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexClaimPosition, nil, nil) } -func (b *Bitfinex) GetBalanceHistory(symbol string, timeSince time.Time, timeUntil time.Time, limit int, wallet string) ([]BitfinexBalanceHistory, error) { +// GetBalanceHistory returns balance history for the account +func (b *Bitfinex) GetBalanceHistory(symbol string, timeSince, timeUntil time.Time, limit int, wallet string) ([]BalanceHistory, error) { + response := []BalanceHistory{} request := make(map[string]interface{}) request["currency"] = symbol if !timeSince.IsZero() { request["since"] = timeSince } - if !timeUntil.IsZero() { request["until"] = timeUntil } - if limit > 0 { request["limit"] = limit } - if len(wallet) > 0 { request["wallet"] = wallet } - response := []BitfinexBalanceHistory{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_HISTORY, request, &response) - - if err != nil { - return nil, err - } - - return response, nil + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexHistory, request, &response) } -func (b *Bitfinex) GetMovementHistory(symbol, method string, timeSince, timeUntil time.Time, limit int) ([]BitfinexMovementHistory, error) { +// GetMovementHistory returns an array of past deposits and withdrawels +func (b *Bitfinex) GetMovementHistory(symbol, method string, timeSince, timeUntil time.Time, limit int) ([]MovementHistory, error) { + response := []MovementHistory{} request := make(map[string]interface{}) request["currency"] = symbol if len(method) > 0 { request["method"] = method } - if !timeSince.IsZero() { request["since"] = timeSince } - if !timeUntil.IsZero() { request["until"] = timeUntil } - if limit > 0 { request["limit"] = limit } - response := []BitfinexMovementHistory{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_HISTORY_MOVEMENTS, request, &response) - - if err != nil { - return nil, err - } - - return response, nil + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexHistoryMovements, request, &response) } -func (b *Bitfinex) GetTradeHistory(symbol string, timestamp, until time.Time, limit, reverse int) ([]BitfinexTradeHistory, error) { +// GetTradeHistory returns past executed trades +func (b *Bitfinex) GetTradeHistory(currencyPair string, timestamp, until time.Time, limit, reverse int) ([]TradeHistory, error) { + response := []TradeHistory{} request := make(map[string]interface{}) - request["currency"] = symbol + request["currency"] = currencyPair request["timestamp"] = timestamp if !until.IsZero() { request["until"] = until } - if limit > 0 { request["limit"] = limit } - if reverse > 0 { request["reverse"] = reverse } - response := []BitfinexTradeHistory{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_TRADE_HISTORY, request, &response) - - if err != nil { - return nil, err - } - - return response, nil + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexTradeHistory, request, &response) } -func (b *Bitfinex) NewOffer(symbol string, amount, rate float64, period int64, direction string) int64 { +// NewOffer submits a new offer +func (b *Bitfinex) NewOffer(symbol string, amount, rate float64, period int64, direction string) (Offer, error) { + response := Offer{} request := make(map[string]interface{}) request["currency"] = symbol request["amount"] = amount @@ -444,157 +484,93 @@ func (b *Bitfinex) NewOffer(symbol string, amount, rate float64, period int64, d request["period"] = period request["direction"] = direction - type OfferResponse struct { - Offer_Id int64 - } - - response := OfferResponse{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_OFFER_NEW, request, &response) - - if err != nil { - log.Println(err) - return 0 - } - - return response.Offer_Id + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexOfferNew, request, &response) } -func (b *Bitfinex) CancelOffer(OfferID int64) (BitfinexOffer, error) { +// CancelOffer cancels offer by offerID +func (b *Bitfinex) CancelOffer(OfferID int64) (Offer, error) { + response := Offer{} request := make(map[string]interface{}) request["offer_id"] = OfferID - response := BitfinexOffer{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_OFFER_CANCEL, request, &response) - - if err != nil { - return response, err - } - - return response, nil + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexOfferCancel, request, &response) } -func (b *Bitfinex) GetOfferStatus(OfferID int64) (BitfinexOffer, error) { +// GetOfferStatus checks offer status whether it has been cancelled, execute or +// is still active +func (b *Bitfinex) GetOfferStatus(OfferID int64) (Offer, error) { + response := Offer{} request := make(map[string]interface{}) request["offer_id"] = OfferID - response := BitfinexOffer{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_ORDER_STATUS, request, &response) - - if err != nil { - return response, err - } - - return response, nil + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexOrderStatus, request, &response) } -func (b *Bitfinex) GetActiveOffers() ([]BitfinexOffer, error) { - response := []BitfinexOffer{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_OFFERS, nil, &response) +// GetActiveCredits returns all available credits +func (b *Bitfinex) GetActiveCredits() ([]Offer, error) { + response := []Offer{} - if err != nil { - return nil, err - } - - return response, nil + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexActiveCredits, nil, &response) } -func (b *Bitfinex) GetActiveMarginFunding() ([]BitfinexMarginFunds, error) { - response := []BitfinexMarginFunds{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_MARGIN_ACTIVE_FUNDS, nil, &response) +// GetActiveOffers returns all current active offers +func (b *Bitfinex) GetActiveOffers() ([]Offer, error) { + response := []Offer{} - if err != nil { - return nil, err - } - - return response, nil + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexOffers, nil, &response) } -func (b *Bitfinex) GetMarginTotalTakenFunds() ([]BitfinexMarginTotalTakenFunds, error) { - response := []BitfinexMarginTotalTakenFunds{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_MARGIN_TOTAL_FUNDS, nil, &response) +// GetActiveMarginFunding returns an array of active margin funds +func (b *Bitfinex) GetActiveMarginFunding() ([]MarginFunds, error) { + response := []MarginFunds{} - if err != nil { - return nil, err - } - - return response, nil + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexMarginActiveFunds, nil, &response) } -func (b *Bitfinex) CloseMarginFunding(SwapID int64) (BitfinexOffer, error) { +// GetUnusedMarginFunds returns an array of funding borrowed but not currently +// used +func (b *Bitfinex) GetUnusedMarginFunds() ([]MarginFunds, error) { + response := []MarginFunds{} + + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexMarginUnusedFunds, nil, &response) +} + +// GetMarginTotalTakenFunds returns an array of active funding used in a +// position +func (b *Bitfinex) GetMarginTotalTakenFunds() ([]MarginTotalTakenFunds, error) { + response := []MarginTotalTakenFunds{} + + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexMarginTotalFunds, nil, &response) +} + +// CloseMarginFunding closes an unused or used taken fund +func (b *Bitfinex) CloseMarginFunding(SwapID int64) (Offer, error) { + response := Offer{} request := make(map[string]interface{}) request["swap_id"] = SwapID - response := BitfinexOffer{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_MARGIN_CLOSE, request, &response) - - if err != nil { - return response, err - } - - return response, nil -} - -func (b *Bitfinex) GetAccountBalance() ([]BitfinexBalance, error) { - response := []BitfinexBalance{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_BALANCES, nil, &response) - if err != nil { - return nil, err - } - return response, nil -} - -func (b *Bitfinex) GetMarginInfo() ([]BitfinexMarginInfo, error) { - response := []BitfinexMarginInfo{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_MARGIN_INFO, nil, &response) - - if err != nil { - return nil, err - } - - return response, nil -} - -func (b *Bitfinex) WalletTransfer(amount float64, currency, walletFrom, walletTo string) ([]BitfinexWalletTransfer, error) { - request := make(map[string]interface{}) - request["amount"] = amount - request["currency"] = currency - request["walletfrom"] = walletFrom - request["walletTo"] = walletTo - - response := []BitfinexWalletTransfer{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_TRANSFER, request, &response) - - if err != nil { - return nil, err - } - - return response, nil -} - -func (b *Bitfinex) Withdrawal(withdrawType, wallet, address string, amount float64) ([]BitfinexWithdrawal, error) { - request := make(map[string]interface{}) - request["withdrawal_type"] = withdrawType - request["walletselected"] = wallet - request["amount"] = strconv.FormatFloat(amount, 'f', -1, 64) - request["address"] = address - - response := []BitfinexWithdrawal{} - err := b.SendAuthenticatedHTTPRequest("POST", BITFINEX_WITHDRAWAL, request, &response) - - if err != nil { - return nil, err - } - - return response, nil + return response, + b.SendAuthenticatedHTTPRequest("POST", bitfinexMarginClose, request, &response) } +// SendAuthenticatedHTTPRequest sends an autheticated http request and json +// unmarshals result to a supplied variable func (b *Bitfinex) SendAuthenticatedHTTPRequest(method, path string, params map[string]interface{}, result interface{}) error { if len(b.APIKey) == 0 { return errors.New("SendAuthenticatedHTTPRequest: Invalid API key") } + respErr := ErrorCapture{} request := make(map[string]interface{}) - request["request"] = fmt.Sprintf("/v%s/%s", BITFINEX_API_VERSION, path) + request["request"] = fmt.Sprintf("/v%s/%s", bitfinexAPIVersion, path) request["nonce"] = strconv.FormatInt(time.Now().UnixNano(), 10) if params != nil { @@ -603,39 +579,43 @@ func (b *Bitfinex) SendAuthenticatedHTTPRequest(method, path string, params map[ } } - PayloadJson, err := common.JSONEncode(request) + PayloadJSON, err := common.JSONEncode(request) if err != nil { return errors.New("SendAuthenticatedHTTPRequest: Unable to JSON request") } if b.Verbose { - log.Printf("Request JSON: %s\n", PayloadJson) + log.Printf("Request JSON: %s\n", PayloadJSON) } - PayloadBase64 := common.Base64Encode(PayloadJson) - hmac := common.GetHMAC(common.HashSHA512_384, []byte(PayloadBase64), []byte(b.APISecret)) + PayloadBase64 := common.Base64Encode(PayloadJSON) + hmac := common.GetHMAC( + common.HashSHA512_384, []byte(PayloadBase64), []byte(b.APISecret), + ) headers := make(map[string]string) headers["X-BFX-APIKEY"] = b.APIKey headers["X-BFX-PAYLOAD"] = PayloadBase64 headers["X-BFX-SIGNATURE"] = common.HexEncodeToString(hmac) - resp, err := common.SendHTTPRequest(method, BITFINEX_API_URL+path, headers, strings.NewReader("")) + resp, err := common.SendHTTPRequest( + method, bitfinexAPIURL+path, headers, strings.NewReader(""), + ) if err != nil { return err } - if strings.Contains(resp, "message") { - return errors.New("SendAuthenticatedHTTPRequest: " + resp[11:]) - } - if b.Verbose { log.Printf("Received raw: \n%s\n", resp) } - err = common.JSONDecode([]byte(resp), &result) - if err != nil { - return errors.New("SendAuthenticatedHTTPRequest: Unable to JSON Unmarshal response.") + if err = common.JSONDecode([]byte(resp), &respErr); err == nil { + if len(respErr.Message) != 0 { + return errors.New("Responded Error Issue: " + respErr.Message) + } } + if err = common.JSONDecode([]byte(resp), &result); err != nil { + return errors.New("sendAuthenticatedHTTPRequest: Unable to JSON Unmarshal response") + } return nil } diff --git a/exchanges/bitfinex/bitfinex_test.go b/exchanges/bitfinex/bitfinex_test.go index 8912c9ce..998bdd93 100644 --- a/exchanges/bitfinex/bitfinex_test.go +++ b/exchanges/bitfinex/bitfinex_test.go @@ -1,10 +1,8 @@ package bitfinex import ( - "fmt" "net/url" "reflect" - "strconv" "testing" "time" @@ -13,7 +11,11 @@ import ( "github.com/thrasher-/gocryptotrader/currency" ) -var ACCOUNT_LIVE_TEST bool = false //Supply correct API keys in testdata/configtest.dat before changing this. +// Please supply your own keys here to do better tests +const ( + testAPIKey = "" + testAPISecret = "" +) func TestSetDefaults(t *testing.T) { t.Parallel() @@ -21,18 +23,15 @@ func TestSetDefaults(t *testing.T) { setDefaults := Bitfinex{} setDefaults.SetDefaults() - if setDefaults.Name != "Bitfinex" || setDefaults.Enabled != false || setDefaults.Verbose != false || - setDefaults.Websocket != false || setDefaults.RESTPollingDelay != 10 { + if setDefaults.Name != "Bitfinex" || setDefaults.Enabled != false || + setDefaults.Verbose != false || setDefaults.Websocket != false || + setDefaults.RESTPollingDelay != 10 { t.Error("Test Failed - Bitfinex SetDefaults values not set correctly") } - if reflect.TypeOf(setDefaults.WebsocketSubdChannels).String() != "map[int]bitfinex.BitfinexWebsocketChanInfo" { - t.Error("Test Failed - Bitfinex SetDefaults value: MAP not set correctly") - } } func TestSetup(t *testing.T) { t.Parallel() - testConfig := config.ExchangeConfig{ Enabled: true, AuthenticatedAPISupport: true, @@ -52,386 +51,84 @@ func TestSetup(t *testing.T) { setup.APISecret != "cutlets" || setup.RESTPollingDelay != time.Duration(10) || !setup.Verbose || !setup.Websocket || len(setup.BaseCurrencies) < 1 || len(setup.AvailablePairs) < 1 || len(setup.EnabledPairs) < 1 { - t.Error("Test Failed - Bitfinex Setup values not set correctly") } + testConfig.Enabled = false + setup.Setup(testConfig) } -//Live Testing func TestGetTicker(t *testing.T) { - t.Parallel() bitfinex := Bitfinex{} - - response, err := bitfinex.GetTicker("BTCUSD", url.Values{}) + _, err := bitfinex.GetTicker("BTCUSD", url.Values{}) if err != nil { t.Error("BitfinexGetTicker init error: ", err) } - if reflect.ValueOf(response).NumField() != 8 { - t.Error("BitfinexGetTicker struct change/or updated") - } - if reflect.TypeOf(response.Timestamp).String() != "string" { - t.Error("Bitfinex ticker.Timestamp value is not a string variable") - } - if reflect.TypeOf(response.Ask).String() != "float64" { - t.Error("Bitfinex ticker.Ask value is not a float64 variable") - } - if reflect.TypeOf(response.Bid).String() != "float64" { - t.Error("Bitfinex ticker.Bid value is not a float64 variable") - } - if reflect.TypeOf(response.High).String() != "float64" { - t.Error("Bitfinex ticker.High value is not a float64 variable") - } - if reflect.TypeOf(response.Last).String() != "float64" { - t.Error("Bitfinex ticker.Last value is not a float64 variable") - } - if reflect.TypeOf(response.Low).String() != "float64" { - t.Error("Bitfinex ticker.Low value is not a float64 variable") - } - if reflect.TypeOf(response.Mid).String() != "float64" { - t.Error("Bitfinex ticker.Mid value is not a float64 variable") - } - if reflect.TypeOf(response.Volume).String() != "float64" { - t.Error("Bitfinex ticker.Volume value is not a float64 variable") - } - responseTimestamp, err := strconv.ParseFloat(response.Timestamp, 64) - if err != nil { - t.Error("ticker.Timestamp value cannot be converted to a float64") - } - if responseTimestamp <= 0 { - t.Error("ticker.Timestamp value is negative or 0") - } - if response.Ask < 0 { - t.Error("ticker.Ask value is negative") - } - if response.Bid < 0 { - t.Error("ticker.Bid value is negative") - } - if response.High < 0 { - t.Error("ticker.High value is negative") - } - if response.Last < 0 { - t.Error("ticker.Last value is negative") - } - if response.Low < 0 { - t.Error("ticker.Low value is negative") - } - if response.Mid < 0 { - t.Error("ticker.Mid value is negative") - } - if response.Volume < 0 { - t.Error("ticker.ask value is negative") + _, err = bitfinex.GetTicker("wigwham", url.Values{}) + if err == nil { + t.Error("Test Failed - GetTicker() error") } } -//Live Testing func TestGetStats(t *testing.T) { - t.Parallel() BitfinexGetStatsTest := Bitfinex{} - - response, err := BitfinexGetStatsTest.GetStats("BTCUSD") + _, err := BitfinexGetStatsTest.GetStats("BTCUSD") if err != nil { t.Error("BitfinexGetStatsTest init error: ", err) } - if reflect.ValueOf(response[0]).NumField() != 2 { - t.Error("BitfinexGetTicker []struct change/or updated") - } - if reflect.TypeOf(response[0].Period).String() != "int64" { - t.Error("Bitfinex Getstats.Period is not an int64") - } - if reflect.TypeOf(response[0].Volume).String() != "float64" { - t.Error("Bitfiniex Getstats.Volume is not a float64") - } - for _, explicitResponse := range response { - if explicitResponse.Period <= 0 { - t.Error("response.Period value is negative or zero") - } - if explicitResponse.Volume < 0 { - t.Error("response.Volume value is negative") - } + _, err = BitfinexGetStatsTest.GetStats("wigwham") + if err == nil { + t.Error("Test Failed - GetStats() error") } } -//Live Testing -func TestGetLendbook(t *testing.T) { - t.Parallel() - BitfinexGetLendbook := Bitfinex{} +func TestGetFundingBook(t *testing.T) { + b := Bitfinex{} + _, err := b.GetFundingBook("USD") + if err != nil { + t.Error("Testing Failed - GetFundingBook() error") + } + _, err = b.GetFundingBook("wigwham") + if err == nil { + t.Error("Testing Failed - GetFundingBook() error") + } +} - response, err := BitfinexGetLendbook.GetLendbook("BTCUSD", url.Values{}) +func TestGetLendbook(t *testing.T) { + BitfinexGetLendbook := Bitfinex{} + _, err := BitfinexGetLendbook.GetLendbook("BTCUSD", url.Values{}) if err != nil { t.Error("BitfinexGetLendbook init error: ", err) } - if reflect.ValueOf(response).NumField() != 2 { - t.Error("BitfinexGetLendbook struct change/or updated") - } - if reflect.ValueOf(response.Asks[0]).NumField() != 5 { - t.Error("BitfinexGetLendbook GetLendbook.Asks []struct change/or updated") - } - if reflect.TypeOf(response.Asks[0].Amount).String() != "float64" { - t.Error("Bitfinex GetLendbook.Asks.Amount is not a float64") - } - if reflect.TypeOf(response.Asks[0].FlashReturnRate).String() != "string" { - t.Error("Bitfinex GetLendbook.Asks.FlashReturnRate is not a string") - } - if reflect.TypeOf(response.Asks[0].Period).String() != "int" { - t.Error("Bitfinex GetLendbook.Asks.Period is not an int") - } - if reflect.TypeOf(response.Asks[0].Rate).String() != "float64" { - t.Error("Bitfinex GetLendbook.Asks.Rate is not a float64") - } - if reflect.ValueOf(response.Bids[0]).NumField() != 5 { - t.Error("BitfinexGetLendbook GetLendbook.Bids []struct change/or updated") - } - if reflect.TypeOf(response.Bids[0].Amount).String() != "float64" { - t.Error("Bitfinex GetLendbook.Bids.Amount is not a float64") - } - if reflect.TypeOf(response.Bids[0].FlashReturnRate).String() != "string" { - t.Error("Bitfinex GetLendbook.Bids.FlashReturnRate is not a string") - } - if reflect.TypeOf(response.Bids[0].Period).String() != "int" { - t.Error("Bitfinex GetLendbook.Bids.Period is not an int") - } - if reflect.TypeOf(response.Bids[0].Rate).String() != "float64" { - t.Error("Bitfinex GetLendbook.Bids.Rate is not a float64") - } - - for _, asks := range response.Asks { - responseTimestamp, err := strconv.ParseFloat(asks.Timestamp, 64) - if err != nil { - t.Error("Could not convert Bitfinex GetLendbook.Asks.Timestamp into float64") - } - if asks.Amount <= 0 { - t.Error("Bitfinex GetLendbook.Asks.Amount is negative or 0") - } - if asks.FlashReturnRate != "No" && asks.FlashReturnRate != "Yes" { - t.Error("Bitfinex GetLendbook.Bids.FlashReturnRate incorrect string") - } - if asks.Period <= 0 { - t.Error("Bitfinex GetLendbook.Asks.Period is negative or 0") - } - if asks.Rate <= 0 { - t.Error("Bitfinex GetLendbook.Asks.Rate is negative or 0") - } - if responseTimestamp <= 0 { - t.Error("Bitfinex GetLendbook.Asks.Timestamp is negative or 0") - } - } - - for _, bids := range response.Bids { - responseTimetamp, err := strconv.ParseFloat(bids.Timestamp, 64) - if err != nil { - t.Error("Could not convert Bitfinex GetLendbook.Bids.Timestamp into float64") - } - if bids.Amount <= 0 { - t.Error("Bitfinex GetLendbook.Bids.Amount is negative or 0") - } - if bids.FlashReturnRate == "no" || bids.FlashReturnRate == "yes" { - t.Error("Bitfinex GetLendbook.Bids.FlashReturnRate incorrect string") - } - if bids.Period <= 0 { - t.Error("Bitfinex GetLendbook.Bids.Period is negative or 0") - } - if bids.Rate <= 0 { - t.Error("Bitfinex GetLendbook.Bids.Rate is negative or 0") - } - if responseTimetamp <= 0 { - t.Error("Bitfinex GetLendbook.Bids.Timestamp is negative or 0") - } - } } -//Live Testing func TestGetOrderbook(t *testing.T) { - t.Parallel() BitfinexGetOrderbook := Bitfinex{} - - orderBook, err := BitfinexGetOrderbook.GetOrderbook("BTCUSD", url.Values{}) + _, err := BitfinexGetOrderbook.GetOrderbook("BTCUSD", url.Values{}) if err != nil { t.Error("BitfinexGetOrderbook init error: ", err) } - if reflect.ValueOf(orderBook).NumField() != 2 { - t.Error("BitfinexGetOrderbook struct change/or updated") - } - if reflect.ValueOf(orderBook.Asks[0]).NumField() != 3 { - t.Error("BitfinexGetOrderbook []struct change/or updated") - } - if reflect.ValueOf(orderBook.Bids[0]).NumField() != 3 { - t.Error("BitfinexGetOrderbook []struct change/or updated") - } - if reflect.TypeOf(orderBook.Asks[0].Amount).String() != "string" { - t.Error("Bitfinex GetOrderbook.Bids.Amount is not a string") - } - if reflect.TypeOf(orderBook.Asks[0].Price).String() != "string" { - t.Error("Bitfinex GetOrderbook.Bids.Amount is not a string") - } - if reflect.TypeOf(orderBook.Asks[0].Timestamp).String() != "string" { - t.Error("Bitfinex GetOrderbook.Bids.Amount is not a string") - } - if reflect.TypeOf(orderBook.Bids[0].Amount).String() != "string" { - t.Error("Bitfinex GetOrderbook.Bids.Amount is not a string") - } - if reflect.TypeOf(orderBook.Bids[0].Price).String() != "string" { - t.Error("Bitfinex GetOrderbook.Bids.Amount is not a string") - } - if reflect.TypeOf(orderBook.Bids[0].Timestamp).String() != "string" { - t.Error("Bitfinex GetOrderbook.Bids.Amount is not a string") - } - - for _, asks := range orderBook.Asks { - amount, err := strconv.ParseFloat(asks.Amount, 64) - if err != nil { - t.Error("Cannot convert Bitfinex Orderbook.Asks.Amount into a float64") - } - if amount < 0 { - t.Error("Bitfinex Orderbook.Asks.Amount is negative") - } - price, err2 := strconv.ParseFloat(asks.Price, 64) - if err2 != nil { - t.Error("Cannot convert Bitfinex Orderbook.Asks.Price into a float64") - } - if price < 0 { - t.Error("Bitfinex Orderbook.Asks.Price is negative") - } - timestamp, err3 := strconv.ParseFloat(asks.Timestamp, 64) - if err3 != nil { - t.Error("Cannot convert Bitfinex Orderbook.Asks.timestamp into a float64") - } - if timestamp <= 0 { - t.Error("Bitfinex Orderbook.Asks.Amount is negative or 0") - } - } - - for _, bids := range orderBook.Bids { - amount, err := strconv.ParseFloat(bids.Amount, 64) - if err != nil { - t.Error("Cannot convert Bitfinex Orderbook.bids.Amount into a float64") - } - if amount < 0 { - t.Error("Bitfinex Orderbook.bids.Amount is negative") - } - price, err2 := strconv.ParseFloat(bids.Price, 64) - if err2 != nil { - t.Error("Cannot convert Bitfinex Orderbook.bids.Price into a float64") - } - if price < 0 { - t.Error("Bitfinex Orderbook.bids.Price is negative") - } - timestamp, err3 := strconv.ParseFloat(bids.Timestamp, 64) - if err3 != nil { - t.Error("Cannot convert Bitfinex Orderbook.bids.timestamp into a float64") - } - if timestamp <= 0 { - t.Error("Bitfinex Orderbook.bids.Amount is negative or 0") - } - } } -//Live Testing func TestGetTrades(t *testing.T) { - t.Parallel() BitfinexGetTrades := Bitfinex{} - - trades, err := BitfinexGetTrades.GetTrades("BTCUSD", url.Values{}) + _, err := BitfinexGetTrades.GetTrades("BTCUSD", url.Values{}) if err != nil { t.Error("BitfinexGetTrades init error: ", err) } - if reflect.ValueOf(trades[0]).NumField() != 6 { - t.Error("BitfinexGetTrades struct change/or updated") - } - if reflect.TypeOf(trades[0].Amount).String() != "string" { - t.Error("Bitfinex GetGetTrades.Amount is not a string") - } - if reflect.TypeOf(trades[0].Exchange).String() != "string" { - t.Error("Bitfinex GetGetTrades.Exchange is not a string") - } - if reflect.TypeOf(trades[0].Price).String() != "string" { - t.Error("Bitfinex GetGetTrades.Price is not a string") - } - if reflect.TypeOf(trades[0].Tid).String() != "int64" { - t.Error("Bitfinex GetGetTrades.Tid is not a int64") - } - if reflect.TypeOf(trades[0].Timestamp).String() != "int64" { - t.Error("Bitfinex GetGetTrades.Timestamp is not a int64") - } - if reflect.TypeOf(trades[0].Type).String() != "string" { - t.Error("Bitfinex GetGetTrades.Type is not a string") - } - - for _, explicitTrades := range trades { - amount, err := strconv.ParseFloat(explicitTrades.Amount, 64) - if err != nil { - t.Error("Cannot convert Bitfinex GetTrades.Amount into a float64") - } - if amount <= 0 { - t.Error("Bitfinex GetTrades.Amount is negative or 0") - } - if explicitTrades.Exchange != "bitfinex" { - t.Error("Bitfinex GetTrades.Exchange incorrect name") - } - price, err2 := strconv.ParseFloat(explicitTrades.Price, 64) - if err2 != nil { - t.Error("Cannot convert Bitfinex GetTrades.Price into a float64") - } - if price <= 0 { - t.Error("Bitfinex GetTrades.Price is negative or 0") - } - if explicitTrades.Tid <= 0 { - t.Error("Bitfinex GetTrades.Tid is negative or 0") - } - if explicitTrades.Timestamp <= 0 { - t.Error("Bitfinex GetTrades.Timestamp is negative or 0") - } - if explicitTrades.Type != "buy" && explicitTrades.Type != "sell" { - t.Error("Bitfinex GetTrades.Type is wrong") - } - } } -//Live Testing func TestGetLends(t *testing.T) { - t.Parallel() BitfinexGetLends := Bitfinex{} - lends, err := BitfinexGetLends.GetLends("BTC", url.Values{}) + _, err := BitfinexGetLends.GetLends("BTC", url.Values{}) if err != nil { t.Error("BitfinexGetLends init error: ", err) } - if reflect.ValueOf(lends[0]).NumField() != 4 { - t.Error("BitfinexGetLends struct change/or updated") - } - if reflect.TypeOf(lends[0].AmountLent).String() != "float64" { - t.Error("Bitfinex GetGetLends.AmountLent is not a float64") - } - if reflect.TypeOf(lends[0].AmountUsed).String() != "float64" { - t.Error("Bitfinex GetGetLends.AmountUsed is not a float64") - } - if reflect.TypeOf(lends[0].Rate).String() != "float64" { - t.Error("Bitfinex GetGetLends.Rate is not a float64") - } - if reflect.TypeOf(lends[0].Timestamp).String() != "int64" { - t.Error("Bitfinex GetGetLends.Timestamp is not a int64") - } - - for _, explicitLends := range lends { - if explicitLends.AmountLent <= 0 { - t.Error("Bitfinex GetLends.AmountLent is negative or 0") - } - if explicitLends.AmountUsed <= 0 { - t.Error("Bitfinex GetLends.AmountUsed is negative or 0") - } - if explicitLends.Rate <= 0 { - t.Error("Bitfinex GetLends.Rate is negative or 0") - } - if explicitLends.Timestamp <= 0 { - t.Error("Bitfinex GetLends.Timestamp is negative or 0") - } - } } -//Live Testing func TestGetSymbols(t *testing.T) { - t.Parallel() BitfinexGetSymbols := Bitfinex{} symbols, err := BitfinexGetSymbols.GetSymbols() @@ -479,1087 +176,361 @@ func TestGetSymbols(t *testing.T) { } } -//Live Testing func TestGetSymbolsDetails(t *testing.T) { - t.Parallel() BitfinexGetSymbolsDetails := Bitfinex{} - - symbolDetails, err := BitfinexGetSymbolsDetails.GetSymbolsDetails() + _, err := BitfinexGetSymbolsDetails.GetSymbolsDetails() if err != nil { t.Error("BitfinexGetSymbolsDetails init error: ", err) } - if reflect.ValueOf(symbolDetails[0]).NumField() != 7 { - t.Error("BitfinexGetSymbolsDetails struct change/or updated") - } - if reflect.TypeOf(symbolDetails[0].Expiration).String() != "string" { - t.Error("Bitfinex GetSymbolsDetails.Expiration is not a string") - } - if reflect.TypeOf(symbolDetails[0].InitialMargin).String() != "float64" { - t.Error("Bitfinex GetSymbolsDetails.InitialMargin is not a float64") - } - if reflect.TypeOf(symbolDetails[0].MaximumOrderSize).String() != "float64" { - t.Error("Bitfinex GetSymbolsDetails.MaximumOrderSize is not a float64") - } - if reflect.TypeOf(symbolDetails[0].MinimumMargin).String() != "float64" { - t.Error("Bitfinex GetSymbolsDetails.MinimumMargin is not a float64") - } - if reflect.TypeOf(symbolDetails[0].MinimumOrderSize).String() != "float64" { - t.Error("Bitfinex GetSymbolsDetails.MinimumOrderSize is not a float64") - } - if reflect.TypeOf(symbolDetails[0].Pair).String() != "string" { - t.Error("Bitfinex GetSymbolsDetails.Pair is not a string") - } - if reflect.TypeOf(symbolDetails[0].PricePrecision).String() != "int" { - t.Error("Bitfinex GetSymbolsDetails.PricePrecision is not a int") - } - - for _, explicitDetails := range symbolDetails { - if explicitDetails.Expiration != "NA" { - expiration, err := strconv.ParseFloat(explicitDetails.Expiration, 64) - if err != nil { - t.Error("Cannot convert Bitfinex GetSymbolsDetails.Expiration into a float64") - } - if expiration < 0 { - t.Error("Bitfinex GetSymbolsDetails.Expiration is negative") - } - } - if explicitDetails.InitialMargin <= 0 { - t.Error("Bitfinex GetSymbolsDetails.InitialMargin is negative or 0") - } - if explicitDetails.MaximumOrderSize <= 0 { - t.Error("Bitfinex GetSymbolsDetails.MaximumOrderSize is negative or 0") - } - if explicitDetails.MinimumMargin <= 0 { - t.Error("Bitfinex GetSymbolsDetails.MinimumMargin is negative or 0") - } - if explicitDetails.MinimumOrderSize <= 0 { - t.Error("Bitfinex GetSymbolsDetails.MinimumOrderSize is negative or 0") - } - if len(explicitDetails.Pair) != 6 { - t.Error("Bitfinex GetSymbolsDetails.Pair incorrect length") - } - if explicitDetails.PricePrecision <= 0 { - t.Error("Bitfinex GetSymbolsDetails.PricePrecision is negative or 0") - } - } } -//Hybrid Testing func TestGetAccountInfo(t *testing.T) { - expectedCryptoCurrencies := []string{ - "BTC", - "LTC", - "ETH", - "ETC", - "ZEC", - "XMR", - "DSH", - } + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret - if ACCOUNT_LIVE_TEST { //Live Test - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - New Order init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - New Order init error: %s\n", err) - } - - BitfinexGetAccountInfo := Bitfinex{} - BitfinexGetAccountInfo.Setup(exchangeConfig) - - response, err := BitfinexGetAccountInfo.GetAccountInfo() - if err != nil { - newErrString := fmt.Sprintf("TestGetAccountInfo: \nError: %s\n", err) - t.Error(newErrString) - response = append(response, BitfinexAccountInfo{}) - } - - if reflect.ValueOf(response[0]).NumField() != 3 { - t.Error("BitfinexGetAccountInfo struct change/or updated") - } - if reflect.TypeOf(response[0].MakerFees).String() != "string" { - t.Error("Bitfinex GetAccountInfo.MakerFees is not a string") - } - if reflect.TypeOf(response[0].TakerFees).String() != "string" { - t.Error("Bitfinex GetAccountInfo.TakerFees is not a string") - } - - if len(expectedCryptoCurrencies) == len(response[0].Fees) { - if !common.DataContains(expectedCryptoCurrencies, response[0].Fees[0].Pairs) { - t.Error("Bitfinex GetAccountInfo currency mismatch") - } - } else if len(expectedCryptoCurrencies) > len(response[0].Fees) { - t.Error("BitfinexGetSymbols currency mismatch, Expected Currencies > Exchange Currencies") - } else { - t.Error("BitfinexGetSymbols currency mismatch, Expected Currencies < Exchange Currencies") - } - - if len(response[0].Fees) != 7 { - t.Error("Bitfinex GetAccountInfo.Fees incorrect length") - } - - for _, explicitAI := range response { - makerFees, err := strconv.ParseFloat(explicitAI.MakerFees, 64) - if err != nil { - t.Error("Cannot convert Bitfinex GetAccountInfo.MakerFees into float64") - } - if makerFees < 0 { - t.Error("Bitfinex GetAccountInfo.MakerFees is negative") - } - - takerFees, err := strconv.ParseFloat(explicitAI.TakerFees, 64) - if err != nil { - t.Error("Cannot convert Bitfinex GetAccountInfo.TakerFees into float64") - } - if takerFees < 0 { - t.Error("Bitfinex GetAccountInfo.TakerFees is negative") - } - - for _, fees := range explicitAI.Fees { - MakerFees, err := strconv.ParseFloat(fees.MakerFees, 64) - if err != nil { - t.Error("Cannot convert Bitfinex GetAccountInfo.Fees.MakerFees into float64") - } - if MakerFees < 0 { - t.Error("Bitfinex GetAccountInfo.Fees.MakerFees is negative") - } - TakerFees, err := strconv.ParseFloat(fees.TakerFees, 64) - if err != nil { - t.Error("Cannot convert Bitfinex GetAccountInfo.Fees.TakerFees into float64") - } - if TakerFees < 0 { - t.Error("Bitfinex GetAccountInfo.Fees.TakerFees is negative") - } - } - } - - } else { //Non-Live Test - type Fees struct { - Pairs string `json:"pairs"` - MakerFees string `json:"maker_fees"` - TakerFees string `json:"taker_fees"` - } - accountInfoNonLive := [1]BitfinexAccountInfo{} - accountInfoNonLive[0].MakerFees = "0.1" - accountInfoNonLive[0].TakerFees = "0.2" - nonLiveFees := Fees{} - nonLiveFees.MakerFees = "0.1" - nonLiveFees.Pairs = "BTC" - nonLiveFees.TakerFees = "0.2" - accountInfoNonLive[0].Fees = append(accountInfoNonLive[0].Fees, nonLiveFees) - - if reflect.ValueOf(accountInfoNonLive[0]).NumField() != 3 { - t.Error("BitfinexGetAccountInfo struct change/or updated") - } - if reflect.TypeOf(accountInfoNonLive[0].MakerFees).String() != "string" { - t.Error("Bitfinex GetAccountInfo.MakerFees is not a string") - } - if reflect.TypeOf(accountInfoNonLive[0].TakerFees).String() != "string" { - t.Error("Bitfinex GetAccountInfo.TakerFees is not a string") - } - - for _, explicitAI := range accountInfoNonLive { - makerFees, err := strconv.ParseFloat(explicitAI.MakerFees, 64) - if err != nil { - t.Error("Cannot convert Bitfinex GetAccountInfo.MakerFees into float64") - } - if makerFees < 0 { - t.Error("Bitfinex GetAccountInfo.MakerFees is negative") - } - - takerFees, err := strconv.ParseFloat(explicitAI.TakerFees, 64) - if err != nil { - t.Error("Cannot convert Bitfinex GetAccountInfo.TakerFees into float64") - } - if takerFees < 0 { - t.Error("Bitfinex GetAccountInfo.TakerFees is negative") - } - if len(explicitAI.Fees) != 1 { - t.Error("Bitfinex GetAccountInfo.Fees.Pairs incorrect length") - } - - for _, fees := range explicitAI.Fees { - MakerFees, err := strconv.ParseFloat(fees.MakerFees, 64) - if err != nil { - t.Error("Cannot convert Bitfinex GetAccountInfo.Fees.MakerFees into float64") - } - if MakerFees < 0 { - t.Error("Bitfinex GetAccountInfo.Fees.MakerFees is negative") - } - TakerFees, err := strconv.ParseFloat(fees.TakerFees, 64) - if err != nil { - t.Error("Cannot convert Bitfinex GetAccountInfo.Fees.TakerFees into float64") - } - if TakerFees < 0 { - t.Error("Bitfinex GetAccountInfo.Fees.TakerFees is negative") - } - } - } + _, err := b.GetAccountInfo() + if err == nil { + t.Error("Test Failed - GetAccountInfo error") + } +} + +func TestGetAccountFees(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.GetAccountFees() + if err == nil { + t.Error("Test Failed - GetAccountFees error") + } +} + +func TestGetAccountSummary(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.GetAccountSummary() + if err == nil { + t.Error("Test Failed - GetAccountSummary() error:") } } -//Hybrid Testing func TestNewDeposit(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret - applicableMethods := []string{ - "bitcoin_address", - "litecoin_address", - "ethereum_address", - "mastercoin_address", //Requires verified account - "ethereumc_address", - "zcash_address", - "monero_address", - } - expectedCryptoCurrencies := []string{ - "BTC", - "LTC", - "ETH", - "ETC", - "ZEC", - "XMR", - "DSH", - } - - if ACCOUNT_LIVE_TEST { //Live Test - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - New Order init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - New Order init error: %s\n", err) - } - - BitfinexNewDeposit := Bitfinex{} - BitfinexNewDeposit.Setup(exchangeConfig) - - liveResponse, err := BitfinexNewDeposit.NewDeposit("bitcoin", "deposit", 0) - if err != nil { - t.Error("BitfinexNewDeposit init error: ", err) - } - - if reflect.ValueOf(liveResponse).NumField() != 4 { - t.Error("BitfinexNewDeposit struct change/or updated") - } - if reflect.TypeOf(liveResponse.Address).String() != "string" { - t.Error("Bitfinex NewDeposit.Address is not a string") - } - if reflect.TypeOf(liveResponse.Currency).String() != "string" { - t.Error("Bitfinex NewDeposit.Currency is not a string") - } - if reflect.TypeOf(liveResponse.Method).String() != "string" { - t.Error("Bitfinex NewDeposit.Method) is not a string") - } - if reflect.TypeOf(liveResponse.Result).String() != "string" { - t.Error("Bitfinex NewDeposit.Result is not a string") - } - if len(liveResponse.Address) != 34 { - t.Error("Bitfinex NewDeposit.Address is incorrect") - } - if !common.DataContains(expectedCryptoCurrencies, liveResponse.Currency) { - t.Error("Bitfinex NewDeposit.Currency currency mismatch" + liveResponse.Currency) - } - if !common.DataContains(applicableMethods, liveResponse.Method) { - t.Error("Bitfinex NewDeposit.Method method mismatch") - } - if liveResponse.Result != "" && liveResponse.Result != "success" { - t.Error("Bitfinex NewDeposit.Result " + liveResponse.Result) - } - - } else { //Non-Live Test - nonLiveResponse := BitfinexDepositResponse{} - nonLiveResponse.Address = "1DPUgBaZoKbL38BEC1A3exPKCDZjQpnBa1" - nonLiveResponse.Currency = "BTC" - nonLiveResponse.Method = "bitcoin_address" - nonLiveResponse.Result = "" - - if reflect.ValueOf(nonLiveResponse).NumField() != 4 { - t.Error("BitfinexNewDeposit struct change/or updated") - } - if reflect.TypeOf(nonLiveResponse.Address).String() != "string" { - t.Error("Bitfinex NewDeposit.Address is not a string") - } - if reflect.TypeOf(nonLiveResponse.Currency).String() != "string" { - t.Error("Bitfinex NewDeposit.Currency is not a string") - } - if reflect.TypeOf(nonLiveResponse.Method).String() != "string" { - t.Error("Bitfinex NewDeposit.Method) is not a string") - } - if reflect.TypeOf(nonLiveResponse.Result).String() != "string" { - t.Error("Bitfinex NewDeposit.Result is not a string") - } - - if len(nonLiveResponse.Address) != 34 { - t.Error("Bitfinex NewDeposit.Address is incorrect") - } - if !common.DataContains(expectedCryptoCurrencies, nonLiveResponse.Currency) { - t.Error("Bitfinex NewDeposit.Currency currency mismatch") - } - if !common.DataContains(applicableMethods, nonLiveResponse.Method) { - t.Error("Bitfinex NewDeposit.Method method mismatch") - } - if nonLiveResponse.Result != "" && nonLiveResponse.Result != "success" { - t.Error("Bitfinex NewDeposit.Result " + nonLiveResponse.Result) - } + _, err := b.NewDeposit("blabla", "testwallet", 1) + if err == nil { + t.Error("Test Failed - NewDeposit() error:", err) } } -//Non-Live Testing -func TestNewOrder(t *testing.T) { - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - New Order init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - New Order init error: %s\n", err) - } - - BitfinexNewOrder := Bitfinex{} - BitfinexNewOrder.Setup(exchangeConfig) - - if ACCOUNT_LIVE_TEST { - response, errLive := BitfinexNewOrder.NewOrder("BTCUSD", 0, 0, true, "test", false) - if errLive == nil { - t.Errorf("Test Failed - BitfinexNewOrder - Error: Expected Error Status: %t", response.IsLive) - } - } - - nonLiveResponse := BitfinexOrder{} - nonLiveResponse.AverageExecutionPrice = 0.0 - nonLiveResponse.Exchange = "bitfinex" - nonLiveResponse.ExecutedAmount = 0.0 - nonLiveResponse.ID = 448364249 - nonLiveResponse.IsCancelled = false - nonLiveResponse.IsHidden = false - nonLiveResponse.IsLive = true - nonLiveResponse.OrderID = 448364249 - nonLiveResponse.OriginalAmount = 0.01 - nonLiveResponse.Price = 0.01 - nonLiveResponse.RemainingAmount = 0.01 - nonLiveResponse.Side = "buy" - nonLiveResponse.Symbol = "btcusd" - nonLiveResponse.Timestamp = "1444272165.252370982" - nonLiveResponse.Type = "exchange limit" - nonLiveResponse.WasForced = false - - if reflect.ValueOf(nonLiveResponse).NumField() != 16 { - t.Error("BitfinexNewDeposit struct change/or updated") - } - if reflect.TypeOf(nonLiveResponse.AverageExecutionPrice).String() != "float64" { - t.Error("Bitfinex NewOrder.AverageExecutionPrice is not a float64") - } - if reflect.TypeOf(nonLiveResponse.Exchange).String() != "string" { - t.Error("Bitfinex NewOrder.Exchange is not a string") - } - if reflect.TypeOf(nonLiveResponse.ExecutedAmount).String() != "float64" { - t.Error("Bitfinex NewOrder.ExecutedAmount is not a float64") - } - if reflect.TypeOf(nonLiveResponse.OrderID).String() != "int64" { - t.Error("Bitfinex NewOrder.ID is not an int64") - } - if reflect.TypeOf(nonLiveResponse.IsCancelled).String() != "bool" { - t.Error("Bitfinex NewOrder.IsCancelled is not a bool") - } - if reflect.TypeOf(nonLiveResponse.IsHidden).String() != "bool" { - t.Error("Bitfinex NewOrder.IsHidden is not a bool") - } - if reflect.TypeOf(nonLiveResponse.IsLive).String() != "bool" { - t.Error("Bitfinex NewOrder.IsLive is not a bool") - } - if reflect.TypeOf(nonLiveResponse.OrderID).String() != "int64" { - t.Error("Bitfinex NewOrder.OrderID is not an int64") - } - if reflect.TypeOf(nonLiveResponse.OriginalAmount).String() != "float64" { - t.Error("Bitfinex NewOrder.OriginalAmount is not a float64") - } - if reflect.TypeOf(nonLiveResponse.Price).String() != "float64" { - t.Error("Bitfinex NewOrder.Price is not a float64") - } - if reflect.TypeOf(nonLiveResponse.RemainingAmount).String() != "float64" { - t.Error("Bitfinex NewOrder.RemainingAmount is not a float64") - } - if reflect.TypeOf(nonLiveResponse.Side).String() != "string" { - t.Error("Bitfinex NewOrder.Side is not a string") - } - if reflect.TypeOf(nonLiveResponse.Symbol).String() != "string" { - t.Error("Bitfinex NewOrder.Address is not a string") - } - if reflect.TypeOf(nonLiveResponse.Timestamp).String() != "string" { - t.Error("Bitfinex NewOrder.Timestamp is not a string") - } - if reflect.TypeOf(nonLiveResponse.Type).String() != "string" { - t.Error("Bitfinex NewOrder.Type is not a string") - } - if reflect.TypeOf(nonLiveResponse.WasForced).String() != "bool" { - t.Error("Bitfinex NewOrder.WasForced is not a bool") - } - - if nonLiveResponse.AverageExecutionPrice < 0 { - t.Error("Bitfinex NewOrder.AverageExecutionPrice is negative") - } - if nonLiveResponse.Exchange != "bitfinex" { - t.Error("Bitfinex NewOrder.AverageExecutionPrice wrong exchange name") - } - if nonLiveResponse.ExecutedAmount < 0 { - t.Error("Bitfinex NewOrder.ExecutedAmount is negative or 0") - } - if nonLiveResponse.ID <= 0 { - t.Error("Bitfinex NewOrder.ID is negative or 0") - } - if nonLiveResponse.OrderID <= 0 { - t.Error("Bitfinex NewOrder.OrderID is negative or 0") - } - if nonLiveResponse.OriginalAmount <= 0 { - t.Error("Bitfinex NewOrder.OriginalAmount is negative or 0") - } - if nonLiveResponse.Price <= 0 { - t.Error("Bitfinex NewOrder.Price is negative or 0") - } - if nonLiveResponse.RemainingAmount <= 0 { - t.Error("Bitfinex NewOrder.RemainingAmount is negative or 0") - } - nonLiveTimestamp, err := strconv.ParseFloat(nonLiveResponse.Timestamp, 64) - if err != nil { - t.Error("Bitfinex NewOrder.Timestamp cannot convert to float64") - } - if nonLiveTimestamp <= 0 { - t.Error("Bitfinex NewOrder.Timestamp is negative or 0") - } -} - -//Non-Live Testing -func TestNewOrderMulti(t *testing.T) { - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - New Order init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - New Order init error: %s\n", err) - } - - BitfinexNewOrderMulti := Bitfinex{} - BitfinexNewOrderMulti.Setup(exchangeConfig) - - var orders []BitfinexPlaceOrder - order := BitfinexPlaceOrder{} - order.Amount = 0.0 - order.Exchange = "bitfinex" - order.Price = 0.0 - order.Side = "test" - order.Symbol = "BTCUSD" - order.Type = "test" - orders = append(orders, order) - - if ACCOUNT_LIVE_TEST { - response, err := BitfinexNewOrderMulti.NewOrderMulti(orders) - if err == nil { - newErrString := fmt.Sprintf("BitfinexNewOrderMulti - Error: Expected Error Status: %s\n", response.Status) - t.Error(newErrString) - } - } - - nonLiveResponse := BitfinexOrderMultiResponse{} - nonLiveResponse.Status = "success" - - orderTest := BitfinexOrder{} - orderTest.AverageExecutionPrice = 0.0 - orderTest.Exchange = "bitfinex" - orderTest.ExecutedAmount = 0.0 - orderTest.ID = 448364249 - orderTest.IsCancelled = false - orderTest.IsHidden = false - orderTest.IsLive = true - orderTest.OrderID = 448364249 - orderTest.OriginalAmount = 0.01 - orderTest.Price = 0.01 - orderTest.RemainingAmount = 0.01 - orderTest.Side = "buy" - orderTest.Symbol = "btcusd" - orderTest.Timestamp = "1444272165.252370982" - orderTest.Type = "exchange limit" - orderTest.WasForced = false - - nonLiveResponse.Orders = append(nonLiveResponse.Orders, orderTest) - - if reflect.ValueOf(nonLiveResponse).NumField() != 2 { - t.Error("Bitfinex NewOrderMulti struct change/or updated") - } - if reflect.TypeOf(nonLiveResponse.Status).String() != "string" { - t.Error("Bitfinex NewOrderMulti.Status is not a string") - } - if reflect.ValueOf(nonLiveResponse.Orders[0]).NumField() != 16 { - t.Error("Bitfinex NewOrderMulti struct change/or updated") - } - if reflect.TypeOf(nonLiveResponse.Orders[0].AverageExecutionPrice).String() != "float64" { - t.Error("Bitfinex NewOrderMulti.AverageExecutionPrice is not a float64") - } - if reflect.TypeOf(nonLiveResponse.Orders[0].Exchange).String() != "string" { - t.Error("Bitfinex NewOrderMulti.Exchange is not a string") - } - if reflect.TypeOf(nonLiveResponse.Orders[0].ExecutedAmount).String() != "float64" { - t.Error("Bitfinex NewOrderMulti.ExecutedAmount is not a float64") - } - if reflect.TypeOf(nonLiveResponse.Orders[0].OrderID).String() != "int64" { - t.Error("Bitfinex NewOrderMulti.ID is not an int64") - } - if reflect.TypeOf(nonLiveResponse.Orders[0].IsCancelled).String() != "bool" { - t.Error("Bitfinex NewOrderMulti.IsCancelled is not a bool") - } - if reflect.TypeOf(nonLiveResponse.Orders[0].IsHidden).String() != "bool" { - t.Error("Bitfinex NewOrderMulti.IsHidden is not a bool") - } - if reflect.TypeOf(nonLiveResponse.Orders[0].IsLive).String() != "bool" { - t.Error("Bitfinex NewOrderMulti.IsLive is not a bool") - } - if reflect.TypeOf(nonLiveResponse.Orders[0].OrderID).String() != "int64" { - t.Error("Bitfinex NewOrderMulti.OrderID is not an int64") - } - if reflect.TypeOf(nonLiveResponse.Orders[0].OriginalAmount).String() != "float64" { - t.Error("Bitfinex NewOrderMulti.OriginalAmount is not a float64") - } - if reflect.TypeOf(nonLiveResponse.Orders[0].Price).String() != "float64" { - t.Error("Bitfinex NewOrderMulti.Price is not a float64") - } - if reflect.TypeOf(nonLiveResponse.Orders[0].RemainingAmount).String() != "float64" { - t.Error("Bitfinex NewOrderMulti.RemainingAmount is not a float64") - } - if reflect.TypeOf(nonLiveResponse.Orders[0].Side).String() != "string" { - t.Error("Bitfinex NewOrderMulti.Side is not a string") - } - if reflect.TypeOf(nonLiveResponse.Orders[0].Symbol).String() != "string" { - t.Error("Bitfinex NewOrderMulti.Address is not a string") - } - if reflect.TypeOf(nonLiveResponse.Orders[0].Timestamp).String() != "string" { - t.Error("Bitfinex NewOrderMulti.Timestamp is not a string") - } - if reflect.TypeOf(nonLiveResponse.Orders[0].Type).String() != "string" { - t.Error("Bitfinex NewOrderMulti.Type is not a string") - } - if reflect.TypeOf(nonLiveResponse.Orders[0].WasForced).String() != "bool" { - t.Error("Bitfinex NewOrderMulti.WasForced is not a bool") - } -} - -func TestCancelOrder(t *testing.T) { - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - Bitfinex CancelOrder init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - Bitfinex CancelOrder init error: %s\n", err) - } - - BitfinexCancelOrder := Bitfinex{} - BitfinexCancelOrder.Setup(exchangeConfig) - - if ACCOUNT_LIVE_TEST { - _, err := BitfinexCancelOrder.CancelOrder(1337) - if err == nil { - t.Errorf("Test Failed - Bitfinex CancelOrder - Error: %s", err) - } - } -} - -func TestCancelMultipleOrders(t *testing.T) { - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - Bitfinex CancelMultipleOrders init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - Bitfinex CancelMultipleOrders init error: %s\n", err) - } - - BitfinexMultipleOrders := Bitfinex{} - BitfinexMultipleOrders.Setup(exchangeConfig) - - if ACCOUNT_LIVE_TEST { - orders := []int64{1336, 1337} - response, err := BitfinexMultipleOrders.CancelMultipleOrders(orders) - if err != nil || response != "" { - t.Errorf("Test Failed - Bitfinex CancelMultipleOrders - Error: %s", err) - } - } -} - -func TestCancelAllOrders(t *testing.T) { - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - Bitfinex CancelAllOrders init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - Bitfinex CancelAllOrders init error: %s\n", err) - } - - BitfinexCancelAllOrders := Bitfinex{} - BitfinexCancelAllOrders.Setup(exchangeConfig) - - if ACCOUNT_LIVE_TEST { - response, err := BitfinexCancelAllOrders.CancelAllOrders() - if err != nil || response != "" { - t.Errorf("Test Failed - Bitfinex CancelAllOrders - Error: %s", err) - } - } -} - -func TestReplaceOrder(t *testing.T) { - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - Bitfinex ReplaceOrder init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - Bitfinex ReplaceOrder init error: %s\n", err) - } - - BitfinexReplaceOrder := Bitfinex{} - BitfinexReplaceOrder.Setup(exchangeConfig) - - if ACCOUNT_LIVE_TEST { - _, err := BitfinexReplaceOrder.ReplaceOrder(1337, "BTC", 0, 0, true, "exchange limit", false) - if err == nil { - t.Error("Test Failed - Bitfinex ReplaceOrder - Expected Error") - } - } -} - -func TestGetOrderStatus(t *testing.T) { - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetOrderStatus init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetOrderStatus init error: %s\n", err) - } - - BitfinexGetOrderStatus := Bitfinex{} - BitfinexGetOrderStatus.Setup(exchangeConfig) - - if ACCOUNT_LIVE_TEST { - _, err := BitfinexGetOrderStatus.GetOrderStatus(1337) - if err == nil { - t.Error("Test Failed - Bitfinex GetOrderStatus - Expected Error") - } - } -} - -func TestGetActiveOrders(t *testing.T) { - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetActiveOrders init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetActiveOrders init error: %s\n", err) - } - - BitfinexGetActiveOrders := Bitfinex{} - BitfinexGetActiveOrders.Setup(exchangeConfig) - - if ACCOUNT_LIVE_TEST { - _, err := BitfinexGetActiveOrders.GetActiveOrders() - if err != nil { - t.Error("Test Failed - Bitfinex GetActiveOrders - Expected Error") - } - } -} - -func TestGetActivePositions(t *testing.T) { - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetActivePositions init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetActivePositions init error: %s\n", err) - } - - BitfinexGetActivePositions := Bitfinex{} - BitfinexGetActivePositions.Setup(exchangeConfig) - - if ACCOUNT_LIVE_TEST { - _, err := BitfinexGetActivePositions.GetActivePositions() - if err != nil { - t.Error("Test Failed - Bitfinex GetActivePositions - Expected Error") - } - } -} - -func TestClaimPosition(t *testing.T) { - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - Bitfinex ClaimPosition init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - Bitfinex ClaimPosition init error: %s\n", err) - } - - BitfinexClaimPosition := Bitfinex{} - BitfinexClaimPosition.Setup(exchangeConfig) - - if ACCOUNT_LIVE_TEST { - _, err := BitfinexClaimPosition.ClaimPosition(1337) - if err == nil { - t.Error("Test Failed - Bitfinex ClaimPosition - Expected Error") - } - } -} - -func TestGetBalanceHistory(t *testing.T) { - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetBalanceHistory init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetBalanceHistory init error: %s\n", err) - } - - BitfinexGetBalanceHistory := Bitfinex{} - BitfinexGetBalanceHistory.Setup(exchangeConfig) - - if ACCOUNT_LIVE_TEST { - _, err := BitfinexGetBalanceHistory.GetBalanceHistory("BTC", time.Now(), time.Now(), 1, "testWallet") - if err == nil { - t.Error("Test Failed - Bitfinex GetBalanceHistory - Expected Error") - } - } -} - -func TestGetMovementHistory(t *testing.T) { - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetMovementHistory init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetMovementHistory init error: %s\n", err) - } - - BitfinexGetMovementHistory := Bitfinex{} - BitfinexGetMovementHistory.Setup(exchangeConfig) - - if ACCOUNT_LIVE_TEST { - _, err := BitfinexGetMovementHistory.GetMovementHistory("BTC", "BITCOIN", time.Now(), time.Now(), 1) - if err == nil { - t.Error("Test Failed - Bitfinex GetMovementHistory - Expected Error") - } - } -} - -func TestGetTradeHistory(t *testing.T) { - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetTradeHistory init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetTradeHistory init error: %s\n", err) - } - - BitfinexGetTradeHistory := Bitfinex{} - BitfinexGetTradeHistory.Setup(exchangeConfig) - - if ACCOUNT_LIVE_TEST { - _, err := BitfinexGetTradeHistory.GetTradeHistory("BTC", time.Now(), time.Now(), 1, 0) - if err == nil { - t.Error("Test Failed - Bitfinex GetTradeHistory - Expected Error") - } - } -} - -func TestNewOffer(t *testing.T) { - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - Bitfinex NewOffer init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - Bitfinex NewOffer init error: %s\n", err) - } - - BitfinexNewOffer := Bitfinex{} - BitfinexNewOffer.Setup(exchangeConfig) - - if ACCOUNT_LIVE_TEST { - response := BitfinexNewOffer.NewOffer("BTC", 1, 2, 2, "buy") - if response != 0 { - t.Error("Test Failed - Bitfinex NewOffer - Expected Error") - } - } -} - -func TestGetOfferStatus(t *testing.T) { - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetOfferStatus init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetOfferStatus init error: %s\n", err) - } - - BitfinexGetOfferStatus := Bitfinex{} - BitfinexGetOfferStatus.Setup(exchangeConfig) - - if ACCOUNT_LIVE_TEST { - _, err := BitfinexGetOfferStatus.GetOfferStatus(1337) - if err == nil { - t.Error("Test Failed - Bitfinex GetOfferStatus - Expected Error") - } - } -} - -func TestGetActiveOffers(t *testing.T) { - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetActiveOffers init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetActiveOffers init error: %s\n", err) - } - - BitfinexGetActiveOffers := Bitfinex{} - BitfinexGetActiveOffers.Setup(exchangeConfig) - - if ACCOUNT_LIVE_TEST { - _, err := BitfinexGetActiveOffers.GetActiveOffers() - if err != nil { - t.Error("Test Failed - Bitfinex GetActiveOffers - Expected Error") - } - } -} - -func TestGetActiveMarginFunding(t *testing.T) { - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetActiveMarginFunding init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetActiveMarginFunding init error: %s\n", err) - } - - BitfinexGetActiveMarginFunding := Bitfinex{} - BitfinexGetActiveMarginFunding.Setup(exchangeConfig) - - if ACCOUNT_LIVE_TEST { - _, err := BitfinexGetActiveMarginFunding.GetActiveMarginFunding() - if err != nil { - t.Error("Test Failed - Bitfinex GetActiveMarginFunding - Expected Error") - } - } -} - -func TestGetMarginTotalTakenFunds(t *testing.T) { - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetMarginTotalTakenFunds init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetMarginTotalTakenFunds init error: %s\n", err) - } - - BitfinexGetMarginTotalTakenFunds := Bitfinex{} - BitfinexGetMarginTotalTakenFunds.Setup(exchangeConfig) - - if ACCOUNT_LIVE_TEST { - _, err := BitfinexGetMarginTotalTakenFunds.GetMarginTotalTakenFunds() - if err != nil { - t.Error("Test Failed - Bitfinex GetMarginTotalTakenFunds - Expected Error") - } - } -} - -func TestCloseMarginFunding(t *testing.T) { - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - Bitfinex CloseMarginFunding init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - Bitfinex CloseMarginFunding init error: %s\n", err) - } - - BitfinexCloseMarginFunding := Bitfinex{} - BitfinexCloseMarginFunding.Setup(exchangeConfig) - - if ACCOUNT_LIVE_TEST { - _, err := BitfinexCloseMarginFunding.CloseMarginFunding(1337) - if err == nil { - t.Error("Test Failed - Bitfinex CloseMarginFunding - Expected Error") - } - } -} - -func TestGetAccountBalance(t *testing.T) { - newConfig := config.Config{} - - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetAccountBalance init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetAccountBalance init error: %s\n", err) - } - - BitfinexGetAccountBalance := Bitfinex{} - BitfinexGetAccountBalance.Setup(exchangeConfig) - - if ACCOUNT_LIVE_TEST { - _, err := BitfinexGetAccountBalance.GetAccountBalance() - if err != nil { - t.Error("Test Failed - Bitfinex GetAccountBalance - Expected Error") - } +func TestGetKeyPermissions(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.GetKeyPermissions() + if err == nil { + t.Error("Test Failed - GetKeyPermissions() error:") } } func TestGetMarginInfo(t *testing.T) { - newConfig := config.Config{} + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetMarginInfo init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - Bitfinex GetMarginInfo init error: %s\n", err) + _, err := b.GetMarginInfo() + if err == nil { + t.Error("Test Failed - GetMarginInfo() error") } +} - BitfinexGetMarginInfo := Bitfinex{} - BitfinexGetMarginInfo.Setup(exchangeConfig) +func TestGetAccountBalance(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret - if ACCOUNT_LIVE_TEST { - _, err := BitfinexGetMarginInfo.GetMarginInfo() - if err == nil { - t.Error("Test Failed - Bitfinex GetMarginInfo - Expected Error") - } + _, err := b.GetAccountBalance() + if err == nil { + t.Error("Test Failed - GetAccountBalance() error") } } func TestWalletTransfer(t *testing.T) { - newConfig := config.Config{} + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - Bitfinex WalletTransfer init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - Bitfinex WalletTransfer init error: %s\n", err) - } - - BitfinexWalletTransfer := Bitfinex{} - BitfinexWalletTransfer.Setup(exchangeConfig) - - if ACCOUNT_LIVE_TEST { - _, err := BitfinexWalletTransfer.WalletTransfer(100, "BTC", "somewallet", "someotherwallet") - if err == nil { - t.Error("Test Failed - Bitfinex WalletTransfer - Expected Error") - } + _, err := b.WalletTransfer(0.01, "bla", "bla", "bla") + if err == nil { + t.Error("Test Failed - WalletTransfer() error") } } func TestWithdrawal(t *testing.T) { - newConfig := config.Config{} + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - Bitfinex Withdrawal init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - Bitfinex Withdrawal init error: %s\n", err) - } - - BitfinexWithdrawal := Bitfinex{} - BitfinexWithdrawal.Setup(exchangeConfig) - - if ACCOUNT_LIVE_TEST { - _, err := BitfinexWithdrawal.Withdrawal("BITCOIN", "somewallet", "123A87612376", 100) - if err == nil { - t.Error("Test Failed - Bitfinex Withdrawal - Expected Error") - } + _, err := b.Withdrawal("LITECOIN", "deposit", "1000", 0.01) + if err == nil { + t.Error("Test Failed - Withdrawal() error") } } -func TestSendAuthenticatedHTTPRequest(t *testing.T) { - if ACCOUNT_LIVE_TEST { - newConfig := config.Config{} +func TestNewOrder(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret - err := newConfig.LoadConfig("../../testdata/configtest.dat") - if err != nil { - t.Errorf("Test Failed - SendAuthenticatedHTTPRequest init error: %s\n", err) - } - exchangeConfig, err := newConfig.GetExchangeConfig("Bitfinex") - if err != nil { - t.Errorf("Test Failed - SendAuthenticatedHTTPRequest init error: %s\n", err) - } - - sendAuthHTTPRequest := Bitfinex{} - sendAuthHTTPRequest.Setup(exchangeConfig) - result := []BitfinexAccountInfo{} - - err = sendAuthHTTPRequest.SendAuthenticatedHTTPRequest("POST", BITFINEX_ACCOUNT_INFO, nil, &result) - if err != nil { - t.Errorf("Test Failed - Bitfinex SendAuthenticatedHTTPRequest() error: %s", err) - } - - if len(result) < 1 { - t.Error("Test Failed - Bitfinex SendAuthenticatedHTTPRequest() incorrect length") - } + _, err := b.NewOrder("BTCUSD", 1, 2, true, "market", false) + if err == nil { + t.Error("Test Failed - NewOrder() error") + } +} + +func TestNewOrderMulti(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + newOrder := []PlaceOrder{ + { + Symbol: "BTCUSD", + Amount: 1, + Price: 1, + Exchange: "bitfinex", + Side: "buy", + Type: "market", + }, + } + + _, err := b.NewOrderMulti(newOrder) + if err == nil { + t.Error("Test Failed - NewOrderMulti() error") + } +} + +func TestCancelOrder(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.CancelOrder(1337) + if err == nil { + t.Error("Test Failed - CancelOrder() error") + } +} + +func TestCancelMultipleOrders(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.CancelMultipleOrders([]int64{1337, 1336}) + if err == nil { + t.Error("Test Failed - CancelMultipleOrders() error") + } +} + +func TestCancelAllOrders(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.CancelAllOrders() + if err == nil { + t.Error("Test Failed - CancelAllOrders() error") + } +} + +func TestReplaceOrder(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.ReplaceOrder(1337, "BTCUSD", 1, 1, true, "market", false) + if err == nil { + t.Error("Test Failed - ReplaceOrder() error") + } +} + +func TestGetOrderStatus(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.GetOrderStatus(1337) + if err == nil { + t.Error("Test Failed - GetOrderStatus() error") + } +} + +func TestGetActiveOrders(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.GetActiveOrders() + if err == nil { + t.Error("Test Failed - GetActiveOrders() error") + } +} + +func TestGetActivePositions(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.GetActivePositions() + if err == nil { + t.Error("Test Failed - GetActivePositions() error") + } +} + +func TestClaimPosition(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.ClaimPosition(1337) + if err == nil { + t.Error("Test Failed - ClaimPosition() error") + } +} + +func TestGetBalanceHistory(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.GetBalanceHistory("USD", time.Time{}, time.Time{}, 1, "deposit") + if err == nil { + t.Error("Test Failed - GetBalanceHistory() error") + } +} + +func TestGetMovementHistory(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.GetMovementHistory("USD", "bitcoin", time.Time{}, time.Time{}, 1) + if err == nil { + t.Error("Test Failed - GetMovementHistory() error") + } +} + +func TestGetTradeHistory(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.GetTradeHistory("BTCUSD", time.Time{}, time.Time{}, 1, 0) + if err == nil { + t.Error("Test Failed - GetTradeHistory() error") + } +} + +func TestNewOffer(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.NewOffer("BTC", 1, 1, 1, "loan") + if err == nil { + t.Error("Test Failed - NewOffer() error") + } +} + +func TestCancelOffer(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.CancelOffer(1337) + if err == nil { + t.Error("Test Failed - CancelOffer() error") + } +} + +func TestGetOfferStatus(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.GetOfferStatus(1337) + if err == nil { + t.Error("Test Failed - NewOffer() error") + } +} + +func TestGetActiveCredits(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.GetActiveCredits() + if err == nil { + t.Error("Test Failed - GetActiveCredits() error", err) + } +} + +func TestGetActiveOffers(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.GetActiveOffers() + if err == nil { + t.Error("Test Failed - GetActiveOffers() error", err) + } +} + +func TestGetActiveMarginFunding(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.GetActiveMarginFunding() + if err == nil { + t.Error("Test Failed - GetActiveMarginFunding() error", err) + } +} + +func TestGetUnusedMarginFunds(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.GetUnusedMarginFunds() + if err == nil { + t.Error("Test Failed - GetUnusedMarginFunds() error", err) + } +} + +func TestGetMarginTotalTakenFunds(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.GetMarginTotalTakenFunds() + if err == nil { + t.Error("Test Failed - GetMarginTotalTakenFunds() error", err) + } +} + +func TestCloseMarginFunding(t *testing.T) { + b := Bitfinex{} + b.APIKey = testAPIKey + b.APISecret = testAPISecret + + _, err := b.CloseMarginFunding(1337) + if err == nil { + t.Error("Test Failed - CloseMarginFunding() error") } } diff --git a/exchanges/bitfinex/bitfinex_types.go b/exchanges/bitfinex/bitfinex_types.go index db9eab38..976c6b02 100644 --- a/exchanges/bitfinex/bitfinex_types.go +++ b/exchanges/bitfinex/bitfinex_types.go @@ -1,50 +1,208 @@ package bitfinex -type BitfinexStats struct { - Period int64 - Volume float64 `json:",string"` +// Ticker holds basic ticker information from the exchange +type Ticker struct { + Mid float64 `json:"mid,string"` + Bid float64 `json:"bid,string"` + Ask float64 `json:"ask,string"` + Last float64 `json:"last_price,string"` + Low float64 `json:"low,string"` + High float64 `json:"high,string"` + Volume float64 `json:"volume,string"` + Timestamp string `json:"timestamp"` } -type BitfinexTicker struct { - Mid float64 `json:",string"` - Bid float64 `json:",string"` - Ask float64 `json:",string"` - Last float64 `json:"Last_price,string"` - Low float64 `json:",string"` - High float64 `json:",string"` - Volume float64 `json:",string"` - Timestamp string +// Stat holds individual statistics from exchange +type Stat struct { + Period int64 `json:"period"` + Volume float64 `json:"volume,string"` } -type BitfinexMarginLimits struct { - On_Pair string +// FundingBook holds current the full margin funding book +type FundingBook struct { + Bids []Book `json:"bids"` + Asks []Book `json:"asks"` +} + +// Orderbook holds orderbook information from bid and ask sides +type Orderbook struct { + Bids []Book + Asks []Book +} + +// TradeStructure holds executed trade information +type TradeStructure struct { + Timestamp int64 `json:"timestamp"` + Tid int64 `json:"tid"` + Price float64 `json:"price,string"` + Amount float64 `json:"amount,string"` + Exchange string `json:"exchange"` + Type string `json:"sell"` +} + +// Lendbook holds most recent funding data for a relevent currency +type Lendbook struct { + Bids []Book `json:"bids"` + Asks []Book `json:"asks"` +} + +// Book is a generalised sub-type to hold book information +type Book struct { + Price float64 `json:"price,string"` + Rate float64 `json:"rate,string"` + Amount float64 `json:"amount,string"` + Period int `json:"period"` + Timestamp string `json:"timestamp"` + FlashReturnRate string `json:"frr"` +} + +// Lends holds the lent information by currency +type Lends struct { + Rate float64 `json:"rate,string"` + AmountLent float64 `json:"amount_lent,string"` + AmountUsed float64 `json:"amount_used,string"` + Timestamp int64 `json:"timestamp"` +} + +// SymbolDetails holds currency pair information +type SymbolDetails struct { + Pair string `json:"pair"` + PricePrecision int `json:"price_precision"` + InitialMargin float64 `json:"initial_margin,string"` + MinimumMargin float64 `json:"minimum_margin,string"` + MaximumOrderSize float64 `json:"maximum_order_size,string"` + MinimumOrderSize float64 `json:"minimum_order_size,string"` + Expiration string `json:"expiration"` +} + +// AccountInfo general account information with fees +type AccountInfo struct { + MakerFees string `json:"maker_fees"` + TakerFees string `json:"taker_fees"` + Fees []struct { + Pairs string `json:"pairs"` + MakerFees string `json:"maker_fees"` + TakerFees string `json:"taker_fees"` + } `json:"fees"` +} + +// AccountFees stores withdrawel account fee data from Bitfinex +type AccountFees struct { + Withdraw struct { + BTC float64 `json:"BTC,string"` + LTC float64 `json:"LTC,string"` + ETH float64 `json:"ETH,string"` + ETC float64 `json:"ETC,string"` + ZEC float64 `json:"ZEC,string"` + XMR float64 `json:"XMR,string"` + DSH float64 `json:"DSH,string"` + XRP float64 `json:"XRP,string"` + IOT float64 `json:"IOT"` + EOS float64 `json:"EOS,string"` + SAN float64 `json:"SAN,string"` + OMG float64 `json:"OMG,string"` + BCH float64 `json:"BCH,string"` + } `json:"withdraw"` +} + +// AccountSummary holds account summary data +type AccountSummary struct { + TradeVolumePer30D []Currency `json:"trade_vol_30d"` + FundingProfit30D []Currency `json:"funding_profit_30d"` + MakerFee float64 `json:"maker_fee"` + TakerFee float64 `json:"taker_fee"` +} + +// Currency is a sub-type for AccountSummary data +type Currency struct { + Currency string `json:"curr"` + Volume float64 `json:"vol,string"` + Amount float64 `json:"amount,string"` +} + +// DepositResponse holds deposit address information +type DepositResponse struct { + Result string `json:"string"` + Method string `json:"method"` + Currency string `json:"currency"` + Address string `json:"address"` +} + +// KeyPermissions holds the key permissions for the API key set +type KeyPermissions struct { + Account Permission `json:"account"` + History Permission `json:"history"` + Orders Permission `json:"orders"` + Positions Permission `json:"positions"` + Funding Permission `json:"funding"` + Wallets Permission `json:"wallets"` + Withdraw Permission `json:"withdraw"` +} + +// Permission sub-type for KeyPermissions +type Permission struct { + Read bool `json:"read"` + Write bool `json:"write"` +} + +// MarginInfo holds metadata for margin information from bitfinex +type MarginInfo struct { + Info MarginData + Message string `json:"message"` +} + +// MarginData holds wallet information for margin trading +type MarginData struct { + MarginBalance float64 `json:"margin_balance,string"` + TradableBalance float64 `json:"tradable_balance,string"` + UnrealizedPL int64 `json:"unrealized_pl"` + UnrealizedSwap int64 `json:"unrealized_swap"` + NetValue float64 `json:"net_value,string"` + RequiredMargin int64 `json:"required_margin"` + Leverage float64 `json:"leverage,string"` + MarginRequirement float64 `json:"margin_requirement,string"` + MarginLimits []MarginLimits `json:"margin_limits"` +} + +// MarginLimits holds limit data per pair +type MarginLimits struct { + OnPair string `json:"on_pair"` InitialMargin float64 `json:"initial_margin,string"` MarginRequirement float64 `json:"margin_requirement,string"` TradableBalance float64 `json:"tradable_balance,string"` } -type BitfinexMarginInfo struct { - MarginBalance float64 `json:"margin_balance,string"` - TradableBalance float64 `json:"tradable_balance,string"` - UnrealizedPL int64 `json:"unrealized_pl"` - UnrealizedSwap int64 `json:"unrealized_swap"` - NetValue float64 `json:"net_value,string"` - RequiredMargin int64 `json:"required_margin"` - Leverage float64 `json:"leverage,string"` - MarginRequirement float64 `json:"margin_requirement,string"` - MarginLimits []BitfinexMarginLimits `json:"margin_limits"` - Message string +// Balance holds current balance data +type Balance struct { + Type string `json:"type"` + Currency string `json:"currency"` + Amount float64 `json:"amount,string"` + Available float64 `json:"available,string"` } -type BitfinexOrder struct { - ID int64 - Symbol string - Exchange string +// WalletTransfer holds status of wallet to wallet content transfer on exchange +type WalletTransfer struct { + Status string `json:"status"` + Message string `json:"message"` +} + +// Withdrawal holds withdrawel status information +type Withdrawal struct { + Status string `json:"status"` + Message string `json:"message"` + WithdrawalID int64 `json:"withdrawal_id,string"` +} + +// Order holds order information when an order is in the market +type Order struct { + ID int64 `json:"id"` + Symbol string `json:"symbol"` + Exchange string `json:"exchange"` Price float64 `json:"price,string"` AverageExecutionPrice float64 `json:"avg_execution_price,string"` - Side string - Type string - Timestamp string + Side string `json:"side"` + Type string `json:"type"` + Timestamp string `json:"timestamp"` IsLive bool `json:"is_live"` IsCancelled bool `json:"is_cancelled"` IsHidden bool `json:"is_hidden"` @@ -55,7 +213,14 @@ type BitfinexOrder struct { OrderID int64 `json:"order_id"` } -type BitfinexPlaceOrder struct { +// OrderMultiResponse holds order information on the executed orders +type OrderMultiResponse struct { + Orders []Order `json:"order_ids"` + Status string `json:"status"` +} + +// PlaceOrder is used for order placement +type PlaceOrder struct { Symbol string `json:"symbol"` Amount float64 `json:"amount,string"` Price float64 `json:"price,string"` @@ -64,101 +229,13 @@ type BitfinexPlaceOrder struct { Type string `json:"type"` } -type BitfinexBalance struct { - Type string - Currency string - Amount float64 `json:"amount,string"` - Available float64 `json:"available,string"` +// GenericResponse holds the result for a generic response +type GenericResponse struct { + Result string `json:"result"` } -type BitfinexOffer struct { - ID int64 - Currency string - Rate float64 `json:"rate,string"` - Period int64 - Direction string - Timestamp string - Type string - IsLive bool `json:"is_live"` - IsCancelled bool `json:"is_cancelled"` - OriginalAmount float64 `json:"original_amount,string"` - RemainingAmount float64 `json:"remaining_amount,string"` - ExecutedAmount float64 `json:"executed_amount,string"` -} - -type BitfinexBookStructure struct { - Price, Amount, Timestamp string -} - -type BitfinexFee struct { - Currency string - TakerFees float64 - MakerFees float64 -} - -type BitfinexOrderbook struct { - Bids []BitfinexBookStructure - Asks []BitfinexBookStructure -} - -type BitfinexTradeStructure struct { - Timestamp, Tid int64 - Price, Amount, Exchange, Type string -} - -type BitfinexSymbolDetails struct { - Pair string `json:"pair"` - PricePrecision int `json:"price_precision"` - InitialMargin float64 `json:"initial_margin,string"` - MinimumMargin float64 `json:"minimum_margin,string"` - MaximumOrderSize float64 `json:"maximum_order_size,string"` - MinimumOrderSize float64 `json:"minimum_order_size,string"` - Expiration string `json:"expiration"` -} - -type BitfinexLends struct { - Rate float64 `json:"rate,string"` - AmountLent float64 `json:"amount_lent,string"` - AmountUsed float64 `json:"amount_used,string"` - Timestamp int64 `json:"timestamp"` -} - -type BitfinexAccountInfo struct { - MakerFees string `json:"maker_fees"` - TakerFees string `json:"taker_fees"` - Fees []struct { - Pairs string `json:"pairs"` - MakerFees string `json:"maker_fees"` - TakerFees string `json:"taker_fees"` - } `json:"fees"` -} - -type BitfinexDepositResponse struct { - Result string `json:"string"` - Method string `json:"method"` - Currency string `json:"currency"` - Address string `json:"address"` -} - -type BitfinexOrderMultiResponse struct { - Orders []BitfinexOrder `json:"order_ids"` - Status string `json:"status"` -} - -type BitfinexLendbookBidAsk struct { - Rate float64 `json:"rate,string"` - Amount float64 `json:"amount,string"` - Period int `json:"period"` - Timestamp string `json:"timestamp"` - FlashReturnRate string `json:"frr"` -} - -type BitfinexLendbook struct { - Bids []BitfinexLendbookBidAsk `json:"bids"` - Asks []BitfinexLendbookBidAsk `json:"asks"` -} - -type BitfinexPosition struct { +// Position holds position information +type Position struct { ID int64 `json:"id"` Symbol string `json:"string"` Status string `json:"active"` @@ -169,7 +246,8 @@ type BitfinexPosition struct { PL float64 `json:"pl,string"` } -type BitfinexBalanceHistory struct { +// BalanceHistory holds balance history information +type BalanceHistory struct { Currency string `json:"currency"` Amount float64 `json:"amount,string"` Balance float64 `json:"balance,string"` @@ -177,18 +255,24 @@ type BitfinexBalanceHistory struct { Timestamp string `json:"timestamp"` } -type BitfinexMovementHistory struct { - ID int64 `json:"id"` - Currency string `json:"currency"` - Method string `json:"method"` - Type string `json:"withdrawal"` - Amount float64 `json:"amount,string"` - Description string `json:"description"` - Status string `json:"status"` - Timestamp string `json:"timestamp"` +// MovementHistory holds deposit and withdrawal history data +type MovementHistory struct { + ID int64 `json:"id"` + TxID int64 `json:"txid"` + Currency string `json:"currency"` + Method string `json:"method"` + Type string `json:"withdrawal"` + Amount float64 `json:"amount,string"` + Description string `json:"description"` + Address string `json:"address"` + Status string `json:"status"` + Timestamp string `json:"timestamp"` + TimestampCreated string `json:"timestamp_created"` + Fee float64 `json:"fee"` } -type BitfinexTradeHistory struct { +// TradeHistory holds trade history data +type TradeHistory struct { Price float64 `json:"price,string"` Amount float64 `json:"amount,string"` Timestamp string `json:"timestamp"` @@ -200,7 +284,24 @@ type BitfinexTradeHistory struct { OrderID int64 `json:"order_id"` } -type BitfinexMarginFunds struct { +// Offer holds offer information +type Offer struct { + ID int64 `json:"id"` + Currency string `json:"currency"` + Rate float64 `json:"rate,string"` + Period int64 `json:"period"` + Direction string `json:"direction"` + Timestamp string `json:"timestamp"` + Type string `json:"type"` + IsLive bool `json:"is_live"` + IsCancelled bool `json:"is_cancelled"` + OriginalAmount float64 `json:"original_amount,string"` + RemainingAmount float64 `json:"remaining_amount,string"` + ExecutedAmount float64 `json:"executed_amount,string"` +} + +// MarginFunds holds active funding information used in a margin positon +type MarginFunds struct { ID int64 `json:"id"` PositionID int64 `json:"position_id"` Currency string `json:"currency"` @@ -208,47 +309,46 @@ type BitfinexMarginFunds struct { Period int `json:"period"` Amount float64 `json:"amount,string"` Timestamp string `json:"timestamp"` + AutoClose bool `json:"auto_close"` } -type BitfinexMarginTotalTakenFunds struct { +// MarginTotalTakenFunds holds position funding including sum of active backing +// as total swaps +type MarginTotalTakenFunds struct { PositionPair string `json:"position_pair"` TotalSwaps float64 `json:"total_swaps,string"` } -type BitfinexWalletTransfer struct { - Status string `json:"status"` - Message string `json:"message"` +// Fee holds fee data for a specified currency +type Fee struct { + Currency string + TakerFees float64 + MakerFees float64 } -type BitfinexWithdrawal struct { - Status string `json:"status"` - Message string `json:"message"` - WithdrawalID int64 `json:"withdrawal_id"` -} - -type BitfinexGenericResponse struct { - Result string `json:"result"` -} - -type BitfinexWebsocketChanInfo struct { +// WebsocketChanInfo holds websocket channel information +type WebsocketChanInfo struct { Channel string Pair string } -type BitfinexWebsocketBook struct { +// WebsocketBook holds booking information +type WebsocketBook struct { Price float64 Count int Amount float64 } -type BitfinexWebsocketTrade struct { +// WebsocketTrade holds trade information +type WebsocketTrade struct { ID int64 Timestamp int64 Price float64 Amount float64 } -type BitfinexWebsocketTicker struct { +// WebsocketTicker holds ticker information +type WebsocketTicker struct { Bid float64 BidSize float64 Ask float64 @@ -259,7 +359,8 @@ type BitfinexWebsocketTicker struct { Volume float64 } -type BitfinexWebsocketPosition struct { +// WebsocketPosition holds position information +type WebsocketPosition struct { Pair string Status string Amount float64 @@ -268,14 +369,16 @@ type BitfinexWebsocketPosition struct { MarginFundingType int } -type BitfinexWebsocketWallet struct { +// WebsocketWallet holds wallet information +type WebsocketWallet struct { Name string Currency string Balance float64 UnsettledInterest float64 } -type BitfinexWebsocketOrder struct { +// WebsocketOrder holds order data +type WebsocketOrder struct { OrderID int64 Pair string Amount float64 @@ -288,7 +391,8 @@ type BitfinexWebsocketOrder struct { Notify int } -type BitfinexWebsocketTradeExecuted struct { +// WebsocketTradeExecuted holds executed trade data +type WebsocketTradeExecuted struct { TradeID int64 Pair string Timestamp int64 @@ -296,3 +400,8 @@ type BitfinexWebsocketTradeExecuted struct { AmountExecuted float64 PriceExecuted float64 } + +// ErrorCapture is a simple type for returned errors from Bitfinex +type ErrorCapture struct { + Message string `json:"message"` +} diff --git a/exchanges/bitfinex/bitfinex_websocket.go b/exchanges/bitfinex/bitfinex_websocket.go index c7a7c064..17feb203 100644 --- a/exchanges/bitfinex/bitfinex_websocket.go +++ b/exchanges/bitfinex/bitfinex_websocket.go @@ -12,50 +12,49 @@ import ( ) const ( - BITFINEX_WEBSOCKET = "wss://api.bitfinex.com/ws" - BITFINEX_WEBSOCKET_VERSION = "1.1" - BITFINEX_WEBSOCKET_POSITION_SNAPSHOT = "ps" - BITFINEX_WEBSOCKET_POSITION_NEW = "pn" - BITFINEX_WEBSOCKET_POSITION_UPDATE = "pu" - BITFINEX_WEBSOCKET_POSITION_CLOSE = "pc" - BITFINEX_WEBSOCKET_WALLET_SNAPSHOT = "ws" - BITFINEX_WEBSOCKET_WALLET_UPDATE = "wu" - BITFINEX_WEBSOCKET_ORDER_SNAPSHOT = "os" - BITFINEX_WEBSOCKET_ORDER_NEW = "on" - BITFINEX_WEBSOCKET_ORDER_UPDATE = "ou" - BITFINEX_WEBSOCKET_ORDER_CANCEL = "oc" - BITFINEX_WEBSOCKET_TRADE_EXECUTED = "te" - BITFINEX_WEBSOCKET_HEARTBEAT = "hb" - BITFINEX_WEBSOCKET_ALERT_RESTARTING = "20051" - BITFINEX_WEBSOCKET_ALERT_REFRESHING = "20060" - BITFINEX_WEBSOCKET_ALERT_RESUME = "20061" - BITFINEX_WEBSOCKET_UNKNOWN_EVENT = "10000" - BITFINEX_WEBSOCKET_UNKNOWN_PAIR = "10001" - BITFINEX_WEBSOCKET_SUBSCRIPTION_FAILED = "10300" - BITFINEX_WEBSOCKET_ALREADY_SUBSCRIBED = "10301" - BITFINEX_WEBSOCKET_UNKNOWN_CHANNEL = "10302" + bitfinexWebsocket = "wss://api.bitfinex.com/ws" + bitfinexWebsocketVersion = "1.1" + bitfinexWebsocketPositionSnapshot = "ps" + bitfinexWebsocketPositionNew = "pn" + bitfinexWebsocketPositionUpdate = "pu" + bitfinexWebsocketPositionClose = "pc" + bitfinexWebsocketWalletSnapshot = "ws" + bitfinexWebsocketWalletUpdate = "wu" + bitfinexWebsocketOrderSnapshot = "os" + bitfinexWebsocketOrderNew = "on" + bitfinexWebsocketOrderUpdate = "ou" + bitfinexWebsocketOrderCancel = "oc" + bitfinexWebsocketTradeExecuted = "te" + bitfinexWebsocketHeartbeat = "hb" + bitfinexWebsocketAlertRestarting = "20051" + bitfinexWebsocketAlertRefreshing = "20060" + bitfinexWebsocketAlertResume = "20061" + bitfinexWebsocketUnknownEvent = "10000" + bitfinexWebsocketUnknownPair = "10001" + bitfinexWebsocketSubscriptionFailed = "10300" + bitfinexWebsocketAlreadySubscribed = "10301" + bitfinexWebsocketUnknownChannel = "10302" ) +// WebsocketPingHandler sends a ping request to the websocket server func (b *Bitfinex) WebsocketPingHandler() error { request := make(map[string]string) request["event"] = "ping" + return b.WebsocketSend(request) } +// WebsocketSend sends data to the websocket server func (b *Bitfinex) WebsocketSend(data interface{}) error { json, err := common.JSONEncode(data) if err != nil { return err } - err = b.WebsocketConn.WriteMessage(websocket.TextMessage, json) - - if err != nil { - return err - } - return nil + return b.WebsocketConn.WriteMessage(websocket.TextMessage, json) } +// WebsocketSubscribe subscribes to the websocket channel func (b *Bitfinex) WebsocketSubscribe(channel string, params map[string]string) error { request := make(map[string]string) request["event"] = "subscribe" @@ -69,6 +68,7 @@ func (b *Bitfinex) WebsocketSubscribe(channel string, params map[string]string) return b.WebsocketSend(request) } +// WebsocketSendAuth sends a autheticated event payload func (b *Bitfinex) WebsocketSendAuth() error { request := make(map[string]interface{}) payload := "AUTH" + strconv.FormatInt(time.Now().UnixNano(), 10)[:13] @@ -76,17 +76,22 @@ func (b *Bitfinex) WebsocketSendAuth() error { request["apiKey"] = b.APIKey request["authSig"] = common.HexEncodeToString(common.GetHMAC(common.HashSHA512_384, []byte(payload), []byte(b.APISecret))) request["authPayload"] = payload + return b.WebsocketSend(request) } +// WebsocketSendUnauth sends an unauthenticated payload func (b *Bitfinex) WebsocketSendUnauth() error { request := make(map[string]string) request["event"] = "unauth" + return b.WebsocketSend(request) } +// WebsocketAddSubscriptionChannel adds a new subscription channel to the +// WebsocketSubdChannels map in bitfinex.go (Bitfinex struct) func (b *Bitfinex) WebsocketAddSubscriptionChannel(chanID int, channel, pair string) { - chanInfo := BitfinexWebsocketChanInfo{Pair: pair, Channel: channel} + chanInfo := WebsocketChanInfo{Pair: pair, Channel: channel} b.WebsocketSubdChannels[chanID] = chanInfo if b.Verbose { @@ -94,12 +99,13 @@ func (b *Bitfinex) WebsocketAddSubscriptionChannel(chanID int, channel, pair str } } +// WebsocketClient makes a connection with the websocket server func (b *Bitfinex) WebsocketClient() { channels := []string{"book", "trades", "ticker"} for b.Enabled && b.Websocket { var Dialer websocket.Dialer var err error - b.WebsocketConn, _, err = Dialer.Dial(BITFINEX_WEBSOCKET, http.Header{}) + b.WebsocketConn, _, err = Dialer.Dial(bitfinexWebsocket, http.Header{}) if err != nil { log.Printf("%s Unable to connect to Websocket. Error: %s\n", b.GetName(), err) @@ -196,89 +202,89 @@ func (b *Bitfinex) WebsocketClient() { } else { if len(chanData) == 2 { if reflect.TypeOf(chanData[1]).String() == "string" { - if chanData[1].(string) == BITFINEX_WEBSOCKET_HEARTBEAT { + if chanData[1].(string) == bitfinexWebsocketHeartbeat { continue } } } switch chanInfo.Channel { case "book": - orderbook := []BitfinexWebsocketBook{} + orderbook := []WebsocketBook{} switch len(chanData) { case 2: data := chanData[1].([]interface{}) for _, x := range data { y := x.([]interface{}) - orderbook = append(orderbook, BitfinexWebsocketBook{Price: y[0].(float64), Count: int(y[1].(float64)), Amount: y[2].(float64)}) + orderbook = append(orderbook, WebsocketBook{Price: y[0].(float64), Count: int(y[1].(float64)), Amount: y[2].(float64)}) } case 4: - orderbook = append(orderbook, BitfinexWebsocketBook{Price: chanData[1].(float64), Count: int(chanData[2].(float64)), Amount: chanData[3].(float64)}) + orderbook = append(orderbook, WebsocketBook{Price: chanData[1].(float64), Count: int(chanData[2].(float64)), Amount: chanData[3].(float64)}) } log.Println(orderbook) case "ticker": - ticker := BitfinexWebsocketTicker{Bid: chanData[1].(float64), BidSize: chanData[2].(float64), Ask: chanData[3].(float64), AskSize: chanData[4].(float64), + ticker := WebsocketTicker{Bid: chanData[1].(float64), BidSize: chanData[2].(float64), Ask: chanData[3].(float64), AskSize: chanData[4].(float64), DailyChange: chanData[5].(float64), DialyChangePerc: chanData[6].(float64), LastPrice: chanData[7].(float64), Volume: chanData[8].(float64)} log.Printf("Bitfinex %s Websocket Last %f Volume %f\n", chanInfo.Pair, ticker.LastPrice, ticker.Volume) case "account": switch chanData[1].(string) { - case BITFINEX_WEBSOCKET_POSITION_SNAPSHOT: - positionSnapshot := []BitfinexWebsocketPosition{} + case bitfinexWebsocketPositionSnapshot: + positionSnapshot := []WebsocketPosition{} data := chanData[2].([]interface{}) for _, x := range data { y := x.([]interface{}) - positionSnapshot = append(positionSnapshot, BitfinexWebsocketPosition{Pair: y[0].(string), Status: y[1].(string), Amount: y[2].(float64), Price: y[3].(float64), + positionSnapshot = append(positionSnapshot, WebsocketPosition{Pair: y[0].(string), Status: y[1].(string), Amount: y[2].(float64), Price: y[3].(float64), MarginFunding: y[4].(float64), MarginFundingType: int(y[5].(float64))}) } log.Println(positionSnapshot) - case BITFINEX_WEBSOCKET_POSITION_NEW, BITFINEX_WEBSOCKET_POSITION_UPDATE, BITFINEX_WEBSOCKET_POSITION_CLOSE: + case bitfinexWebsocketPositionNew, bitfinexWebsocketPositionUpdate, bitfinexWebsocketPositionClose: data := chanData[2].([]interface{}) - position := BitfinexWebsocketPosition{Pair: data[0].(string), Status: data[1].(string), Amount: data[2].(float64), Price: data[3].(float64), + position := WebsocketPosition{Pair: data[0].(string), Status: data[1].(string), Amount: data[2].(float64), Price: data[3].(float64), MarginFunding: data[4].(float64), MarginFundingType: int(data[5].(float64))} log.Println(position) - case BITFINEX_WEBSOCKET_WALLET_SNAPSHOT: + case bitfinexWebsocketWalletSnapshot: data := chanData[2].([]interface{}) - walletSnapshot := []BitfinexWebsocketWallet{} + walletSnapshot := []WebsocketWallet{} for _, x := range data { y := x.([]interface{}) - walletSnapshot = append(walletSnapshot, BitfinexWebsocketWallet{Name: y[0].(string), Currency: y[1].(string), Balance: y[2].(float64), UnsettledInterest: y[3].(float64)}) + walletSnapshot = append(walletSnapshot, WebsocketWallet{Name: y[0].(string), Currency: y[1].(string), Balance: y[2].(float64), UnsettledInterest: y[3].(float64)}) } log.Println(walletSnapshot) - case BITFINEX_WEBSOCKET_WALLET_UPDATE: + case bitfinexWebsocketWalletUpdate: data := chanData[2].([]interface{}) - wallet := BitfinexWebsocketWallet{Name: data[0].(string), Currency: data[1].(string), Balance: data[2].(float64), UnsettledInterest: data[3].(float64)} + wallet := WebsocketWallet{Name: data[0].(string), Currency: data[1].(string), Balance: data[2].(float64), UnsettledInterest: data[3].(float64)} log.Println(wallet) - case BITFINEX_WEBSOCKET_ORDER_SNAPSHOT: - orderSnapshot := []BitfinexWebsocketOrder{} + case bitfinexWebsocketOrderSnapshot: + orderSnapshot := []WebsocketOrder{} data := chanData[2].([]interface{}) for _, x := range data { y := x.([]interface{}) - orderSnapshot = append(orderSnapshot, BitfinexWebsocketOrder{OrderID: int64(y[0].(float64)), Pair: y[1].(string), Amount: y[2].(float64), OrigAmount: y[3].(float64), + orderSnapshot = append(orderSnapshot, WebsocketOrder{OrderID: int64(y[0].(float64)), Pair: y[1].(string), Amount: y[2].(float64), OrigAmount: y[3].(float64), OrderType: y[4].(string), Status: y[5].(string), Price: y[6].(float64), PriceAvg: y[7].(float64), Timestamp: y[8].(string)}) } log.Println(orderSnapshot) - case BITFINEX_WEBSOCKET_ORDER_NEW, BITFINEX_WEBSOCKET_ORDER_UPDATE, BITFINEX_WEBSOCKET_ORDER_CANCEL: + case bitfinexWebsocketOrderNew, bitfinexWebsocketOrderUpdate, bitfinexWebsocketOrderCancel: data := chanData[2].([]interface{}) - order := BitfinexWebsocketOrder{OrderID: int64(data[0].(float64)), Pair: data[1].(string), Amount: data[2].(float64), OrigAmount: data[3].(float64), + order := WebsocketOrder{OrderID: int64(data[0].(float64)), Pair: data[1].(string), Amount: data[2].(float64), OrigAmount: data[3].(float64), OrderType: data[4].(string), Status: data[5].(string), Price: data[6].(float64), PriceAvg: data[7].(float64), Timestamp: data[8].(string), Notify: int(data[9].(float64))} log.Println(order) - case BITFINEX_WEBSOCKET_TRADE_EXECUTED: + case bitfinexWebsocketTradeExecuted: data := chanData[2].([]interface{}) - trade := BitfinexWebsocketTradeExecuted{TradeID: int64(data[0].(float64)), Pair: data[1].(string), Timestamp: int64(data[2].(float64)), OrderID: int64(data[3].(float64)), + trade := WebsocketTradeExecuted{TradeID: int64(data[0].(float64)), Pair: data[1].(string), Timestamp: int64(data[2].(float64)), OrderID: int64(data[3].(float64)), AmountExecuted: data[4].(float64), PriceExecuted: data[5].(float64)} log.Println(trade) } case "trades": - trades := []BitfinexWebsocketTrade{} + trades := []WebsocketTrade{} switch len(chanData) { case 2: data := chanData[1].([]interface{}) for _, x := range data { y := x.([]interface{}) - trades = append(trades, BitfinexWebsocketTrade{ID: int64(y[0].(float64)), Timestamp: int64(y[1].(float64)), Price: y[2].(float64), Amount: y[3].(float64)}) + trades = append(trades, WebsocketTrade{ID: int64(y[0].(float64)), Timestamp: int64(y[1].(float64)), Price: y[2].(float64), Amount: y[3].(float64)}) } case 5: - trade := BitfinexWebsocketTrade{ID: int64(chanData[1].(float64)), Timestamp: int64(chanData[2].(float64)), Price: chanData[3].(float64), Amount: chanData[4].(float64)} + trade := WebsocketTrade{ID: int64(chanData[1].(float64)), Timestamp: int64(chanData[2].(float64)), Price: chanData[3].(float64), Amount: chanData[4].(float64)} trades = append(trades, trade) if b.Verbose { diff --git a/exchanges/bitfinex/bitfinex_websocket_test.go b/exchanges/bitfinex/bitfinex_websocket_test.go index ed802cd0..a3308a73 100644 --- a/exchanges/bitfinex/bitfinex_websocket_test.go +++ b/exchanges/bitfinex/bitfinex_websocket_test.go @@ -5,7 +5,6 @@ import ( "testing" "github.com/gorilla/websocket" - "github.com/thrasher-/gocryptotrader/common" ) func TestWebsocketPingHandler(t *testing.T) { @@ -13,7 +12,7 @@ func TestWebsocketPingHandler(t *testing.T) { var Dialer websocket.Dialer var err error - wsPingHandler.WebsocketConn, _, err = Dialer.Dial(BITFINEX_WEBSOCKET, http.Header{}) + wsPingHandler.WebsocketConn, _, err = Dialer.Dial(bitfinexWebsocket, http.Header{}) if err != nil { t.Errorf("Test Failed - Bitfinex dialer error: %s", err) } @@ -27,131 +26,6 @@ func TestWebsocketPingHandler(t *testing.T) { } } -func TestWebsocketSend(t *testing.T) { - wsSend := Bitfinex{} - var Dialer websocket.Dialer - var err error - - type WebsocketHandshake struct { - Event string `json:"event"` - Code int64 `json:"code"` - Version float64 `json:"version"` - } - - request, dodgyrequest := make(map[string]string), make(map[string]string) - request["event"] = "ping" - dodgyrequest["dodgyEvent"] = "didgereedodge" - - hs := WebsocketHandshake{} - - for { - wsSend.WebsocketConn, _, err = Dialer.Dial(BITFINEX_WEBSOCKET, http.Header{}) - if err != nil { - if err.Error() == "websocket: close 1006 (abnormal closure): unexpected EOF" { - err = wsSend.WebsocketConn.Close() - if err != nil { - t.Errorf("Test Failed - Bitfinex websocketConn.Close() error: %s", err) - } - continue - } else { - t.Errorf("Test Failed - Bitfinex websocket connection error: %s", err) - } - } - mType, resp, err := wsSend.WebsocketConn.ReadMessage() - if err != nil { - t.Errorf("Test Failed - Bitfinex websocketconn.ReadMessage() error: %s", err) - } - if mType != websocket.TextMessage { - t.Errorf("Test Failed - Bitfinex websocketconn.ReadMessage() mType error: %d", mType) - } - err = common.JSONDecode(resp, &hs) - if err != nil { - t.Errorf("Test Failed - Bitfinex JSONDecode error: %s", err) - } - if hs.Code != 0 { - t.Errorf("Test Failed - Bitfinex hs.Code incorrect: %d", hs.Code) - } - if hs.Event != "info" { - t.Errorf("Test Failed - Bitfinex hs.Event incorrect: %s", hs.Event) - } - if hs.Version != 1.1 { - t.Errorf("Test Failed - Bitfinex hs.Version incorrect: %f", hs.Version) - } - - err = wsSend.WebsocketSend(request) - if err != nil { - t.Errorf("Test Failed - Bitfinex websocket send error: %s", err) - } - mType, resp, err = wsSend.WebsocketConn.ReadMessage() - if err != nil { - if err.Error() == "websocket: close 1006 (abnormal closure): unexpected EOF" { - err = wsSend.WebsocketConn.Close() - if err != nil { - t.Errorf("Test Failed - Bitfinex websocketConn.Close() error: %s", err) - } - continue - } else { - t.Errorf("Test Failed - Bitfinex websocketConn.ReadMessage() error: %s", err) - } - } - if mType != websocket.TextMessage { - t.Errorf("Test Failed - Bitfinex websocketconn.ReadMessage() mType error: %d", mType) - } - err = common.JSONDecode(resp, &hs) - if err != nil { - t.Errorf("Test Failed - Bitfinex JSONDecode error: %s", err) - } - if hs.Code != 0 { - t.Errorf("Test Failed - Bitfinex hs.Code incorrect: %d", hs.Code) - } - if hs.Event != "pong" { - t.Errorf("Test Failed - Bitfinex hs.Event incorrect: %s", hs.Event) - } - if hs.Version != 1.1 { - t.Errorf("Test Failed - Bitfinex hs.Version incorrect: %f", hs.Version) - } - - err = wsSend.WebsocketSend(dodgyrequest) - if err != nil { - t.Errorf("Test Failed - Bitfinex websocket send error: %s", err) - } - mType, resp, err = wsSend.WebsocketConn.ReadMessage() - if err != nil { - if err.Error() == "websocket: close 1006 (abnormal closure): unexpected EOF" { - err = wsSend.WebsocketConn.Close() - if err != nil { - t.Errorf("Test Failed - Bitfinex websocketConn.Close() error: %s", err) - } - continue - } else { - t.Errorf("Test Failed - Bitfinex websocketConn.ReadMessage() error: %s", err) - } - } - if mType != websocket.TextMessage { - t.Errorf("Test Failed - Bitfinex websocketconn.ReadMessage() mType error: %d", mType) - } - err = common.JSONDecode(resp, &hs) - if err != nil { - t.Errorf("Test Failed - Bitfinex JSONDecode error: %s", err) - } - if hs.Code != 10000 { - t.Errorf("Test Failed - Bitfinex hs.Code incorrect: %d", hs.Code) - } - if hs.Event != "error" { - t.Errorf("Test Failed - Bitfinex hs.Event incorrect: %s", hs.Event) - } - if hs.Version != 1.1 { - t.Errorf("Test Failed - Bitfinex hs.Version incorrect: %f", hs.Version) - } - - err = wsSend.WebsocketConn.Close() - if err != nil { - t.Errorf("Test Failed - Bitfinex websocketConn.Close() error: %s", err) - } - break - } -} - func TestWebsocketSubscribe(t *testing.T) { websocketSubcribe := Bitfinex{} var Dialer websocket.Dialer @@ -159,7 +33,7 @@ func TestWebsocketSubscribe(t *testing.T) { params := make(map[string]string) params["pair"] = "BTCUSD" - websocketSubcribe.WebsocketConn, _, err = Dialer.Dial(BITFINEX_WEBSOCKET, http.Header{}) + websocketSubcribe.WebsocketConn, _, err = Dialer.Dial(bitfinexWebsocket, http.Header{}) if err != nil { t.Errorf("Test Failed - Bitfinex Dialer error: %s", err) } @@ -179,7 +53,7 @@ func TestWebsocketSendAuth(t *testing.T) { var Dialer websocket.Dialer var err error - wsSendAuth.WebsocketConn, _, err = Dialer.Dial(BITFINEX_WEBSOCKET, http.Header{}) + wsSendAuth.WebsocketConn, _, err = Dialer.Dial(bitfinexWebsocket, http.Header{}) if err != nil { t.Errorf("Test Failed - Bitfinex Dialer error: %s", err) } @@ -189,31 +63,13 @@ func TestWebsocketSendAuth(t *testing.T) { } } -func TestWebsocketSendUnauth(t *testing.T) { - // --- FAIL: TestWebsocketSendUnauth (0.32s) - // bitfinex_websocket_test.go:199: Test Failed - Bitfinex Dialer error: websocket: bad handshake - - // wsSendUnauth := Bitfinex{} - // var Dialer websocket.Dialer - // var err error - // - // wsSendUnauth.WebsocketConn, _, err = Dialer.Dial(BITFINEX_WEBSOCKET, http.Header{}) - // if err != nil { - // t.Errorf("Test Failed - Bitfinex Dialer error: %s", err) - // } - // err = wsSendUnauth.WebsocketSendUnauth() - // if err != nil { - // t.Errorf("Test Failed - Bitfinex WebsocketSendAuth() error: %s", err) - // } -} - func TestWebsocketAddSubscriptionChannel(t *testing.T) { wsAddSubscriptionChannel := Bitfinex{} wsAddSubscriptionChannel.SetDefaults() var Dialer websocket.Dialer var err error - wsAddSubscriptionChannel.WebsocketConn, _, err = Dialer.Dial(BITFINEX_WEBSOCKET, http.Header{}) + wsAddSubscriptionChannel.WebsocketConn, _, err = Dialer.Dial(bitfinexWebsocket, http.Header{}) if err != nil { t.Errorf("Test Failed - Bitfinex Dialer error: %s", err) } @@ -229,7 +85,3 @@ func TestWebsocketAddSubscriptionChannel(t *testing.T) { t.Errorf("Test Failed - Bitfinex WebsocketAddSubscriptionChannel() error: %s", err) } } - -// func TestWebsocketClient(t *testing.T) { -// -// } diff --git a/exchanges/bitfinex/bitfinex_wrapper.go b/exchanges/bitfinex/bitfinex_wrapper.go index 75d26feb..03c7d785 100644 --- a/exchanges/bitfinex/bitfinex_wrapper.go +++ b/exchanges/bitfinex/bitfinex_wrapper.go @@ -2,7 +2,6 @@ package bitfinex import ( "log" - "strconv" "time" "github.com/thrasher-/gocryptotrader/common" @@ -13,10 +12,12 @@ import ( "github.com/thrasher-/gocryptotrader/exchanges/ticker" ) +// Start starts a new wrapper through a go routine func (b *Bitfinex) Start() { go b.Run() } +// Run starts a new websocketclient connection and monitors ticker information func (b *Bitfinex) Run() { if b.Verbose { log.Printf("%s Websocket: %s.", b.GetName(), common.IsEnabled(b.Websocket)) @@ -54,6 +55,7 @@ func (b *Bitfinex) Run() { } } +// GetTickerPrice returns ticker information func (b *Bitfinex) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, error) { tick, err := ticker.GetTicker(b.GetName(), p) if err == nil { @@ -76,6 +78,7 @@ func (b *Bitfinex) GetTickerPrice(p pair.CurrencyPair) (ticker.TickerPrice, erro return tickerPrice, nil } +// GetOrderbookEx returns orderbook information based on currency pair func (b *Bitfinex) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, error) { ob, err := orderbook.GetOrderbook(b.GetName(), p) if err == nil { @@ -89,15 +92,11 @@ func (b *Bitfinex) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, } for x := range orderbookNew.Asks { - price, _ := strconv.ParseFloat(orderbookNew.Asks[x].Price, 64) - amount, _ := strconv.ParseFloat(orderbookNew.Asks[x].Amount, 64) - orderBook.Asks = append(orderBook.Asks, orderbook.OrderbookItem{Price: price, Amount: amount}) + orderBook.Asks = append(orderBook.Asks, orderbook.OrderbookItem{Price: orderbookNew.Asks[x].Price, Amount: orderbookNew.Asks[x].Amount}) } for x := range orderbookNew.Bids { - price, _ := strconv.ParseFloat(orderbookNew.Bids[x].Price, 64) - amount, _ := strconv.ParseFloat(orderbookNew.Bids[x].Amount, 64) - orderBook.Bids = append(orderBook.Bids, orderbook.OrderbookItem{Price: price, Amount: amount}) + orderBook.Bids = append(orderBook.Bids, orderbook.OrderbookItem{Price: orderbookNew.Bids[x].Price, Amount: orderbookNew.Bids[x].Amount}) } orderBook.Pair = p @@ -105,7 +104,8 @@ func (b *Bitfinex) GetOrderbookEx(p pair.CurrencyPair) (orderbook.OrderbookBase, return orderBook, nil } -//GetExchangeAccountInfo : Retrieves balances for all enabled currencies for the Bitfinex exchange +// GetExchangeAccountInfo retrieves balances for all enabled currencies on the +// Bitfinex exchange func (b *Bitfinex) GetExchangeAccountInfo() (exchange.AccountInfo, error) { var response exchange.AccountInfo response.ExchangeName = b.GetName() diff --git a/exchanges/bitfinex/bitfinex_wrapper_test.go b/exchanges/bitfinex/bitfinex_wrapper_test.go index 7def6cad..e1f634ad 100644 --- a/exchanges/bitfinex/bitfinex_wrapper_test.go +++ b/exchanges/bitfinex/bitfinex_wrapper_test.go @@ -31,18 +31,3 @@ func TestGetOrderbookEx(t *testing.T) { t.Errorf("Test Failed - Bitfinex GetOrderbookEx() error: %s", err) } } - -func TestGetExchangeAccountInfo(t *testing.T) { - // getExchangeAccountInfo := Bitfinex{} - // newConfig := config.GetConfig() - // newConfig.LoadConfig("../../testdata/configtest.dat") - // exchConf, err := newConfig.GetExchangeConfig("Bitfinex") - // if err != nil { - // t.Errorf("Test Failed - Bitfinex getExchangeConfig(): %s", err) - // } - // getExchangeAccountInfo.Setup(exchConf) - // _, err = getExchangeAccountInfo.GetExchangeAccountInfo() - // if err != nil { - // t.Errorf("Test Failed - Bitfinex GetExchangeAccountInfo() error: %s", err) - // } -}