Initial commit
This commit is contained in:
commit
c5111cb551
20 changed files with 1764 additions and 0 deletions
138
clients/kraken.go
Normal file
138
clients/kraken.go
Normal file
|
@ -0,0 +1,138 @@
|
|||
package clients
|
||||
|
||||
import (
|
||||
"btclock/broker"
|
||||
"btclock/models"
|
||||
"btclock/modules"
|
||||
"context"
|
||||
"log"
|
||||
|
||||
"github.com/coder/websocket"
|
||||
"github.com/coder/websocket/wsjson"
|
||||
)
|
||||
|
||||
type KrakenClient struct {
|
||||
ws *websocket.Conn
|
||||
eventTypes []string
|
||||
broker *broker.EventBroker
|
||||
}
|
||||
|
||||
type KrakenTickerEvent struct {
|
||||
Symbol string
|
||||
Last float64
|
||||
}
|
||||
|
||||
// Name implements broker.Event.
|
||||
func (k KrakenTickerEvent) Name() string {
|
||||
return "ticker"
|
||||
}
|
||||
|
||||
// Payload implements broker.Event.
|
||||
func (k KrakenTickerEvent) Payload() interface{} {
|
||||
return map[string]interface{}{
|
||||
"symbol": k.Symbol,
|
||||
"last": k.Last,
|
||||
}
|
||||
}
|
||||
|
||||
func init() {
|
||||
modules.Registry.Register(NewKrakenClient())
|
||||
}
|
||||
|
||||
func NewKrakenClient() *KrakenClient {
|
||||
return &KrakenClient{
|
||||
eventTypes: []string{"ticker"},
|
||||
}
|
||||
}
|
||||
|
||||
func (k *KrakenClient) Init(broker *broker.EventBroker) error {
|
||||
k.broker = broker
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k *KrakenClient) Start(ctx context.Context) error {
|
||||
ws, _, err := websocket.Dial(ctx, "wss://ws.kraken.com/v2", nil)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer ws.CloseNow()
|
||||
|
||||
err = wsjson.Write(ctx, ws, map[string]interface{}{
|
||||
"method": "subscribe",
|
||||
"params": map[string]interface{}{
|
||||
"channel": "ticker",
|
||||
"symbol": []string{"BTC/USD", "BTC/EUR", "BTC/GBP", "BTC/JPY", "BTC/CHF", "BTC/CAD", "BTC/AUD"},
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Expect subscription confirmation
|
||||
var v map[string]interface{}
|
||||
err = wsjson.Read(ctx, ws, &v)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Read messages until the connection is closed
|
||||
for {
|
||||
var v map[string]any
|
||||
err = wsjson.Read(ctx, ws, &v)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
channel, ok := v["channel"].(string)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if channel == "ticker" {
|
||||
tickerData := handleTickerMessage(v)
|
||||
tickerEvent := KrakenTickerEvent{
|
||||
Symbol: tickerData.Symbol,
|
||||
Last: tickerData.Last,
|
||||
}
|
||||
k.broker.Publish("ticker", tickerEvent)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (k *KrakenClient) Stop() error {
|
||||
k.ws.Close(websocket.StatusNormalClosure, "")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (k *KrakenClient) ID() string {
|
||||
return "kraken"
|
||||
}
|
||||
|
||||
func handleTickerMessage(v map[string]any) models.Ticker {
|
||||
data, ok := v["data"].([]interface{})
|
||||
if !ok {
|
||||
return models.Ticker{}
|
||||
}
|
||||
|
||||
for _, item := range data {
|
||||
if ticker, ok := item.(map[string]interface{}); ok {
|
||||
symbol, symbolOk := ticker["symbol"].(string)
|
||||
last, lastOk := ticker["last"].(float64)
|
||||
bid, bidOk := ticker["bid"].(float64)
|
||||
ask, askOk := ticker["ask"].(float64)
|
||||
|
||||
if symbolOk && lastOk && bidOk && askOk {
|
||||
ticker := models.Ticker{
|
||||
Symbol: symbol,
|
||||
Last: last,
|
||||
Bid: bid,
|
||||
Ask: ask,
|
||||
}
|
||||
// fmt.Printf("%+v\n", ticker)
|
||||
return ticker
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return models.Ticker{}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue