Fixed linter issues, increased codecov, fixed general bugs for Bitfinex package

This commit is contained in:
Ryan O'Hara-Reid
2017-08-19 13:30:27 +10:00
parent 80f004109f
commit dc4144c1c2
7 changed files with 1058 additions and 2155 deletions

View File

@@ -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
}

File diff suppressed because it is too large Load Diff

View File

@@ -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"`
}

View File

@@ -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 {

View File

@@ -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) {
//
// }

View File

@@ -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()

View File

@@ -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)
// }
}