QOS行情数据API(Quote Ocean System)的Go客户端库。提供HTTP和WebSocket接口访问股票和加密货币的实时行情数据。
- 官网:https://qos.hk
- API文档:https://qos.hk/api.html
- 注册API KEY:https://qos.hk
- 完整实现所有QOS API接口
- 同时支持HTTP和WebSocket协议
- 类型安全的数据结构
- WebSocket自动重连
- 内置心跳机制
- 完善的错误处理
go get github.com/qos-max/qos-quote-api-go-sdk/qosapi # 或者 go mod tidypackage main import ( "fmt" "github.com/qos-max/qos-quote-api-go-sdk/qosapi" "log" "time" ) //官网:https://qos.hk //API文档:https://qos.hk/api.html //注册API KEY:https://qos.hk func main() { // 替换为你的API Key apiKey := "your-api-key" client := qosapi.NewClient(apiKey) // 示例1: 获取基础信息 codes := []string{ "US:AAPL,TSLA", "HK:00700,09988", "SH:600519,600518", "SZ:000001,002594", } info, err := client.GetInstrumentInfo(codes) if err != nil { log.Fatalf("Failed to get instrument info: %v", err) } fmt.Println("Instrument Info:") for _, item := range info { fmt.Printf("%s: %s (%s)\n", item.Code, item.NameCN, item.NameEN) } // 示例2: 获取行情快照 snapshots, err := client.GetSnapshot(codes) if err != nil { log.Fatalf("Failed to get snapshots: %v", err) } fmt.Println("\nSnapshots:") for _, s := range snapshots { fmt.Printf("%s: %s (High: %s, Low: %s)\n", s.Code, s.LastPrice, s.High, s.Low) } // 示例3: 获取盘口深度 depths, err := client.GetDepth(codes) if err != nil { log.Fatalf("Failed to get depths: %v", err) } fmt.Println("\nDepths:") for _, d := range depths { fmt.Printf("%s: Bids %d, Asks %d\n", d.Code, len(d.Bids), len(d.Asks)) } // 示例4: 获取逐笔成交 trades, err := client.GetTrade(codes, 5) if err != nil { log.Fatalf("Failed to get trades: %v", err) } fmt.Println("\nTrades:") for _, t := range trades { fmt.Printf("%s: Price %s, Volume %s, Direction %d\n", t.Code, t.Price, t.Volume, t.Direction) } // 示例5: 获取K线 klineReqs := []qosapi.KLineRequest{ { Codes: "US:AAPL,TSLA", Count: 2, Adjust: 0, KLineType: qosapi.KLineTypeDay, }, { Codes: "CF:BTCUSDT,ETHUSDT", Count: 2, Adjust: 0, KLineType: qosapi.KLineTypeDay, }, } klineData, err := client.GetKLine(klineReqs) if err != nil { log.Fatalf("Failed to get KLine: %v", err) } fmt.Println("\nKLine:") for _, klines := range klineData { for _, k := range klines { fmt.Printf("%s: O:%s C:%s H:%s L:%s V:%s\n", k.Code, k.Open, k.Close, k.High, k.Low, k.Volume) } } // 示例6: 获取历史K线 historyReqs := []qosapi.KLineRequest{ { Codes: "US:AAPL", Count: 2, Adjust: 0, KLineType: qosapi.KLineTypeDay, EndTime: time.Now().Unix(), }, } historyData, err := client.GetHistoryKLine(historyReqs) if err != nil { log.Fatalf("Failed to get history KLine: %v", err) } fmt.Println("\nHistory KLine:") for _, klines := range historyData { for _, k := range klines { fmt.Printf("%s: O:%s C:%s H:%s L:%s V:%s\n", k.Code, k.Open, k.Close, k.High, k.Low, k.Volume) } } }package main import ( "fmt" "log" "time" "github.com/qos-max/qos-quote-api-go-sdk/qosapi" ) // 官网:https://qos.hk // API文档:https://qos.hk/api.html // 注册API KEY:https://qos.hk func main() { // 替换为你的API Key apiKey := "your-api-key" client := qosapi.NewWSClient(apiKey) // 连接到WebSocket服务器 if err := client.Connect(); err != nil { log.Fatalf("Failed to connect: %v", err) } defer client.Close() // 启动心跳 client.StartHeartbeat(20 * time.Second) // 示例1: 订阅实时快照 codes := []string{"US:AAPL,TSLA", "HK:700"} err := client.SubscribeSnapshot(codes, func(s qosapi.WSSnapshot) { fmt.Printf("Snapshot - %s: %s (Time: %v)\n", s.Code, s.LastPrice, time.Unix(s.Timestamp, 0)) }) if err != nil { log.Printf("Failed to subscribe snapshot: %v", err) } // 示例2: 订阅实时逐笔成交 err = client.SubscribeTrade(codes, func(t qosapi.WSTrade) { fmt.Printf("Trade - %s: %s %s (Dir: %d, Time: %v)\n", t.Code, t.Price, t.Volume, t.Direction, time.Unix(t.Timestamp, 0)) }) if err != nil { log.Printf("Failed to subscribe trade: %v", err) } // 示例3: 订阅实时盘口 err = client.SubscribeDepth(codes, func(d qosapi.WSDepth) { fmt.Printf("Depth - %s: Bids %d, Asks %d (Time: %v)\n", d.Code, len(d.Bids), len(d.Asks), time.Unix(d.Timestamp, 0)) }) if err != nil { log.Printf("Failed to subscribe depth: %v", err) } // 示例4: 订阅实时K线 err = client.SubscribeKLine([]string{"CF:BTCUSDT"}, qosapi.KLineTypeDay, func(k qosapi.WSKLine) { fmt.Printf("KLine - %s: O:%s C:%s H:%s L:%s V:%s\n", k.Code, k.Open, k.Close, k.High, k.Low, k.Volume) }) if err != nil { log.Printf("Failed to subscribe KLine: %v", err) } // 示例5: 请求实时快照 go func() { time.Sleep(5 * time.Second) snapshots, err := client.RequestSnapshot(codes) if err != nil { log.Printf("Failed to request snapshots: %v", err) return } fmt.Println("\nRequested Snapshots:") for _, s := range snapshots { fmt.Printf("%s: %s (High: %s, Low: %s)\n", s.Code, s.LastPrice, s.High, s.Low) } }() // 示例6: 请求实时逐笔成交 go func() { time.Sleep(6 * time.Second) trades, err := client.RequestTrade(codes, 5) if err != nil { log.Printf("Failed to request trades: %v", err) return } fmt.Println("\nRequested Trades:") for _, t := range trades { fmt.Printf("%s: Price %s, Volume %s, Direction %d\n", t.Code, t.Price, t.Volume, t.Direction) } }() // 示例7: 请求实时盘口 go func() { time.Sleep(7 * time.Second) depths, err := client.RequestDepth(codes) if err != nil { log.Printf("Failed to request depths: %v", err) return } fmt.Println("\nRequested Depths:") for _, d := range depths { fmt.Printf("%s: Bids %d, Asks %d\n", d.Code, len(d.Bids), len(d.Asks)) } }() // 示例8: 请求实时K线 go func() { time.Sleep(8 * time.Second) klineReqs := []qosapi.KLineRequest{ { Codes: "US:AAPL,TSLA", Count: 2, Adjust: 0, KLineType: qosapi.KLineTypeDay, }, } klineData, err := client.RequestKLine(klineReqs) if err != nil { log.Printf("Failed to request KLine: %v", err) return } fmt.Println("\nRequested KLine:") for _, klines := range klineData { for _, k := range klines { fmt.Printf("%s: O:%s C:%s H:%s L:%s V:%s\n", k.Code, k.Open, k.Close, k.High, k.Low, k.Volume) } } }() // 示例9: 请求历史K线 go func() { time.Sleep(9 * time.Second) historyReqs := []qosapi.KLineRequest{ { Codes: "US:AAPL", Count: 2, Adjust: 0, KLineType: qosapi.KLineTypeDay, EndTime: time.Now().Unix(), }, } historyData, err := client.RequestHistoryKLine(historyReqs) if err != nil { log.Printf("Failed to request history KLine: %v", err) return } fmt.Println("\nRequested History KLine:") for _, klines := range historyData { for _, k := range klines { fmt.Printf("%s: O:%s C:%s H:%s L:%s V:%s\n", k.Code, k.Open, k.Close, k.High, k.Low, k.Volume) } } }() // 示例10: 请求基础信息 go func() { time.Sleep(10 * time.Second) info, err := client.RequestInstrumentInfo(codes) if err != nil { log.Printf("Failed to request instrument info: %v", err) return } fmt.Println("\nRequested Instrument Info:") for _, item := range info { fmt.Printf("%s: %s (%s)\n", item.Code, item.NameCN, item.NameEN) } }() // 保持连接运行 select {} }NewClient(apiKey string) *QOSClient- 创建HTTP客户端GetInstrumentInfo(codes []string) ([]InstrumentInfo, error)- 获取品种基础信息GetSnapshot(codes []string) ([]Snapshot, error)- 获取实时行情快照GetDepth(codes []string) ([]Depth, error)- 获取盘口深度数据GetTrade(codes []string, count int) ([]Trade, error)- 获取逐笔成交数据GetKLine(requests []KLineRequest) ([][]KLine, error)- 获取K线数据GetHistoryKLine(requests []KLineRequest) ([][]KLine, error)- 获取历史K线数据
NewWSClient(apiKey string) *WSClient- 创建WebSocket客户端Connect() error- 连接服务器Close() error- 关闭连接SubscribeSnapshot(codes []string, callback func(WSSnapshot)) error- 订阅行情快照SubscribeTrade(codes []string, callback func(WSTrade)) error- 订阅逐笔成交SubscribeDepth(codes []string, callback func(WSDepth)) error- 订阅盘口深度SubscribeKLine(codes []string, klineType int, callback func(WSKLine)) error- 订阅K线数据SendHeartbeat() error- 发送心跳StartHeartbeat(interval time.Duration)- 启动定时心跳
本项目采用MIT许可证 - 详情见LICENSE文件 License: MIT