浏览代码

Merge branch 'feature/eta2.1.2_predit_edb' into debug

xyxie 6 月之前
父节点
当前提交
020a590a15
共有 1 个文件被更改,包括 126 次插入91 次删除
  1. 126 91
      models/predict_edb_info_rule.go

+ 126 - 91
models/predict_edb_info_rule.go

@@ -1650,110 +1650,145 @@ func GetChartPredictEdbInfoDataListByRuleAnnualValueInversion(edbInfoId int, con
 	}
 	// 每年截止到当前日期的累计值
 	dateTotalMap := make(map[time.Time]float64)
+
+	//把每一期的期数和日期绑定
+	dateIndexMap := make(map[time.Time]int)
+	indexDateMap := make(map[int]time.Time)
 	// 每年的累计值(计算使用)
 	yearTotalMap := make(map[int]float64)
-	for _, v := range allDataList {
-		currTime, tmpErr := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
-		if tmpErr != nil {
-			err = tmpErr
-			return
-		}
-		yearVal := yearTotalMap[currTime.Year()]
-		yearVal = yearVal + v.Value
-		yearTotalMap[currTime.Year()] = yearVal
-		dateTotalMap[currTime] = yearVal
-	}
-
+	//数据按找后值填充的方式处理成连续自然日日度数据
+	allDataListMap := make(map[string]float64)
 	// todo 如果是日度和周度,用后置填充变频成连续自然日日度数据。计算1/1至指标最新日期(2024/3/3/1)的累计值
