StockTV提供了覆盖股票、外汇、期货和加密货币的全球化金融数据接口。本文将详细介绍如何用Go语言对接这些API,包含HTTP请求构建、WebSocket实时订阅、数据解析等核心环节,并提供可直接复用的生产级代码示例。
go get github.com/gorilla/websocket # WebSocket支持
const (
BaseURL = "https://api.stocktv.top"
APIKey = "YOUR_API_KEY" // 替换为实际Key
WSEndpoint = "wss://ws-api.stocktv.top/connect"
)
type StockResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Data struct {
Records []struct {
ID int `json:"id"`
Symbol string `json:"symbol"`
Last float64 `json:"last"`
ChgPct float64 `json:"chgPct"`
} `json:"records"`
} `json:"data"`
}
func GetStockList(countryID int) (*StockResponse, error) {
url := fmt.Sprintf("%s/stock/stocks?countryId=%d&pageSize=10&key=%s",
BaseURL, countryID, APIKey)
resp, err := http.Get(url)
if err != nil {
return nil, fmt.Errorf("请求失败: %v", err)
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
return nil, fmt.Errorf("API返回异常状态码: %d", resp.StatusCode)
}
var result StockResponse
if err := json.NewDecoder(resp.Body).Decode(&result); err != nil {
return nil, fmt.Errorf("JSON解析失败: %v", err)
}
return &result, nil
}
type KlineData struct {
Time int64 `json:"time"`
Open float64 `json:"open"`
High float64 `json:"high"`
Low float64 `json:"low"`
Close float64 `json:"close"`
}
func GetKLine(pid int, interval string) ([]KlineData, error) {
url := fmt.Sprintf("%s/stock/kline?pid=%d&interval=%s&key=%s",
BaseURL, pid, interval, APIKey)
resp, err := http.Get(url)
// 错误处理同上...
var data struct {
Data []KlineData `json:"data"`
}
if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
return nil, err
}
return data.Data, nil
}
var wsConn *websocket.Conn
func ConnectWS() error {
dialer := websocket.DefaultDialer
headers := http.Header{}
headers.Add("key", APIKey)
conn, _, err := dialer.Dial(WSEndpoint, headers)
if err != nil {
return fmt.Errorf("WebSocket连接失败: %v", err)
}
wsConn = conn
go heartbeat() // 启动心跳协程
return nil
}
func heartbeat() {
ticker := time.NewTicker(30 * time.Second)
defer ticker.Stop()
for {
<-ticker.C
if err := wsConn.WriteMessage(websocket.PingMessage, nil); err != nil {
log.Printf("心跳发送失败: %v", err)
return
}
}
}
type WSMessage struct {
PID string `json:"pid"`
Last float64 `json:"last_numeric"`
Bid float64 `json:"bid"`
Ask float64 `json:"ask"`
}
func ListenRealtime() {
for {
_, msg, err := wsConn.ReadMessage()
if err != nil {
log.Printf("消息读取错误: %v", err)
continue
}
var data WSMessage
if err := json.Unmarshal(msg, &data); err != nil {
log.Printf("JSON解析失败: %v", err)
continue
}
fmt.Printf("实时行情更新 PID:%s 最新价:%.2f 买盘:%.2f 卖盘:%.2f\n",
data.PID, data.Last, data.Bid, data.Ask)
}
}
func GetWithRetry(url string, retries int) (*http.Response, error) {
for i := 0; i < retries; i++ {
resp, err := http.Get(url)
if err == nil && resp.StatusCode == 200 {
return resp, nil
}
time.Sleep(time.Duration(i+1) * time.Second) // 指数退避
}
return nil, fmt.Errorf("超过最大重试次数")
}
var limiter = rate.NewLimiter(rate.Every(1*time.Second), 10) // 10 QPS
func RateLimitedGet(url string) (*http.Response, error) {
if err := limiter.Wait(context.Background()); err != nil {
return nil, err
}
return http.Get(url)
}
decimal.Decimal
库代替floatclient := &http.Client{
Transport: &http.Transport{
MaxIdleConns: 100,
IdleConnTimeout: 90 * time.Second,
},
Timeout: 10 * time.Second,
}
本文实现了从基础数据获取到实时流式处理的完整链路,示例代码可直接集成到量化交易系统、行情展示看板等场景。建议进一步: