huobirdcenter / huobi_golang Goto Github PK
View Code? Open in Web Editor NEWGo SDK for Huobi Spot API
Home Page: https://www.htx.com/zh-cn/opend/newApiPages/
License: Apache License 2.0
Go SDK for Huobi Spot API
Home Page: https://www.htx.com/zh-cn/opend/newApiPages/
License: Apache License 2.0
WARNING: DATA RACE
Write at 0x00c000158128 by goroutine 56:
.../pkg/client/websocketclientbase.(*WebSocketV1ClientBase).readLoop()
.../pkg/client/websocketclientbase/websocketv1clientbase.go:212 +0x23c
Previous write at 0x00c000158128 by goroutine 16:
.../pkg/client/websocketclientbase.(*WebSocketV1ClientBase).startTicker()
.../pkg/client/websocketclientbase/websocketv1clientbase.go:137 +0xbc
Sometimes we need to use custom Transport or set Timeout.
build failed with can not find package "."
go version && huobi_golang version
go version go1.16 darwin/amd64
github.com/huobirdcenter/huobi_golang v0.0.0-20201119082032-67bf5220fbce
example code:
package main
import (
"github.com/huobirdcenter/huobi_golang/config"
"github.com/huobirdcenter/huobi_golang/logging/applogger"
"github.com/huobirdcenter/huobi_golang/pkg/client/orderwebsocketclient"
"github.com/huobirdcenter/huobi_golang/pkg/model/auth"
"github.com/huobirdcenter/huobi_golang/pkg/model/order"
)
func main() {
// Initialize a new instance
client := new(orderwebsocketclient.SubscribeOrderWebSocketV2Client).Init(config.AccessKey, config.AccountId, config.Host)
// Set the callback handlers
client.SetHandler(
// Connected handler
func(resp *auth.WebSocketV2AuthenticationResponse) {
if resp.IsSuccess() {
// Subscribe if authentication passed
client.Subscribe("btcusdt", "1149")
} else {
applogger.Info("Authentication error, code: %d, message:%s", resp.Code, resp.Message)
}
},
// Response handler
func(resp interface{}) {
subResponse, ok := resp.(order.SubscribeOrderV2Response)
if ok {
if subResponse.Action == "sub" {
if subResponse.IsSuccess() {
applogger.Info("Subscription topic %s successfully", subResponse.Ch)
} else {
applogger.Error("Subscription topic %s error, code: %d, message: %s", subResponse.Ch, subResponse.Code, subResponse.Message)
}
} else if subResponse.Action == "push" {
if subResponse.Data != nil {
o := subResponse.Data
applogger.Info("Order update, event: %s, symbol: %s, type: %s, status: %s",
o.EventType, o.Symbol, o.Type, o.OrderStatus)
}
}
} else {
applogger.Warn("Received unknown response: %v", resp)
}
})
// Connect to the server and wait for the handler to handle the response
client.Connect(true)}
error info:
cannot find package "." in:
/MY_PROJECT_PATH/vendor/github.com/huobirdcenter/huobi_golang/pkg/client/orderwebsocketclient
GET /market/history/trade
golang sdk
type TradeTick struct {
Id int64 json:"id"
Ts int64 json:"ts"
Data []struct {
Amount decimal.Decimal json:"amount"
TradeId int64 json:"trade-id"
Ts int64 json:"ts"
Id int64 json:"id"
//type of Id is int64
Price decimal.Decimal json:"price"
Direction string json:"direction"
}
}
func (client *MarketClient) GetHistoricalTrade(symbol string, optionalRequest getrequest.GetHistoricalTradeOptionalRequest) ([]market.TradeTick, error) {
...
url := client.publicUrlBuilder.Build("/market/history/trade", request)
getResp, getErr := internal.HttpGet(url)
if getErr != nil {
return nil, getErr
}
result := market.GetHistoricalTradeResponse{}
*jsonErr := json.Unmarshal([]byte(getResp), &result)
...
}
getResp : {"ch":"market.eoseth.trade.detail","status":"ok","ts":1594745613073,"data":[{"id":101110131882,"ts":1594745594604,"data":[{"id":10111013188257230009901629,......
*line error: 10111013188257230009901629 overflows int64
I don't receive any messages if auth wasn't successful.
Problem is here:
Have:
func (p *WebSocketV1AuthenticationResponse) IsAuth() bool {
return p.Op == "auth" && p.ErrorCode == 0
}
Need:
func (p *WebSocketV1AuthenticationResponse) IsAuth() bool {
return p.Op == "auth"
}
in readme
Market data
Candlestick/KLine
client := new(client.MarketClient).Init(config.Host)
optionalRequest := getrequest.GetCandlestickOptionalRequest{Period: getrequest.MIN1, Size: 10}
resp, err := client.GetCandlestick("btcusdt", optionalRequest)
the getrequest package could not be found
&{error order-value-min-error Order total cannot be lower than: 5
}
Since every project has its own logging facilities, make logging module pluggble is more developer friendly.
Huobi response contains numeric order state in case of cancellation error, so this deserialization results in marshalling error:
result := order.CancelOrderByIdResponse{}
jsonErr := json.Unmarshal([]byte(postResp), &result)
Hey
I saw that the v1 API for GetAllSymbols
is deprecated: https://huobiapi.github.io/docs/spot/v1/en/#will-be-offline
Do we consider upgrading the method to its v2 counter part?
use of internal package not allowed
type SubscribeOrderV2Response struct {
base.WebSocketV2ResponseBase
Data *struct {
EventType string `json:"eventType"`
Symbol string `json:"symbol"`
OrderId int64 `json:"orderId"`
ClientOrderId string `json:"clientOrderId"`
OrderPrice string `json:"orderPrice"`
OrderSize string `json:"orderSize"`
Type string `json:"type"`
OrderStatus string `json:"orderStatus"`
OrderCreateTime int64 `json:"orderCreateTime"`
TradePrice string `json:"tradePrice"`
TradeVolume string `json:"tradeVolume"`
TradeId int64 `json:"tradeId"`
TradeTime int64 `json:"tradeTime"`
Aggressor bool `json:"aggressor"`
RemainAmt string `json:"remainAmt"`
LastActTime int64 `json:"lastActTime"`
}
}
there is no OrderValue
, can you upgrade and fix it, thanks!
Message:
{"op":"req","ts":1598615344364,"topic":"orders.list","err-code":10021,"cid":"","err-msg":"req orders.list query error:Please enter a valid account-id."}
RequestOrdersV1Response.ErrCode field must be integer.
Guys you don't reset p.lastReceivedTime
variable while reconnect so that's cause infinite reconnecting loop.
i subscribe websocket market data and receive realtime kline, Client.Subscribe("btcusdt", "1min", "2118")
.
i also obtain historical kline periodically by a time.ticker goroutine, Client.Request(xxxxxxx)
but i got a panic finally after running a period of time,
panic: concurrent write to websocket connection
goroutine 33 [running]:
github.com/gorilla/websocket.(*messageWriter).flushFrame(0xc00007d260, 0xc000170001, 0x0, 0x0, 0x0, 0x7f01d726d108, 0x0)
F:/go/pkg/mod/github.com/gorilla/[email protected]/conn.go:610 +0x5e9
github.com/gorilla/websocket.(*messageWriter).Close(0xc00007d260, 0x0, 0xc0006c5de8)
F:/go/pkg/mod/github.com/gorilla/[email protected]/conn.go:724 +0x62
github.com/gorilla/websocket.(*Conn).beginMessage(0xc00054b4a0, 0xc000170030, 0x1, 0x0, 0xc0006c5e40)
F:/go/pkg/mod/github.com/gorilla/[email protected]/conn.go:473 +0x26d
github.com/gorilla/websocket.(*Conn).NextWriter(0xc00054b4a0, 0x1, 0x9, 0xbf6400, 0xc000328060, 0x20)
F:/go/pkg/mod/github.com/gorilla/[email protected]/conn.go:513 +0x53
github.com/gorilla/websocket.(*Conn).WriteMessage(0xc00054b4a0, 0x1, 0xc000328060, 0x17, 0x20, 0x20, 0x17)
F:/go/pkg/mod/github.com/gorilla/[email protected]/conn.go:766 +0x6e
github.com/huobirdcenter/huobi_golang/pkg/client/websocketclientbase.(*WebSocketClientBase).readLoop(0xc00006e360)
F:/go/pkg/mod/github.com/huobirdcenter/[email protected]/pkg/client/websocketclientbase/websocketclientbase.go:222 +0x528
created by github.com/huobirdcenter/huobi_golang/pkg/client/websocketclientbase.(*WebSocketClientBase).startReadLoop
F:/go/pkg/mod/github.com/huobirdcenter/[email protected]/pkg/client/websocketclientbase/websocketclientbase.go:174 +0x3f
i think the reason is time.Ticker goroutine and ping pong in "startReadLoop --> readLoop" write websocket simultaneous, how to solve it?
go: quant/pkg/grid imports
github.com/huobirdcenter/huobi_Golang/config: github.com/huobirdcenter/[email protected]: parsing go.mod:
module declares its path as: github.com/huobirdcenter/huobi_golang
but was required as: github.com/huobirdcenter/huobi_Golang
好几个接口都没有加入里面
在php的demo中是直接返回,但是在golang中,这个属性被私有化了,如果能把handleMessage放开,自定义解析就好了
I run https://github.com/HuobiRDCenter/huobi_Golang/blob/master/cmd/marketwebsocketclientexample/marketwebsocketclientexample.go#L22 code it just get current data. but I want to get hisotry data, e.g.: 2020-10-01 00:00:00 - 2020-11-01 00:00:00,
I have specified from
and to
params but it does not work.
Referring to https://huobiapi.github.io/docs/spot/v1/cn/#4e53c0fccd, /v1/order/orders/{order-id}/submitcancel should return an "order-state" field when error occurs.
下单后会出现
ERROR Handle message error: json: cannot unmarshal number into Go struct field .Data.orderCreateTime of type string
类型可能得改成int64
WARNING: DATA RACE
Read at 0x0000020d07f0 by goroutine 25:
.../logging/perflogger.GetInstance()
.../logging/perflogger/performancelogger.go:29 +0x65
Previous write at 0x0000020d07f0 by goroutine 24:
.../logging/perflogger.GetInstance()
.../logging/perflogger/performancelogger.go:30 +0x3d5
GetHistoricalTrade error: json: cannot unmarshal number 10043412649746196623382279 into Go struct field .data.Data.id of type int64
https://www.huobi.com/support/en-us/detail/64892083374346
This update involves the below:
github.com\huobirdcenter\huobi_golang\pkg\client\orderclient.go
// Returns orders based on a specific searching criteria.
func (p *OrderClient) GetHistoryOrders(request *model.GetRequest) (*order.GetHistoryOrdersResponse, error) {
url := p.privateUrlBuilder.Build("GET", "/v1/order/orders", request)
getResp, getErr := internal.HttpGet(url)
if getErr != nil {
return nil, getErr
}
result := order.GetHistoryOrdersResponse{}
jsonErr := json.Unmarshal([]byte(getResp), &result)
if jsonErr != nil {
return nil, jsonErr
}
return &result, nil
}
to be: /v1/order/openOrders
order state:
created: The order is created, and not in the matching queue yet.
submitted: The order is submitted, and already in the matching queue, waiting for deal.
partial-filled: The order is already in the matching queue and partially traded, and is waiting for further matching and trade.
filled: The order is already traded and not in the matching queue any more.
partial-canceled: The order is not in the matching queue any more. The status is transferred from 'partial-filled', the order is partially trade, but remaining is canceled.
canceling: The order is under canceling, but haven't been removed from matching queue yet.
canceled: The order is not in the matching queue any more, and completely canceled. There is no trade associated with this order.
or make a new:
// Returns all open orders based on a specific searching criteria.
// https://www.huobi.com/support/en-us/detail/64892083374346
func (p *OrderClient) GetAllOpenOrders(request *model.GetRequest) (*order.GetHistoryOrdersResponse, error) {
url := p.privateUrlBuilder.Build("GET", "/v1/order/openOrders", request)
getResp, getErr := internal.HttpGet(url)
if getErr != nil {
return nil, getErr
}
result := order.GetHistoryOrdersResponse{}
jsonErr := json.Unmarshal([]byte(getResp), &result)
if jsonErr != nil {
return nil, jsonErr
}
return &result, nil
}
first i get accont information by client.AccountClient ,when i recieve the response, i use the same account client instance to get the account balance , this time the response is a error
{"status":"error","err-code":"api-signature-not-valid","err-msg":"Signature not valid: Verification failure [校验失败]","data":null}
but when i change the code like that
`
func (p *Signer) sign(payload string) string {
p.hash.Write([]byte(payload))
result := base64.StdEncoding.EncodeToString(p.hash.Sum(nil))
p.hash.Reset()
return result
}`
then there is no error,but i dont know whether it‘s correct
Is client.Close()
a blocking call?
By this line:
Need to remove it.
好几个接口都没有加入里面
placeOrder 示例错误代码:Invalid order source spot api
代码:
func placeOrder() {
client := new(client.OrderClient).Init(config.AccessKey, config.SecretKey, config.Host)
request := order.PlaceOrderRequest{
AccountId: config.AccountId,
Type: "sell-market",
Symbol: "btcusdt",
Amount: "10",
Source: "spot-api",
}
fmt.Print("request:\n", request, '\n')
resp, err := client.PlaceOrder(&request)
if err != nil {
applogger.Error(err.Error())
} else {
switch resp.Status {
case "ok":
applogger.Info("Place order successfully, order id: %s", resp.Data)
case "error":
applogger.Error("Place order error 哭啊: %s", resp.ErrorMessage)
}
}
}
when i ran "reqAndSubscribeCandlestick",
in client.SetHandler() para is:
client.Request("btcusdt", "4hour", 1569361140, 1600988820, "2305")
client.Subscribe("btcusdt", "4hour", "2118")
but i can't get "Candlestick data, id: xxxxxx" in stdout.
the stdout only contains "Candlestick update, id: xxxxx" data. thx.
Sometimes we need to use custom Transport or set Timeout.
When I placed a buy/sell order, due to it just return an order id for me, I have to request get order api to get more info. But I encounter error for {Status:error ErrorCode:base-record-invalid ErrorMessage:record invalid Data:<nil>}
sometimes. Actually everything is ok,may it is too short time for place order and get order info in the server.
i notice that in v1 version supported subscribe "orders.$symbol.update" in the example "orderwebsocketclientexample.go --> subOrderUpdateV1()", but it will to be obsoleted.
subOrderUpdateV2() only supported subscribe "accounts.update#".
i can not find "orders#${symbol}" in v2 version in golang sdk. https://huobiapi.github.io/docs/spot/v1/en/#subscribe-order-updates
我用sdk的样例,在本地运行没有问题,但是在k8s中运行时报这个错误:
[Error] 2021/02/28 15:06:42 Get "https://api.huobi.pro/market/trade?symbol=btcusdt":
dial tcp: lookup api.huobi.pro on 10.96.0.10:53: server misbehaving
这个错误是该代码报出来的,打印出的日志
const host = "api.huobi.pro"
c = new(client.MarketClient).Init(host)
res, err := c.GetLast24hCandlestick("btcusdt")
if err != nil {
log.L.Error("%s", err)
break
}
不知是k8s dns的问题还是sdk的问题,请问有无k8s运行此sdk的成功样例?
错误 :Get account history error: {"status":"error","err-code":"validation-format-error","err-msg":"Format Error: account-id.","data":null}
``
var (
AccessKey = "xxx-xxx-xxx-xxx"
SecretKey = "xxx-xxxx-xxxx-xxxx"
accountId int64
)
/**
财务流水
*/
func (controller *Index) GetAccountHistory(r *ghttp.Request) {
client := new(client.AccountClient).Init(AccessKey, SecretKey, config.Host)
//if accountId == 0 {
info, err := client.GetAccountInfo()
applogger.Info("Get account ledger error: ", info)
if err == nil {
for _, accountInfo := range info {
if accountInfo.Type == "spot" {
accountId = (accountInfo.Id)
}
}
} else {
base.Error(r, "Get account ledger error"+err.Error())
return
}
//}
fmt.Println(accountId)
getAccountHistoryOptionalRequest := account.GetAccountHistoryOptionalRequest{}
resp, err := client.GetAccountHistory(string((accountId)), getAccountHistoryOptionalRequest)
if err != nil {
applogger.Error("Get account history error: %s", err)
base.Error(r, "Get account history error"+err.Error())
return
} else {
applogger.Info("Get account history, count=%d", len(resp))
base.Succ(r, g.Map{"list": resp, "form": nil})
}
return
}`
panic: d.nx != 0
goroutine 85 [running]:
crypto/sha256.(*digest).checkSum(0xc00043d9f0, 0x0, 0x0, 0x0, 0x0)
c:/go/src/crypto/sha256/sha256.go:234 +0x1e0
crypto/sha256.(*digest).Sum(0xc00009eb00, 0x0, 0x0, 0x0, 0xc0, 0xb6, 0x0)
c:/go/src/crypto/sha256/sha256.go:210 +0x70
crypto/hmac.(*hmac).Sum(0xc0000ae840, 0x0, 0x0, 0x0, 0xb6, 0x0, 0x0)
c:/go/src/crypto/hmac/hmac.go:46 +0x5d
github.com/huobirdcenter/huobi_golang/internal/requestbuilder.(*Signer).sign(0xc00005f250, 0xc00046cfc0, 0xb6, 0x40, 0xb6)
C:/Users/Administrator/go/pkg/mod/github.com/huobirdcenter/[email protected]/internal/requestbuilder/signer.go:40 +0xba
github.com/huobirdcenter/huobi_golang/internal/requestbuilder.(*Signer).Sign(0xc00005f250, 0xb1626e, 0x3, 0xb1be37, 0xd, 0xc000094960, 0x25, 0xc00046cf00, 0x7e, 0xc71190, ...)
C:/Users/Administrator/go/pkg/mod/github.com/huobirdcenter/[email protected]/internal/requestbuilder/signer.go:34 +0x39c
github.com/huobirdcenter/huobi_golang/internal/requestbuilder.(*PrivateUrlBuilder).BuildWithTime(0xc000106510, 0xb1626e, 0x3, 0xc000094960, 0x25, 0x2cd91da0, 0xed654903d, 0x0, 0x0, 0xc00043dd58, ...)
C:/Users/Administrator/go/pkg/mod/github.com/huobirdcenter/[email protected]/internal/requestbuilder/privateurlbuilder.go:55 +0x1c3
github.com/huobirdcenter/huobi_golang/internal/requestbuilder.(*PrivateUrlBuilder).Build(0xc000106510, 0xb1626e, 0x3, 0xc000094960, 0x25, 0x0, 0x8, 0xc000094960)
C:/Users/Administrator/go/pkg/mod/github.com/huobirdcenter/[email protected]/internal/requestbuilder/privateurlbuilder.go:41 +0xf2
github.com/huobirdcenter/huobi_golang/pkg/client.(*AccountClient).GetAccountBalance(0xc0000960b0, 0xb184b4, 0x8, 0x0, 0xc00043df58, 0xc0000c4000)
C:/Users/Administrator/go/pkg/mod/github.com/huobirdcenter/[email protected]/pkg/client/accountclient.go:49 +0xc6
websocket 接口很容易出现重新链接 请检查一下(我自己用golang实现的就不会出现这个问题)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.