|
@@ -2,10 +2,12 @@ package models
|
|
|
|
|
|
import (
|
|
|
"encoding/json"
|
|
|
+ "eta/eta_index_lib/models/mgo"
|
|
|
"eta/eta_index_lib/utils"
|
|
|
"fmt"
|
|
|
"github.com/beego/beego/v2/client/orm"
|
|
|
"github.com/shopspring/decimal"
|
|
|
+ "go.mongodb.org/mongo-driver/bson"
|
|
|
"reflect"
|
|
|
"sort"
|
|
|
"time"
|
|
@@ -73,14 +75,6 @@ type ThsHfRefreshBaseParams struct {
|
|
|
|
|
|
// Add
|
|
|
// @Description: 添加指标
|
|
|
-// @author: Roc
|
|
|
-// @receiver obj
|
|
|
-// @datetime 2024-04-30 17:35:14
|
|
|
-// @param params ThsHfAddBaseParams
|
|
|
-// @param businessIndexItem *BaseFromBusinessIndex
|
|
|
-// @return edbInfo *EdbInfo
|
|
|
-// @return err error
|
|
|
-// @return errMsg string
|
|
|
func (obj EdbThsHf) Add(params ThsHfAddBaseParams, baseIndex *BaseFromThsHfIndex) (edbInfo *EdbInfo, err error) {
|
|
|
o := orm.NewOrm()
|
|
|
tx, e := o.Begin()
|
|
@@ -151,6 +145,13 @@ func (obj EdbThsHf) Add(params ThsHfAddBaseParams, baseIndex *BaseFromThsHfIndex
|
|
|
}
|
|
|
|
|
|
func (obj EdbThsHf) Refresh(edbInfo *EdbInfo, edbBaseMapping *BaseFromEdbMapping, startDate string) (err error) {
|
|
|
+ if utils.UseMongo {
|
|
|
+ return obj.refreshByMongo(edbInfo, edbBaseMapping, startDate)
|
|
|
+ }
|
|
|
+ return obj.refreshByMysql(edbInfo, edbBaseMapping, startDate)
|
|
|
+}
|
|
|
+
|
|
|
+func (obj EdbThsHf) refreshByMysql(edbInfo *EdbInfo, edbBaseMapping *BaseFromEdbMapping, startDate string) (err error) {
|
|
|
if edbInfo == nil || edbBaseMapping == nil {
|
|
|
err = fmt.Errorf("指标信息/关联信息有误, EdbInfo: %v, EdbBaseMapping: %v", edbInfo, edbBaseMapping)
|
|
|
return
|
|
@@ -208,7 +209,14 @@ func (obj EdbThsHf) Refresh(edbInfo *EdbInfo, edbBaseMapping *BaseFromEdbMapping
|
|
|
err = fmt.Errorf("转换规则有误, %v", e)
|
|
|
return
|
|
|
}
|
|
|
- convertData, e := ThsHfConvertData2DayByRule(baseDataList, convertRule)
|
|
|
+ convertOriginData := make([]*ThsHfConvertOriginData, 0)
|
|
|
+ for _, v := range baseDataList {
|
|
|
+ convertOriginData = append(convertOriginData, &ThsHfConvertOriginData{
|
|
|
+ DataTime: v.DataTime,
|
|
|
+ Value: v.Value,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ convertData, e := ThsHfConvertData2DayByRule(convertOriginData, convertRule)
|
|
|
if e != nil {
|
|
|
err = fmt.Errorf("转换数据失败, %v", e)
|
|
|
return
|
|
@@ -320,8 +328,207 @@ func (obj EdbThsHf) Refresh(edbInfo *EdbInfo, edbBaseMapping *BaseFromEdbMapping
|
|
|
return
|
|
|
}
|
|
|
|
|
|
+func (obj EdbThsHf) refreshByMongo(edbInfo *EdbInfo, edbBaseMapping *BaseFromEdbMapping, startDate string) (err error) {
|
|
|
+ var realDataMaxDate, edbDataInsertConfigDate time.Time
|
|
|
+ var edbDataInsertConfig *EdbDataInsertConfig
|
|
|
+ var isFindConfigDateRealData bool //是否找到配置日期的实际数据的值
|
|
|
+ {
|
|
|
+ edbDataInsertConfig, err = GetEdbDataInsertConfigByEdbId(edbInfo.EdbInfoId)
|
|
|
+ if err != nil && err.Error() != utils.ErrNoRow() {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if edbDataInsertConfig != nil {
|
|
|
+ edbDataInsertConfigDate = edbDataInsertConfig.Date
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 查询时间为开始时间-3d
|
|
|
+ var queryDate string
|
|
|
+ if startDate != "" {
|
|
|
+ st, e := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
|
|
|
+ if e != nil {
|
|
|
+ err = fmt.Errorf("刷新开始时间有误, %v", e)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ queryDate = st.AddDate(0, 0, -3).Format(utils.FormatDate)
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取源指标数据
|
|
|
+ baseDataList, e := obj.getBaseIndexDataByMongo(edbInfo, queryDate)
|
|
|
+ if e != nil {
|
|
|
+ err = fmt.Errorf("getBaseIndexDataByMongo, err: %v", e)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // 转换数据
|
|
|
+ convertRule := new(ThsHfIndexConvert2EdbRule)
|
|
|
+ if e := json.Unmarshal([]byte(edbBaseMapping.ConvertRule), &convertRule); e != nil {
|
|
|
+ err = fmt.Errorf("转换规则有误, %v", e)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ convertOriginData := make([]*ThsHfConvertOriginData, 0)
|
|
|
+ for _, v := range baseDataList {
|
|
|
+ convertOriginData = append(convertOriginData, &ThsHfConvertOriginData{
|
|
|
+ DataTime: v.DataTime,
|
|
|
+ Value: v.Value,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ convertData, e := ThsHfConvertData2DayByRule(convertOriginData, convertRule)
|
|
|
+ if e != nil {
|
|
|
+ err = fmt.Errorf("转换数据失败, %v", e)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if len(convertData) == 0 {
|
|
|
+ utils.FileLog.Info("同花顺高频-转换无数据, EdbCode: %s", edbInfo.EdbCode)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取指标所有数据
|
|
|
+ existDataList := make([]*mgo.EdbDataThsHf, 0)
|
|
|
+ mogDataObj := new(mgo.EdbDataThsHf)
|
|
|
+ {
|
|
|
+ // 构建查询条件
|
|
|
+ queryConditions := bson.M{
|
|
|
+ "edb_code": edbInfo.EdbCode,
|
|
|
+ }
|
|
|
+
|
|
|
+ if queryDate != `` {
|
|
|
+ //获取已存在的所有数据
|
|
|
+ startDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, queryDate, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ queryConditions["data_time"] = bson.M{"$gte": startDateTime}
|
|
|
+ }
|
|
|
+ existDataList, err = mogDataObj.GetAllDataList(queryConditions, []string{"data_time"})
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println(obj.GetSourceName() + ",refresh err;getEdbDataThsHfList Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ existDataMap := make(map[string]*mgo.EdbDataThsHf)
|
|
|
+ removeDataTimeMap := make(map[string]bool) //需要移除的日期数据
|
|
|
+ for _, v := range existDataList {
|
|
|
+ tmpDate := v.DataTime.Format(utils.FormatDate)
|
|
|
+ existDataMap[tmpDate] = v
|
|
|
+ removeDataTimeMap[tmpDate] = true
|
|
|
+ }
|
|
|
+
|
|
|
+ // 待添加的数据集
|
|
|
+ addDataList := make([]interface{}, 0)
|
|
|
+ updateDataList := make([]mgo.EdbDataThsHf, 0)
|
|
|
+
|
|
|
+ insertExist := make(map[string]bool)
|
|
|
+ for k, v := range convertData {
|
|
|
+ strDate := k.Format(utils.FormatDate)
|
|
|
+
|
|
|
+ // 手动插入数据的判断
|
|
|
+ if realDataMaxDate.IsZero() || k.After(realDataMaxDate) {
|
|
|
+ realDataMaxDate = k
|
|
|
+ }
|
|
|
+ if edbDataInsertConfigDate.IsZero() || k.Equal(edbDataInsertConfigDate) {
|
|
|
+ isFindConfigDateRealData = true
|
|
|
+ }
|
|
|
+
|
|
|
+ // 入库值
|
|
|
+ saveVal := decimal.NewFromFloat(v).Round(4).String()
|
|
|
+ d, e := decimal.NewFromString(saveVal)
|
|
|
+ if e != nil {
|
|
|
+ utils.FileLog.Info(fmt.Sprintf("EdbDataThsHf NewFromString err: %v", e))
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ saveFloat, _ := d.Float64()
|
|
|
+
|
|
|
+ // 更新
|
|
|
+ exists := existDataMap[strDate]
|
|
|
+ if exists != nil {
|
|
|
+ existVal := decimal.NewFromFloat(exists.Value).Round(4).String()
|
|
|
+ if saveVal != existVal {
|
|
|
+ exists.Value = saveFloat
|
|
|
+ updateDataList = append(updateDataList, *exists)
|
|
|
+ }
|
|
|
+ continue
|
|
|
+ }
|
|
|
+
|
|
|
+ // 新增
|
|
|
+ if insertExist[strDate] {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ insertExist[strDate] = true
|
|
|
+
|
|
|
+ timestamp := k.UnixNano() / 1e6
|
|
|
+ addDataList = append(addDataList, &EdbDataThsHf{
|
|
|
+ EdbInfoId: edbInfo.EdbInfoId,
|
|
|
+ EdbCode: edbInfo.EdbCode,
|
|
|
+ DataTime: k,
|
|
|
+ Value: saveFloat,
|
|
|
+ CreateTime: time.Now(),
|
|
|
+ ModifyTime: time.Now(),
|
|
|
+ DataTimestamp: timestamp,
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ // 入库
|
|
|
+ {
|
|
|
+ coll := mogDataObj.GetCollection()
|
|
|
+
|
|
|
+ //删除已经不存在的指标数据(由于该指标当日的数据删除了)
|
|
|
+ {
|
|
|
+ removeDateList := make([]time.Time, 0)
|
|
|
+ for dateTime := range removeDataTimeMap {
|
|
|
+ //获取已存在的所有数据
|
|
|
+ tmpDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, dateTime, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ removeDateList = append(removeDateList, tmpDateTime)
|
|
|
+ }
|
|
|
+ removeNum := len(removeDateList)
|
|
|
+ if removeNum > 0 {
|
|
|
+ err = mogDataObj.RemoveManyByColl(coll, bson.M{"edb_code": edbInfo.EdbCode, "data_time": bson.M{"$in": removeDateList}})
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("mogDataObj.RemoveMany() Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 插入新数据
|
|
|
+ if len(addDataList) > 0 {
|
|
|
+ err = mogDataObj.BatchInsertDataByColl(coll, 500, addDataList)
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("mogDataObj.BatchInsertData() Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 修改历史数据
|
|
|
+ if len(updateDataList) > 0 {
|
|
|
+ for _, v := range updateDataList {
|
|
|
+ err = mogDataObj.UpdateDataByColl(coll, bson.M{"_id": v.ID}, bson.M{"$set": bson.M{"value": v.Value, "modify_time": v.ModifyTime}})
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("mogDataObj.UpdateDataByColl:Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 处理手工数据补充的配置
|
|
|
+ obj.HandleConfigInsertEdbDataByMongo(realDataMaxDate, edbDataInsertConfig, edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, existDataMap, isFindConfigDateRealData)
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+type ThsHfConvertOriginData struct {
|
|
|
+ DataTime time.Time `description:"数据日期(至时分秒)"`
|
|
|
+ Value float64 `description:"数据值"`
|
|
|
+}
|
|
|
+
|
|
|
// ThsHfConvertData2DayByRule 原指标数据转换为日度数据
|
|
|
-func ThsHfConvertData2DayByRule(originData []*BaseFromThsHfData, convertRule *ThsHfIndexConvert2EdbRule) (timeData map[time.Time]float64, err error) {
|
|
|
+func ThsHfConvertData2DayByRule(originData []*ThsHfConvertOriginData, convertRule *ThsHfIndexConvert2EdbRule) (timeData map[time.Time]float64, err error) {
|
|
|
// PS: originData为期望开始日期前三日(有两天非交易日, 那么周一的前日应当算上周五的)至结束日期的数据
|
|
|
timeData = make(map[time.Time]float64)
|
|
|
if len(originData) == 0 || convertRule == nil {
|
|
@@ -334,19 +541,19 @@ func ThsHfConvertData2DayByRule(originData []*BaseFromThsHfData, convertRule *Th
|
|
|
|
|
|
// 升序排序
|
|
|
sort.Slice(originData, func(i, j int) bool {
|
|
|
- return originData[i].DataTimestamp < originData[j].DataTimestamp
|
|
|
+ return originData[i].DataTime.Before(originData[j].DataTime)
|
|
|
})
|
|
|
|
|
|
// 将数据根据日期进行分组
|
|
|
var sortDates []string
|
|
|
- groupDateData := make(map[string][]*BaseFromThsHfData)
|
|
|
+ groupDateData := make(map[string][]*ThsHfConvertOriginData)
|
|
|
for _, v := range originData {
|
|
|
d := v.DataTime.Format(utils.FormatDate)
|
|
|
if !utils.InArrayByStr(sortDates, d) {
|
|
|
sortDates = append(sortDates, d)
|
|
|
}
|
|
|
if groupDateData[d] == nil {
|
|
|
- groupDateData[d] = make([]*BaseFromThsHfData, 0)
|
|
|
+ groupDateData[d] = make([]*ThsHfConvertOriginData, 0)
|
|
|
}
|
|
|
groupDateData[d] = append(groupDateData[d], v)
|
|
|
}
|
|
@@ -360,7 +567,7 @@ func ThsHfConvertData2DayByRule(originData []*BaseFromThsHfData, convertRule *Th
|
|
|
continue
|
|
|
}
|
|
|
var timeTarget time.Time
|
|
|
- dateData := make([]*BaseFromThsHfData, 0)
|
|
|
+ dateData := make([]*ThsHfConvertOriginData, 0)
|
|
|
|
|
|
// 当日
|
|
|
if convertRule.ConvertFixed.FixedDay == 1 {
|
|
@@ -413,7 +620,7 @@ func ThsHfConvertData2DayByRule(originData []*BaseFromThsHfData, convertRule *Th
|
|
|
}
|
|
|
|
|
|
// 重新获取数据序列中, 时间在目标时间点之后的
|
|
|
- newDateData := make([]*BaseFromThsHfData, 0)
|
|
|
+ newDateData := make([]*ThsHfConvertOriginData, 0)
|
|
|
for kv, dv := range dateData {
|
|
|
if dv.DataTime.Before(timeTarget) {
|
|
|
continue
|
|
@@ -496,7 +703,7 @@ func ThsHfConvertData2DayByRule(originData []*BaseFromThsHfData, convertRule *Th
|
|
|
}
|
|
|
|
|
|
// 合并前日当日数据
|
|
|
- dateData := make([]*BaseFromThsHfData, 0)
|
|
|
+ dateData := make([]*ThsHfConvertOriginData, 0)
|
|
|
if convertRule.ConvertArea.StartDay == 1 && convertRule.ConvertArea.EndDay == 1 {
|
|
|
// 起始截止均为当日
|
|
|
dateData = groupDateData[thisDate]
|
|
@@ -540,7 +747,7 @@ func ThsHfConvertData2DayByRule(originData []*BaseFromThsHfData, convertRule *Th
|
|
|
}
|
|
|
|
|
|
// 重组时间区间内的数据
|
|
|
- newDateData := make([]*BaseFromThsHfData, 0)
|
|
|
+ newDateData := make([]*ThsHfConvertOriginData, 0)
|
|
|
for _, dv := range dateData {
|
|
|
if dv.DataTime.Before(startTimeTarget) || dv.DataTime.After(endTimeTarget) {
|
|
|
continue
|
|
@@ -579,3 +786,73 @@ func ThsHfConvertData2DayByRule(originData []*BaseFromThsHfData, convertRule *Th
|
|
|
}
|
|
|
return
|
|
|
}
|
|
|
+
|
|
|
+func (obj EdbThsHf) getBaseIndexDataByMongo(edbInfo *EdbInfo, startDate string) (newDataList []EdbInfoMgoData, err error) {
|
|
|
+ newDataList = make([]EdbInfoMgoData, 0)
|
|
|
+
|
|
|
+ // 获取数据源的指标数据
|
|
|
+ mogDataObj := new(mgo.BaseFromThsHfData)
|
|
|
+
|
|
|
+ // 构建查询条件
|
|
|
+ queryConditions := bson.M{
|
|
|
+ "index_code": edbInfo.EdbCode,
|
|
|
+ }
|
|
|
+
|
|
|
+ if startDate != `` {
|
|
|
+ //获取已存在的所有数据
|
|
|
+ startDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
|
|
|
+ if tmpErr != nil {
|
|
|
+ err = tmpErr
|
|
|
+ return
|
|
|
+ }
|
|
|
+ queryConditions["data_time"] = bson.M{"$gte": startDateTime}
|
|
|
+ }
|
|
|
+
|
|
|
+ baseDataList, err := mogDataObj.GetAllDataList(queryConditions, []string{"data_time"})
|
|
|
+ if err != nil {
|
|
|
+ fmt.Println("GetAllDataList Err:" + err.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ for _, v := range baseDataList {
|
|
|
+ newDataList = append(newDataList, EdbInfoMgoData{
|
|
|
+ //EdbDataId: v.ID,
|
|
|
+ DataTime: v.DataTime,
|
|
|
+ Value: v.Value,
|
|
|
+ EdbCode: v.IndexCode,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|
|
|
+
|
|
|
+func (obj EdbThsHf) HandleConfigInsertEdbDataByMongo(realDataMaxDate time.Time, edbDataInsertConfig *EdbDataInsertConfig, edbInfoId, source, subSource int, existMap map[string]*mgo.EdbDataThsHf, isFindConfigDateRealData bool) {
|
|
|
+ if edbDataInsertConfig == nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ var err error
|
|
|
+ defer func() {
|
|
|
+ if err != nil {
|
|
|
+ utils.FileLog.Info(fmt.Sprintf("ThsHf-HandleConfigInsertEdbDataByMongo, err: %v", err))
|
|
|
+ }
|
|
|
+ }()
|
|
|
+
|
|
|
+ edbDataInsertConfigDate := edbDataInsertConfig.Date // 配置的日期
|
|
|
+
|
|
|
+ // 如果存在真实数据的最大日期 && 存在配置插入数据的最大日期 && 真实数据的最大日期 晚于/等于 配置插入数据的最大日期
|
|
|
+ if realDataMaxDate.After(edbDataInsertConfigDate) || realDataMaxDate.Equal(edbDataInsertConfigDate) {
|
|
|
+ go DeleteEdbDataInsertConfigByEdbId(edbInfoId)
|
|
|
+
|
|
|
+ mogDataObj := mgo.EdbDataThsHf{}
|
|
|
+ coll := mogDataObj.GetCollection()
|
|
|
+ edbDataInsertConfigDateStr := edbDataInsertConfigDate.Format(utils.FormatDate)
|
|
|
+ // 如果没有找到找到配置日期的实际数据,那么就直接删除
|
|
|
+ if item, ok := existMap[edbDataInsertConfigDateStr]; ok && !isFindConfigDateRealData {
|
|
|
+ mogDataObj.RemoveManyByColl(coll, bson.M{"_id": item.ID})
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ o := orm.NewOrm()
|
|
|
+ edbDataInsertConfig.RealDate = realDataMaxDate
|
|
|
+ _, err = o.Update(edbDataInsertConfig, "RealDate")
|
|
|
+ }
|
|
|
+ return
|
|
|
+}
|