-	//(同比增速=余额/同比年份相应日期的余额,预测值等于同比年份同期值*同比增速);
-	for k, currentDate := range dayList {
-		currYearBalance := yearValueConfig - yearTotalMap[currentDate.Year()] // 当年的余额
-
-		// 上一期的日期
-		prevDateStr := allDataList[len(allDataList)-1].DataTime
-		prevDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, prevDateStr, time.Local)
-		if tmpErr != nil {
-			err = tmpErr
-			return
+	switch frequency {
+	case "日度", "周度":
+		for _, v := range allDataList {
+			allDataListMap[v.DataTime] = v.Value
+		}
+		//找到最早日期的的年份的1月1日,转成time格式
+		earliestYear := allDataList[0].DataTime[:4]
+		earliestYearFirstDay, _ := time.ParseInLocation(utils.FormatDate, earliestYear+"-01-01", time.Local)
+		days := int(currDayTime.Sub(earliestYearFirstDay).Hours() / float64(24))
+		//循环累加日期,直到循环到最新日期
+		for i := 0; i <= days; i++ {
+			currentDate := earliestYearFirstDay.AddDate(0, 0, i)
+			currentDateStr := currentDate.Format(utils.FormatDate)
+			val, ok := allDataListMap[currentDateStr]
+			if !ok { //如果不存在,则填充后值
+				//循环向后查找数据,直到找到
+				for j := i + 1; j <= days; j++ {
+					//循环往后取值
+					currentDateTmp := earliestYearFirstDay.AddDate(0, 0, j)
+					currentDateTmpStr := currentDateTmp.Format(utils.FormatDate)
+					if tmpVal, ok1 := allDataListMap[currentDateTmpStr]; ok1 {
+						allDataListMap[currentDateStr] = tmpVal
+						val = tmpVal
+						break
+					}
+				}
+			}
+			//计算每一天的年初至今累计值
+			yearVal := yearTotalMap[currentDate.Year()]
+			yearVal = yearVal + val
+			yearTotalMap[currentDate.Year()] = yearVal
+			dateTotalMap[currentDate] = yearVal
+			dateIndexMap[currentDate] = i
+			indexDateMap[i] = currentDate
 		}
-
-		//同比年份相应日期
-		lastYear := annualValueInversionConf.Year + (currentDate.Year() - currDayTime.Year())
-
-		// 前N年的上一期时间;前N年的当期时间;
-		var lastPrevDateTime, lastDateTime time.Time
-
-		switch frequency {
-		case "半年度", "季度":
-			lastDateTime = time.Date(lastYear, currentDate.Month(), currentDate.Day(), 0, 0, 0, 0, currentDate.Location())
-			lastPrevDateTime = time.Date(lastYear, prevDateTime.Month(), prevDateTime.Day(), 0, 0, 0, 0, prevDateTime.Location())
-		case "月度":
-			lastDateTime = time.Date(lastYear, currentDate.Month()+1, 1, 0, 0, 0, 0, currentDate.Location()).AddDate(0, 0, -1)
-			lastPrevDateTime = time.Date(lastYear, prevDateTime.Month()+1, 1, 0, 0, 0, 0, prevDateTime.Location()).AddDate(0, 0, -1)
-		case "旬度":
-			if prevDateTime.Day() == 10 || prevDateTime.Day() == 20 {
-				lastDateTime = time.Date(lastYear, currentDate.Month(), currentDate.Day(), 0, 0, 0, 0, currentDate.Location())
-				lastPrevDateTime = time.Date(lastYear, prevDateTime.Month(), prevDateTime.Day(), 0, 0, 0, 0, prevDateTime.Location())
-			} else {
-				lastDateTime = time.Date(lastYear, currentDate.Month()+1, 1, 0, 0, 0, 0, currentDate.Location()).AddDate(0, 0, -1)
-				lastPrevDateTime = time.Date(lastYear, prevDateTime.Month()+1, 1, 0, 0, 0, 0, prevDateTime.Location()).AddDate(0, 0, -1)
+	default:
+		for k, v := range allDataList {
+			currTime, tmpErr := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
+			if tmpErr != nil {
+				err = tmpErr
+				return
 			}
-		case "周度", "日度":
-			lastDateTime = time.Date(lastYear, currentDate.Month(), currentDate.Day(), 0, 0, 0, 0, currentDate.Location())
-			lastPrevDateTime = time.Date(lastYear, prevDateTime.Month(), prevDateTime.Day(), 0, 0, 0, 0, prevDateTime.Location())
+			allDataListMap[v.DataTime] = v.Value
+			yearVal := yearTotalMap[currTime.Year()]
+			yearVal = yearVal + v.Value
+			yearTotalMap[currTime.Year()] = yearVal
+			dateTotalMap[currTime] = yearVal
+			dateIndexMap[currTime] = k
+			indexDateMap[k] = currTime
 		}
-
-		// 同比年份相应日期的累计值
-		var dateTotal float64
-
-		dateTotal, ok := dateTotalMap[lastPrevDateTime]
-		if !ok { //如果没有找到这个日期,那么就往前面找,一直到找到这个累计值,或者找完这一年
-			yearFirstDayTime := time.Date(lastPrevDateTime.Year(), 1, 1, 0, 0, 0, 0, lastDateTime.Location())
-			for tmpDateTime := lastPrevDateTime.AddDate(0, 0, -1); tmpDateTime.After(yearFirstDayTime) || tmpDateTime.Equal(yearFirstDayTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
-				dateTotal, ok = dateTotalMap[tmpDateTime]
-				if ok {
-					break
+	}
+	// 当年的余额
+	currYearBalance := yearValueConfig - yearTotalMap[currDayTime.Year()]
+	// 循环统计同比年份同期余额
+	var sum, avg float64
+	for _, year := range yearList {
+		yearTotal := yearTotalMap[year]
+		tmpDate := time.Date(year, currDayTime.Month(), currDayTime.Day(), 0, 0, 0, 0, currDayTime.Location())
+		dateTotal, ok := dateTotalMap[tmpDate]
+		if ok {
+			sum = sum + (yearTotal - dateTotal)
+		} else {
+			// 查找下一期的余额
+			tmpIndex, ok1 := dateIndexMap[tmpDate]
+			if ok1 {
+				for tmpDateTime := indexDateMap[tmpIndex+1]; tmpDateTime.Year() == year; tmpDateTime = indexDateMap[tmpIndex+1] {
+					dateTotal, ok = dateTotalMap[tmpDateTime]
+					if ok {
+						sum = sum + (yearTotal - dateTotal)
+						break
+					}
+					tmpIndex += 1
 				}
 			}
 		}
-
-		//同比年份相应的上一期日期的余额
-		lastYearDateBalance := yearTotalMap[lastPrevDateTime.Year()] - dateTotal
-		if lastYearDateBalance == 0 {
-			continue
+	}
+	avg = sum / float64(len(yearList))
+	// 同比增速=当年余额/同比年份上一期日期的余额
+	tbVal := decimal.NewFromFloat(currYearBalance).Div(decimal.NewFromFloat(avg))
+	//(同比增速=余额/同比年份相应日期的余额的平均值,预测值等于同比年份同期值*同比增速);
+	for k, currentDate := range dayList {
+		// 循环遍历多个同比年份
+		var valSum float64
+		for _, year := range yearList {
+			//多个同比年份的同期值的平均值
+			tmpCurrentDate := time.Date(year, currentDate.Month(), currentDate.Day(), 0, 0, 0, 0, currentDate.Location())
+			if tmpVal, ok := allDataListMap[tmpCurrentDate.Format(utils.FormatDate)]; ok {
+				valSum += tmpVal
+			} else {
+				// 查找下一期的余额
+				tmpIndex, ok1 := dateIndexMap[tmpCurrentDate]
+				if ok1 {
+					for tmpDateTime := indexDateMap[tmpIndex+1]; tmpDateTime.Year() == year; tmpDateTime = indexDateMap[tmpIndex+1] {
+						tmpVal, ok = allDataListMap[tmpDateTime.Format(utils.FormatDate)]
+						if ok {
+							valSum += tmpVal
+							break
+						}
+						tmpIndex += 1
+					}
+				}
+			}
 		}
+		lastDateVal := valSum / float64(len(yearList))
 
-		// 同比增速=当年余额/同比年份上一期日期的余额
-		tbVal := decimal.NewFromFloat(currYearBalance).Div(decimal.NewFromFloat(lastYearDateBalance))
-
-		// 获取同比年份同期值,获取失败的话,就不处理
-		if lastDateVal, ok := existMap[lastDateTime.Format(utils.FormatDate)]; ok {
-			//预测值 = 同比年份同期值*同比增速
-			tmpVal, _ := decimal.NewFromFloat(lastDateVal).Mul(tbVal).Round(4).Float64()
-			currentDateStr := currentDate.Format(utils.FormatDate)
-			tmpData := &EdbInfoSearchData{
-				EdbDataId: edbInfoId + 100000 + index + k,
-				//EdbInfoId:     edbInfoId,
-				DataTime: currentDateStr,
-				Value:    tmpVal,
-				//DataTimestamp: currentDate.UnixNano() / 1e6,
-			}
-			newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
-			allDataList = append(allDataList, tmpData)
-			existMap[currentDateStr] = tmpVal
+		//预测值 = 同比年份同期值*同比增速
+		tmpVal, _ := decimal.NewFromFloat(lastDateVal).Mul(tbVal).Round(4).Float64()
+		currentDateStr := currentDate.Format(utils.FormatDate)
+		tmpData := &EdbInfoSearchData{
+			EdbDataId: edbInfoId + 100000 + index + k,
+			//EdbInfoId:     edbInfoId,
+			DataTime: currentDateStr,
+			Value:    tmpVal,
+			//DataTimestamp: currentDate.UnixNano() / 1e6,
+		}
+		newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
+		allDataList = append(allDataList, tmpData)
+		existMap[currentDateStr] = tmpVal
 
-			yearVal := yearTotalMap[currentDate.Year()]
-			yearVal = yearVal + tmpVal
-			yearTotalMap[currentDate.Year()] = yearVal
-			dateTotalMap[currentDate] = yearVal
+		yearVal := yearTotalMap[currentDate.Year()]
+		yearVal = yearVal + tmpVal
+		yearTotalMap[currentDate.Year()] = yearVal
+		dateTotalMap[currentDate] = yearVal
 
-			// 最大最小值
-			if tmpVal < minValue {
-				minValue = tmpVal
-			}
-			if tmpVal > maxValue {
-				maxValue = tmpVal
-			}
+		// 最大最小值
+		if tmpVal < minValue {
+			minValue = tmpVal
+		}
+		if tmpVal > maxValue {
+			maxValue = tmpVal
 		}
 	}