This commit is contained in:
2026-05-01 11:03:19 +08:00
parent b6a199887e
commit aa8a1190f0
24 changed files with 2552 additions and 0 deletions

141
tushare/board.go Normal file
View File

@@ -0,0 +1,141 @@
package tushare
/*
LimitCptList 获取限板板块列表
trade_date: 交易日,格式:YYYYMMDD
ts_code: 板块代码
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
*/
func (cli *TushareClient) LimitCptList(trade_date, ts_code, start_date, end_date string) (*TushareRespData, error) {
params := map[string]any{}
if trade_date != "" {
params["trade_date"] = trade_date
}
if ts_code != "" {
params["ts_code"] = ts_code
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
req := TushareReq{
APIName: "limit_cpt_list",
Params: params,
}
fields := []map[string]string{
{"rank": "排名"},
{"ts_code": "板块代码"},
{"name": "板块名称"},
{"pct_chg": "涨跌幅%"},
{"up_stat": "连板高度"},
{"days": "上榜天数"},
{"up_nums": "涨停标的数"},
{"cons_nums": "连板标的数"},
}
return cli.Do(req, fields)
}
/*
LimitListD 获取涨跌停列表(新)
trade_date: 交易日期,格式:YYYYMMDD
ts_code: 股票代码
limit_type: 涨跌停类型U 涨停 D 跌停 Z 炸板
exchange: 交易所SH 上交所 SZ 深交所 BJ 北交所
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
*/
func (cli *TushareClient) LimitListD(trade_date, ts_code, limit_type, exchange, start_date, end_date string) (*TushareRespData, error) {
params := map[string]any{}
if trade_date != "" {
params["trade_date"] = trade_date
}
if ts_code != "" {
params["ts_code"] = ts_code
}
if limit_type != "" {
params["limit_type"] = limit_type
}
if exchange != "" {
params["exchange"] = exchange
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
req := TushareReq{
APIName: "limit_list_d",
Params: params,
}
fields := []map[string]string{
{"trade_date": "交易日期"},
{"ts_code": "股票代码"},
{"industry": "所属行业"},
{"name": "股票名称"},
{"close": "收盘价"},
{"pct_chg": "涨跌幅%"},
{"amount": "成交额"},
{"limit_amount": "板上成交金额"},
{"float_mv": "流通市值"},
{"total_mv": "总市值"},
{"turnover_ratio": "换手率%"},
{"fd_amount": "封单金额"},
{"first_time": "首次封板时间"},
{"last_time": "最后封板时间"},
{"open_times": "炸板次数"},
{"up_stat": "涨停统计"},
{"limit_times": "连板数"},
{"limit": "涨跌停类型"},
}
return cli.Do(req, fields)
}
/*
LimitU 获取涨停股票列表
trade_date: 交易日期,格式:YYYYMMDD
ts_code: 股票代码
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
*/
func (cli *TushareClient) LimitU(trade_date, ts_code, start_date, end_date string) (*TushareRespData, error) {
return cli.LimitListD(trade_date, ts_code, "U", "", start_date, end_date)
}
/*
LimitD 获取跌停股票列表
trade_date: 交易日期,格式:YYYYMMDD
ts_code: 股票代码
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
*/
func (cli *TushareClient) LimitD(trade_date, ts_code, start_date, end_date string) (*TushareRespData, error) {
return cli.LimitListD(trade_date, ts_code, "D", "", start_date, end_date)
}
/*
LimitZ 获取炸板股票列表
trade_date: 交易日期,格式:YYYYMMDD
ts_code: 股票代码
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
*/
func (cli *TushareClient) LimitZ(trade_date, ts_code, start_date, end_date string) (*TushareRespData, error) {
return cli.LimitListD(trade_date, ts_code, "Z", "", start_date, end_date)
}

254
tushare/fina.go Normal file
View File

@@ -0,0 +1,254 @@
package tushare
/*
Income 获取利润表
ts_code: 股票代码,支持多个,逗号分隔
ann_date: 公告日期,格式:YYYYMMDD
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
report_type: 报表类型1:合并报表2:母公司报表
*/
func (cli *TushareClient) Income(ts_code, ann_date, start_date, end_date, report_type string) (*TushareRespData, error) {
params := map[string]any{}
if ts_code != "" {
params["ts_code"] = ts_code
}
if ann_date != "" {
params["ann_date"] = ann_date
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
if report_type != "" {
params["report_type"] = report_type
}
req := TushareReq{
APIName: "income",
Params: params,
}
fields := []map[string]string{
{"ts_code": "股票代码"},
{"ann_date": "公告日期"},
{"f_ann_date": "实际公告日期"},
{"end_date": "报告期"},
{"basic_eps": "基本每股收益"},
{"diluted_eps": "稀释每股收益"},
{"total_revenue": "营业总收入"},
{"revenue": "营业收入"},
{"total_profit": "利润总额"},
{"net_profit": "净利润"},
{"net_profit_attr_sh": "归属于母公司所有者的净利润"},
{"operating_expense": "营业总成本"},
{"operating_cost": "营业成本"},
}
return cli.Do(req, fields)
}
/*
Balancesheet 获取资产负债表
ts_code: 股票代码,支持多个,逗号分隔
ann_date: 公告日期,格式:YYYYMMDD
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
report_type: 报表类型1:合并报表2:母公司报表
*/
func (cli *TushareClient) Balancesheet(ts_code, ann_date, start_date, end_date, report_type string) (*TushareRespData, error) {
params := map[string]any{}
if ts_code != "" {
params["ts_code"] = ts_code
}
if ann_date != "" {
params["ann_date"] = ann_date
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
if report_type != "" {
params["report_type"] = report_type
}
req := TushareReq{
APIName: "balancesheet",
Params: params,
}
fields := []map[string]string{
{"ts_code": "股票代码"},
{"ann_date": "公告日期"},
{"f_ann_date": "实际公告日期"},
{"end_date": "报告期"},
{"total_assets": "资产总计"},
{"total_liab": "负债合计"},
{"total_hldr_eqy_exc_min_int": "股东权益合计"},
{"total_hldr_eqy_inc_min_int": "股东权益合计 (含少数股东权益)"},
{"total_share_capital": "股本"},
{"cap_rsrv": "资本公积"},
{"surplus_rsrv": "盈余公积"},
{"undist_prft": "未分配利润"},
{"monetary_cap": "货币资金"},
{"total_current_assets": "流动资产合计"},
{"total_non_current_assets": "非流动资产合计"},
}
return cli.Do(req, fields)
}
/*
Cashflow 获取现金流量表
ts_code: 股票代码,支持多个,逗号分隔
ann_date: 公告日期,格式:YYYYMMDD
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
report_type: 报表类型1:合并报表2:母公司报表
*/
func (cli *TushareClient) Cashflow(ts_code, ann_date, start_date, end_date, report_type string) (*TushareRespData, error) {
params := map[string]any{}
if ts_code != "" {
params["ts_code"] = ts_code
}
if ann_date != "" {
params["ann_date"] = ann_date
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
if report_type != "" {
params["report_type"] = report_type
}
req := TushareReq{
APIName: "cashflow",
Params: params,
}
fields := []map[string]string{
{"ts_code": "股票代码"},
{"ann_date": "公告日期"},
{"f_ann_date": "实际公告日期"},
{"end_date": "报告期"},
{"net_cash_invest_act": "投资活动产生的现金流量净额"},
{"net_cash_financing_act": "筹资活动产生的现金流量净额"},
{"net_cash_oper_act": "经营活动产生的现金流量净额"},
{"cash_equivalents_end": "现金及现金等价物期末余额"},
{"cash_equivalents_begin": "现金及现金等价物期初余额"},
{"net_increase_cash": "现金及现金等价物净增加额"},
}
return cli.Do(req, fields)
}
/*
FinaIndicator 获取财务指标
ts_code: 股票代码,支持多个,逗号分隔
ann_date: 公告日期,格式:YYYYMMDD
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
*/
func (cli *TushareClient) FinaIndicator(ts_code, ann_date, start_date, end_date string) (*TushareRespData, error) {
params := map[string]any{}
if ts_code != "" {
params["ts_code"] = ts_code
}
if ann_date != "" {
params["ann_date"] = ann_date
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
req := TushareReq{
APIName: "fina_indicator",
Params: params,
}
fields := []map[string]string{
{"ts_code": "股票代码"},
{"ann_date": "公告日期"},
{"end_date": "报告期"},
{"eps_basic": "基本每股收益"},
{"eps_diluted": "稀释每股收益"},
{"roe": "净资产收益率%"},
{"roe_wa": "净资产收益率 (加权)%"},
{"roa": "总资产净利率%"},
{"gross_margin": "销售毛利率%"},
{"net_profit_margin": "销售净利率%"},
{"current_ratio": "流动比率"},
{"quick_ratio": "速动比率"},
{"debt_to_assets": "资产负债率%"},
{"turnover_days": "存货周转天数"},
{"receivables_turnover": "应收账款周转率"},
}
return cli.Do(req, fields)
}
/*
Forecast 获取业绩预告
ts_code: 股票代码,支持多个,逗号分隔
ann_date: 公告日期,格式:YYYYMMDD
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
type: 预告类型,预增/预减/扭亏/续盈/首亏/略增/略减
*/
func (cli *TushareClient) Forecast(ts_code, ann_date, start_date, end_date, forecast_type string) (*TushareRespData, error) {
params := map[string]any{}
if ts_code != "" {
params["ts_code"] = ts_code
}
if ann_date != "" {
params["ann_date"] = ann_date
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
if forecast_type != "" {
params["type"] = forecast_type
}
req := TushareReq{
APIName: "forecast",
Params: params,
}
fields := []map[string]string{
{"ts_code": "股票代码"},
{"ann_date": "公告日期"},
{"end_date": "报告期"},
{"type": "预告类型"},
{"net_profit_min": "净利润下限 (万元)"},
{"net_profit_max": "净利润上限 (万元)"},
{"parent_netprofit_min": "归母净利润下限 (万元)"},
{"parent_netprofit_max": "归母净利润上限 (万元)"},
{"summary": "业绩预告摘要"},
}
return cli.Do(req, fields)
}

206
tushare/finance.go Normal file
View File

@@ -0,0 +1,206 @@
package tushare
/*
DailyBasic 获取股票日线指标
ts_code: 股票代码,支持多个,逗号分隔
trade_date: 交易日期,格式:YYYYMMDD
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
*/
func (cli *TushareClient) DailyBasic(ts_code, trade_date, start_date, end_date string) (*TushareRespData, error) {
params := map[string]any{}
if ts_code != "" {
params["ts_code"] = ts_code
}
if trade_date != "" {
params["trade_date"] = trade_date
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
req := TushareReq{
APIName: "daily_basic",
Params: params,
}
fields := []map[string]string{
{"ts_code": "股票代码"},
{"trade_date": "交易日期"},
{"close": "收盘价"},
{"turnover_rate": "换手率%"},
{"turnover_rate_f": "换手率% (自由流通股本)"},
{"volume_ratio": "量比"},
{"pe": "市盈率"},
{"pe_ttm": "市盈率 TTM"},
{"pb": "市净率"},
{"ps": "市销率"},
{"ps_ttm": "市销率 TTM"},
{"dv_ratio": "股息率%"},
{"total_mv": "总市值"},
{"circ_mv": "流通市值"},
}
return cli.Do(req, fields)
}
/*
AdjFactor 获取复权因子
ts_code: 股票代码,支持多个,逗号分隔
trade_date: 交易日期,格式:YYYYMMDD
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
*/
func (cli *TushareClient) AdjFactor(ts_code, trade_date, start_date, end_date string) (*TushareRespData, error) {
params := map[string]any{}
if ts_code != "" {
params["ts_code"] = ts_code
}
if trade_date != "" {
params["trade_date"] = trade_date
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
req := TushareReq{
APIName: "adj_factor",
Params: params,
}
fields := []map[string]string{
{"ts_code": "股票代码"},
{"trade_date": "交易日期"},
{"adj_factor": "复权因子"},
}
return cli.Do(req, fields)
}
/*
Moneyflow 获取个股资金流向
ts_code: 股票代码,支持多个,逗号分隔
trade_date: 交易日期,格式:YYYYMMDD
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
*/
func (cli *TushareClient) Moneyflow(ts_code, trade_date, start_date, end_date string) (*TushareRespData, error) {
params := map[string]any{}
if ts_code != "" {
params["ts_code"] = ts_code
}
if trade_date != "" {
params["trade_date"] = trade_date
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
req := TushareReq{
APIName: "moneyflow",
Params: params,
}
fields := []map[string]string{
{"ts_code": "股票代码"},
{"trade_date": "交易日期"},
{"buy_sm_amount": "小单买入金额 (千元)"},
{"sell_sm_amount": "小单卖出金额 (千元)"},
{"buy_md_amount": "中单买入金额 (千元)"},
{"sell_md_amount": "中单卖出金额 (千元)"},
{"buy_lg_amount": "大单买入金额 (千元)"},
{"sell_lg_amount": "大单卖出金额 (千元)"},
{"buy_elg_amount": "特大单买入金额 (千元)"},
{"sell_elg_amount": "特大单卖出金额 (千元)"},
{"net_mf_amount": "净流入金额 (千元)"},
}
return cli.Do(req, fields)
}
/*
SuspendList 获取停牌股票列表
suspend_type: 停牌类型1:盘中停牌2:盘中临时停牌3:全天停牌
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
*/
func (cli *TushareClient) SuspendList(suspend_type, start_date, end_date string) (*TushareRespData, error) {
params := map[string]any{}
if suspend_type != "" {
params["suspend_type"] = suspend_type
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
req := TushareReq{
APIName: "suspend_list",
Params: params,
}
fields := []map[string]string{
{"ts_code": "股票代码"},
{"name": "股票名称"},
{"suspend_type": "停牌类型"},
{"suspend_start": "停牌起始日"},
{"suspend_end": "停牌结束日"},
{"reason": "停牌原因"},
}
return cli.Do(req, fields)
}
/*
RealtimeQuote 获取实时行情
ts_code: 股票代码,支持多个,逗号分隔
*/
func (cli *TushareClient) RealtimeQuote(ts_code string) (*TushareRespData, error) {
params := map[string]any{}
if ts_code != "" {
params["ts_code"] = ts_code
}
req := TushareReq{
APIName: "realtime_quote",
Params: params,
}
fields := []map[string]string{
{"ts_code": "股票代码"},
{"price": "最新价"},
{"open": "开盘价"},
{"high": "最高价"},
{"low": "最低价"},
{"pre_close": "昨收价"},
{"vol": "成交量 (手)"},
{"amount": "成交额 (千元)"},
{"buy_vol": "买总量 (手)"},
{"sell_vol": "卖总量 (手)"},
{"buy_amount": "买总额 (千元)"},
{"sell_amount": "卖总额 (千元)"},
}
return cli.Do(req, fields)
}

213
tushare/index.go Normal file
View File

@@ -0,0 +1,213 @@
package tushare
/*
IndexBasic 获取大盘指数基本信息
ts_code: 指数代码,支持多个,逗号分隔
exchange: 交易所代码SSE 上交所SZSE 深交所
*/
func (cli *TushareClient) IndexBasic(ts_code, exchange string) (*TushareRespData, error) {
params := map[string]any{}
if ts_code != "" {
params["ts_code"] = ts_code
}
if exchange != "" {
params["exchange"] = exchange
}
req := TushareReq{
APIName: "index_basic",
Params: params,
}
fields := []map[string]string{
{"ts_code": "指数代码"},
{"name": "指数名称"},
{"market": "市场类别"},
{"publisher": "发布方"},
{"category": "指数类别"},
{"base_date": "基日"},
{"base_point": "基点"},
{"list_date": "发布日期"},
}
return cli.Do(req, fields)
}
/*
IndexWeight 获取指数成分和权重
index_code: 指数代码,如 000300.SH(沪深 300)
trade_date: 交易日期,格式:YYYYMMDD
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
*/
func (cli *TushareClient) IndexWeight(index_code, trade_date, start_date, end_date string) (*TushareRespData, error) {
params := map[string]any{}
if index_code != "" {
params["index_code"] = index_code
}
if trade_date != "" {
params["trade_date"] = trade_date
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
req := TushareReq{
APIName: "index_weight",
Params: params,
}
fields := []map[string]string{
{"index_code": "指数代码"},
{"trade_date": "交易日期"},
{"ts_code": "成分股票代码"},
{"weight": "权重%"},
}
return cli.Do(req, fields)
}
/*
IndexClassify 获取指数分类信息
level: 指数级别L1/L2/L3/L4
src: 指数来源SW 申万ZJW 证监会ICS iFinD
parent_code: 父级代码
*/
func (cli *TushareClient) IndexClassify(level, src, parent_code string) (*TushareRespData, error) {
params := map[string]any{}
if level != "" {
params["level"] = level
}
if src != "" {
params["src"] = src
}
if parent_code != "" {
params["parent_code"] = parent_code
}
req := TushareReq{
APIName: "index_classify",
Params: params,
}
fields := []map[string]string{
{"index_code": "指数代码"},
{"industry_name": "行业名称"},
{"industry_code": "行业代码"},
{"parent_code": "父级代码"},
{"level": "级别"},
{"src": "来源"},
}
return cli.Do(req, fields)
}
/*
IndexMember 获取指数成分股
index_code: 指数代码,如 000300.SH(沪深 300)
trade_date: 交易日期,格式:YYYYMMDD
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
*/
func (cli *TushareClient) IndexMember(index_code, trade_date, start_date, end_date string) (*TushareRespData, error) {
params := map[string]any{}
if index_code != "" {
params["index_code"] = index_code
}
if trade_date != "" {
params["trade_date"] = trade_date
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
req := TushareReq{
APIName: "index_member",
Params: params,
}
fields := []map[string]string{
{"index_code": "指数代码"},
{"trade_date": "交易日期"},
{"ts_code": "成分股票代码"},
{"symbol": "成分股票代码"},
{"name": "成分股票名称"},
{"is_new": "是否新增"},
{"in_date": "纳入日期"},
{"out_date": "剔除日期"},
}
return cli.Do(req, fields)
}
/*
Concept 获取概念板块信息
ts_code: 板块代码,支持多个,逗号分隔
name: 板块名称,支持模糊匹配
*/
func (cli *TushareClient) Concept(ts_code, name string) (*TushareRespData, error) {
params := map[string]any{}
if ts_code != "" {
params["ts_code"] = ts_code
}
if name != "" {
params["name"] = name
}
req := TushareReq{
APIName: "concept",
Params: params,
}
fields := []map[string]string{
{"ts_code": "板块代码"},
{"name": "板块名称"},
{"src": "来源"},
{"pub_date": "发布日期"},
}
return cli.Do(req, fields)
}
/*
ConceptDetail 获取概念板块详情
ts_code: 板块代码
*/
func (cli *TushareClient) ConceptDetail(ts_code string) (*TushareRespData, error) {
params := map[string]any{}
if ts_code != "" {
params["ts_code"] = ts_code
}
req := TushareReq{
APIName: "concept_detail",
Params: params,
}
fields := []map[string]string{
{"ts_code": "板块代码"},
{"name": "板块名称"},
{"concept_name": "概念名称"},
{"stock_count": "成分股票数量"},
}
return cli.Do(req, fields)
}

24
tushare/indicator.go Normal file
View File

@@ -0,0 +1,24 @@
package tushare
func (cli *TushareClient) StkFactorPro(ts_code string, tradeDate string) (*TushareRespData, error) {
params := map[string]any{}
if ts_code != "" {
params["ts_code"] = ts_code
}
if tradeDate != "" {
params["trade_date"] = tradeDate
}
req := TushareReq{
APIName: "stk_factor_pro",
Params: params,
}
fields := []map[string]string{
{"trade_date": "trade_date"},
{"rsi_bfq_24": "rsi_bfq_24"},
{"rsi_hfq_24": "rsi_hfq_24"},
{"rsi_qfq_24": "rsi_qfq_24"},
}
return cli.Do(req, fields)
}

209
tushare/margin.go Normal file
View File

@@ -0,0 +1,209 @@
package tushare
/*
HkHold 获取沪深股通持股明细
ts_code: 股票代码
trade_date: 交易日期,格式:YYYYMMDD
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
*/
func (cli *TushareClient) HkHold(ts_code, trade_date, start_date, end_date string) (*TushareRespData, error) {
params := map[string]any{}
if ts_code != "" {
params["ts_code"] = ts_code
}
if trade_date != "" {
params["trade_date"] = trade_date
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
req := TushareReq{
APIName: "hk_hold",
Params: params,
}
fields := []map[string]string{
{"ts_code": "股票代码"},
{"trade_date": "交易日期"},
{"holding_sh": "沪股通持股数量 (股)"},
{"holding_sz": "深股通持股数量 (股)"},
{"holding_total": "沪深股通持股总量 (股)"},
{"ratio_sh": "沪股通持股比例%"},
{"ratio_sz": "深股通持股比例%"},
{"ratio_total": "沪深股通持股比例合计%"},
}
return cli.Do(req, fields)
}
/*
MarginDetail 获取融资融券明细
trade_date: 交易日期,格式:YYYYMMDD
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
exchange: 交易所代码SSE 上交所SZSE 深交所
*/
func (cli *TushareClient) MarginDetail(trade_date, start_date, end_date, exchange string) (*TushareRespData, error) {
params := map[string]any{}
if trade_date != "" {
params["trade_date"] = trade_date
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
if exchange != "" {
params["exchange"] = exchange
}
req := TushareReq{
APIName: "margin_detail",
Params: params,
}
fields := []map[string]string{
{"trade_date": "交易日期"},
{"ts_code": "股票代码"},
{"buy_value": "融资买入额 (元)"},
{"buy_repay_value": "融资偿还额 (元)"},
{"buy_bal": "融资余额 (元)"},
{"sell_value": "融券卖出量 (股)"},
{"sell_repay_value": "融券偿还量 (股)"},
{"sell_bal": "融券余量 (股)"},
{"sell_amount": "融券余量金额 (元)"},
}
return cli.Do(req, fields)
}
/*
TopList 获取龙虎榜数据
trade_date: 交易日期,格式:YYYYMMDD
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
*/
func (cli *TushareClient) TopList(trade_date, start_date, end_date string) (*TushareRespData, error) {
params := map[string]any{}
if trade_date != "" {
params["trade_date"] = trade_date
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
req := TushareReq{
APIName: "top_list",
Params: params,
}
fields := []map[string]string{
{"trade_date": "交易日期"},
{"ts_code": "股票代码"},
{"name": "股票名称"},
{"close": "收盘价"},
{"pct_chg": "涨跌幅%"},
{"turnover_rate": "换手率%"},
{"total_value": "成交总额 (万元)"},
{"net_value": "净额 (万元)"},
{"buy_value": "买入总额 (万元)"},
{"sell_value": "卖出总额 (万元)"},
{"reason": "上榜原因"},
}
return cli.Do(req, fields)
}
/*
TopInst 获取龙虎榜机构席位数据
trade_date: 交易日期,格式:YYYYMMDD
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
*/
func (cli *TushareClient) TopInst(trade_date, start_date, end_date string) (*TushareRespData, error) {
params := map[string]any{}
if trade_date != "" {
params["trade_date"] = trade_date
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
req := TushareReq{
APIName: "top_inst",
Params: params,
}
fields := []map[string]string{
{"trade_date": "交易日期"},
{"ts_code": "股票代码"},
{"name": "股票名称"},
{"buy_value": "机构买入总额 (万元)"},
{"buy_count": "机构买入次数"},
{"sell_value": "机构卖出总额 (万元)"},
{"sell_count": "机构卖出次数"},
{"net_value": "机构净买入额 (万元)"},
}
return cli.Do(req, fields)
}
/*
BlockTrade 获取大宗交易数据
trade_date: 交易日期,格式:YYYYMMDD
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
*/
func (cli *TushareClient) BlockTrade(trade_date, start_date, end_date string) (*TushareRespData, error) {
params := map[string]any{}
if trade_date != "" {
params["trade_date"] = trade_date
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
req := TushareReq{
APIName: "block_trade",
Params: params,
}
fields := []map[string]string{
{"trade_date": "交易日期"},
{"ts_code": "股票代码"},
{"name": "证券简称"},
{"price": "成交价"},
{"vol": "成交量 (万股)"},
{"amount": "成交额 (万元)"},
{"buyer": "买方营业部"},
{"seller": "卖方营业部"},
{"premium_rate": "溢价率%"},
}
return cli.Do(req, fields)
}

168
tushare/new.go Normal file
View File

@@ -0,0 +1,168 @@
package tushare
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"time"
"github.com/jedib0t/go-pretty/v6/table"
)
// TushareClient Tushare API 客户端
type TushareClient struct {
Token string `json:"token"` // API 访问令牌
BaseUrl string `json:"base_url"` // API 基础 URL
}
// TushareReq Tushare API 请求结构
type TushareReq struct {
APIName string `json:"api_name"` // API 接口名称
Token string `json:"token"` // API 访问令牌
Params map[string]any `json:"params"` // 请求参数
Fields []string `json:"fields"` // 返回字段列表
}
// TushareResp Tushare API 响应结构
type TushareResp struct {
RequestID string `json:"request_id"` // 请求 ID
Code int `json:"code"` // 响应码 (0 表示成功)
Data *TushareRespData `json:"data"` // 响应数据
Msg string `json:"msg"` // 响应消息
}
// TushareRespData Tushare API 响应数据结构
type TushareRespData struct {
Fields []string `json:"fields"` // 字段列表
Headers []string `json:"headers"` // 表头(中文描述)
Items [][]any `json:"items"` // 数据项(二维数组)
HasMore bool `json:"has_more"` // 是否有更多数据
Count int `json:"count"` // 返回数据条数
}
// NewClient 创建并初始化 Tushare 客户端
// 返回配置好 Token 和基础 URL 的客户端实例
func NewClient(token string) *TushareClient {
if token == "" {
token = os.Getenv("TUSHARE_TOKEN")
}
return &TushareClient{
Token: token,
BaseUrl: "http://api.tushare.pro",
}
}
// Do 执行 Tushare API 请求
// req: 请求参数,包含 API 名称、参数等
// fieldsVals: 字段配置列表,每个元素是一个 mapkey 为字段名value 为字段中文描述
// 返回:响应数据和错误信息
func (c *TushareClient) Do(req TushareReq, fieldsVals []map[string]string) (*TushareRespData, error) {
// 构建请求体
payload := TushareReq{
APIName: req.APIName,
Token: c.Token,
Params: req.Params,
}
// 提取字段名和对应的中文表头
var fields []string
var headers []string
for _, setting := range fieldsVals {
for key, value := range setting {
fields = append(fields, key)
headers = append(headers, value)
}
}
payload.Fields = fields
// 序列化请求体为 JSON
reqBytes, err := json.Marshal(payload)
if err != nil {
return nil, fmt.Errorf("#100 请求序列化失败:%w", err)
}
// 创建 HTTP 请求
client := &http.Client{
Timeout: 30 * time.Second, // 设置 30 秒超时
}
resp, err := client.Post(c.BaseUrl, "application/json", bytes.NewReader(reqBytes))
if err != nil {
return nil, fmt.Errorf("#100 发送请求失败:%w", err)
}
defer resp.Body.Close()
// 读取响应体
body, err := io.ReadAll(resp.Body)
if err != nil {
return nil, fmt.Errorf("#101 读取响应失败:%w", err)
}
// 解析响应 JSON
var tushareResp TushareResp
if err := json.Unmarshal(body, &tushareResp); err != nil {
return nil, fmt.Errorf("#101 响应解析失败:%v - %s", err, string(body))
}
// 检查响应码
if tushareResp.Code != 0 {
return nil, fmt.Errorf("#102 API 返回错误:%s", tushareResp.Msg)
}
// 设置表头信息
if tushareResp.Data != nil {
tushareResp.Data.Headers = headers
}
return tushareResp.Data, nil
}
// Map 将响应数据转换为 map 切片
// 每个 map 代表一行数据key 为字段名value 为对应的值
func (c *TushareRespData) Map() []map[string]any {
result := make([]map[string]any, 0)
if c == nil || len(c.Items) == 0 || len(c.Fields) == 0 {
return result
}
for _, item := range c.Items {
rowMap := make(map[string]any, len(c.Fields))
for idx, fn := range c.Fields {
if idx < len(item) {
rowMap[fn] = item[idx]
}
}
result = append(result, rowMap)
}
return result
}
// Json 将响应数据转换为 JSON 字节数组
// 返回JSON 格式的字节数据和错误信息
func (c *TushareRespData) Json() ([]byte, error) {
data := c.Map()
return json.MarshalIndent(data, "", " ")
}
// Output 将响应数据格式化为表格输出
// title: 表格标题
// 返回:格式化的表格写入器
func (c *TushareRespData) Output(title string) table.Writer {
tw := table.NewWriter()
tw.SetStyle(table.StyleLight)
tw.SetTitle(title)
// 构建表头行
headerRow := make(table.Row, 0, len(c.Headers))
for idx, header := range c.Headers {
headerRow = append(headerRow, header+"("+c.Fields[idx]+")")
}
tw.AppendHeader(headerRow)
// 添加数据行
for _, item := range c.Items {
tw.AppendRow(item)
}
return tw
}

241
tushare/stock.go Normal file
View File

@@ -0,0 +1,241 @@
package tushare
import (
"time"
)
/*
TradeCal 获取交易日历
exchange: 交易所代码SSE 上交所SZSE 深交所BSE 北交所,空字符串代表所有
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
is_open: 是否开盘,'0'休市,'1'交易,空字符串代表所有
*/
func (cli *TushareClient) TradeCal(exchange, start_date, end_date, is_open string) (*TushareRespData, error) {
params := map[string]any{}
if exchange != "" {
params["exchange"] = exchange
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
if is_open != "" {
params["is_open"] = is_open
}
req := TushareReq{
APIName: "trade_cal",
Params: params,
}
fields := []map[string]string{
{"exchange": "交易所代码"},
{"cal_date": "日历日期"},
{"is_open": "是否开盘"},
{"pretrade_date": "上一交易日"},
}
return cli.Do(req, fields)
}
func (cli *TushareClient) ReturnLastTradeDay() string {
result, err := cli.TradeCal("SSE", time.Now().AddDate(0, 0, -15).Format("20060102"), time.Now().Format("20060102"), "1")
if err != nil {
return ""
}
cal := result.Map()
return cal[0]["cal_date"].(string)
}
/*
StockBasic 获取股票列表
ts_code: 股票代码,支持多个,如"000002.SZ,000001.SZ"
exchange: 交易所代码SSE 上交所SZSE 深交所
is_shsc: 是否在沪股通或深港通范围内0:否;1:沪股通;2:深股通
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
*/
func (cli *TushareClient) StockBasic(ts_code, exchange, is_shsc, start_date, end_date string) (*TushareRespData, error) {
params := map[string]any{}
if ts_code != "" {
params["ts_code"] = ts_code
}
if exchange != "" {
params["exchange"] = exchange
}
if is_shsc != "" {
params["is_shsc"] = is_shsc
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
req := TushareReq{
APIName: "stock_basic",
Params: params,
}
fields := []map[string]string{
{"ts_code": "TS 代码"},
{"symbol": "股票交易代码"},
{"name": "证券简称"},
{"area": "地区"},
{"industry": "所属行业"},
{"market": "市场类别"},
{"list_status": "上市状态"},
{"list_date": "上市日期"},
{"delist_date": "退市日期"},
{"is_shsc": "是否沪股通或深股通"},
}
return cli.Do(req, fields)
}
/*
Daily 获取日线行情
ts_code: 股票代码格式000001.SZ 或 600000.SH
trade_date: 交易日期,格式:YYYYMMDD
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
*/
func (cli *TushareClient) Daily(ts_code, trade_date, start_date, end_date string) (*TushareRespData, error) {
params := map[string]any{}
if ts_code != "" {
params["ts_code"] = ts_code
}
if trade_date != "" {
params["trade_date"] = trade_date
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
req := TushareReq{
APIName: "daily",
Params: params,
}
fields := []map[string]string{
{"ts_code": "股票代码"},
{"trade_date": "交易日期"},
{"open": "开盘价"},
{"high": "最高价"},
{"low": "最低价"},
{"close": "收盘价"},
{"pre_close": "昨收价"},
{"change": "涨跌额"},
{"pct_chg": "涨跌幅%"},
{"vol": "成交量 (手)"},
{"amount": "成交额 (千元)"},
}
return cli.Do(req, fields)
}
/*
Min 获取分钟线行情
ts_code: 股票代码格式000001.SZ 或 600000.SH
trade_date: 交易日期,格式:YYYYMMDD
minute: 分钟类型1/5/15/30/60 分钟
start_time: 开始时间,格式:HHmmss
end_time: 结束时间,格式:HHmmss
*/
func (cli *TushareClient) Min(ts_code, trade_date, minute, start_time, end_time string) (*TushareRespData, error) {
params := map[string]any{}
if ts_code != "" {
params["ts_code"] = ts_code
}
if trade_date != "" {
params["trade_date"] = trade_date
}
if minute != "" {
params["minute"] = minute
}
if start_time != "" {
params["start_time"] = start_time
}
if end_time != "" {
params["end_time"] = end_time
}
req := TushareReq{
APIName: "min",
Params: params,
}
fields := []map[string]string{
{"ts_code": "股票代码"},
{"trade_time": "交易时间"},
{"open": "开盘价"},
{"high": "最高价"},
{"low": "最低价"},
{"close": "收盘价"},
{"vol": "成交量 (手)"},
{"amount": "成交额 (千元)"},
}
return cli.Do(req, fields)
}
/*
IndexDaily 获取大盘指数日线行情
ts_code: 指数代码,如 000001.SH(上证指数),399001.SZ(深证成指)
trade_date: 交易日期,格式:YYYYMMDD
start_date: 开始日期,格式:YYYYMMDD
end_date: 结束日期,格式:YYYYMMDD
*/
func (cli *TushareClient) IndexDaily(ts_code, trade_date, start_date, end_date string) (*TushareRespData, error) {
params := map[string]any{}
if ts_code != "" {
params["ts_code"] = ts_code
}
if trade_date != "" {
params["trade_date"] = trade_date
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
req := TushareReq{
APIName: "index_daily",
Params: params,
}
fields := []map[string]string{
{"ts_code": "指数代码"},
{"trade_date": "交易日期"},
{"close": "收盘点位"},
{"open": "开盘点位"},
{"high": "最高点位"},
{"low": "最低点位"},
{"pre_close": "昨收点位"},
{"change": "涨跌额"},
{"pct_chg": "涨跌幅%"},
{"vol": "成交量 (手)"},
{"amount": "成交额 (千元)"},
}
return cli.Do(req, fields)
}

213
tushare/ths.go Normal file
View File

@@ -0,0 +1,213 @@
package tushare
/*
ThsHot 同花顺热榜
trade_date str N 交易日期
ts_code str N TS代码
market str N 热榜类型(热股、ETF、可转债、行业板块、概念板块、期货、港股、热基、美股)
is_new str N 是否最新默认Y如果为N则为盘中和盘后阶段采集具体时间可参考rank_time字段状态N每小时更新一次状态Y更新时间为2230
*/
func (cli *TushareClient) ThsHot(trade_date, ts_code, market, is_new string) (*TushareRespData, error) {
params := map[string]any{}
if trade_date != "" {
params["trade_date"] = trade_date
}
if ts_code != "" {
params["ts_code"] = ts_code
}
if market != "" {
params["market"] = market
}
if is_new != "" {
params["is_new"] = is_new
}
req := TushareReq{
APIName: "ths_hot",
Params: params,
}
/*
trade_date str Y 交易日期
data_type str Y 数据类型
ts_code str Y 股票代码
ts_name str Y 股票名称
rank int Y 排行
pct_change float Y 涨跌幅%
current_price float Y 当前价格
concept str Y 标签
rank_reason str Y 上榜解读
hot float Y 热度值
rank_time str Y 排行榜获取时间
*/
fields := []map[string]string{
{"trade_date": "交易日期"},
{"data_type": "数据类型"},
{"ts_code": "TS代码"},
{"ts_name": "股票名称"},
{"rank": "排行"},
{"pct_change": "涨跌幅%"},
{"current_price": "当前价格"},
{"concept": "标签"},
{"rank_reason": "上榜解读"},
{"hot": "热度值"},
{"rank_time": "排行榜获取时间"},
}
return cli.Do(req, fields)
}
/*
ThsIndex 同花顺概念和行业指数
接口说明:
- 描述:获取同花顺板块指数,包括概念、行业、特色指数
- 权限本接口需有6000积分单次最大返回5000行数据一次可提取全部数据请勿循环提取
- 注意事项:数据版权归属同花顺,如做商业用途,请主动联系同花顺
输入参数:
- ts_code: 指数代码(可选)
- exchange: 市场类型A-a股 HK-港股 US-美股(可选)
- type: 指数类型N-概念指数 I-行业指数 R-地域指数 S-同花顺特色指数 ST-同花顺风格指数 TH-同花顺主题指数 BB-同花顺宽基指数(可选)
输出参数:
- ts_code: 代码
- name: 名称
- count: 成分个数
- exchange: 交易所
- list_date: 上市日期
- type: N概念指数S特色指数
*/
func (cli *TushareClient) ThsIndex(ts_code, exchange, typ string) (*TushareRespData, error) {
params := map[string]any{}
if ts_code != "" {
params["ts_code"] = ts_code
}
if exchange != "" {
params["exchange"] = exchange
}
if typ != "" {
params["type"] = typ
}
req := TushareReq{
APIName: "ths_index",
Params: params,
}
fields := []map[string]string{
{"ts_code": "代码"},
{"name": "名称"},
{"count": "成分个数"},
{"exchange": "交易所"},
{"list_date": "上市日期"},
{"type": "类型"},
}
return cli.Do(req, fields)
}
/*
ThsDaily 同花顺板块指数行情
接口说明:
- 描述:获取同花顺板块指数行情
- 限量单次最大3000行数据需6000积分可根据指数代码、日期参数循环提取
- 注意事项:数据版权归属同花顺,如做商业用途,请主动联系同花顺
输入参数:
- ts_code: 指数代码(可选)
- trade_date: 交易日期YYYYMMDD格式可选
- start_date: 开始日期YYYYMMDD格式可选
- end_date: 结束日期YYYYMMDD格式可选
输出参数:
- ts_code: TS指数代码
- trade_date: 交易日
- close: 收盘点位
- open: 开盘点位
- high: 最高点位
- low: 最低点位
- pre_close: 昨日收盘点
- avg_price: 平均价
- change: 涨跌点位
- pct_change: 涨跌幅
- vol: 成交量(手)
- turnover_rate: 换手率(%
- total_mv: 总市值(元)
- float_mv: 流通市值(元)
*/
func (cli *TushareClient) ThsDaily(ts_code, trade_date, start_date, end_date string) (*TushareRespData, error) {
params := map[string]any{}
if ts_code != "" {
params["ts_code"] = ts_code
}
if trade_date != "" {
params["trade_date"] = trade_date
}
if start_date != "" {
params["start_date"] = start_date
}
if end_date != "" {
params["end_date"] = end_date
}
req := TushareReq{
APIName: "ths_daily",
Params: params,
}
fields := []map[string]string{
{"ts_code": "TS指数代码"},
{"trade_date": "交易日"},
{"close": "收盘点位"},
{"open": "开盘点位"},
{"high": "最高点位"},
{"low": "最低点位"},
{"pre_close": "昨日收盘点"},
{"avg_price": "平均价"},
{"change": "涨跌点位"},
{"pct_change": "涨跌幅"},
{"vol": "成交量(手)"},
{"turnover_rate": "换手率(%"},
{"total_mv": "总市值(元)"},
{"float_mv": "流通市值(元)"},
}
return cli.Do(req, fields)
}
/*
ThsMember 获取同花顺概念板块成分
ts_code: 板块指数代码
con_code: 股票代码
*/
func (cli *TushareClient) ThsMember(ts_code, con_code string) (*TushareRespData, error) {
params := map[string]any{}
if ts_code != "" {
params["ts_code"] = ts_code
}
if con_code != "" {
params["con_code"] = con_code
}
req := TushareReq{
APIName: "ths_member",
Params: params,
}
fields := []map[string]string{
{"ts_code": "指数代码"},
{"con_code": "股票代码"},
{"con_name": "股票名称"},
{"weight": "权重"},
{"in_date": "纳入日期"},
{"out_date": "剔除日期"},
{"is_new": "是否最新"},
}
return cli.Do(req, fields)
}