diff --git a/exchanges/hitbtc/hitbtc.go b/exchanges/hitbtc/hitbtc.go index 96cba28b..716690d8 100644 --- a/exchanges/hitbtc/hitbtc.go +++ b/exchanges/hitbtc/hitbtc.go @@ -16,29 +16,29 @@ import ( const ( // API - APIURL = "https://api.hitbtc.com" + apiURL = "https://api.hitbtc.com" // Public - APIv2Trades = "api/2/public/trades" - APIv2Currency = "api/2/public/currency" - APIv2Symbol = "api/2/public/symbol" - APIv2Ticker = "api/2/public/ticker" - APIv2OrderBook = "api/2/public/orderbook" - APIv2Candles = "api/2/public/candles" + apiV2Trades = "api/2/public/trades" + apiV2Currency = "api/2/public/currency" + apiV2Symbol = "api/2/public/symbol" + apiV2Ticker = "api/2/public/ticker" + apiV2Orderbook = "api/2/public/orderbook" + apiV2Candles = "api/2/public/candles" // Authenticated - APIv2Balance = "api/2/trading/balance" - APIv2CryptoAddress = "api/2/account/crypto/address" - APIv2CryptoWithdraw = "api/2/account/crypto/withdraw" - APIv2TradeHistory = "api/2/history/trades" - APIv2FeeInfo = "api/2/trading/fee" - Orders = "order" - OrderBuy = "buy" - OrderSell = "sell" - OrderCancel = "cancelOrder" - OrderMove = "moveOrder" - TradableBalances = "returnTradableBalances" - TransferBalance = "transferBalance" + apiV2Balance = "api/2/trading/balance" + apiV2CryptoAddress = "api/2/account/crypto/address" + apiV2CryptoWithdraw = "api/2/account/crypto/withdraw" + apiV2TradeHistory = "api/2/history/trades" + apiV2FeeInfo = "api/2/trading/fee" + orders = "order" + orderBuy = "buy" + orderSell = "sell" + orderCancel = "cancelOrder" + orderMove = "moveOrder" + tradableBalances = "returnTradableBalances" + transferBalance = "transferBalance" ) // HitBTC is the overarching type across the hitbtc package @@ -94,36 +94,35 @@ func (p *HitBTC) GetFee() float64 { // Public Market Data // https://api.hitbtc.com/?python#market-data -// GetCurrencies -// Return the actual list of available currencies, tokens, ICO etc. +// GetCurrencies returns the actual list of available currencies, tokens, ICO +// etc. func (p *HitBTC) GetCurrencies(currency string) (map[string]Currencies, error) { type Response struct { Data []Currencies } resp := Response{} - path := fmt.Sprintf("%s/%s/%s", APIURL, APIv2Currency, currency) + path := fmt.Sprintf("%s/%s/%s", apiURL, apiV2Currency, currency) err := common.SendHTTPGetRequest(path, true, p.Verbose, &resp.Data) ret := make(map[string]Currencies) for _, id := range resp.Data { - ret[id.Id] = id + ret[id.ID] = id } return ret, err } -// GetSymbols -// Return the actual list of currency symbols (currency pairs) traded on HitBTC exchange. -// The first listed currency of a symbol is called the base currency, and the second currency -// is called the quote currency. The currency pair indicates how much of the quote currency -// is needed to purchase one unit of the base currency. +// GetSymbols Return the actual list of currency symbols (currency pairs) traded +// on HitBTC exchange. The first listed currency of a symbol is called the base +// currency, and the second currency is called the quote currency. The currency +// pair indicates how much of the quote currency is needed to purchase one unit +// of the base currency. func (p *HitBTC) GetSymbols(symbol string) ([]string, error) { - resp := []Symbol{} - path := fmt.Sprintf("%s/%s/%s", APIURL, APIv2Symbol, symbol) + path := fmt.Sprintf("%s/%s/%s", apiURL, apiV2Symbol, symbol) err := common.SendHTTPGetRequest(path, true, p.Verbose, &resp) ret := make([]string, 0, len(resp)) for _, x := range resp { - ret = append(ret, x.Id) + ret = append(ret, x.ID) } return ret, err @@ -133,19 +132,17 @@ func (p *HitBTC) GetSymbols(symbol string) ([]string, error) { // all ther details. func (p *HitBTC) GetSymbolsDetailed() ([]Symbol, error) { resp := []Symbol{} - path := fmt.Sprintf("%s/%s", APIURL, APIv2Symbol) + path := fmt.Sprintf("%s/%s", apiURL, apiV2Symbol) return resp, common.SendHTTPGetRequest(path, true, p.Verbose, &resp) } -// GetTicker -// Return ticker information +// GetTicker returns ticker information func (p *HitBTC) GetTicker(symbol string) (map[string]Ticker, error) { - resp1 := []TickerResponse{} resp2 := TickerResponse{} ret := make(map[string]TickerResponse) result := make(map[string]Ticker) - path := fmt.Sprintf("%s/%s/%s", APIURL, APIv2Ticker, symbol) + path := fmt.Sprintf("%s/%s/%s", apiURL, apiV2Ticker, symbol) var err error if symbol == "" { @@ -236,14 +233,13 @@ func (p *HitBTC) GetTrades(currencyPair, from, till, limit, offset, by, sort str } resp := []TradeHistory{} - path := fmt.Sprintf("%s/%s/%s?%s", APIURL, APIv2Trades, currencyPair, vals.Encode()) + path := fmt.Sprintf("%s/%s/%s?%s", apiURL, apiV2Trades, currencyPair, vals.Encode()) return resp, common.SendHTTPGetRequest(path, true, p.Verbose, &resp) } -// GetOrderbook -// An order book is an electronic list of buy and sell orders for a specific -// symbol, organized by price level. +// GetOrderbook an order book is an electronic list of buy and sell orders for a +// specific symbol, organized by price level. func (p *HitBTC) GetOrderbook(currencyPair string, limit int) (Orderbook, error) { // limit Limit of orderbook levels, default 100. Set 0 to view full orderbook levels vals := url.Values{} @@ -253,7 +249,7 @@ func (p *HitBTC) GetOrderbook(currencyPair string, limit int) (Orderbook, error) } resp := OrderbookResponse{} - path := fmt.Sprintf("%s/%s/%s?%s", APIURL, APIv2OrderBook, currencyPair, vals.Encode()) + path := fmt.Sprintf("%s/%s/%s?%s", apiURL, apiV2Orderbook, currencyPair, vals.Encode()) err := common.SendHTTPGetRequest(path, true, p.Verbose, &resp) if err != nil { @@ -271,8 +267,7 @@ func (p *HitBTC) GetOrderbook(currencyPair string, limit int) (Orderbook, error) return ob, nil } -// GetCandles -// A candles used for OHLC a specific symbol. +// GetCandles returns candles which is used for OHLC a specific symbol. // Note: Result contain candles only with non zero volume. func (p *HitBTC) GetCandles(currencyPair, limit, period string) ([]ChartData, error) { // limit Limit of candles, default 100. @@ -288,24 +283,18 @@ func (p *HitBTC) GetCandles(currencyPair, limit, period string) ([]ChartData, er } resp := []ChartData{} - path := fmt.Sprintf("%s/%s/%s?%s", APIURL, APIv2Candles, currencyPair, vals.Encode()) + path := fmt.Sprintf("%s/%s/%s?%s", apiURL, apiV2Candles, currencyPair, vals.Encode()) - err := common.SendHTTPGetRequest(path, true, p.Verbose, &resp) - if err != nil { - return nil, err - } - - return resp, nil + return resp, common.SendHTTPGetRequest(path, true, p.Verbose, &resp) } // Authenticated Market Data // https://api.hitbtc.com/?python#market-data -// GetBalances +// GetBalances returns full balance for your account func (p *HitBTC) GetBalances() (map[string]Balance, error) { - result := []Balance{} - err := p.SendAuthenticatedHTTPRequest("GET", APIv2Balance, url.Values{}, &result) + err := p.SendAuthenticatedHTTPRequest("GET", apiV2Balance, url.Values{}, &result) ret := make(map[string]Balance) if err != nil { @@ -319,30 +308,31 @@ func (p *HitBTC) GetBalances() (map[string]Balance, error) { return ret, nil } +// GetDepositAddresses returns a deposit address for a specific currency func (p *HitBTC) GetDepositAddresses(currency string) (DepositCryptoAddresses, error) { resp := DepositCryptoAddresses{} - err := p.SendAuthenticatedHTTPRequest("GET", APIv2CryptoAddress+"/"+currency, url.Values{}, &resp) + err := p.SendAuthenticatedHTTPRequest("GET", apiV2CryptoAddress+"/"+currency, url.Values{}, &resp) return resp, err } +// GenerateNewAddress generates a new deposit address for a currency func (p *HitBTC) GenerateNewAddress(currency string) (DepositCryptoAddresses, error) { - resp := DepositCryptoAddresses{} - err := p.SendAuthenticatedHTTPRequest("POST", APIv2CryptoAddress+"/"+currency, url.Values{}, &resp) + err := p.SendAuthenticatedHTTPRequest("POST", apiV2CryptoAddress+"/"+currency, url.Values{}, &resp) return resp, err } -// Get Active orders -func (p *HitBTC) GetActiveOrders(currency string) ([]Order, error) { - +// GetActiveorders returns all your active orders +func (p *HitBTC) GetActiveorders(currency string) ([]Order, error) { resp := []Order{} - err := p.SendAuthenticatedHTTPRequest("GET", Orders+"?symbol="+currency, url.Values{}, &resp) + err := p.SendAuthenticatedHTTPRequest("GET", orders+"?symbol="+currency, url.Values{}, &resp) return resp, err } +// GetAuthenticatedTradeHistory returns your trade history func (p *HitBTC) GetAuthenticatedTradeHistory(currency, start, end string) (interface{}, error) { values := url.Values{} @@ -357,35 +347,26 @@ func (p *HitBTC) GetAuthenticatedTradeHistory(currency, start, end string) (inte if currency != "" && currency != "all" { values.Set("currencyPair", currency) result := AuthenticatedTradeHistoryResponse{} - err := p.SendAuthenticatedHTTPRequest("POST", APIv2TradeHistory, values, &result.Data) - if err != nil { - return result, err - } - - return result, nil - } else { - values.Set("currencyPair", "all") - result := AuthenticatedTradeHistoryAll{} - err := p.SendAuthenticatedHTTPRequest("POST", APIv2TradeHistory, values, &result.Data) - - if err != nil { - return result, err - } - - return result, nil + return result, p.SendAuthenticatedHTTPRequest("POST", apiV2TradeHistory, values, &result.Data) } + + values.Set("currencyPair", "all") + result := AuthenticatedTradeHistoryAll{} + + return result, p.SendAuthenticatedHTTPRequest("POST", apiV2TradeHistory, values, &result.Data) } +// PlaceOrder places an order on the exchange func (p *HitBTC) PlaceOrder(currency string, rate, amount float64, immediate, fillOrKill, buy bool) (OrderResponse, error) { result := OrderResponse{} values := url.Values{} var orderType string if buy { - orderType = OrderBuy + orderType = orderBuy } else { - orderType = OrderSell + orderType = orderSell } values.Set("currencyPair", currency) @@ -409,12 +390,13 @@ func (p *HitBTC) PlaceOrder(currency string, rate, amount float64, immediate, fi return result, nil } +// CancelOrder cancels a specific order by OrderID func (p *HitBTC) CancelOrder(orderID int64) (bool, error) { result := GenericResponse{} values := url.Values{} values.Set("orderNumber", strconv.FormatInt(orderID, 10)) - err := p.SendAuthenticatedHTTPRequest("POST", OrderCancel, values, &result) + err := p.SendAuthenticatedHTTPRequest("POST", orderCancel, values, &result) if err != nil { return false, err @@ -427,6 +409,7 @@ func (p *HitBTC) CancelOrder(orderID int64) (bool, error) { return true, nil } +// MoveOrder generates a new move order func (p *HitBTC) MoveOrder(orderID int64, rate, amount float64) (MoveOrderResponse, error) { result := MoveOrderResponse{} values := url.Values{} @@ -437,7 +420,7 @@ func (p *HitBTC) MoveOrder(orderID int64, rate, amount float64) (MoveOrderRespon values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) } - err := p.SendAuthenticatedHTTPRequest("POST", OrderMove, values, &result) + err := p.SendAuthenticatedHTTPRequest("POST", orderMove, values, &result) if err != nil { return result, err @@ -450,6 +433,7 @@ func (p *HitBTC) MoveOrder(orderID int64, rate, amount float64) (MoveOrderRespon return result, nil } +// Withdraw allows for the withdrawal to a specific address func (p *HitBTC) Withdraw(currency, address string, amount float64) (bool, error) { result := Withdraw{} values := url.Values{} @@ -458,7 +442,7 @@ func (p *HitBTC) Withdraw(currency, address string, amount float64) (bool, error values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64)) values.Set("address", address) - err := p.SendAuthenticatedHTTPRequest("POST", APIv2CryptoWithdraw, values, &result) + err := p.SendAuthenticatedHTTPRequest("POST", apiV2CryptoWithdraw, values, &result) if err != nil { return false, err @@ -471,20 +455,22 @@ func (p *HitBTC) Withdraw(currency, address string, amount float64) (bool, error return true, nil } +// GetFeeInfo returns current fee information func (p *HitBTC) GetFeeInfo(currencyPair string) (Fee, error) { result := Fee{} - err := p.SendAuthenticatedHTTPRequest("GET", APIv2FeeInfo+"/"+currencyPair, url.Values{}, &result) + err := p.SendAuthenticatedHTTPRequest("GET", apiV2FeeInfo+"/"+currencyPair, url.Values{}, &result) return result, err } +// GetTradableBalances returns current tradable balances func (p *HitBTC) GetTradableBalances() (map[string]map[string]float64, error) { type Response struct { Data map[string]map[string]interface{} } result := Response{} - err := p.SendAuthenticatedHTTPRequest("POST", TradableBalances, url.Values{}, &result.Data) + err := p.SendAuthenticatedHTTPRequest("POST", tradableBalances, url.Values{}, &result.Data) if err != nil { return nil, err @@ -502,6 +488,7 @@ func (p *HitBTC) GetTradableBalances() (map[string]map[string]float64, error) { return balances, nil } +// TransferBalance transfers a balance func (p *HitBTC) TransferBalance(currency, from, to string, amount float64) (bool, error) { values := url.Values{} result := GenericResponse{} @@ -511,7 +498,7 @@ func (p *HitBTC) TransferBalance(currency, from, to string, amount float64) (boo values.Set("fromAccount", from) values.Set("toAccount", to) - err := p.SendAuthenticatedHTTPRequest("POST", TransferBalance, values, &result) + err := p.SendAuthenticatedHTTPRequest("POST", transferBalance, values, &result) if err != nil { return false, err @@ -524,6 +511,7 @@ func (p *HitBTC) TransferBalance(currency, from, to string, amount float64) (boo return true, nil } +// SendAuthenticatedHTTPRequest sends an authenticated http request func (p *HitBTC) SendAuthenticatedHTTPRequest(method, endpoint string, values url.Values, result interface{}) error { if !p.AuthenticatedAPISupport { return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, p.Name) @@ -531,17 +519,17 @@ func (p *HitBTC) SendAuthenticatedHTTPRequest(method, endpoint string, values ur headers := make(map[string]string) headers["Authorization"] = "Basic " + common.Base64Encode([]byte(p.APIKey+":"+p.APISecret)) - path := fmt.Sprintf("%s/%s", APIURL, endpoint) - resp, err := common.SendHTTPRequest(method, path, headers, bytes.NewBufferString(values.Encode())) + path := fmt.Sprintf("%s/%s", apiURL, endpoint) + resp, err := common.SendHTTPRequest(method, path, headers, bytes.NewBufferString(values.Encode())) if err != nil { return err } err = common.JSONDecode([]byte(resp), &result) - if err != nil { - return errors.New("Unable to JSON Unmarshal response.") + return err } + return nil } diff --git a/exchanges/hitbtc/hitbtc_types.go b/exchanges/hitbtc/hitbtc_types.go index 2a7d3ccb..7a357b05 100644 --- a/exchanges/hitbtc/hitbtc_types.go +++ b/exchanges/hitbtc/hitbtc_types.go @@ -2,6 +2,7 @@ package hitbtc import "time" +// Ticker holds ticker information type Ticker struct { Last float64 Ask float64 @@ -15,6 +16,7 @@ type Ticker struct { Open float64 } +// TickerResponse is the response type type TickerResponse struct { Last string `json:"last"` // Last trade price Ask string `json:"ask"` // Best ask price @@ -28,8 +30,9 @@ type TickerResponse struct { Open string `json:"open"` // Last trade price 24 hours ago } +// Symbol holds symbol data type Symbol struct { - Id string `json:"id"` // Symbol identifier. In the future, the description will simply use the symbol + ID string `json:"id"` // Symbol identifier. In the future, the description will simply use the symbol BaseCurrency string `json:"baseCurrency"` QuoteCurrency string `json:"quoteCurrency"` QuantityIncrement float64 `json:"quantityIncrement,string"` @@ -39,29 +42,34 @@ type Symbol struct { FeeCurrency string `json:"feeCurrency"` // Default fee rate for market making trades } +// OrderbookResponse is the full orderbook response type OrderbookResponse struct { Asks []OrderbookItem `json:"ask"` // Ask side array of levels Bids []OrderbookItem `json:"bid"` // Bid side array of levels } +// OrderbookItem is a sub type for orderbook response type OrderbookItem struct { Price float64 `json:"price,string"` // Price level Amount float64 `json:"size,string"` // Total volume of orders with the specified price } +// Orderbook contains orderbook data type Orderbook struct { Asks []OrderbookItem `json:"asks"` Bids []OrderbookItem `json:"bids"` } +// TradeHistory contains trade history data type TradeHistory struct { - Id int64 `json:"id"` // Trade id + ID int64 `json:"id"` // Trade id Timestamp string `json:"timestamp"` // Trade timestamp Side string `json:"side"` // Trade side sell or buy Price float64 `json:"price,string"` // Trade price Quantity float64 `json:"quantity,string"` // Trade quantity } +// ChartData contains chart data type ChartData struct { Timestamp time.Time `json:"timestamp,string"` Max float64 `json:"max,string"` // Max price @@ -72,18 +80,20 @@ type ChartData struct { VolumeQuote float64 `json:"volumeQuote,string"` // Volume in quote currency } +// Currencies hold the full range of data for a specified currency type Currencies struct { - Id string `json:"id"` // Currency identifier. + ID string `json:"id"` // Currency identifier. FullName string `json:"fullName"` // Currency full name Crypto bool `json:"crypto,boolean"` // Is currency belongs to blockchain (false for ICO and fiat, like EUR) PayinEnabled bool `json:"payinEnabled"` // Is allowed for deposit (false for ICO) - PayinPaymentId bool `json:"payinPaymentId"` // Is required to provide additional information other than the address for deposit + PayinPaymentID bool `json:"payinPaymentId"` // Is required to provide additional information other than the address for deposit PayinConfirmations int64 `json:"payinConfirmations"` // Blocks confirmations count for deposit PayoutEnabled bool `json:"payoutEnabled"` // Is allowed for withdraw (false for ICO) - PayoutIsPaymentId bool `json:"payoutIsPaymentId"` // Is allowed to provide additional information for withdraw + PayoutIsPaymentID bool `json:"payoutIsPaymentId"` // Is allowed to provide additional information for withdraw TransferEnabled bool `json:"transferEnabled"` // Is allowed to transfer between trading and account (may be disabled on maintain) } +// LoanOrder contains information about your loans type LoanOrder struct { Rate float64 `json:"rate,string"` Amount float64 `json:"amount,string"` @@ -91,11 +101,13 @@ type LoanOrder struct { RangeMax int `json:"rangeMax"` } +// LoanOrders holds information on the full range of loan orders type LoanOrders struct { Offers []LoanOrder `json:"offers"` Demands []LoanOrder `json:"demands"` } +// Balance is a simple balance type type Balance struct { Currency string `json:"currency"` Available float64 `json:"available,string"` // Amount available for trading or transfer to main account @@ -103,14 +115,16 @@ type Balance struct { } +// DepositCryptoAddresses contains address information type DepositCryptoAddresses struct { Address string `json:"address"` // Address for deposit - PaymentId string `json:"paymentId"` // Optional additional parameter. Required for deposit if persist + PaymentID string `json:"paymentId"` // Optional additional parameter. Required for deposit if persist } +// Order contains information about an order type Order struct { - Id int64 `json:"id,string"` // Unique identifier for Order as assigned by exchange - ClientOrderId string `json:"clientOrderId"` // Unique identifier for Order as assigned by trader. Uniqueness must be + ID int64 `json:"id,string"` // Unique identifier for Order as assigned by exchange + ClientOrderID string `json:"clientOrderId"` // Unique identifier for Order as assigned by trader. Uniqueness must be // guaranteed within a single trading day, including all active orders. Symbol string `json:"symbol"` // Trading symbol Side string `json:"side"` // sell buy @@ -134,14 +148,17 @@ type Order struct { ExpireTime time.Time `json:"expireTime,string"` } +// OpenOrdersResponseAll holds the full open order response type OpenOrdersResponseAll struct { Data map[string][]Order } +// OpenOrdersResponse contains open order information type OpenOrdersResponse struct { Data []Order } +// AuthentictedTradeHistory contains trade history data type AuthentictedTradeHistory struct { GlobalTradeID int64 `json:"globalTradeID"` TradeID int64 `json:"tradeID,string"` @@ -155,14 +172,17 @@ type AuthentictedTradeHistory struct { Category string `json:"category"` } +// AuthenticatedTradeHistoryAll contains the full trade history type AuthenticatedTradeHistoryAll struct { Data map[string][]AuthentictedTradeHistory } +// AuthenticatedTradeHistoryResponse is the resp type for trade history type AuthenticatedTradeHistoryResponse struct { Data []AuthentictedTradeHistory } +// ResultingTrades holds resulting trade information type ResultingTrades struct { Amount float64 `json:"amount,string"` Date string `json:"date"` @@ -172,16 +192,19 @@ type ResultingTrades struct { Type string `json:"type"` } +// OrderResponse holds the order response information type OrderResponse struct { OrderNumber int64 `json:"orderNumber,string"` Trades []ResultingTrades `json:"resultingTrades"` } +// GenericResponse is the common response from HitBTC type GenericResponse struct { Success int `json:"success"` Error string `json:"error"` } +// MoveOrderResponse holds information about a move order type MoveOrderResponse struct { Success int `json:"success"` Error string `json:"error"` @@ -189,16 +212,19 @@ type MoveOrderResponse struct { Trades map[string][]ResultingTrades `json:"resultingTrades"` } +// Withdraw holds response for a withdrawel process type Withdraw struct { Response string `json:"response"` Error string `json:"error"` } +// Fee holds fee structure type Fee struct { TakeLiquidityRate float64 `json:"takeLiquidityRate,string"` // Taker ProvideLiquidityRate float64 `json:"provideLiquidityRate,string"` // Maker } +// Margin holds full margin information type Margin struct { TotalValue float64 `json:"totalValue,string"` ProfitLoss float64 `json:"pl,string"` @@ -208,6 +234,7 @@ type Margin struct { CurrentMargin float64 `json:"currentMargin,string"` } +// MarginPosition holds information about your current margin position type MarginPosition struct { Amount float64 `json:"amount,string"` Total float64 `json:"total,string"` @@ -218,6 +245,7 @@ type MarginPosition struct { Type string `json:"type"` } +// LoanOffer holds information about your loan offers type LoanOffer struct { ID int64 `json:"id"` Rate float64 `json:"rate,string"` @@ -227,11 +255,13 @@ type LoanOffer struct { Date string `json:"date"` } +// ActiveLoans holds information about your active loans type ActiveLoans struct { Provided []LoanOffer `json:"provided"` Used []LoanOffer `json:"used"` } +// LendingHistory contains lending history data type LendingHistory struct { ID int64 `json:"id"` Currency string `json:"currency"` diff --git a/exchanges/hitbtc/hitbtc_websocket.go b/exchanges/hitbtc/hitbtc_websocket.go index 5552f8dd..623429fb 100644 --- a/exchanges/hitbtc/hitbtc_websocket.go +++ b/exchanges/hitbtc/hitbtc_websocket.go @@ -8,13 +8,14 @@ import ( ) const ( - HITBTC_WEBSOCKET_ADDRESS = "wss://api.hitbtc.com" - HITBTC_WEBSOCKET_REALM = "realm1" - HITBTC_WEBSOCKET_TICKER = "ticker" - HITBTC_WEBSOCKET_TROLLBOX = "trollbox" + hitbtcWebsocketAddress = "wss://api.hitbtc.com" + hitbtcWebsocketRealm = "realm1" + hitbtcWebsocketTicker = "ticker" + hitbtcWebsocketTrollbox = "trollbox" ) -type HitBTCWebsocketTicker struct { +// WebsocketTicker holds ticker data +type WebsocketTicker struct { CurrencyPair string Last float64 LowestAsk float64 @@ -27,8 +28,9 @@ type HitBTCWebsocketTicker struct { Low float64 } -func HitBTCOnTicker(args []interface{}, kwargs map[string]interface{}) { - ticker := HitBTCWebsocketTicker{} +// OnTicker converts ticker to websocket ticker +func OnTicker(args []interface{}, kwargs map[string]interface{}) { + ticker := WebsocketTicker{} ticker.CurrencyPair = args[0].(string) ticker.Last, _ = strconv.ParseFloat(args[1].(string), 64) ticker.LowestAsk, _ = strconv.ParseFloat(args[2].(string), 64) @@ -47,15 +49,17 @@ func HitBTCOnTicker(args []interface{}, kwargs map[string]interface{}) { ticker.Low, _ = strconv.ParseFloat(args[9].(string), 64) } -type HitBTCWebsocketTrollboxMessage struct { +// WebsocketTrollboxMessage contains trollbox message information +type WebsocketTrollboxMessage struct { MessageNumber float64 Username string Message string Reputation float64 } -func HitBTCOnTrollbox(args []interface{}, kwargs map[string]interface{}) { - message := HitBTCWebsocketTrollboxMessage{} +// OnTrollbox converts trollbox messages +func OnTrollbox(args []interface{}, kwargs map[string]interface{}) { + message := WebsocketTrollboxMessage{} message.MessageNumber, _ = args[1].(float64) message.Username = args[2].(string) message.Message = args[3].(string) @@ -64,7 +68,8 @@ func HitBTCOnTrollbox(args []interface{}, kwargs map[string]interface{}) { } } -func HitBTCOnDepthOrTrade(args []interface{}, kwargs map[string]interface{}) { +// OnDepthOrTrade converts depth and trade data +func OnDepthOrTrade(args []interface{}, kwargs map[string]interface{}) { for x := range args { data := args[x].(map[string]interface{}) msgData := data["data"].(map[string]interface{}) @@ -133,9 +138,10 @@ func HitBTCOnDepthOrTrade(args []interface{}, kwargs map[string]interface{}) { } } +// WebsocketClient initiates a websocket client func (p *HitBTC) WebsocketClient() { for p.Enabled && p.Websocket { - c, err := turnpike.NewWebsocketClient(turnpike.JSON, HITBTC_WEBSOCKET_ADDRESS, nil) + c, err := turnpike.NewWebsocketClient(turnpike.JSON, hitbtcWebsocketAddress, nil) if err != nil { log.Printf("%s Unable to connect to Websocket. Error: %s\n", p.GetName(), err) continue @@ -145,7 +151,7 @@ func (p *HitBTC) WebsocketClient() { log.Printf("%s Connected to Websocket.\n", p.GetName()) } - _, err = c.JoinRealm(HITBTC_WEBSOCKET_REALM, nil) + _, err = c.JoinRealm(hitbtcWebsocketRealm, nil) if err != nil { log.Printf("%s Unable to join realm. Error: %s\n", p.GetName(), err) continue @@ -157,17 +163,17 @@ func (p *HitBTC) WebsocketClient() { c.ReceiveDone = make(chan bool) - if err := c.Subscribe(HITBTC_WEBSOCKET_TICKER, HitBTCOnTicker); err != nil { + if err := c.Subscribe(hitbtcWebsocketTicker, OnTicker); err != nil { log.Printf("%s Error subscribing to ticker channel: %s\n", p.GetName(), err) } - if err := c.Subscribe(HITBTC_WEBSOCKET_TROLLBOX, HitBTCOnTrollbox); err != nil { + if err := c.Subscribe(hitbtcWebsocketTrollbox, OnTrollbox); err != nil { log.Printf("%s Error subscribing to trollbox channel: %s\n", p.GetName(), err) } for x := range p.EnabledPairs { currency := p.EnabledPairs[x] - if err := c.Subscribe(currency, HitBTCOnDepthOrTrade); err != nil { + if err := c.Subscribe(currency, OnDepthOrTrade); err != nil { log.Printf("%s Error subscribing to %s channel: %s\n", p.GetName(), currency, err) } } diff --git a/exchanges/hitbtc/hitbtc_wrapper.go b/exchanges/hitbtc/hitbtc_wrapper.go index 2eb7d025..d5489cd7 100644 --- a/exchanges/hitbtc/hitbtc_wrapper.go +++ b/exchanges/hitbtc/hitbtc_wrapper.go @@ -12,28 +12,28 @@ import ( ) // Start starts the HitBTC go routine -func (p *HitBTC) Start() { - go p.Run() +func (h *HitBTC) Start() { + go h.Run() } // Run implements the HitBTC wrapper -func (p *HitBTC) Run() { - if p.Verbose { - log.Printf("%s Websocket: %s (url: %s).\n", p.GetName(), common.IsEnabled(p.Websocket), HITBTC_WEBSOCKET_ADDRESS) - log.Printf("%s polling delay: %ds.\n", p.GetName(), p.RESTPollingDelay) - log.Printf("%s %d currencies enabled: %s.\n", p.GetName(), len(p.EnabledPairs), p.EnabledPairs) +func (h *HitBTC) Run() { + if h.Verbose { + log.Printf("%s Websocket: %s (url: %s).\n", h.GetName(), common.IsEnabled(h.Websocket), hitbtcWebsocketAddress) + log.Printf("%s polling delay: %ds.\n", h.GetName(), h.RESTPollingDelay) + log.Printf("%s %d currencies enabled: %s.\n", h.GetName(), len(h.EnabledPairs), h.EnabledPairs) } - if p.Websocket { - go p.WebsocketClient() + if h.Websocket { + go h.WebsocketClient() } - exchangeProducts, err := p.GetSymbolsDetailed() + exchangeProducts, err := h.GetSymbolsDetailed() if err != nil { - log.Printf("%s Failed to get available symbols.\n", p.GetName()) + log.Printf("%s Failed to get available symbols.\n", h.GetName()) } else { forceUpgrade := false - if !common.StringDataContains(p.EnabledPairs, "-") || !common.StringDataContains(p.AvailablePairs, "-") { + if !common.StringDataContains(h.EnabledPairs, "-") || !common.StringDataContains(h.AvailablePairs, "-") { forceUpgrade = true } var currencies []string @@ -45,28 +45,28 @@ func (p *HitBTC) Run() { enabledPairs := []string{"BTC-USD"} log.Println("WARNING: Available pairs for HitBTC reset due to config upgrade, please enable the ones you would like again.") - err = p.UpdateEnabledCurrencies(enabledPairs, true) + err = h.UpdateEnabledCurrencies(enabledPairs, true) if err != nil { - log.Printf("%s Failed to update enabled currencies.\n", p.GetName()) + log.Printf("%s Failed to update enabled currencies.\n", h.GetName()) } } - err = p.UpdateAvailableCurrencies(currencies, forceUpgrade) + err = h.UpdateAvailableCurrencies(currencies, forceUpgrade) if err != nil { - log.Printf("%s Failed to update available currencies.\n", p.GetName()) + log.Printf("%s Failed to update available currencies.\n", h.GetName()) } } } // UpdateTicker updates and returns the ticker for a currency pair -func (p *HitBTC) UpdateTicker(currencyPair pair.CurrencyPair, assetType string) (ticker.Price, error) { - tick, err := p.GetTicker("") +func (h *HitBTC) UpdateTicker(currencyPair pair.CurrencyPair, assetType string) (ticker.Price, error) { + tick, err := h.GetTicker("") if err != nil { return ticker.Price{}, err } - for _, x := range p.GetEnabledCurrencies() { + for _, x := range h.GetEnabledCurrencies() { var tp ticker.Price - curr := exchange.FormatExchangeCurrency(p.GetName(), x).String() + curr := exchange.FormatExchangeCurrency(h.GetName(), x).String() tp.Pair = x tp.Ask = tick[curr].Ask tp.Bid = tick[curr].Bid @@ -74,33 +74,33 @@ func (p *HitBTC) UpdateTicker(currencyPair pair.CurrencyPair, assetType string) tp.Last = tick[curr].Last tp.Low = tick[curr].Low tp.Volume = tick[curr].Volume - ticker.ProcessTicker(p.GetName(), x, tp, assetType) + ticker.ProcessTicker(h.GetName(), x, tp, assetType) } - return ticker.GetTicker(p.Name, currencyPair, assetType) + return ticker.GetTicker(h.Name, currencyPair, assetType) } // GetTickerPrice returns the ticker for a currency pair -func (p *HitBTC) GetTickerPrice(currencyPair pair.CurrencyPair, assetType string) (ticker.Price, error) { - tickerNew, err := ticker.GetTicker(p.GetName(), currencyPair, assetType) +func (h *HitBTC) GetTickerPrice(currencyPair pair.CurrencyPair, assetType string) (ticker.Price, error) { + tickerNew, err := ticker.GetTicker(h.GetName(), currencyPair, assetType) if err != nil { - return p.UpdateTicker(currencyPair, assetType) + return h.UpdateTicker(currencyPair, assetType) } return tickerNew, nil } // GetOrderbookEx returns orderbook base on the currency pair -func (p *HitBTC) GetOrderbookEx(currencyPair pair.CurrencyPair, assetType string) (orderbook.Base, error) { - ob, err := orderbook.GetOrderbook(p.GetName(), currencyPair, assetType) +func (h *HitBTC) GetOrderbookEx(currencyPair pair.CurrencyPair, assetType string) (orderbook.Base, error) { + ob, err := orderbook.GetOrderbook(h.GetName(), currencyPair, assetType) if err != nil { - return p.UpdateOrderbook(currencyPair, assetType) + return h.UpdateOrderbook(currencyPair, assetType) } return ob, nil } // UpdateOrderbook updates and returns the orderbook for a currency pair -func (p *HitBTC) UpdateOrderbook(currencyPair pair.CurrencyPair, assetType string) (orderbook.Base, error) { +func (h *HitBTC) UpdateOrderbook(currencyPair pair.CurrencyPair, assetType string) (orderbook.Base, error) { var orderBook orderbook.Base - orderbookNew, err := p.GetOrderbook(exchange.FormatExchangeCurrency(p.GetName(), currencyPair).String(), 1000) + orderbookNew, err := h.GetOrderbook(exchange.FormatExchangeCurrency(h.GetName(), currencyPair).String(), 1000) if err != nil { return orderBook, err } @@ -115,16 +115,16 @@ func (p *HitBTC) UpdateOrderbook(currencyPair pair.CurrencyPair, assetType strin orderBook.Asks = append(orderBook.Asks, orderbook.Item{Amount: data.Amount, Price: data.Price}) } - orderbook.ProcessOrderbook(p.GetName(), currencyPair, orderBook, assetType) - return orderbook.GetOrderbook(p.Name, currencyPair, assetType) + orderbook.ProcessOrderbook(h.GetName(), currencyPair, orderBook, assetType) + return orderbook.GetOrderbook(h.Name, currencyPair, assetType) } // GetExchangeAccountInfo retrieves balances for all enabled currencies for the // HitBTC exchange -func (p *HitBTC) GetExchangeAccountInfo() (exchange.AccountInfo, error) { +func (h *HitBTC) GetExchangeAccountInfo() (exchange.AccountInfo, error) { var response exchange.AccountInfo - response.ExchangeName = p.GetName() - accountBalance, err := p.GetBalances() + response.ExchangeName = h.GetName() + accountBalance, err := h.GetBalances() if err != nil { return response, err }