package okx import ( "encoding/json" "fmt" "github.com/google/go-querystring/query" // 用于将 struct 转为 URL 参数,需要安装:go get github.com/google/go-querystring "net/http" "net/url" ) type OkxPublicDataService struct { BaseURL string } // NewOkxPublicDataService 创建服务实例 func NewOkxPublicDataService() *OkxPublicDataService { return &OkxPublicDataService{ BaseURL: "https://www.okx.com/api/v5", } } // GetInstruments 获取交易对信息 func (s *OkxPublicDataService) GetInstruments(params InstrumentsRequest) ([]Instrument, error) { u, err := url.Parse(s.BaseURL + "/public/instruments") if err != nil { return nil, err } // 将 struct 转为查询参数 q, err := query.Values(params) if err != nil { return nil, err } u.RawQuery = q.Encode() resp, err := http.Get(u.String()) if err != nil { return nil, err } defer resp.Body.Close() var apiResp ApiResponse apiResp.Data = new([]Instrument) // 预分配 Data 字段为 Instrument 切片 if err := json.NewDecoder(resp.Body).Decode(&apiResp); err != nil { return nil, err } if apiResp.Code != "0" { return nil, fmt.Errorf("API error: %s", apiResp.Msg) } return *apiResp.Data.(*[]Instrument), nil } // GetCandles 获取K线数据 func (s *OkxPublicDataService) GetCandles(params CandlesRequest) ([]Candle, error) { u, err := url.Parse(s.BaseURL + "/market/candles") if err != nil { return nil, err } // 将 struct 转为查询参数 q, err := query.Values(params) if err != nil { return nil, err } u.RawQuery = q.Encode() resp, err := http.Get(u.String()) if err != nil { return nil, err } defer resp.Body.Close() var apiResp struct { Code string `json:"code"` Msg string `json:"msg"` Data [][]string `json:"data"` // K线数据是二维数组 } if err := json.NewDecoder(resp.Body).Decode(&apiResp); err != nil { return nil, err } if apiResp.Code != "0" { return nil, fmt.Errorf("API error: %s", apiResp.Msg) } // 将二维数组转为 Candle 切片 candles := make([]Candle, len(apiResp.Data)) for i, item := range apiResp.Data { candles[i] = Candle{ Timestamp: item[0], Open: item[1], High: item[2], Low: item[3], Close: item[4], Volume: item[5], VolumeCcy: item[6], } } return candles, nil } // GetTicker 获取单个交易对的 ticker 数据 func (s *OkxPublicDataService) GetTicker(params TickerRequest) (*Ticker, error) { u, err := url.Parse(s.BaseURL + "/market/ticker") if err != nil { return nil, err } // 将 struct 转为查询参数 q, err := query.Values(params) if err != nil { return nil, err } u.RawQuery = q.Encode() resp, err := http.Get(u.String()) if err != nil { return nil, err } defer resp.Body.Close() var apiResp struct { Code string `json:"code"` Msg string `json:"msg"` Data []Ticker `json:"data"` // 返回的是数组 } if err := json.NewDecoder(resp.Body).Decode(&apiResp); err != nil { return nil, err } if apiResp.Code != "0" { return nil, fmt.Errorf("API error: %s", apiResp.Msg) } if len(apiResp.Data) == 0 { return nil, fmt.Errorf("no ticker data returned") } // 返回第一个 ticker(通常只返回一个) return &apiResp.Data[0], nil }