mirror of
https://github.com/d0zingcat/gocryptotrader.git
synced 2026-05-26 23:16:48 +00:00
Improve ticker batching and websocket pair consistency
This commit is contained in:
@@ -73,6 +73,20 @@ func NewPairFromString(currencyPair string) Pair {
|
||||
return NewPairFromStrings(currencyPair[0:3], currencyPair[3:])
|
||||
}
|
||||
|
||||
// NewPairFromFormattedPairs matches a supplied currency pair to a list of pairs
|
||||
// with a specific format. This is helpful for exchanges which
|
||||
// provide currency pairs with no delimiter so we can match it with a list and
|
||||
// apply the same format
|
||||
func NewPairFromFormattedPairs(currencyPair string, pairs Pairs, pairFmt PairFormat) Pair {
|
||||
for x := range pairs {
|
||||
if strings.EqualFold(pairs[x].Format(pairFmt.Delimiter,
|
||||
pairFmt.Uppercase).String(), currencyPair) {
|
||||
return pairs[x]
|
||||
}
|
||||
}
|
||||
return NewPairFromString(currencyPair)
|
||||
}
|
||||
|
||||
// Pair holds currency pair information
|
||||
type Pair struct {
|
||||
Delimiter string `json:"delimiter"`
|
||||
@@ -133,7 +147,8 @@ func (p Pair) Format(delimiter string, uppercase bool) Pair {
|
||||
|
||||
// Equal compares two currency pairs and returns whether or not they are equal
|
||||
func (p Pair) Equal(cPair Pair) bool {
|
||||
return p.Base.Item == cPair.Base.Item && p.Quote.Item == cPair.Quote.Item
|
||||
return strings.EqualFold(p.Base.String(), cPair.Base.String()) &&
|
||||
strings.EqualFold(p.Quote.String(), cPair.Quote.String())
|
||||
}
|
||||
|
||||
// EqualIncludeReciprocal compares two currency pairs and returns whether or not
|
||||
|
||||
@@ -407,6 +407,30 @@ func TestNewPairFromString(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewPairFromFormattedPairs(t *testing.T) {
|
||||
t.Parallel()
|
||||
pairs := Pairs{
|
||||
NewPairDelimiter("BTC-USDT", "-"),
|
||||
NewPairDelimiter("LTC-USD", "-"),
|
||||
}
|
||||
|
||||
p := NewPairFromFormattedPairs("BTCUSDT", pairs, PairFormat{Uppercase: true})
|
||||
if p.String() != "BTC-USDT" {
|
||||
t.Error("Test failed. TestNewPairFromFormattedPairs: Expected currency was not found")
|
||||
}
|
||||
|
||||
p = NewPairFromFormattedPairs("btcusdt", pairs, PairFormat{Uppercase: false})
|
||||
if p.String() != "BTC-USDT" {
|
||||
t.Error("Test failed. TestNewPairFromFormattedPairs: Expected currency was not found")
|
||||
}
|
||||
|
||||
// Now a wrong one, will default to NewPairFromString
|
||||
p = NewPairFromFormattedPairs("ethusdt", pairs, PairFormat{})
|
||||
if p.String() != "ethusdt" && p.Base.String() != "eth" {
|
||||
t.Error("Test failed. TestNewPairFromFormattedPairs: Expected currency was not found")
|
||||
}
|
||||
}
|
||||
|
||||
func TestContainsCurrency(t *testing.T) {
|
||||
p := NewPair(BTC, USD)
|
||||
|
||||
|
||||
@@ -167,29 +167,29 @@ type KlineStream struct {
|
||||
|
||||
// TickerStream holds the ticker stream data
|
||||
type TickerStream struct {
|
||||
EventType string `json:"e"`
|
||||
EventTime int64 `json:"E"`
|
||||
Symbol currency.Pair `json:"s"`
|
||||
PriceChange float64 `json:"p,string"`
|
||||
PriceChangePercent float64 `json:"P,string"`
|
||||
WeightedAvgPrice float64 `json:"w,string"`
|
||||
ClosePrice float64 `json:"x,string"`
|
||||
LastPrice float64 `json:"c,string"`
|
||||
LastPriceQuantity float64 `json:"Q,string"`
|
||||
BestBidPrice float64 `json:"b,string"`
|
||||
BestBidQuantity float64 `json:"B,string"`
|
||||
BestAskPrice float64 `json:"a,string"`
|
||||
BestAskQuantity float64 `json:"A,string"`
|
||||
OpenPrice float64 `json:"o,string"`
|
||||
HighPrice float64 `json:"h,string"`
|
||||
LowPrice float64 `json:"l,string"`
|
||||
TotalTradedVolume float64 `json:"v,string"`
|
||||
TotalTradedQuoteVolume float64 `json:"q,string"`
|
||||
OpenTime int64 `json:"O"`
|
||||
CloseTime int64 `json:"C"`
|
||||
FirstTradeID int64 `json:"F"`
|
||||
LastTradeID int64 `json:"L"`
|
||||
NumberOfTrades int64 `json:"n"`
|
||||
EventType string `json:"e"`
|
||||
EventTime int64 `json:"E"`
|
||||
Symbol string `json:"s"`
|
||||
PriceChange float64 `json:"p,string"`
|
||||
PriceChangePercent float64 `json:"P,string"`
|
||||
WeightedAvgPrice float64 `json:"w,string"`
|
||||
ClosePrice float64 `json:"x,string"`
|
||||
LastPrice float64 `json:"c,string"`
|
||||
LastPriceQuantity float64 `json:"Q,string"`
|
||||
BestBidPrice float64 `json:"b,string"`
|
||||
BestBidQuantity float64 `json:"B,string"`
|
||||
BestAskPrice float64 `json:"a,string"`
|
||||
BestAskQuantity float64 `json:"A,string"`
|
||||
OpenPrice float64 `json:"o,string"`
|
||||
HighPrice float64 `json:"h,string"`
|
||||
LowPrice float64 `json:"l,string"`
|
||||
TotalTradedVolume float64 `json:"v,string"`
|
||||
TotalTradedQuoteVolume float64 `json:"q,string"`
|
||||
OpenTime int64 `json:"O"`
|
||||
CloseTime int64 `json:"C"`
|
||||
FirstTradeID int64 `json:"F"`
|
||||
LastTradeID int64 `json:"L"`
|
||||
NumberOfTrades int64 `json:"n"`
|
||||
}
|
||||
|
||||
// HistoricalTrade holds recent trade data
|
||||
@@ -239,25 +239,25 @@ type AveragePrice struct {
|
||||
|
||||
// PriceChangeStats contains statistics for the last 24 hours trade
|
||||
type PriceChangeStats struct {
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
PriceChange float64 `json:"priceChange,string"`
|
||||
PriceChangePercent float64 `json:"priceChangePercent,string"`
|
||||
WeightedAvgPrice float64 `json:"weightedAvgPrice,string"`
|
||||
PrevClosePrice float64 `json:"prevClosePrice,string"`
|
||||
LastPrice float64 `json:"lastPrice,string"`
|
||||
LastQty float64 `json:"lastQty,string"`
|
||||
BidPrice float64 `json:"bidPrice,string"`
|
||||
AskPrice float64 `json:"askPrice,string"`
|
||||
OpenPrice float64 `json:"openPrice,string"`
|
||||
HighPrice float64 `json:"highPrice,string"`
|
||||
LowPrice float64 `json:"lowPrice,string"`
|
||||
Volume float64 `json:"volume,string"`
|
||||
QuoteVolume float64 `json:"quoteVolume,string"`
|
||||
OpenTime int64 `json:"openTime"`
|
||||
CloseTime int64 `json:"closeTime"`
|
||||
FirstID int64 `json:"fristId"`
|
||||
LastID int64 `json:"lastId"`
|
||||
Count int64 `json:"count"`
|
||||
Symbol string `json:"symbol"`
|
||||
PriceChange float64 `json:"priceChange,string"`
|
||||
PriceChangePercent float64 `json:"priceChangePercent,string"`
|
||||
WeightedAvgPrice float64 `json:"weightedAvgPrice,string"`
|
||||
PrevClosePrice float64 `json:"prevClosePrice,string"`
|
||||
LastPrice float64 `json:"lastPrice,string"`
|
||||
LastQty float64 `json:"lastQty,string"`
|
||||
BidPrice float64 `json:"bidPrice,string"`
|
||||
AskPrice float64 `json:"askPrice,string"`
|
||||
OpenPrice float64 `json:"openPrice,string"`
|
||||
HighPrice float64 `json:"highPrice,string"`
|
||||
LowPrice float64 `json:"lowPrice,string"`
|
||||
Volume float64 `json:"volume,string"`
|
||||
QuoteVolume float64 `json:"quoteVolume,string"`
|
||||
OpenTime int64 `json:"openTime"`
|
||||
CloseTime int64 `json:"closeTime"`
|
||||
FirstID int64 `json:"fristId"`
|
||||
LastID int64 `json:"lastId"`
|
||||
Count int64 `json:"count"`
|
||||
}
|
||||
|
||||
// SymbolPrice holds basic symbol price
|
||||
|
||||
@@ -128,13 +128,14 @@ func (b *Binance) WsHandleData() {
|
||||
}
|
||||
|
||||
b.Websocket.DataHandler <- wshandler.TradeData{
|
||||
CurrencyPair: currency.NewPairFromString(trade.Symbol),
|
||||
Timestamp: time.Unix(0, trade.TimeStamp),
|
||||
Price: price,
|
||||
Amount: amount,
|
||||
Exchange: b.GetName(),
|
||||
AssetType: asset.Spot,
|
||||
Side: trade.EventType,
|
||||
CurrencyPair: currency.NewPairFromFormattedPairs(trade.Symbol, b.GetEnabledPairs(asset.Spot),
|
||||
b.GetPairFormat(asset.Spot, true)),
|
||||
Timestamp: time.Unix(0, trade.TimeStamp),
|
||||
Price: price,
|
||||
Amount: amount,
|
||||
Exchange: b.GetName(),
|
||||
AssetType: asset.Spot,
|
||||
Side: trade.EventType,
|
||||
}
|
||||
continue
|
||||
case "ticker":
|
||||
@@ -160,7 +161,8 @@ func (b *Binance) WsHandleData() {
|
||||
Last: t.LastPrice,
|
||||
Timestamp: time.Unix(0, t.EventTime),
|
||||
AssetType: asset.Spot,
|
||||
Pair: t.Symbol,
|
||||
Pair: currency.NewPairFromFormattedPairs(t.Symbol, b.GetEnabledPairs(asset.Spot),
|
||||
b.GetPairFormat(asset.Spot, true)),
|
||||
}
|
||||
|
||||
continue
|
||||
@@ -176,7 +178,8 @@ func (b *Binance) WsHandleData() {
|
||||
|
||||
var wsKline wshandler.KlineData
|
||||
wsKline.Timestamp = time.Unix(0, kline.EventTime)
|
||||
wsKline.Pair = currency.NewPairFromString(kline.Symbol)
|
||||
wsKline.Pair = currency.NewPairFromFormattedPairs(kline.Symbol, b.GetEnabledPairs(asset.Spot),
|
||||
b.GetPairFormat(asset.Spot, true))
|
||||
wsKline.AssetType = asset.Spot
|
||||
wsKline.Exchange = b.GetName()
|
||||
wsKline.StartTime = time.Unix(0, kline.Kline.StartTime)
|
||||
@@ -207,7 +210,8 @@ func (b *Binance) WsHandleData() {
|
||||
continue
|
||||
}
|
||||
|
||||
currencyPair := currency.NewPairFromString(depth.Pair)
|
||||
currencyPair := currency.NewPairFromFormattedPairs(depth.Pair, b.GetEnabledPairs(asset.Spot),
|
||||
b.GetPairFormat(asset.Spot, true))
|
||||
b.Websocket.DataHandler <- wshandler.WebsocketOrderbookUpdate{
|
||||
Pair: currencyPair,
|
||||
Asset: asset.Spot,
|
||||
@@ -222,10 +226,9 @@ func (b *Binance) WsHandleData() {
|
||||
// SeedLocalCache seeds depth data
|
||||
func (b *Binance) SeedLocalCache(p currency.Pair) error {
|
||||
var newOrderBook orderbook.Base
|
||||
formattedPair := b.FormatExchangeCurrency(p, asset.Spot)
|
||||
orderbookNew, err := b.GetOrderBook(
|
||||
OrderBookDataRequestParams{
|
||||
Symbol: formattedPair.String(),
|
||||
Symbol: b.FormatExchangeCurrency(p, asset.Spot).String(),
|
||||
Limit: 1000,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -242,7 +245,7 @@ func (b *Binance) SeedLocalCache(p currency.Pair) error {
|
||||
}
|
||||
|
||||
newOrderBook.LastUpdated = time.Unix(orderbookNew.LastUpdateID, 0)
|
||||
newOrderBook.Pair = currency.NewPairFromString(formattedPair.String())
|
||||
newOrderBook.Pair = p
|
||||
newOrderBook.AssetType = asset.Spot
|
||||
|
||||
return b.Websocket.Orderbook.LoadSnapshot(&newOrderBook, false)
|
||||
@@ -276,7 +279,8 @@ func (b *Binance) UpdateLocalCache(wsdp *WebsocketDepthStream) error {
|
||||
}
|
||||
updateAsk = append(updateAsk, priceToBeUpdated)
|
||||
}
|
||||
currencyPair := currency.NewPairFromString(wsdp.Pair)
|
||||
currencyPair := currency.NewPairFromFormattedPairs(wsdp.Pair, b.GetEnabledPairs(asset.Spot),
|
||||
b.GetPairFormat(asset.Spot, true))
|
||||
|
||||
return b.Websocket.Orderbook.Update(&wsorderbook.WebsocketOrderbookUpdate{
|
||||
Bids: updateBid,
|
||||
|
||||
@@ -167,7 +167,7 @@ func (b *Binance) Run() {
|
||||
!common.StringDataContains(b.GetAvailablePairs(asset.Spot).Strings(), b.GetPairFormat(asset.Spot, false).Delimiter) {
|
||||
enabledPairs := currency.NewPairsFromStrings([]string{fmt.Sprintf("BTC%vUSDT", b.GetPairFormat(asset.Spot, false).Delimiter)})
|
||||
log.Warn(log.ExchangeSys,
|
||||
"Available pairs for Binance reset due to config upgrade, please enable the ones you would like again")
|
||||
"Available pairs for Binance reset due to config upgrade, please enable the ones you would like to use again")
|
||||
forceUpdate = true
|
||||
|
||||
err := b.UpdatePairs(enabledPairs, asset.Spot, true, true)
|
||||
@@ -227,7 +227,8 @@ func (b *Binance) UpdateTicker(p currency.Pair, assetType asset.Item) (ticker.Pr
|
||||
pairs := b.GetEnabledPairs(assetType)
|
||||
for i := range pairs {
|
||||
for y := range tick {
|
||||
if !tick[y].Symbol.Equal(pairs[i]) {
|
||||
pairFmt := b.FormatExchangeCurrency(pairs[i], assetType).String()
|
||||
if tick[y].Symbol != pairFmt {
|
||||
continue
|
||||
}
|
||||
tickerPrice := ticker.Price{
|
||||
|
||||
@@ -562,7 +562,8 @@ func (b *Bitfinex) Subscribe(channelToSubscribe wshandler.WebsocketChannelSubscr
|
||||
req["event"] = "subscribe"
|
||||
req["channel"] = channelToSubscribe.Channel
|
||||
if channelToSubscribe.Currency.String() != "" {
|
||||
req["pair"] = channelToSubscribe.Currency.String()
|
||||
req["pair"] = b.FormatExchangeCurrency(channelToSubscribe.Currency,
|
||||
asset.Spot).String()
|
||||
}
|
||||
if len(channelToSubscribe.Params) > 0 {
|
||||
for k, v := range channelToSubscribe.Params {
|
||||
|
||||
@@ -62,6 +62,7 @@ func (c *CoinbasePro) SetDefaults() {
|
||||
Uppercase: true,
|
||||
},
|
||||
ConfigFormat: ¤cy.PairFormat{
|
||||
Delimiter: "-",
|
||||
Uppercase: true,
|
||||
},
|
||||
}
|
||||
@@ -162,11 +163,25 @@ func (c *CoinbasePro) Run() {
|
||||
c.PrintEnabledPairs()
|
||||
}
|
||||
|
||||
if !c.GetEnabledFeatures().AutoPairUpdates {
|
||||
forceUpdate := false
|
||||
if !common.StringDataContains(c.GetEnabledPairs(asset.Spot).Strings(), c.GetPairFormat(asset.Spot, false).Delimiter) ||
|
||||
!common.StringDataContains(c.GetAvailablePairs(asset.Spot).Strings(), c.GetPairFormat(asset.Spot, false).Delimiter) {
|
||||
enabledPairs := currency.NewPairsFromStrings([]string{fmt.Sprintf("BTC%vUSD", c.GetPairFormat(asset.Spot, false).Delimiter)})
|
||||
log.Warn(log.ExchangeSys,
|
||||
"Enabled pairs for CoinbasePro reset due to config upgrade, please enable the ones you would like to use again")
|
||||
forceUpdate = true
|
||||
|
||||
err := c.UpdatePairs(enabledPairs, asset.Spot, true, true)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s failed to update currencies. Err: %s\n", c.Name, err)
|
||||
}
|
||||
}
|
||||
|
||||
if !c.GetEnabledFeatures().AutoPairUpdates && !forceUpdate {
|
||||
return
|
||||
}
|
||||
|
||||
err := c.UpdateTradablePairs(false)
|
||||
err := c.UpdateTradablePairs(forceUpdate)
|
||||
if err != nil {
|
||||
log.Errorf(log.ExchangeSys, "%s failed to update tradable pairs. Err: %s", c.Name, err)
|
||||
}
|
||||
@@ -181,7 +196,8 @@ func (c *CoinbasePro) FetchTradablePairs(asset asset.Item) ([]string, error) {
|
||||
|
||||
var products []string
|
||||
for x := range pairs {
|
||||
products = append(products, pairs[x].BaseCurrency+pairs[x].QuoteCurrency)
|
||||
products = append(products, fmt.Sprintf("%s%s%s", pairs[x].BaseCurrency,
|
||||
c.GetPairFormat(asset, false).Delimiter, pairs[x].QuoteCurrency))
|
||||
}
|
||||
|
||||
return products, nil
|
||||
|
||||
@@ -262,7 +262,6 @@ func (e *Base) SetCurrencyPairFormat() {
|
||||
if e.Config.CurrencyPairs.RequestFormat == nil {
|
||||
e.Config.CurrencyPairs.RequestFormat = e.CurrencyPairs.RequestFormat
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -338,7 +338,8 @@ func (g *Gateio) GenerateDefaultSubscriptions() {
|
||||
|
||||
// Subscribe sends a websocket message to receive data from the channel
|
||||
func (g *Gateio) Subscribe(channelToSubscribe wshandler.WebsocketChannelSubscription) error {
|
||||
params := []interface{}{channelToSubscribe.Currency.String()}
|
||||
params := []interface{}{g.FormatExchangeCurrency(channelToSubscribe.Currency,
|
||||
asset.Spot).String()}
|
||||
for i := range channelToSubscribe.Params {
|
||||
params = append(params, channelToSubscribe.Params[i])
|
||||
}
|
||||
@@ -370,7 +371,8 @@ func (g *Gateio) Unsubscribe(channelToSubscribe wshandler.WebsocketChannelSubscr
|
||||
subscribe := WebsocketRequest{
|
||||
ID: g.WebsocketConn.GenerateMessageID(true),
|
||||
Method: unsbuscribeText,
|
||||
Params: []interface{}{channelToSubscribe.Currency.String(), 1800},
|
||||
Params: []interface{}{g.FormatExchangeCurrency(channelToSubscribe.Currency,
|
||||
asset.Spot).String(), 1800},
|
||||
}
|
||||
resp, err := g.WebsocketConn.SendMessageReturnResponse(subscribe.ID, subscribe)
|
||||
if err != nil {
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/thrasher-corp/gocryptotrader/config"
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
exchange "github.com/thrasher-corp/gocryptotrader/exchanges"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/asset"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/sharedtestvalues"
|
||||
"github.com/thrasher-corp/gocryptotrader/exchanges/websocket/wshandler"
|
||||
)
|
||||
@@ -97,6 +98,22 @@ func TestGetFeeByTypeOfflineTradeFee(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateTicker(t *testing.T) {
|
||||
h.SetDefaults()
|
||||
TestSetup(t)
|
||||
|
||||
h.CurrencyPairs.StorePairs(asset.Spot, currency.NewPairsFromStrings([]string{"BTC-USD", "XRP-USD"}), true)
|
||||
_, err := h.UpdateTicker(currency.NewPair(currency.BTC, currency.USD), asset.Spot)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
_, err = h.FetchTicker(currency.NewPair(currency.XRP, currency.USD), asset.Spot)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetAllTickers(t *testing.T) {
|
||||
_, err := h.GetTickers()
|
||||
if err != nil {
|
||||
|
||||
@@ -8,16 +8,16 @@ import (
|
||||
|
||||
// TickerResponse is the response type
|
||||
type TickerResponse struct {
|
||||
Ask float64 `json:"ask,string"`
|
||||
Bid float64 `json:"bid,string"`
|
||||
High float64 `json:"high,string"`
|
||||
Last float64 `json:"last,string"`
|
||||
Low float64 `json:"low,string"`
|
||||
Open float64 `json:"open,string"`
|
||||
Volume float64 `json:"volume,string"`
|
||||
VolumeQuote float64 `json:"volumeQuote,string"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
Ask float64 `json:"ask,string"`
|
||||
Bid float64 `json:"bid,string"`
|
||||
High float64 `json:"high,string"`
|
||||
Last float64 `json:"last,string"`
|
||||
Low float64 `json:"low,string"`
|
||||
Open float64 `json:"open,string"`
|
||||
Volume float64 `json:"volume,string"`
|
||||
VolumeQuote float64 `json:"volumeQuote,string"`
|
||||
Symbol string `json:"symbol"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
}
|
||||
|
||||
// Symbol holds symbol data
|
||||
@@ -322,16 +322,16 @@ type params struct {
|
||||
// WsTicker defines websocket ticker feed return params
|
||||
type WsTicker struct {
|
||||
Params struct {
|
||||
Ask float64 `json:"ask,string"`
|
||||
Bid float64 `json:"bid,string"`
|
||||
Last float64 `json:"last,string"`
|
||||
Open float64 `json:"open,string"`
|
||||
Low float64 `json:"low,string"`
|
||||
High float64 `json:"high,string"`
|
||||
Volume float64 `json:"volume,string"`
|
||||
VolumeQuote float64 `json:"volumeQuote,string"`
|
||||
Timestamp string `json:"timestamp"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
Ask float64 `json:"ask,string"`
|
||||
Bid float64 `json:"bid,string"`
|
||||
Last float64 `json:"last,string"`
|
||||
Open float64 `json:"open,string"`
|
||||
Low float64 `json:"low,string"`
|
||||
High float64 `json:"high,string"`
|
||||
Volume float64 `json:"volume,string"`
|
||||
VolumeQuote float64 `json:"volumeQuote,string"`
|
||||
Timestamp string `json:"timestamp"`
|
||||
Symbol string `json:"symbol"`
|
||||
} `json:"params"`
|
||||
}
|
||||
|
||||
@@ -387,20 +387,20 @@ type WsActiveOrdersResponse struct {
|
||||
|
||||
// WsActiveOrdersResponseData Active order data for WsActiveOrdersResponse
|
||||
type WsActiveOrdersResponseData struct {
|
||||
ID string `json:"id"`
|
||||
ClientOrderID string `json:"clientOrderId,omitempty"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
TimeInForce string `json:"timeInForce"`
|
||||
Quantity float64 `json:"quantity,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
CumQuantity float64 `json:"cumQuantity,string"`
|
||||
PostOnly bool `json:"postOnly"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
ReportType string `json:"reportType"`
|
||||
ID string `json:"id"`
|
||||
ClientOrderID string `json:"clientOrderId,omitempty"`
|
||||
Symbol string `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
TimeInForce string `json:"timeInForce"`
|
||||
Quantity float64 `json:"quantity,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
CumQuantity float64 `json:"cumQuantity,string"`
|
||||
PostOnly bool `json:"postOnly"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
ReportType string `json:"reportType"`
|
||||
}
|
||||
|
||||
// WsReportResponse report response for auth subscription to reports
|
||||
@@ -411,24 +411,24 @@ type WsReportResponse struct {
|
||||
|
||||
// WsReportResponseData Report data for WsReportResponse
|
||||
type WsReportResponseData struct {
|
||||
ID string `json:"id"`
|
||||
ClientOrderID string `json:"clientOrderId,omitempty"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
TimeInForce string `json:"timeInForce"`
|
||||
Quantity float64 `json:"quantity,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
CumQuantity float64 `json:"cumQuantity,string"`
|
||||
PostOnly bool `json:"postOnly"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
ReportType string `json:"reportType"`
|
||||
TradeQuantity float64 `json:"tradeQuantity,string"`
|
||||
TradePrice float64 `json:"tradePrice,string"`
|
||||
TradeID int64 `json:"tradeId"`
|
||||
TradeFee float64 `json:"tradeFee,string"`
|
||||
ID string `json:"id"`
|
||||
ClientOrderID string `json:"clientOrderId,omitempty"`
|
||||
Symbol string `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
TimeInForce string `json:"timeInForce"`
|
||||
Quantity float64 `json:"quantity,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
CumQuantity float64 `json:"cumQuantity,string"`
|
||||
PostOnly bool `json:"postOnly"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
ReportType string `json:"reportType"`
|
||||
TradeQuantity float64 `json:"tradeQuantity,string"`
|
||||
TradePrice float64 `json:"tradePrice,string"`
|
||||
TradeID int64 `json:"tradeId"`
|
||||
TradeFee float64 `json:"tradeFee,string"`
|
||||
}
|
||||
|
||||
// WsSubmitOrderRequest WS request
|
||||
@@ -440,11 +440,11 @@ type WsSubmitOrderRequest struct {
|
||||
|
||||
// WsSubmitOrderRequestData WS request data
|
||||
type WsSubmitOrderRequestData struct {
|
||||
ClientOrderID int64 `json:"clientOrderId,string,omitempty"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
Price float64 `json:"price,string"`
|
||||
Quantity float64 `json:"quantity,string"`
|
||||
ClientOrderID int64 `json:"clientOrderId,string,omitempty"`
|
||||
Symbol string `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
Price float64 `json:"price,string"`
|
||||
Quantity float64 `json:"quantity,string"`
|
||||
}
|
||||
|
||||
// WsSubmitOrderSuccessResponse WS response
|
||||
@@ -494,20 +494,20 @@ type WsCancelOrderResponse struct {
|
||||
|
||||
// WsCancelOrderResponseData WS response data
|
||||
type WsCancelOrderResponseData struct {
|
||||
ID string `json:"id"`
|
||||
ClientOrderID string `json:"clientOrderId,omitempty"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
TimeInForce string `json:"timeInForce"`
|
||||
Quantity float64 `json:"quantity,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
CumQuantity float64 `json:"cumQuantity,string"`
|
||||
PostOnly bool `json:"postOnly"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
ReportType string `json:"reportType"`
|
||||
ID string `json:"id"`
|
||||
ClientOrderID string `json:"clientOrderId,omitempty"`
|
||||
Symbol string `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
TimeInForce string `json:"timeInForce"`
|
||||
Quantity float64 `json:"quantity,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
CumQuantity float64 `json:"cumQuantity,string"`
|
||||
PostOnly bool `json:"postOnly"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
ReportType string `json:"reportType"`
|
||||
}
|
||||
|
||||
// WsReplaceOrderResponse WS response
|
||||
@@ -519,21 +519,21 @@ type WsReplaceOrderResponse struct {
|
||||
|
||||
// WsReplaceOrderResponseData WS response data
|
||||
type WsReplaceOrderResponseData struct {
|
||||
ID string `json:"id"`
|
||||
ClientOrderID string `json:"clientOrderId,omitempty"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
TimeInForce string `json:"timeInForce"`
|
||||
Quantity float64 `json:"quantity,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
CumQuantity float64 `json:"cumQuantity,string"`
|
||||
PostOnly bool `json:"postOnly"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
ReportType string `json:"reportType"`
|
||||
OriginalRequestClientOrderID string `json:"originalRequestClientOrderId"`
|
||||
ID string `json:"id"`
|
||||
ClientOrderID string `json:"clientOrderId,omitempty"`
|
||||
Symbol string `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
TimeInForce string `json:"timeInForce"`
|
||||
Quantity float64 `json:"quantity,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
CumQuantity float64 `json:"cumQuantity,string"`
|
||||
PostOnly bool `json:"postOnly"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
ReportType string `json:"reportType"`
|
||||
OriginalRequestClientOrderID string `json:"originalRequestClientOrderId"`
|
||||
}
|
||||
|
||||
// WsGetActiveOrdersResponse WS response
|
||||
@@ -545,21 +545,21 @@ type WsGetActiveOrdersResponse struct {
|
||||
|
||||
// WsGetActiveOrdersResponseData WS response data
|
||||
type WsGetActiveOrdersResponseData struct {
|
||||
ID string `json:"id"`
|
||||
ClientOrderID string `json:"clientOrderId,omitempty"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
TimeInForce string `json:"timeInForce"`
|
||||
Quantity float64 `json:"quantity,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
CumQuantity float64 `json:"cumQuantity,string"`
|
||||
PostOnly bool `json:"postOnly"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
ReportType string `json:"reportType"`
|
||||
OriginalRequestClientOrderID string `json:"originalRequestClientOrderId"`
|
||||
ID string `json:"id"`
|
||||
ClientOrderID string `json:"clientOrderId,omitempty"`
|
||||
Symbol string `json:"symbol"`
|
||||
Side string `json:"side"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
TimeInForce string `json:"timeInForce"`
|
||||
Quantity float64 `json:"quantity,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
CumQuantity float64 `json:"cumQuantity,string"`
|
||||
PostOnly bool `json:"postOnly"`
|
||||
CreatedAt time.Time `json:"createdAt"`
|
||||
UpdatedAt time.Time `json:"updatedAt"`
|
||||
ReportType string `json:"reportType"`
|
||||
OriginalRequestClientOrderID string `json:"originalRequestClientOrderId"`
|
||||
}
|
||||
|
||||
// WsGetTradingBalanceResponse WS response
|
||||
@@ -646,7 +646,7 @@ type WsGetSymbolsRequest struct {
|
||||
|
||||
// WsGetSymbolsRequestParameters request parameters
|
||||
type WsGetSymbolsRequestParameters struct {
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
Symbol string `json:"symbol"`
|
||||
}
|
||||
|
||||
// WsGetSymbolsResponse symbol response
|
||||
@@ -658,7 +658,7 @@ type WsGetSymbolsResponse struct {
|
||||
|
||||
// WsGetSymbolsResponseData symbol response data
|
||||
type WsGetSymbolsResponseData struct {
|
||||
ID currency.Pair `json:"id"`
|
||||
ID string `json:"id"`
|
||||
BaseCurrency currency.Code `json:"baseCurrency"`
|
||||
QuoteCurrency currency.Code `json:"quoteCurrency"`
|
||||
QuantityIncrement float64 `json:"quantityIncrement,string"`
|
||||
@@ -677,10 +677,10 @@ type WsGetTradesRequest struct {
|
||||
|
||||
// WsGetTradesRequestParameters trade request params
|
||||
type WsGetTradesRequestParameters struct {
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
Limit int64 `json:"limit"`
|
||||
Sort string `json:"sort"`
|
||||
By string `json:"by"`
|
||||
Symbol string `json:"symbol"`
|
||||
Limit int64 `json:"limit"`
|
||||
Sort string `json:"sort"`
|
||||
By string `json:"by"`
|
||||
}
|
||||
|
||||
// WsGetTradesResponse response
|
||||
|
||||
@@ -127,7 +127,8 @@ func (h *HitBTC) handleSubscriptionUpdates(resp wshandler.WebsocketResponse, ini
|
||||
Last: ticker.Params.Last,
|
||||
Timestamp: ts,
|
||||
AssetType: asset.Spot,
|
||||
Pair: ticker.Params.Symbol,
|
||||
Pair: currency.NewPairFromFormattedPairs(ticker.Params.Symbol,
|
||||
h.GetEnabledPairs(asset.Spot), h.GetPairFormat(asset.Spot, true)),
|
||||
}
|
||||
case "snapshotOrderbook":
|
||||
var obSnapshot WsOrderbook
|
||||
@@ -241,7 +242,8 @@ func (h *HitBTC) WsProcessOrderbookSnapshot(ob WsOrderbook) error {
|
||||
asks = append(asks, orderbook.Item{Amount: ob.Params.Ask[i].Size, Price: ob.Params.Ask[i].Price})
|
||||
}
|
||||
|
||||
p := currency.NewPairFromString(ob.Params.Symbol)
|
||||
p := currency.NewPairFromFormattedPairs(ob.Params.Symbol,
|
||||
h.GetEnabledPairs(asset.Spot), h.GetPairFormat(asset.Spot, true))
|
||||
|
||||
var newOrderBook orderbook.Base
|
||||
newOrderBook.Asks = asks
|
||||
@@ -278,7 +280,8 @@ func (h *HitBTC) WsProcessOrderbookUpdate(update WsOrderbook) error {
|
||||
asks = append(asks, orderbook.Item{Price: update.Params.Ask[i].Price, Amount: update.Params.Ask[i].Size})
|
||||
}
|
||||
|
||||
p := currency.NewPairFromString(update.Params.Symbol)
|
||||
p := currency.NewPairFromFormattedPairs(update.Params.Symbol,
|
||||
h.GetEnabledPairs(asset.Spot), h.GetPairFormat(asset.Spot, true))
|
||||
err := h.Websocket.Orderbook.Update(&wsorderbook.WebsocketOrderbookUpdate{
|
||||
Asks: asks,
|
||||
Bids: bids,
|
||||
@@ -327,17 +330,20 @@ func (h *HitBTC) Subscribe(channelToSubscribe wshandler.WebsocketChannelSubscrip
|
||||
}
|
||||
if channelToSubscribe.Currency.String() != "" {
|
||||
subscribe.Params = params{
|
||||
Symbol: channelToSubscribe.Currency.String(),
|
||||
Symbol: h.FormatExchangeCurrency(channelToSubscribe.Currency,
|
||||
asset.Spot).String(),
|
||||
}
|
||||
}
|
||||
if strings.EqualFold(channelToSubscribe.Channel, "subscribeTrades") {
|
||||
subscribe.Params = params{
|
||||
Symbol: channelToSubscribe.Currency.String(),
|
||||
Limit: 100,
|
||||
Symbol: h.FormatExchangeCurrency(channelToSubscribe.Currency,
|
||||
asset.Spot).String(),
|
||||
Limit: 100,
|
||||
}
|
||||
} else if strings.EqualFold(channelToSubscribe.Channel, "subscribeCandles") {
|
||||
subscribe.Params = params{
|
||||
Symbol: channelToSubscribe.Currency.String(),
|
||||
Symbol: h.FormatExchangeCurrency(channelToSubscribe.Currency,
|
||||
asset.Spot).String(),
|
||||
Period: "M30",
|
||||
Limit: 100,
|
||||
}
|
||||
@@ -353,17 +359,20 @@ func (h *HitBTC) Unsubscribe(channelToSubscribe wshandler.WebsocketChannelSubscr
|
||||
JSONRPCVersion: rpcVersion,
|
||||
Method: unsubscribeChannel,
|
||||
Params: params{
|
||||
Symbol: channelToSubscribe.Currency.String(),
|
||||
Symbol: h.FormatExchangeCurrency(channelToSubscribe.Currency,
|
||||
asset.Spot).String(),
|
||||
},
|
||||
}
|
||||
if strings.EqualFold(unsubscribeChannel, "unsubscribeTrades") {
|
||||
subscribe.Params = params{
|
||||
Symbol: channelToSubscribe.Currency.String(),
|
||||
Limit: 100,
|
||||
Symbol: h.FormatExchangeCurrency(channelToSubscribe.Currency,
|
||||
asset.Spot).String(),
|
||||
Limit: 100,
|
||||
}
|
||||
} else if strings.EqualFold(unsubscribeChannel, "unsubscribeCandles") {
|
||||
subscribe.Params = params{
|
||||
Symbol: channelToSubscribe.Currency.String(),
|
||||
Symbol: h.FormatExchangeCurrency(channelToSubscribe.Currency,
|
||||
asset.Spot).String(),
|
||||
Period: "M30",
|
||||
Limit: 100,
|
||||
}
|
||||
@@ -408,7 +417,7 @@ func (h *HitBTC) wsPlaceOrder(pair currency.Pair, side string, price, quantity f
|
||||
Method: "newOrder",
|
||||
Params: WsSubmitOrderRequestData{
|
||||
ClientOrderID: id,
|
||||
Symbol: pair,
|
||||
Symbol: h.FormatExchangeCurrency(pair, asset.Spot).String(),
|
||||
Side: strings.ToLower(side),
|
||||
Price: price,
|
||||
Quantity: quantity,
|
||||
@@ -566,7 +575,7 @@ func (h *HitBTC) wsGetSymbols(currencyItem currency.Pair) (*WsGetSymbolsResponse
|
||||
request := WsGetSymbolsRequest{
|
||||
Method: "getSymbol",
|
||||
Params: WsGetSymbolsRequestParameters{
|
||||
Symbol: currencyItem,
|
||||
Symbol: h.FormatExchangeCurrency(currencyItem, asset.Spot).String(),
|
||||
},
|
||||
ID: h.WebsocketConn.GenerateMessageID(false),
|
||||
}
|
||||
@@ -590,7 +599,7 @@ func (h *HitBTC) wsGetTrades(currencyItem currency.Pair, limit int64, sort, by s
|
||||
request := WsGetTradesRequest{
|
||||
Method: "getTrades",
|
||||
Params: WsGetTradesRequestParameters{
|
||||
Symbol: currencyItem,
|
||||
Symbol: h.FormatExchangeCurrency(currencyItem, asset.Spot).String(),
|
||||
Limit: limit,
|
||||
Sort: sort,
|
||||
By: by,
|
||||
|
||||
@@ -196,7 +196,8 @@ func (h *HitBTC) FetchTradablePairs(asset asset.Item) ([]string, error) {
|
||||
|
||||
var pairs []string
|
||||
for x := range symbols {
|
||||
pairs = append(pairs, fmt.Sprintf("%v%v%v", symbols[x].BaseCurrency, h.GetPairFormat(asset, false).Delimiter, symbols[x].QuoteCurrency))
|
||||
pairs = append(pairs, fmt.Sprintf("%v%v%v", symbols[x].BaseCurrency,
|
||||
h.GetPairFormat(asset, false).Delimiter, symbols[x].QuoteCurrency))
|
||||
}
|
||||
return pairs, nil
|
||||
}
|
||||
@@ -222,8 +223,17 @@ func (h *HitBTC) UpdateTicker(currencyPair currency.Pair, assetType asset.Item)
|
||||
pairs := h.GetEnabledPairs(assetType)
|
||||
for i := range pairs {
|
||||
for j := range tick {
|
||||
if !tick[j].Symbol.Equal(pairs[i]) {
|
||||
continue
|
||||
pairFmt := h.FormatExchangeCurrency(pairs[i], assetType).String()
|
||||
if tick[j].Symbol != pairFmt {
|
||||
found := false
|
||||
if strings.Contains(tick[j].Symbol, "USDT") {
|
||||
if pairFmt == tick[j].Symbol[0:len(tick[j].Symbol)-1] {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
continue
|
||||
}
|
||||
}
|
||||
tickerPrice := ticker.Price{
|
||||
Last: tick[j].Last,
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
package huobi
|
||||
|
||||
import "github.com/thrasher-corp/gocryptotrader/currency"
|
||||
|
||||
// Response stores the Huobi response information
|
||||
type Response struct {
|
||||
Status string `json:"status"`
|
||||
@@ -49,14 +47,14 @@ type Tickers struct {
|
||||
|
||||
// Ticker latest ticker data
|
||||
type Ticker struct {
|
||||
Amount float64 `json:"amount"`
|
||||
Close float64 `json:"close"`
|
||||
Count int64 `json:"count"`
|
||||
High float64 `json:"high"`
|
||||
Low float64 `json:"low"`
|
||||
Open float64 `json:"open"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
Volume float64 `json:"vol"`
|
||||
Amount float64 `json:"amount"`
|
||||
Close float64 `json:"close"`
|
||||
Count int64 `json:"count"`
|
||||
High float64 `json:"high"`
|
||||
Low float64 `json:"low"`
|
||||
Open float64 `json:"open"`
|
||||
Symbol string `json:"symbol"`
|
||||
Volume float64 `json:"vol"`
|
||||
}
|
||||
|
||||
// OrderBookDataRequestParamsType var for request param types
|
||||
@@ -118,11 +116,17 @@ type Detail struct {
|
||||
|
||||
// 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"`
|
||||
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"`
|
||||
Innovation string `json:"innovation"`
|
||||
State string `json:"state"`
|
||||
ValuePrecision int `json:"value-precision"`
|
||||
MinimumOrderAmount float64 `json:"min-order-amt"`
|
||||
MaximumOrderAmount float64 `json:"max-order-amt"`
|
||||
MinimumOrderValue float64 `json:"min-order-value"`
|
||||
}
|
||||
|
||||
// Account stores the account data
|
||||
@@ -339,6 +343,7 @@ type WsKline struct {
|
||||
}
|
||||
}
|
||||
|
||||
// WsTick stores websocket ticker data
|
||||
type WsTick struct {
|
||||
Channel string `json:"ch"`
|
||||
Timestamp int64 `json:"ts"`
|
||||
@@ -403,15 +408,15 @@ type WsAuthenticatedSubscriptionRequest struct {
|
||||
|
||||
// WsAuthenticatedAccountsListRequest request for account list authenticated connection
|
||||
type WsAuthenticatedAccountsListRequest struct {
|
||||
Op string `json:"op"`
|
||||
AccessKeyID string `json:"AccessKeyId"`
|
||||
SignatureMethod string `json:"SignatureMethod"`
|
||||
SignatureVersion string `json:"SignatureVersion"`
|
||||
Timestamp string `json:"Timestamp"`
|
||||
Signature string `json:"Signature"`
|
||||
Topic string `json:"topic"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
ClientID int64 `json:"cid,string,omitempty"`
|
||||
Op string `json:"op"`
|
||||
AccessKeyID string `json:"AccessKeyId"`
|
||||
SignatureMethod string `json:"SignatureMethod"`
|
||||
SignatureVersion string `json:"SignatureVersion"`
|
||||
Timestamp string `json:"Timestamp"`
|
||||
Signature string `json:"Signature"`
|
||||
Topic string `json:"topic"`
|
||||
Symbol string `json:"symbol"`
|
||||
ClientID int64 `json:"cid,string,omitempty"`
|
||||
}
|
||||
|
||||
// WsAuthenticatedOrderDetailsRequest request for order details authenticated connection
|
||||
@@ -429,17 +434,17 @@ type WsAuthenticatedOrderDetailsRequest struct {
|
||||
|
||||
// WsAuthenticatedOrdersListRequest request for orderslist authenticated connection
|
||||
type WsAuthenticatedOrdersListRequest struct {
|
||||
Op string `json:"op"`
|
||||
AccessKeyID string `json:"AccessKeyId"`
|
||||
SignatureMethod string `json:"SignatureMethod"`
|
||||
SignatureVersion string `json:"SignatureVersion"`
|
||||
Timestamp string `json:"Timestamp"`
|
||||
Signature string `json:"Signature"`
|
||||
Topic string `json:"topic"`
|
||||
States string `json:"states"`
|
||||
AccountID int64 `json:"account-id"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
ClientID int64 `json:"cid,string,omitempty"`
|
||||
Op string `json:"op"`
|
||||
AccessKeyID string `json:"AccessKeyId"`
|
||||
SignatureMethod string `json:"SignatureMethod"`
|
||||
SignatureVersion string `json:"SignatureVersion"`
|
||||
Timestamp string `json:"Timestamp"`
|
||||
Signature string `json:"Signature"`
|
||||
Topic string `json:"topic"`
|
||||
States string `json:"states"`
|
||||
AccountID int64 `json:"account-id"`
|
||||
Symbol string `json:"symbol"`
|
||||
ClientID int64 `json:"cid,string,omitempty"`
|
||||
}
|
||||
|
||||
// WsAuthenticatedDataResponse response from authenticated connection
|
||||
@@ -481,15 +486,15 @@ type WsAuthenticatedOrdersUpdateResponse struct {
|
||||
|
||||
// WsAuthenticatedOrdersUpdateResponseData order updatedata
|
||||
type WsAuthenticatedOrdersUpdateResponseData struct {
|
||||
UnfilledAmount float64 `json:"unfilled-amount,string"`
|
||||
FilledAmount float64 `json:"filled-amount,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
OrderID int64 `json:"order-id"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
MatchID int64 `json:"match-id"`
|
||||
FilledCashAmount float64 `json:"filled-cash-amount,string"`
|
||||
Role string `json:"role"`
|
||||
OrderState string `json:"order-state"`
|
||||
UnfilledAmount float64 `json:"unfilled-amount,string"`
|
||||
FilledAmount float64 `json:"filled-amount,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
OrderID int64 `json:"order-id"`
|
||||
Symbol string `json:"symbol"`
|
||||
MatchID int64 `json:"match-id"`
|
||||
FilledCashAmount float64 `json:"filled-cash-amount,string"`
|
||||
Role string `json:"role"`
|
||||
OrderState string `json:"order-state"`
|
||||
}
|
||||
|
||||
// WsAuthenticatedOrdersResponse response from Orders authenticated subscription
|
||||
@@ -500,22 +505,22 @@ type WsAuthenticatedOrdersResponse struct {
|
||||
|
||||
// WsAuthenticatedOrdersResponseData order data
|
||||
type WsAuthenticatedOrdersResponseData struct {
|
||||
SeqID int64 `json:"seq-id"`
|
||||
OrderID int64 `json:"order-id"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
AccountID int64 `json:"account-id"`
|
||||
OrderAmount float64 `json:"order-amount,string"`
|
||||
OrderPrice float64 `json:"order-price,string"`
|
||||
CreatedAt int64 `json:"created-at"`
|
||||
OrderType string `json:"order-type"`
|
||||
OrderSource string `json:"order-source"`
|
||||
OrderState string `json:"order-state"`
|
||||
Role string `json:"role"`
|
||||
Price float64 `json:"price,string"`
|
||||
FilledAmount float64 `json:"filled-amount,string"`
|
||||
UnfilledAmount float64 `json:"unfilled-amount,string"`
|
||||
FilledCashAmount float64 `json:"filled-cash-amount,string"`
|
||||
FilledFees float64 `json:"filled-fees,string"`
|
||||
SeqID int64 `json:"seq-id"`
|
||||
OrderID int64 `json:"order-id"`
|
||||
Symbol string `json:"symbol"`
|
||||
AccountID int64 `json:"account-id"`
|
||||
OrderAmount float64 `json:"order-amount,string"`
|
||||
OrderPrice float64 `json:"order-price,string"`
|
||||
CreatedAt int64 `json:"created-at"`
|
||||
OrderType string `json:"order-type"`
|
||||
OrderSource string `json:"order-source"`
|
||||
OrderState string `json:"order-state"`
|
||||
Role string `json:"role"`
|
||||
Price float64 `json:"price,string"`
|
||||
FilledAmount float64 `json:"filled-amount,string"`
|
||||
UnfilledAmount float64 `json:"unfilled-amount,string"`
|
||||
FilledCashAmount float64 `json:"filled-cash-amount,string"`
|
||||
FilledFees float64 `json:"filled-fees,string"`
|
||||
}
|
||||
|
||||
// WsAuthenticatedAccountsListResponse response from AccountsList authenticated endpoint
|
||||
@@ -547,20 +552,20 @@ type WsAuthenticatedOrdersListResponse struct {
|
||||
|
||||
// WsAuthenticatedOrdersListResponseData contains order details
|
||||
type WsAuthenticatedOrdersListResponseData struct {
|
||||
ID int64 `json:"id"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
AccountID int64 `json:"account-id"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
CreatedAt int64 `json:"created-at"`
|
||||
Type string `json:"type"`
|
||||
FilledAmount float64 `json:"filled-amount,string"`
|
||||
FilledCashAmount float64 `json:"filled-cash-amount,string"`
|
||||
FilledFees float64 `json:"filled-fees,string"`
|
||||
FinishedAt int64 `json:"finished-at"`
|
||||
Source string `json:"source"`
|
||||
State string `json:"state"`
|
||||
CanceledAt int64 `json:"canceled-at"`
|
||||
ID int64 `json:"id"`
|
||||
Symbol string `json:"symbol"`
|
||||
AccountID int64 `json:"account-id"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
CreatedAt int64 `json:"created-at"`
|
||||
Type string `json:"type"`
|
||||
FilledAmount float64 `json:"filled-amount,string"`
|
||||
FilledCashAmount float64 `json:"filled-cash-amount,string"`
|
||||
FilledFees float64 `json:"filled-fees,string"`
|
||||
FinishedAt int64 `json:"finished-at"`
|
||||
Source string `json:"source"`
|
||||
State string `json:"state"`
|
||||
CanceledAt int64 `json:"canceled-at"`
|
||||
}
|
||||
|
||||
// WsAuthenticatedOrderDetailResponse response from OrderDetail authenticated endpoint
|
||||
|
||||
@@ -244,10 +244,11 @@ func (h *HUOBI) wsHandleMarketData(resp WsMessage) {
|
||||
}
|
||||
data := strings.Split(kline.Channel, ".")
|
||||
h.Websocket.DataHandler <- wshandler.KlineData{
|
||||
Timestamp: time.Unix(0, kline.Timestamp),
|
||||
Exchange: h.GetName(),
|
||||
AssetType: asset.Spot,
|
||||
Pair: currency.NewPairFromString(data[1]),
|
||||
Timestamp: time.Unix(0, kline.Timestamp),
|
||||
Exchange: h.GetName(),
|
||||
AssetType: asset.Spot,
|
||||
Pair: currency.NewPairFromFormattedPairs(data[1],
|
||||
h.GetEnabledPairs(asset.Spot), h.GetPairFormat(asset.Spot, true)),
|
||||
OpenPrice: kline.Tick.Open,
|
||||
ClosePrice: kline.Tick.Close,
|
||||
HighPrice: kline.Tick.High,
|
||||
@@ -263,10 +264,11 @@ func (h *HUOBI) wsHandleMarketData(resp WsMessage) {
|
||||
}
|
||||
data := strings.Split(trade.Channel, ".")
|
||||
h.Websocket.DataHandler <- wshandler.TradeData{
|
||||
Exchange: h.GetName(),
|
||||
AssetType: asset.Spot,
|
||||
CurrencyPair: currency.NewPairFromString(data[1]),
|
||||
Timestamp: time.Unix(0, trade.Tick.Timestamp),
|
||||
Exchange: h.GetName(),
|
||||
AssetType: asset.Spot,
|
||||
CurrencyPair: currency.NewPairFromFormattedPairs(data[1],
|
||||
h.GetEnabledPairs(asset.Spot), h.GetPairFormat(asset.Spot, true)),
|
||||
Timestamp: time.Unix(0, trade.Tick.Timestamp),
|
||||
}
|
||||
case strings.Contains(init.Channel, "detail"):
|
||||
var ticker WsTick
|
||||
@@ -286,14 +288,16 @@ func (h *HUOBI) wsHandleMarketData(resp WsMessage) {
|
||||
Low: ticker.Tick.Low,
|
||||
Timestamp: time.Unix(0, ticker.Timestamp),
|
||||
AssetType: asset.Spot,
|
||||
Pair: currency.NewPairFromString(data[1]),
|
||||
Pair: currency.NewPairFromFormattedPairs(data[1],
|
||||
h.GetEnabledPairs(asset.Spot), h.GetPairFormat(asset.Spot, true)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WsProcessOrderbook processes new orderbook data
|
||||
func (h *HUOBI) WsProcessOrderbook(update *WsDepth, symbol string) error {
|
||||
p := currency.NewPairFromString(symbol)
|
||||
p := currency.NewPairFromFormattedPairs(symbol,
|
||||
h.GetEnabledPairs(asset.Spot), h.GetPairFormat(asset.Spot, true))
|
||||
var bids, asks []orderbook.Item
|
||||
for i := 0; i < len(update.Tick.Bids); i++ {
|
||||
bidLevel := update.Tick.Bids[i].([]interface{})
|
||||
@@ -428,7 +432,7 @@ func (h *HUOBI) wsGetAccountsList(pair currency.Pair) (*WsAuthenticatedAccountsL
|
||||
SignatureVersion: signatureVersion,
|
||||
Timestamp: timestamp,
|
||||
Topic: wsAccountsList,
|
||||
Symbol: pair,
|
||||
Symbol: h.FormatExchangeCurrency(pair, asset.Spot).String(),
|
||||
}
|
||||
hmac := h.wsGenerateSignature(timestamp, wsAccountListEndpoint)
|
||||
request.Signature = crypto.Base64Encode(hmac)
|
||||
@@ -455,7 +459,7 @@ func (h *HUOBI) wsGetOrdersList(accountID int64, pair currency.Pair) (*WsAuthent
|
||||
Timestamp: timestamp,
|
||||
Topic: wsOrdersList,
|
||||
AccountID: accountID,
|
||||
Symbol: pair.Lower(),
|
||||
Symbol: h.FormatExchangeCurrency(pair, asset.Spot).String(),
|
||||
States: "submitted,partial-filled",
|
||||
}
|
||||
hmac := h.wsGenerateSignature(timestamp, wsOrdersListEndpoint)
|
||||
|
||||
@@ -228,7 +228,11 @@ func (h *HUOBI) FetchTradablePairs(asset asset.Item) ([]string, error) {
|
||||
|
||||
var pairs []string
|
||||
for x := range symbols {
|
||||
pairs = append(pairs, fmt.Sprintf("%v%v%v", symbols[x].BaseCurrency, h.GetPairFormat(asset, false).Delimiter, symbols[x].QuoteCurrency))
|
||||
if symbols[x].State != "online" {
|
||||
continue
|
||||
}
|
||||
pairs = append(pairs, fmt.Sprintf("%v%v%v", symbols[x].BaseCurrency,
|
||||
h.GetPairFormat(asset, false).Delimiter, symbols[x].QuoteCurrency))
|
||||
}
|
||||
|
||||
return pairs, nil
|
||||
@@ -255,7 +259,8 @@ func (h *HUOBI) UpdateTicker(p currency.Pair, assetType asset.Item) (ticker.Pric
|
||||
pairs := h.GetEnabledPairs(assetType)
|
||||
for i := range pairs {
|
||||
for j := range tickers.Data {
|
||||
if !pairs[i].Equal(tickers.Data[j].Symbol) {
|
||||
pairFmt := h.FormatExchangeCurrency(pairs[i], assetType).String()
|
||||
if pairFmt != tickers.Data[j].Symbol {
|
||||
continue
|
||||
}
|
||||
tickerPrice := ticker.Price{
|
||||
@@ -264,7 +269,7 @@ func (h *HUOBI) UpdateTicker(p currency.Pair, assetType asset.Item) (ticker.Pric
|
||||
Volume: tickers.Data[j].Volume,
|
||||
Open: tickers.Data[j].Open,
|
||||
Close: tickers.Data[j].Close,
|
||||
Pair: tickers.Data[j].Symbol,
|
||||
Pair: pairs[i],
|
||||
}
|
||||
err = ticker.ProcessTicker(h.GetName(), &tickerPrice, assetType)
|
||||
if err != nil {
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
package huobihadax
|
||||
|
||||
import (
|
||||
"github.com/thrasher-corp/gocryptotrader/currency"
|
||||
)
|
||||
|
||||
// Response stores the Huobi response information
|
||||
type Response struct {
|
||||
Status string `json:"status"`
|
||||
@@ -25,6 +21,7 @@ type KlineItem struct {
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
// WsTick stores websocket ticker data
|
||||
type WsTick struct {
|
||||
Channel string `json:"ch"`
|
||||
Timestamp int64 `json:"ts"`
|
||||
@@ -48,14 +45,14 @@ type Tickers struct {
|
||||
|
||||
// Ticker latest ticker data
|
||||
type Ticker struct {
|
||||
Amount float64 `json:"amount"`
|
||||
Close float64 `json:"close"`
|
||||
Count int64 `json:"count"`
|
||||
High float64 `json:"high"`
|
||||
Low float64 `json:"low"`
|
||||
Open float64 `json:"open"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
Volume float64 `json:"vol"`
|
||||
Amount float64 `json:"amount"`
|
||||
Close float64 `json:"close"`
|
||||
Count int64 `json:"count"`
|
||||
High float64 `json:"high"`
|
||||
Low float64 `json:"low"`
|
||||
Open float64 `json:"open"`
|
||||
Symbol string `json:"symbol"`
|
||||
Volume float64 `json:"vol"`
|
||||
}
|
||||
|
||||
// DetailMerged stores the ticker detail merged data
|
||||
@@ -121,6 +118,7 @@ type Symbol struct {
|
||||
PricePrecision int `json:"price-precision"`
|
||||
AmountPrecision int `json:"amount-precision"`
|
||||
SymbolPartition string `json:"symbol-partition"`
|
||||
Symbol string `json:"innovation"`
|
||||
}
|
||||
|
||||
// Account stores the account data
|
||||
@@ -396,15 +394,15 @@ type WsAuthenticatedSubscriptionRequest struct {
|
||||
|
||||
// WsAuthenticatedAccountsListRequest request for account list authenticated connection
|
||||
type WsAuthenticatedAccountsListRequest struct {
|
||||
Op string `json:"op"`
|
||||
AccessKeyID string `json:"AccessKeyId"`
|
||||
SignatureMethod string `json:"SignatureMethod"`
|
||||
SignatureVersion string `json:"SignatureVersion"`
|
||||
Timestamp string `json:"Timestamp"`
|
||||
Signature string `json:"Signature"`
|
||||
Topic string `json:"topic"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
ClientID int64 `json:"cid,string,omitempty"`
|
||||
Op string `json:"op"`
|
||||
AccessKeyID string `json:"AccessKeyId"`
|
||||
SignatureMethod string `json:"SignatureMethod"`
|
||||
SignatureVersion string `json:"SignatureVersion"`
|
||||
Timestamp string `json:"Timestamp"`
|
||||
Signature string `json:"Signature"`
|
||||
Topic string `json:"topic"`
|
||||
Symbol string `json:"symbol"`
|
||||
ClientID int64 `json:"cid,string,omitempty"`
|
||||
}
|
||||
|
||||
// WsAuthenticatedOrderDetailsRequest request for order details authenticated connection
|
||||
@@ -422,17 +420,17 @@ type WsAuthenticatedOrderDetailsRequest struct {
|
||||
|
||||
// WsAuthenticatedOrdersListRequest request for orderslist authenticated connection
|
||||
type WsAuthenticatedOrdersListRequest struct {
|
||||
Op string `json:"op"`
|
||||
AccessKeyID string `json:"AccessKeyId"`
|
||||
SignatureMethod string `json:"SignatureMethod"`
|
||||
SignatureVersion string `json:"SignatureVersion"`
|
||||
Timestamp string `json:"Timestamp"`
|
||||
Signature string `json:"Signature"`
|
||||
Topic string `json:"topic"`
|
||||
States string `json:"states"`
|
||||
AccountID int64 `json:"account-id"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
ClientID int64 `json:"cid,string,omitempty"`
|
||||
Op string `json:"op"`
|
||||
AccessKeyID string `json:"AccessKeyId"`
|
||||
SignatureMethod string `json:"SignatureMethod"`
|
||||
SignatureVersion string `json:"SignatureVersion"`
|
||||
Timestamp string `json:"Timestamp"`
|
||||
Signature string `json:"Signature"`
|
||||
Topic string `json:"topic"`
|
||||
States string `json:"states"`
|
||||
AccountID int64 `json:"account-id"`
|
||||
Symbol string `json:"symbol"`
|
||||
ClientID int64 `json:"cid,string,omitempty"`
|
||||
}
|
||||
|
||||
// WsAuthenticatedDataResponse response from authenticated connection
|
||||
@@ -474,15 +472,15 @@ type WsAuthenticatedOrdersUpdateResponse struct {
|
||||
|
||||
// WsAuthenticatedOrdersUpdateResponseData order updatedata
|
||||
type WsAuthenticatedOrdersUpdateResponseData struct {
|
||||
UnfilledAmount float64 `json:"unfilled-amount,string"`
|
||||
FilledAmount float64 `json:"filled-amount,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
OrderID int64 `json:"order-id"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
MatchID int64 `json:"match-id"`
|
||||
FilledCashAmount float64 `json:"filled-cash-amount,string"`
|
||||
Role string `json:"role"`
|
||||
OrderState string `json:"order-state"`
|
||||
UnfilledAmount float64 `json:"unfilled-amount,string"`
|
||||
FilledAmount float64 `json:"filled-amount,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
OrderID int64 `json:"order-id"`
|
||||
Symbol string `json:"symbol"`
|
||||
MatchID int64 `json:"match-id"`
|
||||
FilledCashAmount float64 `json:"filled-cash-amount,string"`
|
||||
Role string `json:"role"`
|
||||
OrderState string `json:"order-state"`
|
||||
}
|
||||
|
||||
// WsAuthenticatedOrdersResponse response from Orders authenticated subscription
|
||||
@@ -493,22 +491,22 @@ type WsAuthenticatedOrdersResponse struct {
|
||||
|
||||
// WsAuthenticatedOrdersResponseData order data
|
||||
type WsAuthenticatedOrdersResponseData struct {
|
||||
SeqID int64 `json:"seq-id"`
|
||||
OrderID int64 `json:"order-id"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
AccountID int64 `json:"account-id"`
|
||||
OrderAmount float64 `json:"order-amount,string"`
|
||||
OrderPrice float64 `json:"order-price,string"`
|
||||
CreatedAt int64 `json:"created-at"`
|
||||
OrderType string `json:"order-type"`
|
||||
OrderSource string `json:"order-source"`
|
||||
OrderState string `json:"order-state"`
|
||||
Role string `json:"role"`
|
||||
Price float64 `json:"price,string"`
|
||||
FilledAmount float64 `json:"filled-amount,string"`
|
||||
UnfilledAmount float64 `json:"unfilled-amount,string"`
|
||||
FilledCashAmount float64 `json:"filled-cash-amount,string"`
|
||||
FilledFees float64 `json:"filled-fees,string"`
|
||||
SeqID int64 `json:"seq-id"`
|
||||
OrderID int64 `json:"order-id"`
|
||||
Symbol string `json:"symbol"`
|
||||
AccountID int64 `json:"account-id"`
|
||||
OrderAmount float64 `json:"order-amount,string"`
|
||||
OrderPrice float64 `json:"order-price,string"`
|
||||
CreatedAt int64 `json:"created-at"`
|
||||
OrderType string `json:"order-type"`
|
||||
OrderSource string `json:"order-source"`
|
||||
OrderState string `json:"order-state"`
|
||||
Role string `json:"role"`
|
||||
Price float64 `json:"price,string"`
|
||||
FilledAmount float64 `json:"filled-amount,string"`
|
||||
UnfilledAmount float64 `json:"unfilled-amount,string"`
|
||||
FilledCashAmount float64 `json:"filled-cash-amount,string"`
|
||||
FilledFees float64 `json:"filled-fees,string"`
|
||||
}
|
||||
|
||||
// WsAuthenticatedAccountsListResponse response from AccountsList authenticated endpoint
|
||||
@@ -540,20 +538,20 @@ type WsAuthenticatedOrdersListResponse struct {
|
||||
|
||||
// WsAuthenticatedOrdersListResponseData contains order details
|
||||
type WsAuthenticatedOrdersListResponseData struct {
|
||||
ID int64 `json:"id"`
|
||||
Symbol currency.Pair `json:"symbol"`
|
||||
AccountID int64 `json:"account-id"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
CreatedAt int64 `json:"created-at"`
|
||||
Type string `json:"type"`
|
||||
FilledAmount float64 `json:"filled-amount,string"`
|
||||
FilledCashAmount float64 `json:"filled-cash-amount,string"`
|
||||
FilledFees float64 `json:"filled-fees,string"`
|
||||
FinishedAt int64 `json:"finished-at"`
|
||||
Source string `json:"source"`
|
||||
State string `json:"state"`
|
||||
CanceledAt int64 `json:"canceled-at"`
|
||||
ID int64 `json:"id"`
|
||||
Symbol string `json:"symbol"`
|
||||
AccountID int64 `json:"account-id"`
|
||||
Amount float64 `json:"amount,string"`
|
||||
Price float64 `json:"price,string"`
|
||||
CreatedAt int64 `json:"created-at"`
|
||||
Type string `json:"type"`
|
||||
FilledAmount float64 `json:"filled-amount,string"`
|
||||
FilledCashAmount float64 `json:"filled-cash-amount,string"`
|
||||
FilledFees float64 `json:"filled-fees,string"`
|
||||
FinishedAt int64 `json:"finished-at"`
|
||||
Source string `json:"source"`
|
||||
State string `json:"state"`
|
||||
CanceledAt int64 `json:"canceled-at"`
|
||||
}
|
||||
|
||||
// WsAuthenticatedOrderDetailResponse response from OrderDetail authenticated endpoint
|
||||
|
||||
@@ -245,10 +245,11 @@ func (h *HUOBIHADAX) wsHandleMarketData(resp WsMessage) {
|
||||
}
|
||||
data := strings.Split(kline.Channel, ".")
|
||||
h.Websocket.DataHandler <- wshandler.KlineData{
|
||||
Timestamp: time.Unix(0, kline.Timestamp),
|
||||
Exchange: h.GetName(),
|
||||
AssetType: asset.Spot,
|
||||
Pair: currency.NewPairFromString(data[1]),
|
||||
Timestamp: time.Unix(0, kline.Timestamp),
|
||||
Exchange: h.GetName(),
|
||||
AssetType: asset.Spot,
|
||||
Pair: currency.NewPairFromFormattedPairs(data[1],
|
||||
h.GetEnabledPairs(asset.Spot), h.GetPairFormat(asset.Spot, true)),
|
||||
OpenPrice: kline.Tick.Open,
|
||||
ClosePrice: kline.Tick.Close,
|
||||
HighPrice: kline.Tick.High,
|
||||
@@ -264,10 +265,11 @@ func (h *HUOBIHADAX) wsHandleMarketData(resp WsMessage) {
|
||||
}
|
||||
data := strings.Split(trade.Channel, ".")
|
||||
h.Websocket.DataHandler <- wshandler.TradeData{
|
||||
Exchange: h.GetName(),
|
||||
AssetType: asset.Spot,
|
||||
CurrencyPair: currency.NewPairFromString(data[1]),
|
||||
Timestamp: time.Unix(0, trade.Tick.Timestamp),
|
||||
Exchange: h.GetName(),
|
||||
AssetType: asset.Spot,
|
||||
CurrencyPair: currency.NewPairFromFormattedPairs(data[1],
|
||||
h.GetEnabledPairs(asset.Spot), h.GetPairFormat(asset.Spot, true)),
|
||||
Timestamp: time.Unix(0, trade.Tick.Timestamp),
|
||||
}
|
||||
case strings.Contains(init.Channel, "detail"):
|
||||
var ticker WsTick
|
||||
@@ -287,14 +289,16 @@ func (h *HUOBIHADAX) wsHandleMarketData(resp WsMessage) {
|
||||
Low: ticker.Tick.Low,
|
||||
Timestamp: time.Unix(0, ticker.Timestamp),
|
||||
AssetType: asset.Spot,
|
||||
Pair: currency.NewPairFromString(data[1]),
|
||||
Pair: currency.NewPairFromFormattedPairs(data[1],
|
||||
h.GetEnabledPairs(asset.Spot), h.GetPairFormat(asset.Spot, true)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WsProcessOrderbook processes new orderbook data
|
||||
func (h *HUOBIHADAX) WsProcessOrderbook(update *WsDepth, symbol string) error {
|
||||
p := currency.NewPairFromString(symbol)
|
||||
p := currency.NewPairFromFormattedPairs(symbol,
|
||||
h.GetEnabledPairs(asset.Spot), h.GetPairFormat(asset.Spot, true))
|
||||
var bids, asks []orderbook.Item
|
||||
for i := 0; i < len(update.Tick.Bids); i++ {
|
||||
bidLevel := update.Tick.Bids[i].([]interface{})
|
||||
@@ -429,7 +433,7 @@ func (h *HUOBIHADAX) wsGetAccountsList(pair currency.Pair) (*WsAuthenticatedAcco
|
||||
SignatureVersion: signatureVersion,
|
||||
Timestamp: timestamp,
|
||||
Topic: wsAccountsList,
|
||||
Symbol: pair,
|
||||
Symbol: h.FormatExchangeCurrency(pair, asset.Spot).String(),
|
||||
}
|
||||
hmac := h.wsGenerateSignature(timestamp, wsAccountListEndpoint)
|
||||
request.Signature = crypto.Base64Encode(hmac)
|
||||
@@ -456,7 +460,7 @@ func (h *HUOBIHADAX) wsGetOrdersList(accountID int64, pair currency.Pair) (*WsAu
|
||||
Timestamp: timestamp,
|
||||
Topic: wsOrdersList,
|
||||
AccountID: accountID,
|
||||
Symbol: pair.Lower(),
|
||||
Symbol: h.FormatExchangeCurrency(pair, asset.Spot).String(),
|
||||
States: "submitted,partial-filled",
|
||||
}
|
||||
hmac := h.wsGenerateSignature(timestamp, wsOrdersListEndpoint)
|
||||
|
||||
@@ -191,7 +191,8 @@ func (h *HUOBIHADAX) FetchTradablePairs(asset asset.Item) ([]string, error) {
|
||||
|
||||
var pairs []string
|
||||
for x := range symbols {
|
||||
pairs = append(pairs, fmt.Sprintf("%v%v%v", symbols[x].BaseCurrency, h.GetPairFormat(asset, false).Delimiter, symbols[x].QuoteCurrency))
|
||||
pairs = append(pairs, fmt.Sprintf("%v%v%v", symbols[x].BaseCurrency,
|
||||
h.GetPairFormat(asset, false).Delimiter, symbols[x].QuoteCurrency))
|
||||
}
|
||||
|
||||
return pairs, nil
|
||||
@@ -218,7 +219,8 @@ func (h *HUOBIHADAX) UpdateTicker(p currency.Pair, assetType asset.Item) (ticker
|
||||
pairs := h.GetEnabledPairs(assetType)
|
||||
for i := range pairs {
|
||||
for j := range tickers.Data {
|
||||
if !pairs[i].Equal(tickers.Data[j].Symbol) {
|
||||
pairFmt := h.FormatExchangeCurrency(pairs[i], assetType).String()
|
||||
if pairFmt != tickers.Data[j].Symbol {
|
||||
continue
|
||||
}
|
||||
tickerPrice := ticker.Price{
|
||||
@@ -227,7 +229,7 @@ func (h *HUOBIHADAX) UpdateTicker(p currency.Pair, assetType asset.Item) (ticker
|
||||
Volume: tickers.Data[j].Volume,
|
||||
Open: tickers.Data[j].Open,
|
||||
Close: tickers.Data[j].Close,
|
||||
Pair: tickers.Data[j].Symbol,
|
||||
Pair: pairs[i],
|
||||
}
|
||||
err = ticker.ProcessTicker(h.GetName(), &tickerPrice, assetType)
|
||||
if err != nil {
|
||||
|
||||
@@ -220,7 +220,8 @@ func (k *Kraken) WsHandleEventResponse(response *WebsocketEventResponse, rawResp
|
||||
// allowing correlation between subscriptions and returned data
|
||||
func addNewSubscriptionChannelData(response *WebsocketEventResponse) {
|
||||
// We change the / to - to maintain compatibility with REST/config
|
||||
pair := currency.NewPairWithDelimiter(response.Pair.Base.String(), response.Pair.Quote.String(), "-")
|
||||
pair := currency.NewPairWithDelimiter(response.Pair.Base.String(),
|
||||
response.Pair.Quote.String(), "-")
|
||||
subscriptionChannelPair = append(subscriptionChannelPair, WebsocketChannelData{
|
||||
Subscription: response.Subscription.Name,
|
||||
Pair: pair,
|
||||
|
||||
@@ -170,7 +170,7 @@ func (k *Kraken) Run() {
|
||||
forceUpdate := false
|
||||
if !common.StringDataContains(k.GetEnabledPairs(asset.Spot).Strings(), k.GetPairFormat(asset.Spot, false).Delimiter) ||
|
||||
!common.StringDataContains(k.GetAvailablePairs(asset.Spot).Strings(), k.GetPairFormat(asset.Spot, false).Delimiter) {
|
||||
enabledPairs := currency.NewPairsFromStrings([]string{fmt.Sprintf("BTC%vUSD", k.GetPairFormat(asset.Spot, false).Delimiter)})
|
||||
enabledPairs := currency.NewPairsFromStrings([]string{fmt.Sprintf("XBT%vUSD", k.GetPairFormat(asset.Spot, false).Delimiter)})
|
||||
log.Warn(log.ExchangeSys, "Available pairs for Kraken reset due to config upgrade, please enable the ones you would like again")
|
||||
forceUpdate = true
|
||||
|
||||
@@ -242,13 +242,14 @@ func (k *Kraken) UpdateTicker(p currency.Pair, assetType asset.Item) (ticker.Pri
|
||||
|
||||
for i := range pairs {
|
||||
for curr, v := range tickers {
|
||||
if !strings.EqualFold(pairs[i].String(), curr) {
|
||||
pairFmt := k.FormatExchangeCurrency(pairs[i], assetType).String()
|
||||
if !strings.EqualFold(pairFmt, curr) {
|
||||
var altCurrency string
|
||||
var ok bool
|
||||
if altCurrency, ok = assetPairMap[curr]; !ok {
|
||||
continue
|
||||
}
|
||||
if !strings.EqualFold(pairs[i].String(), altCurrency) {
|
||||
if !strings.EqualFold(pairFmt, altCurrency) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
@@ -491,8 +491,9 @@ func TestWsTradeProcessing(t *testing.T) {
|
||||
func TestWsTickerProcessing(t *testing.T) {
|
||||
TestSetDefaults(t)
|
||||
TestSetup(t)
|
||||
l.Websocket.DataHandler = sharedtestvalues.GetWebsocketInterfaceChannelOverride()
|
||||
l.Websocket.TrafficAlert = sharedtestvalues.GetWebsocketStructChannelOverride()
|
||||
const testChanSize = 26
|
||||
l.Websocket.DataHandler = make(chan interface{}, testChanSize)
|
||||
l.Websocket.TrafficAlert = make(chan struct{}, testChanSize)
|
||||
json := `{"btcusd":{"low":"10990.05","high":"11966.24","last":"11903.29","volume":"1803.967079","sell":"11912.39","buy":"11902.2"},"btceur":{"low":"9886.87","high":"10732.72","last":"10691.44","volume":"87.994478","sell":"10711.62","buy":"10691.44"},"btchkd":{"low":null,"high":null,"last":"51776.98","volume":null,"sell":"93307.37","buy":"93177.56"},"btcjpy":{"low":"1176039.0","high":"1272246.0","last":"1265680.0","volume":"129.021421","sell":"1266764.0","buy":"1265680.0"},"btcgbp":{"low":"9157.12","high":"9953.43","last":"9941.28","volume":"10.4997","sell":"10007.89","buy":"9941.28"},"btcaud":{"low":"16102.57","high":"17594.22","last":"17548.16","volume":"7.338316","sell":"17616.67","buy":"17549.69"},"btccad":{"low":"14541.69","high":"15834.87","last":"15763.54","volume":"30.480309","sell":"15793.45","buy":"15756.13"},"btcsgd":{"low":"15133.82","high":"16501.62","last":"16455.53","volume":"4.044026","sell":"16484.37","buy":"16462.18"},"btcchf":{"low":"10800.58","high":"11526.24","last":"11526.24","volume":"0.1765","sell":"11675.34","buy":"11632.02"},"btcnzd":{"low":null,"high":null,"last":"8340.98","volume":null,"sell":"18315.49","buy":"18221.37"},"btcngn":{"low":null,"high":null,"last":"600000.0","volume":null,"sell":null,"buy":null},"eurusd":{"low":"1.1088","high":"1.1138","last":"1.1125","volume":"2680.105249","sell":"1.1142","buy":"1.1121"},"gbpusd":{"low":"1.1934","high":"1.1958","last":"1.1934","volume":"1493.923823","sell":"1.1979","buy":"1.1903"},"usdjpy":{"low":"105.26","high":"107.25","last":"106.33","volume":"114490.2179","sell":"106.34","buy":"106.27"},"usdhkd":{"low":null,"high":null,"last":"7.851","volume":null,"sell":"7.8328","buy":"7.8286"},"usdcad":{"low":"1.3225","high":"1.3272","last":"1.3255","volume":"11033.9877","sell":"1.3258","buy":"1.3238"},"usdsgd":{"low":"1.3776","high":"1.3839","last":"1.3838","volume":"2523.75","sell":"1.3838","buy":"1.3819"},"audusd":{"low":"0.6764","high":"0.6853","last":"0.6771","volume":"5442.608321","sell":"0.6782","buy":"0.6762"},"nzdusd":{"low":null,"high":null,"last":"0.6758","volume":null,"sell":"0.6532","buy":"0.6504"},"usdchf":{"low":"0.9838","high":"0.9838","last":"0.9838","volume":"108.3352","sell":"0.9801","buy":"0.9773"},"usdngn":{"low":null,"high":null,"last":"200.0","volume":null,"sell":null,"buy":null},"ethbtc":{"low":"0.0205","high":"0.025","last":"0.0205","volume":null,"sell":"0.03","buy":"0.0194"},"ltcbtc":{"low":null,"high":null,"last":"0.0114","volume":null,"sell":"0.009","buy":"0.0073"},"bchbtc":{"low":null,"high":null,"last":"0.0544","volume":null,"sell":"0.0322","buy":"0.0274"},"xrpbtc":{"low":"0.000042","high":"0.000042","last":"0.000042","volume":null,"sell":"0.000037","buy":"0.000022"},"baceth":{"low":"0.000035","high":"0.000035","last":"0.000035","volume":null,"sell":"0.0015","buy":null}}`
|
||||
err := l.processTicker(json)
|
||||
if err != nil {
|
||||
|
||||
@@ -21,9 +21,12 @@ const (
|
||||
marketGlobalEndpoint = "market-global"
|
||||
marketSubstring = "market-"
|
||||
globalSubstring = "-global"
|
||||
volumeString = "volume"
|
||||
highString = "high"
|
||||
lowString = "low"
|
||||
tickerBuyString = "buy"
|
||||
tickerHighString = "high"
|
||||
tickerLastString = "last"
|
||||
tickerLowString = "low"
|
||||
tickerSellString = "sell"
|
||||
tickerVolumeString = "volume"
|
||||
wssSchem = "wss"
|
||||
)
|
||||
|
||||
@@ -220,29 +223,28 @@ func (l *LakeBTC) processTicker(ticker string) error {
|
||||
}
|
||||
for k, v := range tUpdate {
|
||||
tickerData := v.(map[string]interface{})
|
||||
if tickerData[highString] == nil || tickerData[lowString] == nil || tickerData[volumeString] == nil {
|
||||
continue
|
||||
}
|
||||
high, err := strconv.ParseFloat(tickerData[highString].(string), 64)
|
||||
if err != nil {
|
||||
l.Websocket.DataHandler <- fmt.Errorf("%v error parsing ticker data 'high' %v", l.Name, tickerData)
|
||||
continue
|
||||
}
|
||||
low, err := strconv.ParseFloat(tickerData[lowString].(string), 64)
|
||||
if err != nil {
|
||||
l.Websocket.DataHandler <- fmt.Errorf("%v error parsing ticker data 'low' %v", l.Name, tickerData)
|
||||
continue
|
||||
}
|
||||
vol, err := strconv.ParseFloat(tickerData[volumeString].(string), 64)
|
||||
if err != nil {
|
||||
l.Websocket.DataHandler <- fmt.Errorf("%v error parsing ticker data 'volume' %v", l.Name, tickerData)
|
||||
continue
|
||||
processTickerItem := func(tick map[string]interface{}, item string) float64 {
|
||||
if tick[item] == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
p, err := strconv.ParseFloat(tick[item].(string), 64)
|
||||
if err != nil {
|
||||
l.Websocket.DataHandler <- fmt.Errorf("%s error parsing ticker data '%s' %v", l.Name, item, tickerData)
|
||||
return 0
|
||||
}
|
||||
|
||||
return p
|
||||
}
|
||||
|
||||
l.Websocket.DataHandler <- wshandler.TickerData{
|
||||
Exchange: l.Name,
|
||||
Volume: vol,
|
||||
High: high,
|
||||
Low: low,
|
||||
Bid: processTickerItem(tickerData, tickerBuyString),
|
||||
High: processTickerItem(tickerData, tickerHighString),
|
||||
Last: processTickerItem(tickerData, tickerLastString),
|
||||
Low: processTickerItem(tickerData, tickerLowString),
|
||||
Ask: processTickerItem(tickerData, tickerSellString),
|
||||
Volume: processTickerItem(tickerData, tickerVolumeString),
|
||||
AssetType: asset.Spot,
|
||||
Pair: currency.NewPairFromString(k),
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -188,9 +187,8 @@ func (z *ZB) FetchTradablePairs(asset asset.Item) ([]string, error) {
|
||||
func (z *ZB) UpdateTradablePairs(forceUpdate bool) error {
|
||||
pairs, err := z.FetchTradablePairs(asset.Spot)
|
||||
if err != nil {
|
||||
return nil
|
||||
return err
|
||||
}
|
||||
|
||||
return z.UpdatePairs(currency.NewPairsFromStrings(pairs), asset.Spot, false, forceUpdate)
|
||||
}
|
||||
|
||||
@@ -204,8 +202,9 @@ func (z *ZB) UpdateTicker(p currency.Pair, assetType asset.Item) (ticker.Price,
|
||||
}
|
||||
|
||||
for _, x := range z.GetEnabledPairs(assetType) {
|
||||
currencySplit := strings.Split(z.FormatExchangeCurrency(x, assetType).String(), z.GetPairFormat(assetType, false).Delimiter)
|
||||
curr := currencySplit[0] + currencySplit[1]
|
||||
// We can't use either pair format here, so format it to lower-
|
||||
// case and without any delimiter
|
||||
curr := x.Format("", false).String()
|
||||
if _, ok := result[curr]; !ok {
|
||||
continue
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user