跳到主要内容
版本:Next (V2.0)

签名代码示例

package main

import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"fmt"
"net/http"
"net/url"
"sort"
"strconv"
"strings"
"time"
)

const (
APIKey = "your_api_key"
SecretKey = "your_secret_key"
BaseURL = "https://test.test9527.xyz/api/v1/stock/open-api"
)

// sign 生成签名
func sign(method, requestPath, queryString, body string, timestamp int64) string {
// 拼接签名字符串:timestamp + method + requestPath + queryString + body
timestampStr := strconv.FormatInt(timestamp, 10)
preHash := timestampStr + method + requestPath + queryString + body

// HMAC-SHA256 签名
mac := hmac.New(sha256.New, []byte(SecretKey))
mac.Write([]byte(preHash))

// Base64 编码
return base64.StdEncoding.EncodeToString(mac.Sum(nil))
}

// request 发送 POST 请求
func request(endpoint string, params map[string]interface{}) (map[string]interface{}, error) {
timestamp := time.Now().UnixMilli()
requestPath := "/api/v1/stock/open-api" + endpoint

body, _ := json.Marshal(params)
signature := sign("POST", requestPath, "", string(body), timestamp)

req, _ := http.NewRequest("POST", BaseURL+endpoint, bytes.NewBuffer(body))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("ACCESS-KEY", APIKey)
req.Header.Set("ACCESS-SIGN", signature)
req.Header.Set("ACCESS-TIMESTAMP", strconv.FormatInt(timestamp, 10))

client := &http.Client{Timeout: 30 * time.Second}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
return result, nil
}

// requestGET 发送 GET 请求
func requestGET(endpoint string, params map[string]interface{}) (map[string]interface{}, error) {
timestamp := time.Now().UnixMilli()
requestPath := "/api/v1/stock/open-api" + endpoint

// 构造 query string
keys := make([]string, 0, len(params))
for k := range params {
keys = append(keys, k)
}
sort.Strings(keys)

queryParts := make([]string, 0, len(keys))
for _, k := range keys {
queryParts = append(queryParts, fmt.Sprintf("%s=%v", k, url.QueryEscape(fmt.Sprintf("%v", params[k]))))
}
queryString := "?" + strings.Join(queryParts, "&")

signature := sign("GET", requestPath, queryString, "", timestamp)

req, _ := http.NewRequest("GET", BaseURL+endpoint+queryString, nil)
req.Header.Set("ACCESS-KEY", APIKey)
req.Header.Set("ACCESS-SIGN", signature)
req.Header.Set("ACCESS-TIMESTAMP", strconv.FormatInt(timestamp, 10))

client := &http.Client{Timeout: 30 * time.Second}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()

var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
return result, nil
}

func main() {
// 下单示例
result, _ := request("/order", map[string]interface{}{
"symbol": "AAPL",
"side": "buy",
"type": "limit",
"price": "185.50",
"quantity": "1000",
"clientOid": "test-001",
})
fmt.Printf("%+v\n", result)

// 查询深度示例
depth, _ := requestGET("/depth", map[string]interface{}{
"symbol": "XSM",
"limit": 20,
})
fmt.Printf("%+v\n", depth)
}