go语言http调用Tushare财经数据包

go语言http调用Tushare财经数据包

Tushare平台介绍

  1. Tushare平台网址 https://tushare.pro/document/1,网址上就有下载安装以及数据获取的方式。Tushare Pro提供了包括股票、指数、基金、期货、数字货币在内的各类资产交易行情的分钟数据。
  2. 免费获取,数据准确,适合量化投资分析师(Quant),对金融市场进行大数据分析的企业和个人,开发以证券为基础的金融类产品和解决方案的公司,正在学习利用python进行数据分析的人使用。
  3. 有以下几种获取方式,今天介绍的是通过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_holder200
Kline500
dividends200
suspensions200

具体限制次数请参照官网(可能会变化)。

切勿攻击,滥用tushare数据包。数据只供策略研究和学习使用,不允许作为商业目的。日渐增多的数据采集和处理需求、持续上升的用户请求,给服务器和带宽的扩容造成了很大压力。做遵纪守法的好公民,每个人心中都应该有一条线。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值