|
@@ -1,13 +1,10 @@
|
|
|
package correlation
|
|
|
|
|
|
import (
|
|
|
- "encoding/json"
|
|
|
"errors"
|
|
|
"fmt"
|
|
|
"github.com/shopspring/decimal"
|
|
|
"hongze/hongze_chart_lib/models"
|
|
|
- "hongze/hongze_chart_lib/models/data_manage"
|
|
|
- "hongze/hongze_chart_lib/services/alarm_msg"
|
|
|
"hongze/hongze_chart_lib/services/data"
|
|
|
"hongze/hongze_chart_lib/utils"
|
|
|
"math"
|
|
@@ -205,38 +202,85 @@ func GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB *models.ChartEdbInfo
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // 2023-03-02 时间序列始终以指标B为基准, 始终是A进行平移
|
|
|
- baseEdbInfo := edbInfoMappingB
|
|
|
- changeEdbInfo := edbInfoMappingA
|
|
|
+ //// 2023-03-02 时间序列始终以指标B为基准, 始终是A进行平移
|
|
|
+ //baseEdbInfo := edbInfoMappingB
|
|
|
+ //changeEdbInfo := edbInfoMappingA
|
|
|
+ // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
|
|
|
+ baseEdbInfo := edbInfoMappingA
|
|
|
+ changeEdbInfo := edbInfoMappingB
|
|
|
|
|
|
// 获取时间基准指标在时间区间内的值
|
|
|
- baseDataList := make([]*models.EdbDataList, 0)
|
|
|
+ aDataList := make([]*models.EdbDataList, 0)
|
|
|
switch baseEdbInfo.EdbInfoCategoryType {
|
|
|
case 0:
|
|
|
- baseDataList, err = models.GetEdbDataList(baseEdbInfo.Source, baseEdbInfo.EdbInfoId, startDate, endDate)
|
|
|
+ aDataList, err = models.GetEdbDataList(baseEdbInfo.Source, baseEdbInfo.EdbInfoId, startDate, endDate)
|
|
|
case 1:
|
|
|
- _, baseDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(baseEdbInfo.EdbInfoId, startDate, endDate, false)
|
|
|
+ _, aDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(baseEdbInfo.EdbInfoId, startDate, endDate, false)
|
|
|
default:
|
|
|
err = errors.New("指标base类型异常")
|
|
|
return
|
|
|
}
|
|
|
|
|
|
// 获取变频指标所有日期的值, 插值法完善数据
|
|
|
- changeDataList := make([]*models.EdbDataList, 0)
|
|
|
+ bDataList := make([]*models.EdbDataList, 0)
|
|
|
switch changeEdbInfo.EdbInfoCategoryType {
|
|
|
case 0:
|
|
|
- changeDataList, err = models.GetEdbDataList(changeEdbInfo.Source, changeEdbInfo.EdbInfoId, "", "")
|
|
|
+ bDataList, err = models.GetEdbDataList(changeEdbInfo.Source, changeEdbInfo.EdbInfoId, "", "")
|
|
|
case 1:
|
|
|
- _, changeDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(changeEdbInfo.EdbInfoId, "", "", false)
|
|
|
+ _, bDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(changeEdbInfo.EdbInfoId, "", "", false)
|
|
|
default:
|
|
|
err = errors.New("指标change类型异常")
|
|
|
return
|
|
|
}
|
|
|
+ //changeDataMap := make(map[string]float64)
|
|
|
+ //newChangeDataList, e := HandleDataByLinearRegression(bDataList, changeDataMap)
|
|
|
+ //if e != nil {
|
|
|
+ // err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
|
|
|
+ // return
|
|
|
+ //}
|
|
|
+
|
|
|
+ // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
|
|
|
+ baseDataList := make([]*models.EdbDataList, 0)
|
|
|
+ changeDataList := make([]*models.EdbDataList, 0)
|
|
|
changeDataMap := make(map[string]float64)
|
|
|
- newChangeDataList, e := HandleDataByLinearRegression(changeDataList, changeDataMap)
|
|
|
- if e != nil {
|
|
|
- err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
|
|
|
- return
|
|
|
+
|
|
|
+ // 先把低频指标升频为高频
|
|
|
+ {
|
|
|
+ frequencyIntMap := map[string]int{
|
|
|
+ "日度": 1,
|
|
|
+ "周度": 2,
|
|
|
+ "旬度": 3,
|
|
|
+ "月度": 4,
|
|
|
+ "季度": 5,
|
|
|
+ "年度": 6,
|
|
|
+ }
|
|
|
+
|
|
|
+ // 如果A指标是高频,那么就需要对B指标进行升频
|
|
|
+ if frequencyIntMap[edbInfoMappingA.Frequency] < frequencyIntMap[edbInfoMappingB.Frequency] {
|
|
|
+ aDataMap := make(map[string]float64)
|
|
|
+ tmpNewChangeDataList, e := HandleDataByLinearRegression(aDataList, aDataMap)
|
|
|
+ if e != nil {
|
|
|
+ err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ baseDataList = tmpNewChangeDataList
|
|
|
+ } else {
|
|
|
+ baseDataList = aDataList
|
|
|
+ }
|
|
|
+ // 如果B指标是高频,那么就需要对A指标进行升频
|
|
|
+ if frequencyIntMap[edbInfoMappingA.Frequency] > frequencyIntMap[edbInfoMappingB.Frequency] {
|
|
|
+ tmpNewChangeDataList, e := HandleDataByLinearRegression(bDataList, changeDataMap)
|
|
|
+ if e != nil {
|
|
|
+ err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ changeDataList = tmpNewChangeDataList
|
|
|
+ } else {
|
|
|
+ changeDataList = bDataList
|
|
|
+ for _, v := range baseDataList {
|
|
|
+ changeDataMap[v.DataTime] = v.Value
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// 计算不领先也不滞后时的相关系数
|
|
@@ -262,10 +306,7 @@ func GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB *models.ChartEdbInfo
|
|
|
// 计算领先/滞后N期
|
|
|
if leadValue > 0 {
|
|
|
// 平移变频指标领先/滞后的日期(单位天)
|
|
|
- frequencyDaysMap := map[string]float64{
|
|
|
- "天": 1, "周": 7, "月": 30, "季": 90, "年": 365,
|
|
|
- }
|
|
|
- moveUnitDays := frequencyDaysMap[leadUnit]
|
|
|
+ moveUnitDays := utils.FrequencyDaysMap[leadUnit]
|
|
|
|
|
|
for i := range xData {
|
|
|
if xData[i] == 0 {
|
|
@@ -274,9 +315,9 @@ func GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB *models.ChartEdbInfo
|
|
|
}
|
|
|
yCalculateData := make([]float64, 0)
|
|
|
|
|
|
- // 判断是向前平移还是向后平移
|
|
|
+ // 平移指定天数
|
|
|
mDays := int(moveUnitDays) * xData[i]
|
|
|
- _, dMap := MoveDataDaysToNewDataList(newChangeDataList, mDays)
|
|
|
+ _, dMap := MoveDataDaysToNewDataList(changeDataList, mDays)
|
|
|
|
|
|
// 取出对应的基准日期的值
|
|
|
for i2 := range baseDataTimeArr {
|
|
@@ -303,59 +344,102 @@ func GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB *models.ChartEdbInfo
|
|
|
return
|
|
|
}
|
|
|
|
|
|
-// ChartInfoRefresh 图表刷新
|
|
|
-func ChartInfoRefresh(chartInfoId int) (err error) {
|
|
|
- var errMsg string
|
|
|
- defer func() {
|
|
|
- if err != nil {
|
|
|
- go alarm_msg.SendAlarmMsg("CorrelationChartInfoRefresh: "+errMsg, 3)
|
|
|
- }
|
|
|
- }()
|
|
|
- correlationChart := new(data_manage.ChartInfoCorrelation)
|
|
|
- if err = correlationChart.GetItemById(chartInfoId); err != nil {
|
|
|
- errMsg = "获取相关性图表失败, Err: " + err.Error()
|
|
|
- return
|
|
|
- }
|
|
|
+// GetRollingCorrelationChartDataByEdbInfo 滚动相关性计算
|
|
|
+func GetRollingCorrelationChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB *models.ChartEdbInfoMapping, leadValue int, leadUnit string, calculateValue int, calculateUnit string, startDate, endDate string) (xDateTimeValue []string, yDataList []models.YData, err error) {
|
|
|
+ xDateTimeValue = make([]string, 0)
|
|
|
+ yData := make([]float64, 0)
|
|
|
|
|
|
- // 批量刷新ETA指标
|
|
|
- err, errMsg = data.EdbInfoRefreshAllFromBase([]int{correlationChart.EdbInfoIdFirst, correlationChart.EdbInfoIdSecond}, false)
|
|
|
- if err != nil {
|
|
|
- return
|
|
|
- }
|
|
|
+ baseEdbInfo := edbInfoMappingA
|
|
|
+ changeEdbInfo := edbInfoMappingB
|
|
|
|
|
|
- // 重新生成数据并更新
|
|
|
- edbInfoMappingA, err := models.GetChartEdbMappingByEdbInfoId(correlationChart.EdbInfoIdFirst)
|
|
|
- if err != nil {
|
|
|
- errMsg = "获取相关性图表, A指标mapping信息失败, Err:" + err.Error()
|
|
|
- return
|
|
|
- }
|
|
|
- edbInfoMappingB, err := models.GetChartEdbMappingByEdbInfoId(correlationChart.EdbInfoIdSecond)
|
|
|
- if err != nil {
|
|
|
- errMsg = "获取相关性图表, B指标mapping信息失败, Err:" + err.Error()
|
|
|
+ // 获取时间基准指标在时间区间内的值
|
|
|
+ aDataList := make([]*models.EdbDataList, 0)
|
|
|
+ switch baseEdbInfo.EdbInfoCategoryType {
|
|
|
+ case 0:
|
|
|
+ aDataList, err = models.GetEdbDataList(baseEdbInfo.Source, baseEdbInfo.EdbInfoId, startDate, endDate)
|
|
|
+ case 1:
|
|
|
+ _, aDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(baseEdbInfo.EdbInfoId, startDate, endDate, false)
|
|
|
+ default:
|
|
|
+ err = errors.New("指标base类型异常")
|
|
|
return
|
|
|
}
|
|
|
- periodData, correlationData, err := GetChartDataByEdbInfo(edbInfoMappingA, edbInfoMappingB, correlationChart.LeadValue, correlationChart.LeadUnit, correlationChart.StartDate.Format(utils.FormatDate), correlationChart.EndDate.Format(utils.FormatDate))
|
|
|
- if err != nil {
|
|
|
- errMsg = "获取相关性图表, 图表计算值失败, Err:" + err.Error()
|
|
|
+
|
|
|
+ // 获取变频指标所有日期的值, 插值法完善数据
|
|
|
+ bDataList := make([]*models.EdbDataList, 0)
|
|
|
+ switch changeEdbInfo.EdbInfoCategoryType {
|
|
|
+ case 0:
|
|
|
+ bDataList, err = models.GetEdbDataList(changeEdbInfo.Source, changeEdbInfo.EdbInfoId, "", "")
|
|
|
+ case 1:
|
|
|
+ _, bDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(changeEdbInfo.EdbInfoId, "", "", false)
|
|
|
+ default:
|
|
|
+ err = errors.New("指标change类型异常")
|
|
|
return
|
|
|
}
|
|
|
- periodDataByte, err := json.Marshal(periodData)
|
|
|
- if err != nil {
|
|
|
- errMsg = "相关性图表, X轴信息有误, Err:" + err.Error()
|
|
|
- return
|
|
|
+
|
|
|
+ // 数据平移变频指标领先/滞后的日期(单位天)
|
|
|
+ // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
|
|
|
+ //baseDataList := make([]*models.EdbDataList, 0)
|
|
|
+ baseDataMap := make(map[string]float64)
|
|
|
+ changeDataList := make([]*models.EdbDataList, 0)
|
|
|
+ changeDataMap := make(map[string]float64)
|
|
|
+
|
|
|
+ // A指标不管三七二十一,先变个频再说
|
|
|
+ {
|
|
|
+ _, e := HandleDataByLinearRegression(aDataList, baseDataMap)
|
|
|
+ if e != nil {
|
|
|
+ err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ //baseDataList = tmpNewChangeDataList
|
|
|
}
|
|
|
- correlationDataByte, err := json.Marshal(correlationData[0].Value)
|
|
|
- if err != nil {
|
|
|
- errMsg = "相关性图表, Y轴信息有误, Err:" + err.Error()
|
|
|
- return
|
|
|
+ // A指标不管三七二十一,先变个频再说
|
|
|
+ {
|
|
|
+ tmpNewChangeDataList, e := HandleDataByLinearRegression(bDataList, changeDataMap)
|
|
|
+ if e != nil {
|
|
|
+ err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
|
|
|
+ return
|
|
|
+ }
|
|
|
+ changeDataList = tmpNewChangeDataList
|
|
|
+
|
|
|
+ // 平移下日期
|
|
|
+ moveUnitDays := utils.FrequencyDaysMap[leadUnit]
|
|
|
+ _, changeDataMap = MoveDataDaysToNewDataList(changeDataList, leadValue*moveUnitDays)
|
|
|
}
|
|
|
- correlationChart.PeriodData = string(periodDataByte)
|
|
|
- correlationChart.CorrelationData = string(correlationDataByte)
|
|
|
- correlationChart.ModifyTime = time.Now().Local()
|
|
|
- correlationUpdateCols := []string{"PeriodData", "CorrelationData", "ModifyTime"}
|
|
|
- if err = correlationChart.Update(correlationUpdateCols); err != nil {
|
|
|
- errMsg = "更新相关性图表失败, Err:" + err.Error()
|
|
|
- return
|
|
|
+
|
|
|
+ // 计算计算时,需要多少个日期内数据
|
|
|
+ calculateDay := utils.FrequencyDaysMap[calculateUnit] * calculateValue
|
|
|
+
|
|
|
+ // 计算 每个日期的相关性值
|
|
|
+ {
|
|
|
+ startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
|
|
|
+ endDateTime, _ := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
|
|
|
+
|
|
|
+ for currDay := startDateTime; !currDay.After(endDateTime); currDay = currDay.AddDate(0, 0, 1) {
|
|
|
+ yCalculateData := make([]float64, 0)
|
|
|
+ baseCalculateData := make([]float64, 0)
|
|
|
+
|
|
|
+ // 取出对应的基准日期的值
|
|
|
+ for i := 0; i < calculateDay; i++ {
|
|
|
+ iDay := currDay.AddDate(0, 0, i).Format(utils.FormatDate)
|
|
|
+ baseCalculateData = append(baseCalculateData, baseDataMap[iDay])
|
|
|
+ yCalculateData = append(yCalculateData, changeDataMap[iDay])
|
|
|
+ }
|
|
|
+
|
|
|
+ // 公式计算出领先/滞后频度对应点的相关性系数
|
|
|
+ var ratio float64
|
|
|
+ if len(baseCalculateData) > 0 {
|
|
|
+ ratio = utils.CalculateCorrelationByIntArr(baseCalculateData, yCalculateData)
|
|
|
+ }
|
|
|
+ yData = append(yData, ratio)
|
|
|
+ xDateTimeValue = append(xDateTimeValue, currDay.AddDate(0, 0, calculateDay).Format(utils.FormatDate))
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ yDataList = make([]models.YData, 0)
|
|
|
+ yDate := "0000-00-00"
|
|
|
+ yDataList = append(yDataList, models.YData{
|
|
|
+ Date: yDate,
|
|
|
+ Value: yData,
|
|
|
+ })
|
|
|
return
|
|
|
}
|