Initial commit
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
package exchange
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"time"
|
||||
)
|
||||
|
||||
// BitgetWS connects to Bitget WebSocket for ticker channel.
|
||||
type BitgetWS struct {
|
||||
Conn *PriceConnector
|
||||
Tracked []string // Bitget symbols like BTCUSDT
|
||||
}
|
||||
|
||||
type bitgetSubscribeMsg struct {
|
||||
Op string `json:"op"`
|
||||
Args []bitgetChannel `json:"args"`
|
||||
}
|
||||
|
||||
type bitgetChannel struct {
|
||||
InstType string `json:"instType"`
|
||||
Channel string `json:"channel"`
|
||||
InstID string `json:"instId"`
|
||||
}
|
||||
|
||||
type bitgetTickerMsg struct {
|
||||
Action string `json:"action"`
|
||||
Arg bitgetChannel `json:"arg"`
|
||||
Data []bitgetTickerData `json:"data"`
|
||||
}
|
||||
|
||||
type bitgetTickerData struct {
|
||||
LastPr string `json:"lastPr"`
|
||||
BidPr string `json:"bidPr"`
|
||||
AskPr string `json:"askPr"`
|
||||
}
|
||||
|
||||
func NewBitgetWS(tracked []string) *BitgetWS {
|
||||
return &BitgetWS{
|
||||
Tracked: tracked,
|
||||
}
|
||||
}
|
||||
|
||||
// Run connects to Bitget WS and streams ticker data.
|
||||
func (b *BitgetWS) Run(updateFn func(coin string, price, bid, ask float64)) error {
|
||||
url := "wss://ws.bitget.com/v2/ws/public"
|
||||
|
||||
b.Conn = NewPriceConnector(url, "Bitget", 120*time.Second, 30*time.Second)
|
||||
b.Conn.PingInterval = 25 * time.Second // Bitget requires ping within 30s
|
||||
|
||||
b.Conn.OnConnect = func() {
|
||||
log.Printf("[Bitget WS] Connected, subscribing")
|
||||
|
||||
args := make([]map[string]string, 0, len(b.Tracked))
|
||||
for _, sym := range b.Tracked {
|
||||
args = append(args, map[string]string{
|
||||
"instType": "USDT-FUTURES",
|
||||
"channel": "ticker",
|
||||
"instId": sym,
|
||||
})
|
||||
}
|
||||
sub := map[string]interface{}{
|
||||
"op": "subscribe",
|
||||
"args": args,
|
||||
}
|
||||
if err := b.Conn.SendJSON(sub); err != nil {
|
||||
log.Printf("[Bitget WS] Subscribe error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
b.Conn.OnMessage = func(msg []byte) {
|
||||
var ticker bitgetTickerMsg
|
||||
if err := json.Unmarshal(msg, &ticker); err != nil {
|
||||
return
|
||||
}
|
||||
if len(ticker.Data) == 0 || ticker.Data[0].LastPr == "" {
|
||||
return
|
||||
}
|
||||
|
||||
// Convert BTCUSDT -> BTC
|
||||
coin := symbolToCoin(ticker.Arg.InstID, "USDT")
|
||||
if coin == "" {
|
||||
return
|
||||
}
|
||||
|
||||
price := parseFloat(ticker.Data[0].LastPr)
|
||||
if price > 0 {
|
||||
bid := parseFloat(ticker.Data[0].BidPr)
|
||||
ask := parseFloat(ticker.Data[0].AskPr)
|
||||
updateFn(coin, price, bid, ask)
|
||||
}
|
||||
}
|
||||
|
||||
return b.Conn.Run()
|
||||
}
|
||||
Reference in New Issue
Block a user