123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195 |
- package logic
- import (
- "eta/eta_index_lib/models"
- "eta/eta_index_lib/utils"
- "fmt"
- )
- // CalculateCorrelation 计算相关性-获取x轴和y轴
- func CalculateCorrelation(leadValue int, leadUnit, frequencyA, frequencyB string, dataListA, dataListB []*models.EdbInfoSearchData) (xEdbIdValue []int, yDataList []YData, err error) {
- xData := make([]int, 0)
- yData := make([]float64, 0)
- if leadValue == 0 {
- xData = append(xData, 0)
- }
- if leadValue > 0 {
- leadMin := 0 - leadValue
- xLen := 2*leadValue + 1
- for i := 0; i < xLen; i++ {
- n := leadMin + i
- xData = append(xData, n)
- }
- }
- // 计算窗口,不包含第一天
- //startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
- //startDate = startDateTime.AddDate(0, 0, 1).Format(utils.FormatDate)
- //// 2023-03-02 时间序列始终以指标B为基准, 始终是A进行平移
- //baseEdbInfo := edbInfoMappingB
- //changeEdbInfo := edbInfoMappingA
- // 2023-03-17 时间序列始终以指标A为基准, 始终是B进行平移
- //baseEdbInfo := edbInfoMappingA
- //changeEdbInfo := edbInfoMappingB
- // 获取时间基准指标在时间区间内的值
- //aDataList := make([]*EdbDataList, 0)
- //switch baseEdbInfo.EdbInfoCategoryType {
- //case 0:
- // aDataList, err = GetEdbDataList(baseEdbInfo.Source, baseEdbInfo.SubSource, baseEdbInfo.EdbInfoId, startDate, endDate)
- //case 1:
- // _, aDataList, _, _, err, _ = data.GetPredictDataListByPredictEdbInfoId(baseEdbInfo.EdbInfoId, startDate, endDate, false)
- //default:
- // err = errors.New("指标base类型异常")
- // return
- //}
- //
- //// 获取变频指标所有日期的值, 插值法完善数据
- //bDataList := make([]*EdbDataList, 0)
- //switch changeEdbInfo.EdbInfoCategoryType {
- //case 0:
- // bDataList, err = GetEdbDataList(changeEdbInfo.Source, changeEdbInfo.SubSource, changeEdbInfo.EdbInfoId, "", "")
- //case 1:
- // _, 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.EdbInfoSearchData, 0)
- baseDataMap := make(map[string]float64)
- changeDataList := make([]*models.EdbInfoSearchData, 0)
- changeDataMap := make(map[string]float64)
- // 先把低频指标升频为高频
- {
- frequencyIntMap := map[string]int{
- "日度": 1,
- "周度": 2,
- "旬度": 3,
- "月度": 4,
- "季度": 5,
- "年度": 6,
- }
- // 如果A指标是高频,那么就需要对B指标进行升频
- if frequencyIntMap[frequencyA] < frequencyIntMap[frequencyB] {
- tmpNewChangeDataList, e := models.HandleDataByLinearRegression(dataListB, changeDataMap)
- if e != nil {
- err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
- return
- }
- changeDataList = tmpNewChangeDataList
- baseDataList = dataListA
- for _, v := range baseDataList {
- baseDataMap[v.DataTime] = v.Value
- }
- } else if frequencyIntMap[frequencyA] > frequencyIntMap[frequencyB] {
- // 如果B指标是高频,那么就需要对A指标进行升频
- tmpNewChangeDataList, e := models.HandleDataByLinearRegression(dataListA, baseDataMap)
- if e != nil {
- err = fmt.Errorf("获取变频指标插值法Map失败, Err: %s", e.Error())
- return
- }
- baseDataList = tmpNewChangeDataList
- changeDataList = dataListB
- for _, v := range changeDataList {
- changeDataMap[v.DataTime] = v.Value
- }
- } else {
- baseDataList = dataListA
- for _, v := range baseDataList {
- baseDataMap[v.DataTime] = v.Value
- }
- changeDataList = dataListB
- for _, v := range changeDataList {
- changeDataMap[v.DataTime] = v.Value
- }
- }
- }
- // 计算不领先也不滞后时的相关系数
- baseCalculateData := make([]float64, 0)
- baseDataTimeArr := make([]string, 0)
- for i := range baseDataList {
- baseDataTimeArr = append(baseDataTimeArr, baseDataList[i].DataTime)
- baseCalculateData = append(baseCalculateData, baseDataList[i].Value)
- }
- //zeroBaseData := make([]float64, 0)
- //zeroCalculateData := make([]float64, 0)
- //for i := range baseDataTimeArr {
- // tmpBaseVal, ok1 := baseDataMap[baseDataTimeArr[i]]
- // tmpCalculateVal, ok2 := changeDataMap[baseDataTimeArr[i]]
- // if ok1 && ok2 {
- // zeroBaseData = append(zeroBaseData, tmpBaseVal)
- // zeroCalculateData = append(zeroCalculateData, tmpCalculateVal)
- // }
- //}
- //if len(zeroBaseData) != len(zeroCalculateData) {
- // err = fmt.Errorf("相关系数两组序列元素数不一致, %d-%d", len(baseCalculateData), len(zeroCalculateData))
- // return
- //}
- //zeroRatio := utils.CalculateCorrelationByIntArr(zeroBaseData, zeroCalculateData)
- //if leadValue == 0 {
- // yData = append(yData, zeroRatio)
- //}
- // 计算领先/滞后N期
- if leadValue > 0 {
- // 平移变频指标领先/滞后的日期(单位天)
- moveUnitDays := utils.FrequencyDaysMap[leadUnit]
- for i := range xData {
- //if xData[i] == 0 {
- // yData = append(yData, zeroRatio)
- // continue
- //}
- xCalculateData := make([]float64, 0)
- yCalculateData := make([]float64, 0)
- // 平移指定天数
- mDays := int(moveUnitDays) * xData[i]
- _, dMap := models.MoveDataDaysToNewDataList(changeDataList, mDays)
- // 取出对应的基准日期的值
- for i2 := range baseDataTimeArr {
- tmpDate := baseDataTimeArr[i2]
- if yVal, ok := dMap[tmpDate]; ok {
- xCalculateData = append(xCalculateData, baseCalculateData[i2])
- yCalculateData = append(yCalculateData, yVal)
- }
- }
- if len(yCalculateData) <= 0 {
- //err = fmt.Errorf("领先滞后相关系数两组序列元素数不一致, %d-%d", len(baseCalculateData), len(yCalculateData))
- //return
- // 领先滞后后,没有可以计算的数据了
- continue
- }
- // 公式计算出领先/滞后频度对应点的相关性系数
- ratio := utils.CalculateCorrelationByIntArr(xCalculateData, yCalculateData)
- yData = append(yData, ratio)
- }
- }
- xEdbIdValue = xData
- yDataList = make([]YData, 0)
- yDate := "0000-00-00"
- yDataList = append(yDataList, YData{
- Date: yDate,
- Value: yData,
- })
- return
- }
|