go語言http呼叫Tushare財經資料包
阿新 • • 發佈:2020-12-12
go語言http呼叫Tushare財經資料包
Tushare平臺介紹
- Tushare平臺網址 https://tushare.pro/document/1,網址上就有下載安裝以及資料獲取的方式。Tushare Pro提供了包括股票、指數、基金、期貨、數字貨幣在內的各類資產交易行情的分鐘資料。
- 免費獲取,資料準確,適合量化投資分析師(Quant),對金融市場進行大資料分析的企業和個人,開發以證券為基礎的金融類產品和解決方案的公司,正在學習利用python進行資料分析的人使用。
- 有以下幾種獲取方式,今天介紹的是通過http來獲取資料。
4. 為了避免部分使用者低門檻無限制的惡意調取資料,更好地保證大多數使用者調取資料的穩定性,同時也為了Tushare社群的可持續發展,Pro介面開始引入積分制度。只有具備一定積分級別的使用者才能調取相應的API,目前只是一個分級門檻,並不消耗積分。以下只是基礎積分許可權,積分越多頻次越高,除分鐘資料外5000以上正常調取資料無頻次限制。 https://waditu.com/document/1?doc_id=108
使用go + http方式呼叫Tushare資料
// 具體http網站檢視https://tushare.pro/document/1?doc_id=130 const endpoint string = "http://api.waditu.com" const timeLayout string = "20060102" type KLine struct { TsCode string `json:"ts_code" structs:"1"` TradeDate int64 `json:"trade_date" structs:"2"` Close float64 `json:"close" structs:"3"` Open float64 `json:"open" structs:"4"` High float64 `json:"high" structs:"5"` Low float64 `json:"low" structs:"6"` PreClose float64 `json:"pre_close" structs:"7"` LowLimit float64 `json:"low_limit" structs:"8"` HighLimit float64 `json:"high_limit" structs:"9"` Volume float64 `json:"volume" structs:"10"` Amount float64 `json:"amount" structs:"11"` Factor float64 `json:"factor" structs:"12"` } type Response struct { Code int `json:"code"` Msg string `json:"msg"` Data ResponseData `json:"data"` } // ResponseData stands for the field "data" in the body. type ResponseData struct { Fields []string `json:"fields"` Items [][]interface{} `json:"items"` } type Client struct { // token is the token given by tushare token string } // NewClient creates a new instance of Client func NewClient(token string) *Client { return &Client{token: token} } // makeBody makes a request body to tushare by apiName, fields and params. func (c *Client) makeBody(apiName, fields string, params map[string]interface{}) (io.Reader, error) { m := map[string]interface{}{ "api_name": apiName, "token": c.token, "fields": fields, } if params == nil { m["params"] = "" } else { m["params"] = params } b, err := json.Marshal(m) if err != nil { return nil, err } return bytes.NewBuffer(b), nil } // request makes a http request to tushare func (c *Client) request(body io.Reader) (*Response, error) { // do the request resp, err := http.Post(endpoint, "application/json", body) for err != nil { resp, err = http.Post(endpoint, "application/json", body) } // read the data from the body // if the data is abnormal, error will be returned defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, err } var res Response err = json.Unmarshal(b, &res) if err != nil { return nil, err } if res.Code != 0 { return nil, errors.New(res.Msg) } return &res, nil } func parseUnix(tsDate string) int64 { date, _ := time.Parse(timeLayout, tsDate) return date.Unix() - 28800 } // parseRecord parse a list of a record in tushare's response body to our // entity func (c *Client) parseRecord(schema []string, record []interface{}, e interface{}) { switch v := e.(type) { case *Top10Holder: // ts_code,ann_date,end_date,holder_name,hold_amount,hold_ratio for i := range record { if record[i] == nil { continue } switch schema[i] { case "ts_code": v.TsCode = record[i].(string) case "ann_date": v.AnnDate = parseUnix(record[i].(string)) case "end_date": v.Year, _ = strconv.Atoi(record[i].(string)[0:4]) case "holder_name": v.HolderName = record[i].(string) case "hold_amount": v.HoldAmount = record[i].(float64) case "hold_ratio": v.HoldRatio = record[i].(float64) / 100.0 } } case *KLine: // ts_code,trade_date,open,high,low,close,pre_close,change, // pct_chg,vol,amount for i := range record { if record[i] == nil { continue } switch schema[i] { case "ts_code": v.TsCode = record[i].(string) case "trade_date": v.TradeDate = parseUnix(record[i].(string)) case "open": v.Open = record[i].(float64) case "high": v.High = record[i].(float64) case "low": v.Low = record[i].(float64) case "close": v.Close = record[i].(float64) case "pre_close": v.PreClose = record[i].(float64) v.LowLimit = v.PreClose * 0.9 v.HighLimit = v.PreClose * 1.1 case "vol": v.Volume = record[i].(float64) case "amount": v.Amount = record[i].(float64) * 1000 } v.Factor = 1.0 } } } // FetchKLineByTsCode fetches kline data of a single asset func (c *Client) FetchKLineByTsCode(tsCode string, tradeDate, startDate, endDate *time.Time, index bool) ([]KLine, error) { fields := "ts_code,trade_date,open,high,low,close,pre_close,change," + "pct_chg,vol,amount" lines := make([]KLine, 0) table := "" if !index { table = "daily" } else { table = "index_daily" } params := map[string]interface{}{ "ts_code": tsCode, } if tradeDate != nil { params["trade_date"] = tradeDate.Format(timeLayout) } if startDate != nil { params["start_date"] = startDate.Format(timeLayout) } if endDate != nil { params["end_date"] = endDate.Format(timeLayout) } reqBody, err := c.makeBody(table, fields, params) if err != nil { return nil, err } resp, err := c.request(reqBody) if err != nil { return nil, err } for _, record := range resp.Data.Items { line := KLine{} c.parseRecord(resp.Data.Fields, record, &line) lines = append(lines, line) } return lines, nil }
上述程式碼即為構造一個結構體Kline,然後使用http post方式獲取tushare資料,將資料轉化為結構體形式。涉及到json資料格式轉化,reqBody的構造。
重點在於獲取tushare的token,token獲取方式可參照https://waditu.com/document/1?doc_id=130。
以上就是go通過http方式來獲取tushare資料的過程。
注意事項
http方式呼叫tushare是有次數限制的,免費資料來源不可隨意調取,按照平臺給出的每分鐘呼叫次數限制來使用。
不同資料型別的限制次數不同,下面給出一個大概的參考次數,
獲取資料項 | 次數限制 |
---|---|
top10_holder | 200 |
Kline | 500 |
dividends | 200 |
suspensions | 200 |
具體限制次數請參照官網(可能會變化)。
切勿攻擊,濫用tushare資料包。資料只供策略研究和學習使用,不允許作為商業目的。日漸增多的資料採集和處理需求、持續上升的使用者請求,給伺服器和頻寬的擴容造成了很大壓力。做遵紀守法的好公民,每個人心中都應該有一條線。