mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-21 07:26:48 +00:00
Update Huobi REST authenticated and unauthenticated requests
This commit is contained in:
@@ -1,11 +1,12 @@
|
||||
package huobi
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
@@ -15,8 +16,35 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
huobiAPIURL = "https://api.huobi.com/apiv2.php"
|
||||
huobiAPIVersion = "2"
|
||||
huobiAPIURL = "https://api.huobi.pro"
|
||||
huobiAPIVersion = "1"
|
||||
|
||||
huobiMarketHistoryKline = "market/history/kline"
|
||||
huobiMarketDetail = "market/detail"
|
||||
huobiMarketDetailMerged = "market/detail/merged"
|
||||
huobiMarketDepth = "market/depth"
|
||||
huobiMarketTrade = "market/trade"
|
||||
huobiMarketTradeHistory = "market/history/trade"
|
||||
huobiSymbols = "common/symbols"
|
||||
huobiCurrencies = "common/currencys"
|
||||
huobiTimestamp = "common/timestamp"
|
||||
huobiAccounts = "account/accounts"
|
||||
huobiAccountBalance = "account/accounts/%s/balance"
|
||||
huobiOrderPlace = "order/orders/place"
|
||||
huobiOrderCancel = "order/orders/%s/submitcancel"
|
||||
huobiOrderCancelBatch = "order/orders/batchcancel"
|
||||
huobiGetOrder = "order/orders/%s"
|
||||
huobiGetOrderMatch = "order/orders/%s/matchresults"
|
||||
huobiGetOrders = "order/orders"
|
||||
huobiGetOrdersMatch = "orders/matchresults"
|
||||
huobiMarginTransferIn = "dw/transfer-in/margin"
|
||||
huobiMarginTransferOut = "dw/transfer-out/margin"
|
||||
huobiMarginOrders = "margin/orders"
|
||||
huobiMarginRepay = "margin/orders/%s/repay"
|
||||
huobiMarginLoanOrders = "margin/loan-orders"
|
||||
huobiMarginAccountBalance = "margin/accounts/balance"
|
||||
huobiWithdrawCreate = "dw/withdraw/api/create"
|
||||
huobiWithdrawCancel = "dw/withdraw-virtual/%s/cancel"
|
||||
)
|
||||
|
||||
// HUOBI is the overarching type across this package
|
||||
@@ -34,7 +62,7 @@ func (h *HUOBI) SetDefaults() {
|
||||
h.RESTPollingDelay = 10
|
||||
h.RequestCurrencyPairFormat.Delimiter = ""
|
||||
h.RequestCurrencyPairFormat.Uppercase = false
|
||||
h.ConfigCurrencyPairFormat.Delimiter = ""
|
||||
h.ConfigCurrencyPairFormat.Delimiter = "-"
|
||||
h.ConfigCurrencyPairFormat.Uppercase = true
|
||||
h.AssetTypes = []string{ticker.Spot}
|
||||
}
|
||||
@@ -69,163 +97,628 @@ func (h *HUOBI) GetFee() float64 {
|
||||
return h.Fee
|
||||
}
|
||||
|
||||
// GetTicker returns the Huobi ticker
|
||||
func (h *HUOBI) GetTicker(symbol string) (Ticker, error) {
|
||||
resp := TickerResponse{}
|
||||
path := fmt.Sprintf("https://api.huobi.com/staticmarket/ticker_%s_json.js", symbol)
|
||||
// GetKline returns kline data
|
||||
func (h *HUOBI) GetKline(symbol, period, size string) ([]Klines, error) {
|
||||
vals := url.Values{}
|
||||
vals.Set("symbol", symbol)
|
||||
|
||||
return resp.Ticker, common.SendHTTPGetRequest(path, true, h.Verbose, &resp)
|
||||
if period != "" {
|
||||
vals.Set("period", period)
|
||||
}
|
||||
|
||||
if size != "" {
|
||||
vals.Set("size", size)
|
||||
}
|
||||
|
||||
type response struct {
|
||||
Response
|
||||
Data []Klines `json:"data"`
|
||||
}
|
||||
|
||||
var result response
|
||||
url := fmt.Sprintf("%s/%s", huobiAPIURL, huobiMarketHistoryKline)
|
||||
err := common.SendHTTPGetRequest(common.EncodeURLValues(url, vals), true, h.Verbose, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return nil, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.Data, err
|
||||
}
|
||||
|
||||
// GetOrderBook returns the Huobi current orderbook for a currency pair
|
||||
func (h *HUOBI) GetOrderBook(symbol string) (Orderbook, error) {
|
||||
path := fmt.Sprintf("https://api.huobi.com/staticmarket/depth_%s_json.js", symbol)
|
||||
resp := Orderbook{}
|
||||
// GetMarketDetailMerged returns the ticker for the specified symbol
|
||||
func (h *HUOBI) GetMarketDetailMerged(symbol string) (DetailMerged, error) {
|
||||
vals := url.Values{}
|
||||
vals.Set("symbol", symbol)
|
||||
|
||||
return resp, common.SendHTTPGetRequest(path, true, h.Verbose, &resp)
|
||||
type response struct {
|
||||
Response
|
||||
Tick DetailMerged `json:"tick"`
|
||||
}
|
||||
|
||||
var result response
|
||||
url := fmt.Sprintf("%s/%s", huobiAPIURL, huobiMarketDetailMerged)
|
||||
err := common.SendHTTPGetRequest(common.EncodeURLValues(url, vals), true, h.Verbose, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return result.Tick, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.Tick, err
|
||||
}
|
||||
|
||||
// GetAccountInfo returns account information
|
||||
func (h *HUOBI) GetAccountInfo() {
|
||||
err := h.SendAuthenticatedRequest("get_account_info", url.Values{})
|
||||
// GetDepth returns the depth for the specified symbol
|
||||
func (h *HUOBI) GetDepth(symbol, depthType string) (Orderbook, error) {
|
||||
vals := url.Values{}
|
||||
vals.Set("symbol", symbol)
|
||||
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
if depthType != "" {
|
||||
vals.Set("type", depthType)
|
||||
}
|
||||
|
||||
type response struct {
|
||||
Response
|
||||
Depth Orderbook `json:"tick"`
|
||||
}
|
||||
|
||||
var result response
|
||||
url := fmt.Sprintf("%s/%s", huobiAPIURL, huobiMarketDepth)
|
||||
err := common.SendHTTPGetRequest(common.EncodeURLValues(url, vals), true, h.Verbose, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return result.Depth, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.Depth, err
|
||||
}
|
||||
|
||||
// GetOrders returns full list of orders
|
||||
func (h *HUOBI) GetOrders(coinType int) {
|
||||
values := url.Values{}
|
||||
values.Set("coin_type", strconv.Itoa(coinType))
|
||||
err := h.SendAuthenticatedRequest("get_orders", values)
|
||||
// GetTrades returns the trades for the specified symbol
|
||||
func (h *HUOBI) GetTrades(symbol string) ([]Trade, error) {
|
||||
vals := url.Values{}
|
||||
vals.Set("symbol", symbol)
|
||||
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
type response struct {
|
||||
Response
|
||||
tick struct {
|
||||
Data []Trade `json:"data"`
|
||||
} `json:"tick"`
|
||||
}
|
||||
|
||||
var result response
|
||||
url := fmt.Sprintf("%s/%s", huobiAPIURL, huobiMarketTrade)
|
||||
err := common.SendHTTPGetRequest(common.EncodeURLValues(url, vals), true, h.Verbose, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return nil, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.tick.Data, err
|
||||
}
|
||||
|
||||
// GetOrderInfo returns specific info on an order
|
||||
func (h *HUOBI) GetOrderInfo(orderID, coinType int) {
|
||||
values := url.Values{}
|
||||
values.Set("id", strconv.Itoa(orderID))
|
||||
values.Set("coin_type", strconv.Itoa(coinType))
|
||||
err := h.SendAuthenticatedRequest("order_info", values)
|
||||
// GetTradeHistory returns the trades for the specified symbol
|
||||
func (h *HUOBI) GetTradeHistory(symbol, size string) ([]TradeHistory, error) {
|
||||
vals := url.Values{}
|
||||
vals.Set("symbol", symbol)
|
||||
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
if size != "" {
|
||||
vals.Set("size", size)
|
||||
}
|
||||
|
||||
type response struct {
|
||||
Response
|
||||
TradeHistory []TradeHistory `json:"data"`
|
||||
}
|
||||
|
||||
var result response
|
||||
url := fmt.Sprintf("%s/%s", huobiAPIURL, huobiMarketTradeHistory)
|
||||
err := common.SendHTTPGetRequest(common.EncodeURLValues(url, vals), true, h.Verbose, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return nil, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.TradeHistory, err
|
||||
}
|
||||
|
||||
// Trade opens a trade on the Huobi exchange
|
||||
func (h *HUOBI) Trade(orderType string, coinType int, price, amount float64) {
|
||||
values := url.Values{}
|
||||
if orderType != "buy" {
|
||||
orderType = "sell"
|
||||
}
|
||||
values.Set("coin_type", strconv.Itoa(coinType))
|
||||
values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64))
|
||||
values.Set("price", strconv.FormatFloat(price, 'f', -1, 64))
|
||||
err := h.SendAuthenticatedRequest(orderType, values)
|
||||
// GetMarketDetail returns the ticker for the specified symbol
|
||||
func (h *HUOBI) GetMarketDetail(symbol string) (Detail, error) {
|
||||
vals := url.Values{}
|
||||
vals.Set("symbol", symbol)
|
||||
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
type response struct {
|
||||
Response
|
||||
tick Detail `json:"tick"`
|
||||
}
|
||||
|
||||
var result response
|
||||
url := fmt.Sprintf("%s/%s", huobiAPIURL, huobiMarketDetail)
|
||||
err := common.SendHTTPGetRequest(common.EncodeURLValues(url, vals), true, h.Verbose, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return result.tick, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.tick, err
|
||||
}
|
||||
|
||||
// MarketTrade initiates a market trade
|
||||
func (h *HUOBI) MarketTrade(orderType string, coinType int, price, amount float64) {
|
||||
values := url.Values{}
|
||||
if orderType != "buy_market" {
|
||||
orderType = "sell_market"
|
||||
// GetSymbols returns an array of symbols supported by Huobi
|
||||
func (h *HUOBI) GetSymbols() ([]Symbol, error) {
|
||||
type response struct {
|
||||
Response
|
||||
Symbols []Symbol `json:"data"`
|
||||
}
|
||||
values.Set("coin_type", strconv.Itoa(coinType))
|
||||
values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64))
|
||||
values.Set("price", strconv.FormatFloat(price, 'f', -1, 64))
|
||||
err := h.SendAuthenticatedRequest(orderType, values)
|
||||
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
var result response
|
||||
url := fmt.Sprintf("%s/v%s/%s", huobiAPIURL, huobiAPIVersion, huobiSymbols)
|
||||
err := common.SendHTTPGetRequest(url, true, h.Verbose, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return nil, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.Symbols, err
|
||||
}
|
||||
|
||||
// CancelOrder cancels order by order ID
|
||||
func (h *HUOBI) CancelOrder(orderID, coinType int) {
|
||||
values := url.Values{}
|
||||
values.Set("coin_type", strconv.Itoa(coinType))
|
||||
values.Set("id", strconv.Itoa(orderID))
|
||||
err := h.SendAuthenticatedRequest("cancel_order", values)
|
||||
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
// GetCurrencies returns a list of currencies supported by Huobi
|
||||
func (h *HUOBI) GetCurrencies() ([]string, error) {
|
||||
type response struct {
|
||||
Response
|
||||
Currencies []string `json:"data"`
|
||||
}
|
||||
|
||||
var result response
|
||||
url := fmt.Sprintf("%s/v%s/%s", huobiAPIURL, huobiAPIVersion, huobiCurrencies)
|
||||
err := common.SendHTTPGetRequest(url, true, h.Verbose, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return nil, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.Currencies, err
|
||||
}
|
||||
|
||||
// ModifyOrder modifies an order
|
||||
func (h *HUOBI) ModifyOrder(orderType string, coinType, orderID int, price, amount float64) {
|
||||
values := url.Values{}
|
||||
values.Set("coin_type", strconv.Itoa(coinType))
|
||||
values.Set("id", strconv.Itoa(orderID))
|
||||
values.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64))
|
||||
values.Set("price", strconv.FormatFloat(price, 'f', -1, 64))
|
||||
err := h.SendAuthenticatedRequest("modify_order", values)
|
||||
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
// GetTimestamp returns the Huobi server time
|
||||
func (h *HUOBI) GetTimestamp() (int64, error) {
|
||||
type response struct {
|
||||
Response
|
||||
Timestamp int64 `json:"data"`
|
||||
}
|
||||
|
||||
var result response
|
||||
url := fmt.Sprintf("%s/v%s/%s", huobiAPIURL, huobiAPIVersion, huobiTimestamp)
|
||||
err := common.SendHTTPGetRequest(url, true, h.Verbose, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return 0, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.Timestamp, err
|
||||
}
|
||||
|
||||
// GetNewDealOrders creates a new deal
|
||||
func (h *HUOBI) GetNewDealOrders(coinType int) {
|
||||
values := url.Values{}
|
||||
values.Set("coin_type", strconv.Itoa(coinType))
|
||||
err := h.SendAuthenticatedRequest("get_new_deal_orders", values)
|
||||
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
// GetAccounts returns the Huobi user accounts
|
||||
func (h *HUOBI) GetAccounts() ([]Account, error) {
|
||||
type response struct {
|
||||
Response
|
||||
AccountData []Account `json:"data"`
|
||||
}
|
||||
|
||||
var result response
|
||||
err := h.SendAuthenticatedHTTPRequest("GET", huobiAccounts, url.Values{}, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return nil, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.AccountData, err
|
||||
}
|
||||
|
||||
// GetOrderIDByTradeID returns ORDERID by Trade ID
|
||||
func (h *HUOBI) GetOrderIDByTradeID(coinType, orderID int) {
|
||||
values := url.Values{}
|
||||
values.Set("coin_type", strconv.Itoa(coinType))
|
||||
values.Set("trade_id", strconv.Itoa(orderID))
|
||||
err := h.SendAuthenticatedRequest("get_order_id_by_trade_id", values)
|
||||
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
// GetAccountBalance returns the users Huobi account balance
|
||||
func (h *HUOBI) GetAccountBalance(accountID string) ([]AccountBalance, error) {
|
||||
type response struct {
|
||||
Response
|
||||
AccountData []AccountBalance `json:"list"`
|
||||
}
|
||||
|
||||
var result response
|
||||
endpoint := fmt.Sprintf(huobiAccountBalance, accountID)
|
||||
err := h.SendAuthenticatedHTTPRequest("GET", endpoint, url.Values{}, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return nil, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.AccountData, err
|
||||
}
|
||||
|
||||
// SendAuthenticatedRequest sends an autheticated HTTP request to Huobi
|
||||
func (h *HUOBI) SendAuthenticatedRequest(method string, v url.Values) error {
|
||||
// PlaceOrder submits an order to Huobi
|
||||
func (h *HUOBI) PlaceOrder(symbol, source, accountID, orderType string, amount, price float64) (int64, error) {
|
||||
vals := url.Values{}
|
||||
vals.Set("account-id", accountID)
|
||||
vals.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64))
|
||||
|
||||
// Only set price if order type is not equal to buy-market or sell-market
|
||||
if orderType != "buy-market" && orderType != "sell-market" {
|
||||
vals.Set("price", strconv.FormatFloat(price, 'f', -1, 64))
|
||||
}
|
||||
|
||||
if source != "" {
|
||||
vals.Set("source", source)
|
||||
}
|
||||
|
||||
vals.Set("symbol", symbol)
|
||||
vals.Set("type", orderType)
|
||||
|
||||
type response struct {
|
||||
Response
|
||||
OrderID int64 `json:"data,string"`
|
||||
}
|
||||
|
||||
var result response
|
||||
err := h.SendAuthenticatedHTTPRequest("POST", huobiOrderPlace, vals, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return 0, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.OrderID, err
|
||||
}
|
||||
|
||||
// CancelOrder cancels an order on Huobi
|
||||
func (h *HUOBI) CancelOrder(orderID int64) (int64, error) {
|
||||
type response struct {
|
||||
Response
|
||||
OrderID int64 `json:"data,string"`
|
||||
}
|
||||
|
||||
var result response
|
||||
endpoint := fmt.Sprintf(huobiOrderCancel, strconv.FormatInt(orderID, 10))
|
||||
err := h.SendAuthenticatedHTTPRequest("POST", endpoint, url.Values{}, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return 0, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.OrderID, err
|
||||
}
|
||||
|
||||
// CancelOrderBatch cancels a batch of orders -- to-do
|
||||
func (h *HUOBI) CancelOrderBatch(orderIDs []int64) ([]CancelOrderBatch, error) {
|
||||
type response struct {
|
||||
Response
|
||||
Data []CancelOrderBatch `json:"data"`
|
||||
}
|
||||
|
||||
var result response
|
||||
err := h.SendAuthenticatedHTTPRequest("POST", huobiOrderCancelBatch, url.Values{}, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return nil, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.Data, err
|
||||
}
|
||||
|
||||
// GetOrder returns order information for the specified order
|
||||
func (h *HUOBI) GetOrder(orderID int64) (OrderInfo, error) {
|
||||
type response struct {
|
||||
Response
|
||||
Order OrderInfo `json:"data"`
|
||||
}
|
||||
|
||||
var result response
|
||||
endpoint := fmt.Sprintf(huobiGetOrder, strconv.FormatInt(orderID, 10))
|
||||
err := h.SendAuthenticatedHTTPRequest("GET", endpoint, url.Values{}, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return result.Order, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.Order, err
|
||||
}
|
||||
|
||||
// GetOrderMatchResults returns matched order info for the specified order
|
||||
func (h *HUOBI) GetOrderMatchResults(orderID int64) ([]OrderMatchInfo, error) {
|
||||
type response struct {
|
||||
Response
|
||||
Orders []OrderMatchInfo `json:"data"`
|
||||
}
|
||||
|
||||
var result response
|
||||
endpoint := fmt.Sprintf(huobiGetOrderMatch, strconv.FormatInt(orderID, 10))
|
||||
err := h.SendAuthenticatedHTTPRequest("GET", endpoint, url.Values{}, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return nil, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.Orders, err
|
||||
}
|
||||
|
||||
// GetOrders returns a list of orders
|
||||
func (h *HUOBI) GetOrders(symbol, types, start, end, states, from, direct, size string) ([]OrderInfo, error) {
|
||||
type response struct {
|
||||
Response
|
||||
Orders []OrderInfo `json:"data"`
|
||||
}
|
||||
|
||||
vals := url.Values{}
|
||||
vals.Set("symbol", symbol)
|
||||
vals.Set("states", states)
|
||||
|
||||
if types != "" {
|
||||
vals.Set("types", types)
|
||||
}
|
||||
|
||||
if start != "" {
|
||||
vals.Set("start-date", start)
|
||||
}
|
||||
|
||||
if end != "" {
|
||||
vals.Set("end-date", end)
|
||||
}
|
||||
|
||||
if from != "" {
|
||||
vals.Set("from", from)
|
||||
}
|
||||
|
||||
if direct != "" {
|
||||
vals.Set("direct", direct)
|
||||
}
|
||||
|
||||
if size != "" {
|
||||
vals.Set("size", size)
|
||||
}
|
||||
|
||||
var result response
|
||||
err := h.SendAuthenticatedHTTPRequest("GET", huobiGetOrders, vals, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return nil, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.Orders, err
|
||||
}
|
||||
|
||||
// GetOrdersMatch returns a list of matched orders
|
||||
func (h *HUOBI) GetOrdersMatch(symbol, types, start, end, from, direct, size string) ([]OrderMatchInfo, error) {
|
||||
type response struct {
|
||||
Response
|
||||
Orders []OrderMatchInfo `json:"data"`
|
||||
}
|
||||
|
||||
vals := url.Values{}
|
||||
vals.Set("symbol", symbol)
|
||||
|
||||
if types != "" {
|
||||
vals.Set("types", types)
|
||||
}
|
||||
|
||||
if start != "" {
|
||||
vals.Set("start-date", start)
|
||||
}
|
||||
|
||||
if end != "" {
|
||||
vals.Set("end-date", end)
|
||||
}
|
||||
|
||||
if from != "" {
|
||||
vals.Set("from", from)
|
||||
}
|
||||
|
||||
if direct != "" {
|
||||
vals.Set("direct", direct)
|
||||
}
|
||||
|
||||
if size != "" {
|
||||
vals.Set("size", size)
|
||||
}
|
||||
|
||||
var result response
|
||||
err := h.SendAuthenticatedHTTPRequest("GET", huobiGetOrdersMatch, vals, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return nil, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.Orders, err
|
||||
}
|
||||
|
||||
// MarginTransfer transfers assets into or out of the margin account
|
||||
func (h *HUOBI) MarginTransfer(symbol, currency string, amount float64, in bool) (int64, error) {
|
||||
vals := url.Values{}
|
||||
vals.Set("symbol", symbol)
|
||||
vals.Set("currency", currency)
|
||||
vals.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64))
|
||||
|
||||
path := huobiMarginTransferIn
|
||||
if !in {
|
||||
path = huobiMarginTransferOut
|
||||
}
|
||||
|
||||
type response struct {
|
||||
Response
|
||||
TransferID int64 `json:"data"`
|
||||
}
|
||||
|
||||
var result response
|
||||
err := h.SendAuthenticatedHTTPRequest("POST", path, vals, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return 0, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.TransferID, err
|
||||
}
|
||||
|
||||
// MarginOrder submits a margin order application
|
||||
func (h *HUOBI) MarginOrder(symbol, currency string, amount float64) (int64, error) {
|
||||
vals := url.Values{}
|
||||
vals.Set("symbol", symbol)
|
||||
vals.Set("currency", currency)
|
||||
vals.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64))
|
||||
|
||||
type response struct {
|
||||
Response
|
||||
MarginOrderID int64 `json:"data"`
|
||||
}
|
||||
|
||||
var result response
|
||||
err := h.SendAuthenticatedHTTPRequest("POST", huobiMarginOrders, vals, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return 0, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.MarginOrderID, err
|
||||
}
|
||||
|
||||
// MarginRepayment repays a margin amount for a margin ID
|
||||
func (h *HUOBI) MarginRepayment(orderID int64, amount float64) (int64, error) {
|
||||
vals := url.Values{}
|
||||
vals.Set("order-id", strconv.FormatInt(orderID, 10))
|
||||
vals.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64))
|
||||
|
||||
type response struct {
|
||||
Response
|
||||
MarginOrderID int64 `json:"data"`
|
||||
}
|
||||
|
||||
var result response
|
||||
endpoint := fmt.Sprintf(huobiMarginRepay, strconv.FormatInt(orderID, 10))
|
||||
err := h.SendAuthenticatedHTTPRequest("POST", endpoint, vals, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return 0, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.MarginOrderID, err
|
||||
}
|
||||
|
||||
// GetMarginLoanOrders returns the margin loan orders
|
||||
func (h *HUOBI) GetMarginLoanOrders(symbol, currency, start, end, states, from, direct, size string) ([]MarginOrder, error) {
|
||||
vals := url.Values{}
|
||||
vals.Set("symbol", symbol)
|
||||
vals.Set("currency", currency)
|
||||
|
||||
if start != "" {
|
||||
vals.Set("start-date", start)
|
||||
}
|
||||
|
||||
if end != "" {
|
||||
vals.Set("end-date", end)
|
||||
}
|
||||
|
||||
if states != "" {
|
||||
vals.Set("states", states)
|
||||
}
|
||||
|
||||
if from != "" {
|
||||
vals.Set("from", from)
|
||||
}
|
||||
|
||||
if direct != "" {
|
||||
vals.Set("direct", direct)
|
||||
}
|
||||
|
||||
if size != "" {
|
||||
vals.Set("size", size)
|
||||
}
|
||||
|
||||
type response struct {
|
||||
Response
|
||||
MarginLoanOrders []MarginOrder `json:"data"`
|
||||
}
|
||||
|
||||
var result response
|
||||
err := h.SendAuthenticatedHTTPRequest("GET", huobiMarginLoanOrders, vals, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return nil, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.MarginLoanOrders, err
|
||||
}
|
||||
|
||||
// GetMarginAccountBalance returns the margin account balances
|
||||
func (h *HUOBI) GetMarginAccountBalance(symbol string) ([]MarginAccountBalance, error) {
|
||||
type response struct {
|
||||
Response
|
||||
Balances []MarginAccountBalance `json:"data"`
|
||||
}
|
||||
|
||||
vals := url.Values{}
|
||||
if symbol != "" {
|
||||
vals.Set("symbol", symbol)
|
||||
}
|
||||
|
||||
var result response
|
||||
err := h.SendAuthenticatedHTTPRequest("GET", huobiMarginAccountBalance, vals, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return nil, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.Balances, err
|
||||
}
|
||||
|
||||
// Withdraw withdraws the desired amount and currency
|
||||
func (h *HUOBI) Withdraw(address, currency, addrTag string, amount, fee float64) (int64, error) {
|
||||
type response struct {
|
||||
Response
|
||||
WithdrawID int64 `json:"data"`
|
||||
}
|
||||
|
||||
vals := url.Values{}
|
||||
vals.Set("address", address)
|
||||
vals.Set("currency", currency)
|
||||
vals.Set("amount", strconv.FormatFloat(amount, 'f', -1, 64))
|
||||
|
||||
if fee != 0 {
|
||||
vals.Set("fee", strconv.FormatFloat(fee, 'f', -1, 64))
|
||||
}
|
||||
|
||||
if currency == "XRP" {
|
||||
vals.Set("addr-tag", addrTag)
|
||||
}
|
||||
|
||||
var result response
|
||||
err := h.SendAuthenticatedHTTPRequest("POST", huobiWithdrawCreate, vals, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return 0, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.WithdrawID, err
|
||||
}
|
||||
|
||||
// CancelWithdraw cancels a withdraw request
|
||||
func (h *HUOBI) CancelWithdraw(withdrawID int64) (int64, error) {
|
||||
type response struct {
|
||||
Response
|
||||
WithdrawID int64 `json:"data"`
|
||||
}
|
||||
|
||||
vals := url.Values{}
|
||||
vals.Set("withdraw-id", strconv.FormatInt(withdrawID, 10))
|
||||
|
||||
var result response
|
||||
endpoint := fmt.Sprintf(huobiWithdrawCancel, strconv.FormatInt(withdrawID, 10))
|
||||
err := h.SendAuthenticatedHTTPRequest("POST", endpoint, vals, &result)
|
||||
|
||||
if result.ErrorMessage != "" {
|
||||
return 0, errors.New(result.ErrorMessage)
|
||||
}
|
||||
return result.WithdrawID, err
|
||||
}
|
||||
|
||||
// SendAuthenticatedHTTPRequest sends authenticated requests to the HUOBI API
|
||||
func (h *HUOBI) SendAuthenticatedHTTPRequest(method, endpoint string, values url.Values, result interface{}) error {
|
||||
if !h.AuthenticatedAPISupport {
|
||||
return fmt.Errorf(exchange.WarningAuthenticatedRequestWithoutCredentialsSet, h.Name)
|
||||
}
|
||||
|
||||
v.Set("access_key", h.APIKey)
|
||||
v.Set("created", strconv.FormatInt(time.Now().Unix(), 10))
|
||||
v.Set("method", method)
|
||||
hash := common.GetMD5([]byte(v.Encode() + "&secret_key=" + h.APISecret))
|
||||
v.Set("sign", common.StringToLower(common.HexEncodeToString(hash)))
|
||||
encoded := v.Encode()
|
||||
values.Set("AccessKeyId", h.APIKey)
|
||||
values.Set("SignatureMethod", "HmacSHA256")
|
||||
values.Set("SignatureVersion", "2")
|
||||
values.Set("Timestamp", time.Now().UTC().Format("2006-01-02T15:04:05"))
|
||||
|
||||
if h.Verbose {
|
||||
log.Printf("Sending POST request to %s with params %s\n", huobiAPIURL, encoded)
|
||||
}
|
||||
endpoint = fmt.Sprintf("/v%s/%s", huobiAPIVersion, endpoint)
|
||||
payload := fmt.Sprintf("%s\napi.huobi.pro\n%s\n%s",
|
||||
method, endpoint, values.Encode())
|
||||
|
||||
headers := make(map[string]string)
|
||||
headers["Content-Type"] = "application/x-www-form-urlencoded"
|
||||
|
||||
resp, err := common.SendHTTPRequest("POST", huobiAPIURL, headers, strings.NewReader(encoded))
|
||||
hmac := common.GetHMAC(common.HashSHA256, []byte(payload), []byte(h.APISecret))
|
||||
values.Set("Signature", common.Base64Encode(hmac))
|
||||
|
||||
url := fmt.Sprintf("%s%s", huobiAPIURL, endpoint)
|
||||
url = common.EncodeURLValues(url, values)
|
||||
resp, err := common.SendHTTPRequest(method, url, headers, bytes.NewBufferString(""))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if h.Verbose {
|
||||
log.Printf("Received raw: %s\n", resp)
|
||||
err = common.JSONDecode([]byte(resp), &result)
|
||||
if err != nil {
|
||||
return errors.New("unable to JSON Unmarshal response")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package huobi
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
@@ -37,14 +38,216 @@ func TestSetup(t *testing.T) {
|
||||
func TestGetFee(t *testing.T) {
|
||||
t.Parallel()
|
||||
if h.GetFee() != 0 {
|
||||
t.Error("test failed - Huobi GetFee() error")
|
||||
t.Errorf("test failed - Huobi GetFee() error")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTicker(t *testing.T) {
|
||||
func TestGetKline(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := h.GetTicker("btcusd")
|
||||
if err == nil {
|
||||
t.Error("test failed - Huobi GetTicker() error", err)
|
||||
_, err := h.GetKline("btcusdt", "1week", "")
|
||||
if err != nil {
|
||||
t.Errorf("Test failed - Huobi TestGetKline: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetMarketDetailMerged(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := h.GetMarketDetailMerged("btcusdt")
|
||||
if err != nil {
|
||||
t.Errorf("Test failed - Huobi TestGetMarketDetailMerged: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDepth(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := h.GetDepth("btcusdt", "step1")
|
||||
if err != nil {
|
||||
t.Errorf("Test failed - Huobi TestGetDepth: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTrades(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := h.GetTrades("btcusdt")
|
||||
if err != nil {
|
||||
t.Errorf("Test failed - Huobi TestGetTrades: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTradeHistory(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := h.GetTradeHistory("btcusdt", "50")
|
||||
if err != nil {
|
||||
t.Errorf("Test failed - Huobi TestGetTradeHistory: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetMarketDetail(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := h.GetMarketDetail("btcusdt")
|
||||
if err != nil {
|
||||
t.Errorf("Test failed - Huobi TestGetTradeHistory: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetSymbols(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := h.GetSymbols()
|
||||
if err != nil {
|
||||
t.Errorf("Test failed - Huobi TestGetSymbols: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetCurrencies(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := h.GetCurrencies()
|
||||
if err != nil {
|
||||
t.Errorf("Test failed - Huobi TestGetCurrencies: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetTimestamp(t *testing.T) {
|
||||
t.Parallel()
|
||||
_, err := h.GetTimestamp()
|
||||
if err != nil {
|
||||
t.Errorf("Test failed - Huobi TestGetTimestamp: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAccounts(t *testing.T) {
|
||||
t.Parallel()
|
||||
if apiKey == "" && apiSecret == "" {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
h.APIKey = apiKey
|
||||
h.APISecret = apiSecret
|
||||
h.AuthenticatedAPISupport = true
|
||||
|
||||
_, err := h.GetAccounts()
|
||||
if err != nil {
|
||||
t.Errorf("Test failed - Huobi GetAccounts: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAccountBalance(t *testing.T) {
|
||||
t.Parallel()
|
||||
if apiKey == "" && apiSecret == "" {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
h.APIKey = apiKey
|
||||
h.APISecret = apiSecret
|
||||
h.AuthenticatedAPISupport = true
|
||||
|
||||
result, err := h.GetAccounts()
|
||||
if err != nil {
|
||||
t.Errorf("Test failed - Huobi GetAccounts: %s", err)
|
||||
}
|
||||
|
||||
userID := strconv.FormatInt(result[0].ID, 10)
|
||||
_, err = h.GetAccountBalance(userID)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed - Huobi GetAccountBalance: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPlaceOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
if apiKey == "" && apiSecret == "" {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
h.APIKey = apiKey
|
||||
h.APISecret = apiSecret
|
||||
h.AuthenticatedAPISupport = true
|
||||
|
||||
_, err := h.GetAccounts()
|
||||
if err != nil {
|
||||
t.Errorf("Test failed - Huobi GetAccounts: %s", err)
|
||||
}
|
||||
|
||||
/*
|
||||
userID := strconv.FormatInt(result[0].ID, 10)
|
||||
_, err = h.PlaceOrder("ethusdt", "api", userID, "buy-limit", 10.1, 100.1)
|
||||
if err != nil {
|
||||
t.Errorf("Test failed - Huobi TestPlaceOrder: %s", err)
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
func TestCancelOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
if apiKey == "" && apiSecret == "" {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
h.APIKey = apiKey
|
||||
h.APISecret = apiSecret
|
||||
h.AuthenticatedAPISupport = true
|
||||
|
||||
_, err := h.CancelOrder(1337)
|
||||
if err == nil {
|
||||
t.Error("Test failed - Huobi TestCancelOrder: Invalid orderID returned true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetOrder(t *testing.T) {
|
||||
t.Parallel()
|
||||
if apiKey == "" && apiSecret == "" {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
h.APIKey = apiKey
|
||||
h.APISecret = apiSecret
|
||||
h.AuthenticatedAPISupport = true
|
||||
_, err := h.GetOrder(1337)
|
||||
if err == nil {
|
||||
t.Error("Test failed - Huobi TestCancelOrder: Invalid orderID returned true")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetMarginLoanOrders(t *testing.T) {
|
||||
t.Parallel()
|
||||
if apiKey == "" && apiSecret == "" {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
h.APIKey = apiKey
|
||||
h.APISecret = apiSecret
|
||||
h.AuthenticatedAPISupport = true
|
||||
_, err := h.GetMarginLoanOrders("btcusdt", "", "", "", "", "", "", "")
|
||||
if err != nil {
|
||||
t.Errorf("Test failed - Huobi TestGetMarginLoanOrders: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetMarginAccountBalance(t *testing.T) {
|
||||
t.Parallel()
|
||||
if apiKey == "" && apiSecret == "" {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
h.APIKey = apiKey
|
||||
h.APISecret = apiSecret
|
||||
h.AuthenticatedAPISupport = true
|
||||
_, err := h.GetMarginAccountBalance("btcusdt")
|
||||
if err != nil {
|
||||
t.Errorf("Test failed - Huobi TestGetMarginAccountBalance: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCancelWithdraw(t *testing.T) {
|
||||
t.Parallel()
|
||||
if apiKey == "" && apiSecret == "" {
|
||||
t.Skip()
|
||||
}
|
||||
|
||||
h.APIKey = apiKey
|
||||
h.APISecret = apiSecret
|
||||
h.AuthenticatedAPISupport = true
|
||||
_, err := h.CancelWithdraw(1337)
|
||||
if err == nil {
|
||||
t.Error("Test failed - Huobi TestCancelWithdraw: Invalid withdraw-ID was valid")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,171 @@
|
||||
package huobi
|
||||
|
||||
// Ticker holds ticker information
|
||||
type Ticker struct {
|
||||
High float64
|
||||
Low float64
|
||||
Last float64
|
||||
Vol float64
|
||||
Buy float64
|
||||
Sell float64
|
||||
// Response stores the Huobi response information
|
||||
type Response struct {
|
||||
Status string `json:"status"`
|
||||
Channel string `json:"ch"`
|
||||
Timestamp int64 `json:"ts"`
|
||||
ErrorCode string `json:"err-code"`
|
||||
ErrorMessage string `json:"err-msg"`
|
||||
}
|
||||
|
||||
// TickerResponse holds the initial response type
|
||||
type TickerResponse struct {
|
||||
Time string
|
||||
Ticker Ticker
|
||||
// KlineItem stores a kline item
|
||||
type KlineItem struct {
|
||||
ID int `json:"id"`
|
||||
Open float64 `json:"open"`
|
||||
Close float64 `json:"close"`
|
||||
Low float64 `json:"low"`
|
||||
High float64 `json:"high"`
|
||||
Amount float64 `json:"amount"`
|
||||
Vol float64 `json:"vol"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
// Orderbook holds the order book information
|
||||
// Klines stores tan array of kline items
|
||||
type Klines struct {
|
||||
Klines []KlineItem `json:"data"`
|
||||
}
|
||||
|
||||
// DetailMerged stores the ticker detail merged data
|
||||
type DetailMerged struct {
|
||||
Detail
|
||||
Version int `json:"version"`
|
||||
Ask []float64 `json:"ask"`
|
||||
Bid []float64 `json:"bid"`
|
||||
}
|
||||
|
||||
// Orderbook stores the orderbook data
|
||||
type Orderbook struct {
|
||||
ID float64
|
||||
TS float64
|
||||
Bids [][]float64 `json:"bids"`
|
||||
Asks [][]float64 `json:"asks"`
|
||||
Symbol string `json:"string"`
|
||||
ID int64 `json:"id"`
|
||||
Timetstamp int64 `json:"ts"`
|
||||
Bids [][]float64 `json:"bids"`
|
||||
Asks [][]float64 `json:"asks"`
|
||||
}
|
||||
|
||||
// Trade stores the trade data
|
||||
type Trade struct {
|
||||
ID float64 `json:"id"`
|
||||
Price float64 `json:"price"`
|
||||
Amount float64 `json:"amount"`
|
||||
Direction string `json:"direction"`
|
||||
Timestamp int64 `json:"ts"`
|
||||
}
|
||||
|
||||
// TradeHistory stores the the trade history data
|
||||
type TradeHistory struct {
|
||||
ID int64 `json:"id"`
|
||||
Timestamp int64 `json:"ts"`
|
||||
Trades []Trade `json:"data"`
|
||||
}
|
||||
|
||||
// Detail stores the ticker detail data
|
||||
type Detail struct {
|
||||
Amount float64 `json:"amount"`
|
||||
Open float64 `json:"open"`
|
||||
Close float64 `json:"close"`
|
||||
High float64 `json:"high"`
|
||||
Timestamp int64 `json:"id"`
|
||||
ID int `json:"id"`
|
||||
Count int `json:"count"`
|
||||
Low float64 `json:"low"`
|
||||
Volume float64 `json:"vol"`
|
||||
}
|
||||
|
||||
// Symbol stores the symbol data
|
||||
type Symbol struct {
|
||||
BaseCurrency string `json:"base-currency"`
|
||||
QuoteCurrency string `json:"quote-currency"`
|
||||
PricePrecision int `json:"price-precision"`
|
||||
AmountPrecision int `json:"amount-precision"`
|
||||
SymbolPartition string `json:"symbol-partition"`
|
||||
}
|
||||
|
||||
// Account stores the account data
|
||||
type Account struct {
|
||||
ID int64 `json:"id"`
|
||||
Type string `json:"type"`
|
||||
State string `json:"working"`
|
||||
UserID int64 `json:"user-id"`
|
||||
}
|
||||
|
||||
// AccountBalance stores the user account balance
|
||||
type AccountBalance struct {
|
||||
Currency string `json:"currency"`
|
||||
Type string `json:"type"`
|
||||
Balance float64 `json:"balance,string"`
|
||||
}
|
||||
|
||||
// CancelOrderBatch stores the cancel order batch data
|
||||
type CancelOrderBatch struct {
|
||||
Success []string `json:"success"`
|
||||
Failed []struct {
|
||||
OrderID int64 `json:"order-id,string"`
|
||||
ErrorCode string `json:"err-code"`
|
||||
ErrorMessage string `json:"err-msg"`
|
||||
} `json:"failed"`
|
||||
}
|
||||
|
||||
// OrderInfo stores the order info
|
||||
type OrderInfo struct {
|
||||
ID int `json:"id"`
|
||||
Symbol string `json:"symbol"`
|
||||
AccountID int `json:"account-id"`
|
||||
Amount string `json:"amount"`
|
||||
Price string `json:"price"`
|
||||
CreatedAt int64 `json:"created-at"`
|
||||
Type string `json:"type"`
|
||||
FieldAmount string `json:"field-amount"`
|
||||
FieldCashAmount string `json:"field-cash-amount"`
|
||||
FieldFees string `json:"field-fees"`
|
||||
FinishedAt int64 `json:"finished-at"`
|
||||
UserID int `json:"user-id"`
|
||||
Source string `json:"source"`
|
||||
State string `json:"state"`
|
||||
CanceledAt int `json:"canceled-at"`
|
||||
Exchange string `json:"exchange"`
|
||||
Batch string `json:"batch"`
|
||||
}
|
||||
|
||||
// OrderMatchInfo stores the order match info
|
||||
type OrderMatchInfo struct {
|
||||
ID int `json:"id"`
|
||||
OrderID int `json:"order-id"`
|
||||
MatchID int `json:"match-id"`
|
||||
Symbol string `json:"symbol"`
|
||||
Type string `json:"type"`
|
||||
Source string `json:"source"`
|
||||
Price string `json:"price"`
|
||||
FilledAmount string `json:"filled-amount"`
|
||||
FilledFees string `json:"filled-fees"`
|
||||
CreatedAt int64 `json:"created-at"`
|
||||
}
|
||||
|
||||
// MarginOrder stores the margin order info
|
||||
type MarginOrder struct {
|
||||
Currency string `json:"currency"`
|
||||
Symbol string `json:"symbol"`
|
||||
AccruedAt int64 `json:"accrued-at"`
|
||||
LoanAmount string `json:"loan-amount"`
|
||||
LoanBalance string `json:"loan-balance"`
|
||||
InterestBalance string `json:"interest-balance"`
|
||||
CreatedAt int64 `json:"created-at"`
|
||||
InterestAmount string `json:"interest-amount"`
|
||||
InterestRate string `json:"interest-rate"`
|
||||
AccountID int `json:"account-id"`
|
||||
UserID int `json:"user-id"`
|
||||
UpdatedAt int64 `json:"updated-at"`
|
||||
ID int `json:"id"`
|
||||
State string `json:"state"`
|
||||
}
|
||||
|
||||
// MarginAccountBalance stores the margin account balance info
|
||||
type MarginAccountBalance struct {
|
||||
ID int `json:"id"`
|
||||
Type string `json:"type"`
|
||||
State string `json:"state"`
|
||||
Symbol string `json:"symbol"`
|
||||
FlPrice string `json:"fl-price"`
|
||||
FlType string `json:"fl-type"`
|
||||
RiskRate string `json:"risk-rate"`
|
||||
List []AccountBalance `json:"list"`
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import (
|
||||
"log"
|
||||
|
||||
"github.com/thrasher-/gocryptotrader/common"
|
||||
"github.com/thrasher-/gocryptotrader/config"
|
||||
"github.com/thrasher-/gocryptotrader/currency/pair"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-/gocryptotrader/exchanges/orderbook"
|
||||
@@ -26,22 +27,70 @@ func (h *HUOBI) Run() {
|
||||
if h.Websocket {
|
||||
go h.WebsocketClient()
|
||||
}
|
||||
|
||||
exchangeProducts, err := h.GetSymbols()
|
||||
if err != nil {
|
||||
log.Printf("%s Failed to get available symbols.\n", h.GetName())
|
||||
} else {
|
||||
forceUpgrade := false
|
||||
if common.DataContains(h.EnabledPairs, "CNY") || common.DataContains(h.AvailablePairs, "CNY") {
|
||||
forceUpgrade = true
|
||||
}
|
||||
|
||||
if common.DataContains(h.BaseCurrencies, "CNY") {
|
||||
cfg := config.GetConfig()
|
||||
exchCfg, err := cfg.GetExchangeConfig(h.Name)
|
||||
if err != nil {
|
||||
log.Printf("%s failed to get exchange config. %s\n", h.Name, err)
|
||||
return
|
||||
}
|
||||
exchCfg.BaseCurrencies = "USD"
|
||||
h.BaseCurrencies = []string{"USD"}
|
||||
|
||||
err = cfg.UpdateExchangeConfig(exchCfg)
|
||||
if err != nil {
|
||||
log.Printf("%s failed to update config. %s\n", h.Name, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
var currencies []string
|
||||
for x := range exchangeProducts {
|
||||
newCurrency := exchangeProducts[x].BaseCurrency + "-" + exchangeProducts[x].QuoteCurrency
|
||||
currencies = append(currencies, newCurrency)
|
||||
}
|
||||
|
||||
if forceUpgrade {
|
||||
enabledPairs := []string{"btc-usdt"}
|
||||
log.Println("WARNING: Available and enabled pairs for Huobi reset due to config upgrade, please enable the ones you would like again")
|
||||
|
||||
err = h.UpdateEnabledCurrencies(enabledPairs, true)
|
||||
if err != nil {
|
||||
log.Printf("%s Failed to update enabled currencies.\n", h.GetName())
|
||||
}
|
||||
}
|
||||
err = h.UpdateAvailableCurrencies(currencies, forceUpgrade)
|
||||
if err != nil {
|
||||
log.Printf("%s Failed to update available currencies.\n", h.GetName())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// UpdateTicker updates and returns the ticker for a currency pair
|
||||
func (h *HUOBI) UpdateTicker(p pair.CurrencyPair, assetType string) (ticker.Price, error) {
|
||||
var tickerPrice ticker.Price
|
||||
tick, err := h.GetTicker(p.GetFirstCurrency().Lower().String())
|
||||
tick, err := h.GetMarketDetailMerged(exchange.FormatExchangeCurrency(h.Name, p).String())
|
||||
if err != nil {
|
||||
return tickerPrice, err
|
||||
}
|
||||
|
||||
tickerPrice.Pair = p
|
||||
tickerPrice.Ask = tick.Sell
|
||||
tickerPrice.Bid = tick.Buy
|
||||
tickerPrice.Low = tick.Low
|
||||
tickerPrice.Last = tick.Last
|
||||
tickerPrice.Volume = tick.Vol
|
||||
tickerPrice.Last = tick.Close
|
||||
tickerPrice.Volume = tick.Volume
|
||||
tickerPrice.High = tick.High
|
||||
tickerPrice.Ask = tick.Ask[0]
|
||||
tickerPrice.Bid = tick.Bid[0]
|
||||
ticker.ProcessTicker(h.GetName(), p, tickerPrice, assetType)
|
||||
return ticker.GetTicker(h.Name, p, assetType)
|
||||
}
|
||||
@@ -67,7 +116,7 @@ func (h *HUOBI) GetOrderbookEx(p pair.CurrencyPair, assetType string) (orderbook
|
||||
// UpdateOrderbook updates and returns the orderbook for a currency pair
|
||||
func (h *HUOBI) UpdateOrderbook(p pair.CurrencyPair, assetType string) (orderbook.Base, error) {
|
||||
var orderBook orderbook.Base
|
||||
orderbookNew, err := h.GetOrderBook(p.GetFirstCurrency().Lower().String())
|
||||
orderbookNew, err := h.GetDepth(exchange.FormatExchangeCurrency(h.Name, p).String(), "step1")
|
||||
if err != nil {
|
||||
return orderBook, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user