|
@@ -8,6 +8,7 @@ import (
|
|
"github.com/nosixtools/solarlunar"
|
|
"github.com/nosixtools/solarlunar"
|
|
"github.com/shopspring/decimal"
|
|
"github.com/shopspring/decimal"
|
|
"math"
|
|
"math"
|
|
|
|
+ "strconv"
|
|
"strings"
|
|
"strings"
|
|
"time"
|
|
"time"
|
|
)
|
|
)
|
|
@@ -1849,3 +1850,129 @@ func getYearListBySeasonConf(configValue string) (yearList []int, seasonConf Sea
|
|
|
|
|
|
return
|
|
return
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+// GetChartPredictEdbInfoDataListByRuleDynamicYOYComparisonOrDifference 动态同比
|
|
|
|
+// 2、指标选择范围为预测指标。
|
|
|
|
+// 3、动态同比计算方法:预测值=去年同期值*(1+同比指标预测值)
|
|
|
|
+// 4、上述“去年同期”如果没有严格对应的日期,则前后查找最近35天的值。
|
|
|
|
+// 5、选择的同比指标日期需要与预测指标未来日期对应上,对应不上的不生成预测值。
|
|
|
|
+func GetChartPredictEdbInfoDataListByRuleDynamicYOYComparisonOrDifference(ruleType, edbInfoId int, configValue string, dayList []time.Time, realPredictEdbInfoData []*EdbInfoSearchData, existMap map[string]float64) (newPredictEdbInfoData []*EdbInfoSearchData, minValue, maxValue float64, err error) {
|
|
|
|
+ //预测指标的去年同期数据
|
|
|
|
+ baseDynamicDataList := make(map[string]decimal.Decimal, len(dayList))
|
|
|
|
+ //动态同比同差指标
|
|
|
|
+ DynamicCalculateDataList := make(map[string]decimal.Decimal, len(dayList))
|
|
|
|
+ index := len(realPredictEdbInfoData)
|
|
|
|
+ if index <= 0 {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ dynamicYOYComparisonIndexId, err := strconv.Atoi(configValue)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ newPredictEdbInfoData = make([]*EdbInfoSearchData, 0, len(dayList))
|
|
|
|
+ // 获取同比预测指标的预测数据
|
|
|
|
+ dynamicYOYComparisonIndex, err := GetEdbInfoById(dynamicYOYComparisonIndexId)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ if dynamicYOYComparisonIndex.EdbInfoType != 1 {
|
|
|
|
+ err = errors.New("选择的指标不是预测指标")
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ startDate, endDate := dayList[0].Format(utils.FormatDate), dayList[len(dayList)-1].Format(utils.FormatDate)
|
|
|
|
+ //获取动态同比指标对应预测日期的预测数据
|
|
|
|
+ dynamicYOYComparisonIndexDataList, err := GetEdbDataList(dynamicYOYComparisonIndex.Source, dynamicYOYComparisonIndex.SubSource, dynamicYOYComparisonIndex.EdbInfoId, startDate, endDate)
|
|
|
|
+ if err != nil {
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ if len(dynamicYOYComparisonIndexDataList) <= 0 {
|
|
|
|
+ return
|
|
|
|
+ } else {
|
|
|
|
+ for _, v := range dynamicYOYComparisonIndexDataList {
|
|
|
|
+ DynamicCalculateDataList[v.DataTime] = decimal.NewFromFloat(v.Value)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ var predictDayList []time.Time
|
|
|
|
+ //获取上一期的同期数据
|
|
|
|
+ for _, date := range dayList {
|
|
|
|
+ preDate := date.AddDate(-1, 0, 0)
|
|
|
|
+ preDateStr := preDate.Format(utils.FormatDate)
|
|
|
|
+ if preValue, ok := existMap[preDateStr]; ok { //上一年同期找到
|
|
|
|
+ baseDynamicDataList[preDateStr] = decimal.NewFromFloat(preValue)
|
|
|
|
+ predictDayList = append(predictDayList, date)
|
|
|
|
+ } else {
|
|
|
|
+ if replaceValue, replaceOk := getReplaceValue(existMap, 35, 1, -1, preDate); !replaceOk {
|
|
|
|
+ continue
|
|
|
|
+ } else {
|
|
|
|
+ baseDynamicDataList[preDateStr] = replaceValue
|
|
|
|
+ predictDayList = append(predictDayList, date)
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ //获取后面的预测数据
|
|
|
|
+
|
|
|
|
+ for k, currentDate := range predictDayList {
|
|
|
|
+ var calculateValue decimal.Decimal
|
|
|
|
+ var dateStr = currentDate.Format(utils.FormatDate)
|
|
|
|
+ preDate := currentDate.AddDate(-1, 0, 0)
|
|
|
|
+ preDateStr := preDate.Format(utils.FormatDate)
|
|
|
|
+ _, dynamicVal := DynamicCalculateDataList[dateStr]
|
|
|
|
+ _, baseVal := baseDynamicDataList[preDateStr]
|
|
|
|
+ if dynamicVal && baseVal {
|
|
|
|
+ switch ruleType {
|
|
|
|
+ case 17:
|
|
|
|
+ calculateValue = baseDynamicDataList[preDateStr].Mul(DynamicCalculateDataList[dateStr].Add(decimal.NewFromInt(1)))
|
|
|
|
+ case 18:
|
|
|
|
+ calculateValue = baseDynamicDataList[preDateStr].Add(DynamicCalculateDataList[dateStr])
|
|
|
|
+ default:
|
|
|
|
+ err = errors.New("计算规则不存在")
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ tmpData := &EdbInfoSearchData{
|
|
|
|
+ EdbDataId: edbInfoId + 100000 + index + k,
|
|
|
|
+ EdbInfoId: edbInfoId,
|
|
|
|
+ DataTime: currentDate.Format(utils.FormatDate),
|
|
|
|
+ DataTimestamp: currentDate.UnixNano() / 1e6,
|
|
|
|
+ }
|
|
|
|
+ var val = calculateValue.InexactFloat64()
|
|
|
|
+ tmpData.Value = val
|
|
|
|
+ newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
|
|
|
|
+ existMap[tmpData.DataTime] = val
|
|
|
|
+ if k == 0 {
|
|
|
|
+ minValue = val
|
|
|
|
+ maxValue = val
|
|
|
|
+ } else {
|
|
|
|
+ // 最大最小值
|
|
|
|
+ if val < minValue {
|
|
|
|
+ minValue = val
|
|
|
|
+ }
|
|
|
|
+ if val > maxValue {
|
|
|
|
+ maxValue = val
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return
|
|
|
|
+}
|
|
|
|
+func getReplaceValue(replaceValueMap map[string]float64, days, dayStepForward int, dayStepBack int, currentDate time.Time) (replaceValue decimal.Decimal, success bool) {
|
|
|
|
+ nextDateDay := currentDate
|
|
|
|
+ backDateDay := currentDate
|
|
|
|
+ for i := 0; i <= days; i++ {
|
|
|
|
+ nextDateDayStr := nextDateDay.Format(utils.FormatDate)
|
|
|
|
+ if preValue, ok := replaceValueMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
|
|
|
|
+ replaceValue = decimal.NewFromFloat(preValue)
|
|
|
|
+ success = true
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ backDateDayStr := backDateDay.Format(utils.FormatDate)
|
|
|
|
+ if backValue, ok := replaceValueMap[backDateDayStr]; ok { //上一年同期->下一个月找到
|
|
|
|
+ replaceValue = decimal.NewFromFloat(backValue)
|
|
|
|
+ success = true
|
|
|
|
+ return
|
|
|
|
+ }
|
|
|
|
+ nextDateDay = nextDateDay.AddDate(0, 0, dayStepForward)
|
|
|
|
+ backDateDay = nextDateDay.AddDate(0, 0, dayStepBack)
|
|
|
|
+ }
|
|
|
|
+ return decimal.NewFromInt(0), false
|
|
|
|
+}
|