6 Commits
v0.0.6 ... main

Author SHA1 Message Date
62c420c8bf fix bug 2026-05-03 21:48:42 +08:00
0d008bb3ab fix cal 2026-05-03 18:53:48 +08:00
165423e668 fix bug 2026-05-02 22:47:06 +08:00
ea69c515d2 fix bug 2026-05-02 13:00:06 +08:00
a2b101621b fix bug 2026-05-02 12:58:16 +08:00
7f3117fd88 fix bug 2026-05-02 12:03:47 +08:00
8 changed files with 133 additions and 110 deletions

View File

@@ -2,7 +2,6 @@ package markdown
import (
"bytes"
"io"
"os"
"strings"
)
@@ -78,6 +77,10 @@ func (m *Builder) SaveToFile(filePath string) error {
}
defer rf.Close()
_, err = io.Copy(rf, &m.buf)
return err
_, err = rf.WriteString(m.Build())
if err != nil {
return err
}
return nil
}

View File

@@ -1,10 +1,8 @@
package schema
import "gorm.io/gorm"
// DatasetBlocksMember 板块成分股。
type DatasetBlocksMember struct {
gorm.Model
ID uint `gorm:"primarykey"`
TiCode string `gorm:"type:varchar(50);not null;default:'';comment:板块代码;index" json:"ti_code"`
TsCode string `gorm:"type:varchar(50);not null;default:'';comment:股票代码;index" json:"ts_code"`
Weight float64 `gorm:"type:float;not null;default:0;comment:权重" json:"weight"`

View File

@@ -32,25 +32,25 @@ type DatasetIndicatorPro struct {
TotalMv float64 `gorm:"type:decimal(20,4);comment:总市值(万元)"`
CircMv float64 `gorm:"type:decimal(20,4);comment:流通市值(万元)"`
AdjFactor float64 `gorm:"type:decimal(20,6);comment:复权因子"`
MaBfq5 float64 `gorm:"type:decimal(20,6);comment:MA5复权"`
MaBfq10 float64 `gorm:"type:decimal(20,6);comment:MA10复权"`
MaBfq20 float64 `gorm:"type:decimal(20,6);comment:MA20复权"`
MaBfq60 float64 `gorm:"type:decimal(20,6);comment:MA60复权"`
EmaBfq5 float64 `gorm:"type:decimal(20,6);comment:EMA5复权"`
EmaBfq10 float64 `gorm:"type:decimal(20,6);comment:EMA10复权"`
EmaBfq20 float64 `gorm:"type:decimal(20,6);comment:EMA20复权"`
MacdBfq float64 `gorm:"type:decimal(20,6);comment:MACD复权"`
MacdDifBfq float64 `gorm:"type:decimal(20,6);comment:MACD DIF复权"`
MacdDeaBfq float64 `gorm:"type:decimal(20,6);comment:MACD DEA复权"`
RsiBfq6 float64 `gorm:"type:decimal(20,6);comment:RSI6复权"`
RsiBfq12 float64 `gorm:"type:decimal(20,6);comment:RSI12复权"`
RsiBfq24 float64 `gorm:"type:decimal(20,6);comment:RSI24复权"`
KdjKBfq float64 `gorm:"type:decimal(20,6);comment:KDJ-K复权"`
KdjDBfq float64 `gorm:"type:decimal(20,6);comment:KDJ-D复权"`
KdjBfq float64 `gorm:"type:decimal(20,6);comment:KDJ-J复权"`
BollUpperBfq float64 `gorm:"type:decimal(20,6);comment:BOLL上轨复权"`
BollMidBfq float64 `gorm:"type:decimal(20,6);comment:BOLL中轨复权"`
BollLowerBfq float64 `gorm:"type:decimal(20,6);comment:BOLL下轨复权"`
MaQfq5 float64 `gorm:"type:decimal(20,6);comment:MA5复权"`
MaQfq10 float64 `gorm:"type:decimal(20,6);comment:MA10复权"`
MaQfq20 float64 `gorm:"type:decimal(20,6);comment:MA20复权"`
MaQfq60 float64 `gorm:"type:decimal(20,6);comment:MA60复权"`
EmaQfq5 float64 `gorm:"type:decimal(20,6);comment:EMA5复权"`
EmaQfq10 float64 `gorm:"type:decimal(20,6);comment:EMA10复权"`
EmaQfq20 float64 `gorm:"type:decimal(20,6);comment:EMA20复权"`
MacdQfq float64 `gorm:"type:decimal(20,6);comment:MACD复权"`
MacdDifQfq float64 `gorm:"type:decimal(20,6);comment:MACD DIF复权"`
MacdDeaQfq float64 `gorm:"type:decimal(20,6);comment:MACD DEA复权"`
RsiQfq6 float64 `gorm:"type:decimal(20,6);comment:RSI6复权"`
RsiQfq12 float64 `gorm:"type:decimal(20,6);comment:RSI12复权"`
RsiQfq24 float64 `gorm:"type:decimal(20,6);comment:RSI24复权"`
KdjKQfq float64 `gorm:"type:decimal(20,6);comment:KDJ-K复权"`
KdjDQfq float64 `gorm:"type:decimal(20,6);comment:KDJ-D复权"`
KdjQfq float64 `gorm:"type:decimal(20,6);comment:KDJ-J复权"`
BollUpperQfq float64 `gorm:"type:decimal(20,6);comment:BOLL上轨复权"`
BollMidQfq float64 `gorm:"type:decimal(20,6);comment:BOLL中轨复权"`
BollLowerQfq float64 `gorm:"type:decimal(20,6);comment:BOLL下轨复权"`
}
func (DatasetIndicatorPro) TableName() string {

View File

@@ -5,7 +5,7 @@ package schema
type DatasetMoney struct {
ID uint `gorm:"primarykey;autoIncrement"`
TsCode string `gorm:"type:varchar(20);not null;uniqueIndex:un_money_ts_date;index;comment:TS代码" json:"ts_code"`
UpdateYmd int `gorm:"index;comment:更新日期" json:"update_ymd"`
UpdateYmd int `gorm:"uniqueIndex:un_money_ts_date;index;comment:更新日期" json:"update_ymd"`
BuySmVol int64 `gorm:"comment:小单买入量(手)" json:"buy_sm_vol"`
BuySmAmount float64 `gorm:"type:decimal(20,4);comment:小单买入金额(万元)" json:"buy_sm_amount"`

View File

@@ -14,7 +14,7 @@ import (
type DatasetSummary struct {
ID uint `gorm:"primarykey"`
TsCode string `gorm:"type:varchar(20);not null;uniqueIndex:uq_dataset_summary_ts_code;index;comment:TS代码" json:"ts_code"`
UpdateYmd int `gorm:"index;comment:更新日期" json:"update_ymd"`
UpdateYmd int `gorm:"uniqueIndex:uq_dataset_summary_ts_code;index;comment:更新日期" json:"update_ymd"`
// --- DatasetBasic身份与分类 ---
Name string `gorm:"type:varchar(50);not null;default:'';comment:股票名称" json:"name"`
@@ -44,10 +44,10 @@ type DatasetSummary struct {
TotalMv float64 `gorm:"type:decimal(20,4);comment:总市值(万元)" json:"total_mv"`
CircMv float64 `gorm:"type:decimal(20,4);comment:流通市值(万元)" json:"circ_mv"`
AdjFactor float64 `gorm:"type:decimal(20,6);comment:复权因子(来自因子表)" json:"adj_factor"`
MaBfq5 float64 `gorm:"type:decimal(20,6);comment:MA5复权" json:"ma_bfq5"`
MaBfq20 float64 `gorm:"type:decimal(20,6);comment:MA20复权" json:"ma_bfq20"`
MacdDifBfq float64 `gorm:"type:decimal(20,6);comment:MACD DIF复权" json:"macd_dif_bfq"`
RsiBfq12 float64 `gorm:"type:decimal(20,6);comment:RSI12复权" json:"rsi_bfq12"`
MaQfq5 float64 `gorm:"type:decimal(20,6);comment:MA5复权" json:"ma_bfq5"`
MaQfq20 float64 `gorm:"type:decimal(20,6);comment:MA20复权" json:"ma_bfq20"`
MacdDifQfq float64 `gorm:"type:decimal(20,6);comment:MACD DIF复权" json:"macd_dif_bfq"`
RsiQfq12 float64 `gorm:"type:decimal(20,6);comment:RSI12复权" json:"rsi_bfq12"`
// --- DatasetFinaIndicator最近一期财务核心 ---
FinaPeriod int `gorm:"index;comment:财务报告期数(与 fina 表 period 一致)" json:"fina_period"`
@@ -230,10 +230,10 @@ func buildDatasetSummary(db *gorm.DB, tsCode string) (*DatasetSummary, error) {
s.TotalMv = dip.TotalMv
s.CircMv = dip.CircMv
s.AdjFactor = dip.AdjFactor
s.MaBfq5 = dip.MaBfq5
s.MaBfq20 = dip.MaBfq20
s.MacdDifBfq = dip.MacdDifBfq
s.RsiBfq12 = dip.RsiBfq12
s.MaQfq5 = dip.MaQfq5
s.MaQfq20 = dip.MaQfq20
s.MacdDifQfq = dip.MacdDifQfq
s.RsiQfq12 = dip.RsiQfq12
case hasDay:
s.Close = day.Close
s.PctChg = day.PctChg

78
tushare/cal.go Normal file
View File

@@ -0,0 +1,78 @@
package tushare
import (
"time"
"git.apinb.com/quant/qsdk/conv"
)
/*
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) LastTradeDay() 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()
if len(cal) == 0 {
return ""
}
return conv.AnyToString(cal[0]["cal_date"])
}
func (cli *TushareClient) LimitTradeDay(limit int) []string {
if limit <= 0 {
return []string{}
}
if limit > 100 {
limit = 100
}
result, err := cli.TradeCal("SSE", time.Now().AddDate(0, 0, -100).Format("20060102"), time.Now().Format("20060102"), "1")
if err != nil {
return []string{}
}
cal := result.Map()
days := []string{}
for i := 0; i < limit; i++ {
item := cal[i]
days = append(days, conv.AnyToString(item["cal_date"]))
}
return days
}

View File

@@ -55,25 +55,25 @@ func (cli *TushareClient) StkFactorPro(ts_code, trade_date, start_date, end_date
{"total_mv": "总市值(万元)"},
{"circ_mv": "流通市值(万元)"},
{"adj_factor": "复权因子"},
{"ma_bfq_5": "MA5复权"},
{"ma_bfq_10": "MA10复权"},
{"ma_bfq_20": "MA20复权"},
{"ma_bfq_60": "MA60复权"},
{"ema_bfq_5": "EMA5复权"},
{"ema_bfq_10": "EMA10复权"},
{"ema_bfq_20": "EMA20复权"},
{"macd_bfq": "MACD复权"},
{"macd_dif_bfq": "MACD DIF复权"},
{"macd_dea_bfq": "MACD DEA复权"},
{"rsi_bfq_6": "RSI6复权"},
{"rsi_bfq_12": "RSI12复权"},
{"rsi_bfq_24": "RSI24复权"},
{"kdj_k_bfq": "KDJ-K复权"},
{"kdj_d_bfq": "KDJ-D复权"},
{"kdj_bfq": "KDJ-J复权"},
{"boll_upper_bfq": "BOLL上轨复权"},
{"boll_mid_bfq": "BOLL中轨复权"},
{"boll_lower_bfq": "BOLL下轨复权"},
{"ma_qfq_5": "MA5复权"},
{"ma_qfq_10": "MA10复权"},
{"ma_qfq_20": "MA20复权"},
{"ma_qfq_60": "MA60复权"},
{"ema_qfq_5": "EMA5复权"},
{"ema_qfq_10": "EMA10复权"},
{"ema_qfq_20": "EMA20复权"},
{"macd_qfq": "MACD复权"},
{"macd_dif_qfq": "MACD DIF复权"},
{"macd_dea_qfq": "MACD DEA复权"},
{"rsi_qfq_6": "RSI6复权"},
{"rsi_qfq_12": "RSI12复权"},
{"rsi_qfq_24": "RSI24复权"},
{"kdj_k_qfq": "KDJ-K复权"},
{"kdj_d_qfq": "KDJ-D复权"},
{"kdj_qfq": "KDJ-J复权"},
{"boll_upper_qfq": "BOLL上轨复权"},
{"boll_mid_qfq": "BOLL中轨复权"},
{"boll_lower_qfq": "BOLL下轨复权"},
}
return cli.Do(req, fields)

View File

@@ -1,61 +1,5 @@
package tushare
import (
"time"
"git.apinb.com/quant/qsdk/conv"
)
/*
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()
if len(cal) == 0 {
return ""
}
return conv.AnyToString(cal[0]["cal_date"])
}
/*
StockBasic 获取股票列表