package a import ( "encoding/json" "fmt" "io" "net/http" "strings" "git.apinb.com/bsm-sdk/core/utils" "git.apinb.com/dataset/stock/internal/impl" "git.apinb.com/dataset/stock/internal/models" ) // 请求结构(根据Tushare API格式定义) type TushareReq struct { APIName string `json:"api_name"` Token string `json:"token"` Params MParams `json:"params"` Fields []string `json:"fields"` } type MParams map[string]interface{} // 响应结构 type TushareResp struct { RequestID string `json:"request_id"` Code int `json:"code"` Data struct { Fields []string `json:"fields"` Items [][]any `json:"items"` HasMore bool `json:"has_more"` Count int `json:"count"` } `json:"data"` Msg string `json:"msg"` } // 资金流数据模型 type Moneyflow struct { TsCode string `json:"ts_code"` // 股票代码 TradeDate string `json:"trade_date"` // 交易日期 BuySmAmount float64 `json:"buy_sm_amount"` // 小单买入 BuyMdAmount float64 `json:"buy_md_amount"` // 中单买入 BuyLgAmount float64 `json:"buy_lg_amount"` // 大单买入 BuyElgAmount float64 `json:"buy_elg_amount"` // 超大单买入 // 可根据需要补充净流入字段 NetMfAmount float64 `json:"net_mf_amount"` // 净流入额(万元) } func GetTushareMoneyFlow() { dates := GetTradeDateBy(3, true) allData := make(map[string][]Moneyflow) for _, date := range dates { list, _ := fetchMoneyFlowByDate(TushareToken, date) for _, mf := range list { allData[mf.TsCode] = append(allData[mf.TsCode], mf) } } for code, dailyList := range allData { if len(dailyList) < 3 { continue } // 判断资金流向是否正在正增长。 isGrenter := false if dailyList[2].NetMfAmount > dailyList[1].NetMfAmount { isGrenter = true } if dailyList[2].NetMfAmount > dailyList[1].NetMfAmount && dailyList[1].NetMfAmount > dailyList[0].NetMfAmount { // 资金连续3日流入,可能已经进入尾声 isGrenter = false } data := models.MoneyTotal{ Code: code, Last1DayMfAmount: dailyList[2].NetMfAmount, Last1DayTotalAmount: dailyList[2].BuySmAmount + dailyList[2].BuyMdAmount + dailyList[2].BuyLgAmount + dailyList[2].BuyElgAmount, IsGreaterPervious: isGrenter, } for _, item := range dailyList { data.Last3DayMfAmount += item.NetMfAmount data.Last3DayTotalAmount += item.BuySmAmount + item.BuyMdAmount + item.BuyLgAmount + item.BuyElgAmount } data.Last1DayMfAmount = utils.FloatRound(data.Last1DayMfAmount, 2) data.Last1DayTotalAmount = utils.FloatRound(data.Last1DayTotalAmount, 2) data.Last3DayMfAmount = utils.FloatRound(data.Last3DayMfAmount, 2) data.Last3DayTotalAmount = utils.FloatRound(data.Last3DayTotalAmount, 2) var cnt int64 impl.DBService.Model(&models.MoneyTotal{}).Where("code=?", code).Count(&cnt) if cnt == 0 { impl.DBService.Create(&data) } else { impl.DBService.Model(&models.MoneyTotal{}).Where("code=?", code).Updates(&data) } } } // 1. 获取指定日期所有股票的资金流向 func fetchMoneyFlowByDate(token, date string) ([]Moneyflow, error) { url := "http://api.tushare.pro" payload := TushareReq{ APIName: "moneyflow", Token: token, Params: MParams{"trade_date": date}, Fields: []string{"ts_code", "trade_date", "buy_sm_amount", "buy_md_amount", "buy_lg_amount", "buy_elg_amount", "net_mf_amount"}, } reqBytes, _ := json.Marshal(payload) resp, err := http.Post(url, "application/json", strings.NewReader(string(reqBytes))) if err != nil { return nil, fmt.Errorf("#100 %v", err) } defer resp.Body.Close() body, _ := io.ReadAll(resp.Body) var tushareResp TushareResp if err := json.Unmarshal(body, &tushareResp); err != nil { fmt.Println(string(body)) return nil, fmt.Errorf("#101 %v", err) } // 解析二维数组 var result []Moneyflow for _, item := range tushareResp.Data.Items { // 此处简化了类型转换,生产环境需严格处理err mf := Moneyflow{ TsCode: item[0].(string), TradeDate: item[1].(string), BuySmAmount: item[2].(float64), BuyMdAmount: item[3].(float64), BuyLgAmount: item[4].(float64), BuyElgAmount: item[5].(float64), NetMfAmount: item[6].(float64), } result = append(result, mf) } return result, nil }