Browse Source

feat:预测指标新增N数值移动平均计算

Roc 2 years ago
parent
commit
2609b66af3

+ 26 - 0
controllers/base_from_predict_calculate.go

@@ -594,6 +594,9 @@ func (this *PredictCalculateController) CalculateBatchSave() {
 	} else if req.Source == utils.DATA_SOURCE_PREDICT_CALCULATE_TCZ {
 		sourName = "预测同差"
 		edbInfo, latestDateStr, latestValue, err, errMsg = models.SavePredictCalculateTcz(req.EdbInfoId, req.ClassifyId, req.EdbName, req.Frequency, req.Unit, req.Formula, fromEdbInfo, edbCode, uniqueCode, adminId, adminName)
+	} else if req.Source == utils.DATA_SOURCE_PREDICT_CALCULATE_NSZYDPJJS {
+		sourName = "预测同差"
+		edbInfo, latestDateStr, latestValue, err, errMsg = models.SavePredictCalculateNszydpjjs(req.EdbInfoId, req.ClassifyId, req.EdbName, req.Frequency, req.Unit, req.Formula, fromEdbInfo, edbCode, uniqueCode, adminId, adminName)
 	} else {
 		br.Msg = "无效计算方式"
 		br.ErrMsg = "无效计算方式,source:" + strconv.Itoa(req.Source)
@@ -773,6 +776,29 @@ func (this *PredictCalculateController) Refresh() {
 			errMsg = "RefreshCalculateTcz Err:" + err.Error()
 			break
 		}
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_NSZYDPJJS: //N数值移动平均计算
+		calculateInfo, err := models.GetEdbInfoCalculateMappingDetail(edbInfoId)
+		if err != nil {
+			errMsg = "GetEdbInfoCalculateTczDetail Err:" + err.Error()
+			break
+		}
+		fromEdbInfo, err := models.GetEdbInfoById(calculateInfo.FromEdbInfoId)
+		if err != nil {
+			errMsg = "GetEdbInfoById Err:" + err.Error()
+			break
+		}
+		var formulaInt int
+		formulaInt, _ = strconv.Atoi(calculateInfo.CalculateFormula)
+		if formulaInt <= 0 {
+			errMsg = "N值输入错误,请重新输入"
+			break
+		}
+		startDate = edbInfo.StartDate
+		latestDateStr, latestValue, err = models.RefreshAllPredictCalculateNszydpjjs(edbInfoId, source, formulaInt, fromEdbInfo, calculateInfo.EdbCode, startDate)
+		if err != nil && err.Error() != utils.ErrNoRow() {
+			errMsg = "RefreshAllPredictCalculateNszydpjjs Err:" + err.Error()
+			break
+		}
 	default:
 		br.Msg = "来源异常,请联系相关开发!"
 		br.ErrMsg = "来源异常,请联系相关开发"

+ 2 - 0
models/edb_data_table.go

@@ -79,6 +79,8 @@ func GetEdbDataTableName(source int) (tableName string) {
 		tableName = "edb_data_calculate_nhcc"
 	case utils.DATA_SOURCE_COM_TRADE:
 		tableName = "edb_data_com_trade"
+	case utils.DATA_SOURCE_PREDICT_CALCULATE_NSZYDPJJS:
+		tableName = "edb_data_predict_calculate_nszydpjjs"
 	default:
 		tableName = ""
 	}

+ 276 - 0
models/predict_edb_data_calculate_nszydbpjjs.go

@@ -0,0 +1,276 @@
+package models
+
+import (
+	"errors"
+	"fmt"
+	"github.com/beego/beego/v2/client/orm"
+	"github.com/shopspring/decimal"
+	"hongze/hongze_edb_lib/utils"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// SavePredictCalculateNszydpjjs 新增/编辑 预测 N数值移动平均计算指标
+func SavePredictCalculateNszydpjjs(reqEdbInfoId, classifyId int, edbName, frequency, unit, formula string, fromEdbInfo *EdbInfo, edbCode, uniqueCode string, sysUserId int, sysUserRealName string) (edbInfo *EdbInfo, latestDateStr string, latestValue float64, err error, errMsg string) {
+	o := orm.NewOrm()
+	to, err := o.Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			fmt.Println("SavePredictCalculateNszydpjjs,Err:" + err.Error())
+			_ = to.Rollback()
+		} else {
+			_ = to.Commit()
+		}
+	}()
+
+	var formulaInt int
+	formulaInt, _ = strconv.Atoi(formula)
+	if formulaInt <= 0 {
+		err = errors.New("N值输入错误,请重新输入")
+		return
+	}
+
+	if reqEdbInfoId <= 0 {
+		edbInfo = &EdbInfo{
+			//EdbInfoId:        0,
+			EdbInfoType:   1,
+			SourceName:    "预测N数值移动平均计算",
+			Source:        utils.DATA_SOURCE_PREDICT_CALCULATE_NSZYDPJJS,
+			EdbCode:       edbCode,
+			EdbName:       edbName,
+			EdbNameSource: edbName,
+			Frequency:     frequency,
+			Unit:          unit,
+			//StartDate:        "",
+			//EndDate:          "",
+			ClassifyId:       classifyId,
+			SysUserId:        sysUserId,
+			SysUserRealName:  sysUserRealName,
+			UniqueCode:       uniqueCode,
+			CreateTime:       time.Now(),
+			ModifyTime:       time.Now(),
+			MinValue:         0,
+			MaxValue:         0,
+			CalculateFormula: formula,
+			EdbType:          2,
+			Sort:             0,
+			MoveType:         0,
+			MoveFrequency:    "",
+			NoUpdate:         0,
+			ServerUrl:        "",
+			EdbNameEn:        "",
+			UnitEn:           "",
+			LatestDate:       "",
+			LatestValue:      0,
+			ChartImage:       "",
+		}
+		newEdbInfoId, tmpErr := to.Insert(edbInfo)
+		if tmpErr != nil {
+			err = tmpErr
+			return
+		}
+		edbInfo.EdbInfoId = int(newEdbInfoId)
+
+		// 添加关联关系
+		{
+			calculateMappingItem := &EdbInfoCalculateMapping{
+				EdbInfoCalculateMappingId: 0,
+				EdbInfoId:                 edbInfo.EdbInfoId,
+				Source:                    edbInfo.Source,
+				SourceName:                edbInfo.SourceName,
+				EdbCode:                   edbCode,
+				FromEdbInfoId:             fromEdbInfo.EdbInfoId,
+				FromEdbCode:               fromEdbInfo.EdbCode,
+				FromEdbName:               fromEdbInfo.EdbName,
+				FromSource:                fromEdbInfo.Source,
+				FromSourceName:            fromEdbInfo.SourceName,
+				FromTag:                   "",
+				Sort:                      1,
+				CreateTime:                time.Now(),
+				ModifyTime:                time.Now(),
+			}
+			_, err = to.Insert(calculateMappingItem)
+			if err != nil {
+				return
+			}
+		}
+
+	} else {
+		edbInfo, err = GetEdbInfoById(reqEdbInfoId)
+		if err != nil {
+			if err.Error() == utils.ErrNoRow() {
+				errMsg = `获取指标信息失败`
+			}
+			return
+		}
+		if edbInfo.EdbInfoType != 1 {
+			errMsg = `该指标不是预测指标`
+			err = errors.New(errMsg)
+			return
+		}
+
+		// 删除该指标所有的同比数据
+		dataTableName := GetEdbDataTableName(utils.DATA_SOURCE_PREDICT_CALCULATE_NSZYDPJJS)
+		deleteSql := ` DELETE FROM %s WHERE edb_info_id=? `
+		deleteSql = fmt.Sprintf(deleteSql, dataTableName)
+		_, err = to.Raw(deleteSql, edbInfo.EdbInfoId).Exec()
+		if err != nil {
+			return
+		}
+	}
+
+	latestDateStr, latestValue, err = refreshAllPredictCalculateNszydpjjs(to, edbInfo.EdbInfoId, edbInfo.Source, formulaInt, fromEdbInfo, edbCode, "")
+
+	return
+}
+
+// RefreshAllPredictCalculateNszydpjjs 刷新所有 N数值移动平均计算指标 数据
+func RefreshAllPredictCalculateNszydpjjs(edbInfoId, source, formulaInt int, fromEdbInfo *EdbInfo, edbCode, startDate string) (latestDateStr string, latestValue float64, err error) {
+	o := orm.NewOrm()
+	to, err := o.Begin()
+	if err != nil {
+		return
+	}
+	defer func() {
+		if err != nil {
+			fmt.Println("RefreshAllPredictCalculateNszydpjjs,Err:" + err.Error())
+			_ = to.Rollback()
+		} else {
+			_ = to.Commit()
+		}
+	}()
+
+	latestDateStr, latestValue, err = refreshAllPredictCalculateNszydpjjs(to, edbInfoId, source, formulaInt, fromEdbInfo, edbCode, startDate)
+
+	return
+}
+
+// refreshAllPredictCalculateNszydpjjs 更新全部N数值移动平均计算
+func refreshAllPredictCalculateNszydpjjs(to orm.TxOrmer, edbInfoId, source, formulaInt int, fromEdbInfo *EdbInfo, edbCode, startDate string) (latestDateStr string, latestValue float64, err error) {
+	edbInfoIdStr := strconv.Itoa(edbInfoId)
+	fmt.Println(edbInfoIdStr)
+	fmt.Println("refreshAllCalculateNszydpjjs startDate:", startDate)
+
+	// 获取关联指标数据
+	existDataList, err := GetPredictEdbDataListAllByStartDate(fromEdbInfo, 0, startDate)
+	if err != nil {
+		return
+	}
+
+	latestDateStr = fromEdbInfo.LatestDate
+
+	existDataMap := make(map[string]*EdbInfoSearchData)
+	for _, v := range existDataList {
+		existDataMap[v.DataTime] = v
+	}
+
+	//计算来源数据
+	var fromCondition string
+	var fromPars []interface{}
+	fromCondition += " AND edb_info_id=? "
+	fromPars = append(fromPars, fromEdbInfo.EdbInfoId)
+	if startDate != `` {
+		fromCondition += " AND data_time>=? "
+		fromPars = append(fromPars, startDate)
+	}
+
+	//fmt.Println("fromPars:", fromPars)
+	fromDataList, err := GetEdbDataListAllV1ByTo(to, fromCondition, fromPars, fromEdbInfo.Source, 0)
+	if err != nil {
+		fmt.Println("from GetEdbDataListAll Err:" + err.Error())
+		return
+	}
+
+	var fromDateArr []string
+	fromDataMap := make(map[string]*EdbInfoSearchDataV1)
+	for _, v := range fromDataList {
+		fromDateArr = append(fromDateArr, v.DataTime)
+		fromDataMap[v.DataTime] = v
+	}
+
+	addSql := ` INSERT INTO edb_data_calculate_nszydpjjs(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	var isAdd bool
+	dataTableName := GetEdbDataTableName(source)
+	arrLen := len(fromDateArr)
+	existAddDataMap := make(map[string]string)
+	for ak, av := range fromDateArr {
+		//处理第一个值
+		var valArr []string
+		if findItem, ok := fromDataMap[av]; ok {
+			valArr = append(valArr, findItem.Value)
+		} else {
+			continue
+		}
+		if ak+1 != arrLen {
+			//处理除第一个值之外的N-1个值
+			for i := 1; i < formulaInt; i++ {
+				arrIndex := ak + i
+				if arrIndex >= arrLen {
+					break
+				}
+				arrVal := fromDateArr[arrIndex]
+				if findItem, ok := fromDataMap[arrVal]; ok {
+					valArr = append(valArr, findItem.Value)
+				} else {
+					continue
+				}
+			}
+		}
+		valArrLen := len(valArr)
+		//var totalVal float64
+		totalVal := decimal.NewFromFloat(0.00)
+		for _, v := range valArr {
+			newDecimal, _ := decimal.NewFromString(v)
+			totalVal = totalVal.Add(newDecimal)
+		}
+		af := totalVal //decimal.NewFromFloat(totalVal)
+		bf := decimal.NewFromFloat(float64(valArrLen))
+		val, _ := af.Div(bf).Float64()
+		valStr := decimal.NewFromFloat(val).RoundCeil(4).String()
+
+		// 实际数据的值
+		if fromEdbInfo.LatestDate == av {
+			latestValue = val
+		}
+
+		if existVal, existOk := existDataMap[av]; !existOk {
+			currentDate, tmpErr := time.Parse(utils.FormatDate, av)
+			if tmpErr != nil {
+				err = tmpErr
+				return
+			}
+			timestamp := currentDate.UnixNano() / 1e6
+			timestampStr := fmt.Sprintf("%d", timestamp)
+			if _, existOk := existAddDataMap[av]; !existOk {
+				addSql += GetAddSql(edbInfoIdStr, edbCode, av, timestampStr, valStr)
+				isAdd = true
+			}
+			existAddDataMap[av] = av
+		} else {
+			existValDecimal := decimal.NewFromFloat(existVal.Value)
+			existStr := existValDecimal.String()
+			fmt.Println(existStr, valStr, av)
+			if existStr != valStr {
+				sql := ` UPDATE %s SET value=?,modify_time=NOW() WHERE edb_info_id=? AND data_time=? `
+				sql = fmt.Sprintf(sql, dataTableName)
+				_, err = to.Raw(sql, valStr, edbInfoId, av).Exec()
+				if err != nil {
+					return
+				}
+			}
+		}
+	}
+	if isAdd {
+		addSql = strings.TrimRight(addSql, ",")
+		//utils.FileLog.Info("addSql:" + addSql)
+		_, err = to.Raw(addSql).Exec()
+		if err != nil {
+			return
+		}
+	}
+	return
+}

+ 2 - 2
models/predict_edb_data_calculate_tcz.go

@@ -107,7 +107,7 @@ func SavePredictCalculateTcz(reqEdbInfoId, classifyId int, edbName, frequency, u
 		}
 
 		// 删除该指标所有的同差数据
-		dataTableName := GetEdbDataTableName(utils.DATA_SOURCE_CALCULATE_TCZ)
+		dataTableName := GetEdbDataTableName(utils.DATA_SOURCE_PREDICT_CALCULATE_TCZ)
 		fmt.Println("dataTableName:", dataTableName)
 		deleteSql := ` DELETE FROM %s WHERE edb_info_id=? `
 		deleteSql = fmt.Sprintf(deleteSql, dataTableName)
@@ -136,7 +136,7 @@ func SavePredictCalculateTcz(reqEdbInfoId, classifyId int, edbName, frequency, u
 	}
 	//fmt.Println("Frequency:", fromEdbInfo.Frequency)
 
-	addSql := ` INSERT INTO edb_data_predict_calculate_tcz(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
+	addSql := ` INSERT INTO edb_data_predict_calculate_tcz (edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
 	var isAdd bool
 	existMap := make(map[string]string)
 	for _, av := range dateArr {

+ 39 - 38
utils/constants.go

@@ -29,44 +29,45 @@ const (
 
 //数据来源渠道
 const (
-	DATA_SOURCE_THS                   = iota + 1 //同花顺
-	DATA_SOURCE_WIND                             //wind
-	DATA_SOURCE_PB                               //彭博
-	DATA_SOURCE_CALCULATE                        //指标运算
-	DATA_SOURCE_CALCULATE_LJZZY                  //累计值转月
-	DATA_SOURCE_CALCULATE_TBZ                    //同比值
-	DATA_SOURCE_CALCULATE_TCZ                    //同差值
-	DATA_SOURCE_CALCULATE_NSZYDPJJS              //N数值移动平均计算
-	DATA_SOURCE_MANUAL                           //手工指标
-	DATA_SOURCE_LZ                               //隆众
-	DATA_SOURCE_YS                               //有色
-	DATA_SOURCE_CALCULATE_HBZ                    //环比值->12
-	DATA_SOURCE_CALCULATE_HCZ                    //环差值->13
-	DATA_SOURCE_CALCULATE_BP                     //变频->14
-	DATA_SOURCE_GL                               //钢联->15
-	DATA_SOURCE_ZZ                               //郑商所->16
-	DATA_SOURCE_DL                               //大商所->17
-	DATA_SOURCE_SH                               //上期所->18
-	DATA_SOURCE_CFFEX                            //中金所->19
-	DATA_SOURCE_SHFE                             //上期能源->20
-	DATA_SOURCE_GIE                              //欧洲天然气->21
-	DATA_SOURCE_CALCULATE_TIME_SHIFT             //时间移位->22
-	DATA_SOURCE_CALCULATE_ZJPJ                   //直接拼接->23
-	DATA_SOURCE_CALCULATE_LJZTBPJ                //累计值同比拼接->24
-	DATA_SOURCE_LT                               //路透->25
-	DATA_SOURCE_COAL                             //煤炭网->26
-	DATA_SOURCE_PYTHON                           //python代码->27
-	DATA_SOURCE_PB_FINANCE                       //彭博财务数据->28
-	DATA_SOURCE_GOOGLE_TRAVEL                    //谷歌出行数据->29
-	DATA_SOURCE_PREDICT                          //普通预测指标->30
-	DATA_SOURCE_PREDICT_CALCULATE                //预测指标运算->31
-	DATA_SOURCE_PREDICT_CALCULATE_TBZ            //同比值->32
-	DATA_SOURCE_PREDICT_CALCULATE_TCZ            //同差值->33
-	DATA_SOURCE_MYSTEEL_CHEMICAL                 //钢联化工->34
-	DATA_SOURCE_CALCULATE_CJJX                   //超季节性->35
-	DATA_SOURCE_EIA_STEO                         //eia steo报告->36
-	DATA_SOURCE_CALCULATE_NHCC                   //计算指标(拟合残差)->37
-	DATA_SOURCE_COM_TRADE                        //联合国商品贸易数据->38
+	DATA_SOURCE_THS                         = iota + 1 //同花顺
+	DATA_SOURCE_WIND                                   //wind
+	DATA_SOURCE_PB                                     //彭博
+	DATA_SOURCE_CALCULATE                              //指标运算
+	DATA_SOURCE_CALCULATE_LJZZY                        //累计值转月
+	DATA_SOURCE_CALCULATE_TBZ                          //同比值
+	DATA_SOURCE_CALCULATE_TCZ                          //同差值
+	DATA_SOURCE_CALCULATE_NSZYDPJJS                    //N数值移动平均计算
+	DATA_SOURCE_MANUAL                                 //手工指标
+	DATA_SOURCE_LZ                                     //隆众
+	DATA_SOURCE_YS                                     //有色
+	DATA_SOURCE_CALCULATE_HBZ                          //环比值->12
+	DATA_SOURCE_CALCULATE_HCZ                          //环差值->13
+	DATA_SOURCE_CALCULATE_BP                           //变频->14
+	DATA_SOURCE_GL                                     //钢联->15
+	DATA_SOURCE_ZZ                                     //郑商所->16
+	DATA_SOURCE_DL                                     //大商所->17
+	DATA_SOURCE_SH                                     //上期所->18
+	DATA_SOURCE_CFFEX                                  //中金所->19
+	DATA_SOURCE_SHFE                                   //上期能源->20
+	DATA_SOURCE_GIE                                    //欧洲天然气->21
+	DATA_SOURCE_CALCULATE_TIME_SHIFT                   //时间移位->22
+	DATA_SOURCE_CALCULATE_ZJPJ                         //直接拼接->23
+	DATA_SOURCE_CALCULATE_LJZTBPJ                      //累计值同比拼接->24
+	DATA_SOURCE_LT                                     //路透->25
+	DATA_SOURCE_COAL                                   //煤炭网->26
+	DATA_SOURCE_PYTHON                                 //python代码->27
+	DATA_SOURCE_PB_FINANCE                             //彭博财务数据->28
+	DATA_SOURCE_GOOGLE_TRAVEL                          //谷歌出行数据->29
+	DATA_SOURCE_PREDICT                                //普通预测指标->30
+	DATA_SOURCE_PREDICT_CALCULATE                      //预测指标运算->31
+	DATA_SOURCE_PREDICT_CALCULATE_TBZ                  //预测指标 - 同比值->32
+	DATA_SOURCE_PREDICT_CALCULATE_TCZ                  //预测指标 - 同差值->33
+	DATA_SOURCE_MYSTEEL_CHEMICAL                       //钢联化工->34
+	DATA_SOURCE_CALCULATE_CJJX                         //超季节性->35
+	DATA_SOURCE_EIA_STEO                               //eia steo报告->36
+	DATA_SOURCE_CALCULATE_NHCC                         //计算指标(拟合残差)->37
+	DATA_SOURCE_COM_TRADE                              //联合国商品贸易数据->38
+	DATA_SOURCE_PREDICT_CALCULATE_NSZYDPJJS            //预测指标 - N数值移动平均计算 -> 39
 )
 
 //基础数据初始化日期