|
@@ -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
|
|
|
}
|
|
|
}
|
|
|
|