package future_good import ( "errors" "fmt" "github.com/shopspring/decimal" "hongze/hz_crm_api/models/data_manage" future_good2 "hongze/hz_crm_api/models/data_manage/future_good" "hongze/hz_crm_api/services/alarm_msg" "hongze/hz_crm_api/services/data" "hongze/hz_crm_api/utils" "sort" "strconv" "time" ) // GetChartEdbData 获取图表的指标数据 func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping, futureGoodEdbInfoMapping *data_manage.ChartEdbInfoMapping, barChartInfoDateList []data_manage.BarChartInfoDateReq, barChartInfoSort data_manage.BarChartInfoSortReq) (barConfigEdbInfoIdList []data_manage.BarChartInfoEdbItemReq, edbList []*data_manage.ChartEdbInfoMapping, xEdbIdValue []int, xDataList []data_manage.XData, yDataList []data_manage.YData, err error) { edbList = make([]*data_manage.ChartEdbInfoMapping, 0) if futureGoodEdbInfoMapping == nil { err = errors.New("商品指标未选取") return } if edbInfoMapping == nil { err = errors.New("ETA指标未选取") return } // 指标对应的所有数据 edbDataListMap := make(map[int][]*data_manage.EdbDataList) item := new(data_manage.ChartEdbInfoMapping) edbInfoMapping.FrequencyEn = data.GetFrequencyEn(edbInfoMapping.Frequency) if edbInfoMapping.Unit == `无` { edbInfoMapping.Unit = `` } if futureGoodEdbInfoMapping.Unit == `无` { futureGoodEdbInfoMapping.Unit = `` } if chartInfoId <= 0 { edbInfoMapping.IsAxis = 1 edbInfoMapping.LeadValue = 0 edbInfoMapping.LeadUnit = "" edbInfoMapping.ChartEdbMappingId = 0 edbInfoMapping.ChartInfoId = 0 edbInfoMapping.IsOrder = false edbInfoMapping.EdbInfoType = 1 edbInfoMapping.ChartStyle = "" edbInfoMapping.ChartColor = "" edbInfoMapping.ChartWidth = 0 futureGoodEdbInfoMapping.IsAxis = 1 futureGoodEdbInfoMapping.LeadValue = 0 futureGoodEdbInfoMapping.LeadUnit = "" futureGoodEdbInfoMapping.ChartEdbMappingId = 0 futureGoodEdbInfoMapping.ChartInfoId = 0 futureGoodEdbInfoMapping.IsOrder = false futureGoodEdbInfoMapping.EdbInfoType = 1 futureGoodEdbInfoMapping.ChartStyle = "" futureGoodEdbInfoMapping.ChartColor = "" futureGoodEdbInfoMapping.ChartWidth = 0 } else { edbInfoMapping.LeadUnitEn = data.GetLeadUnitEn(edbInfoMapping.LeadUnit) futureGoodEdbInfoMapping.LeadUnitEn = data.GetLeadUnitEn(futureGoodEdbInfoMapping.LeadUnit) } // 普通的指标数据 { dataList := make([]*data_manage.EdbDataList, 0) dataList, err = data_manage.GetEdbDataList(edbInfoMapping.Source, edbInfoMapping.EdbInfoId, startDate, endDate) edbDataListMap[edbInfoMapping.EdbInfoId] = dataList item.DataList = dataList edbList = append(edbList, edbInfoMapping) barConfigEdbInfoIdList = append(barConfigEdbInfoIdList, data_manage.BarChartInfoEdbItemReq{ EdbInfoId: edbInfoMapping.EdbInfoId, //Name: edbInfoMapping.EdbName, Name: "现货价", NameEn: "Spot Price", Source: edbInfoMapping.Source, }) } // 获取主力合约和最新日期 var zlFutureGoodEdbInfo *future_good2.FutureGoodEdbInfo var latestDate string // 最新日期是这个 var regionType string // 交易所来源:“国内”,“海外” var futureGoodEdbType int { // 寻找主力合约 zlFutureGoodEdbInfo, err = future_good2.GetFutureGoodEdbInfo(futureGoodEdbInfoMapping.EdbInfoId) if err != nil { return } regionType = zlFutureGoodEdbInfo.RegionType futureGoodEdbType = zlFutureGoodEdbInfo.FutureGoodEdbType // 如果当前合约配置的 "画图时,日期来源的指标id" 并不是自己的话,那么就去查找对应配置的合约 if zlFutureGoodEdbInfo.DateSourceId != zlFutureGoodEdbInfo.FutureGoodEdbInfoId { sourceDateFutureGoodEdbInfo, tmpErr := future_good2.GetFutureGoodEdbInfo(zlFutureGoodEdbInfo.DateSourceId) if tmpErr != nil { err = tmpErr return } latestDate = sourceDateFutureGoodEdbInfo.EndDate // 最新日期是这个 } else { latestDate = zlFutureGoodEdbInfo.EndDate // 最新日期是这个 } if latestDate == `0000-00-00` { err = errors.New("日期异常") return } } // 获取期货指标以及期货数据 tmpFutureGoodEdbInfoList, err := future_good2.GetFutureGoodEdbInfoListByParentId(futureGoodEdbInfoMapping.EdbInfoId) if err != nil { return } latestDateTime, _ := time.ParseInLocation(utils.FormatDate, latestDate, time.Local) _, futureGoodEdbInfoList, err := getFutureGoodEdbInfoList(latestDateTime, tmpFutureGoodEdbInfoList, barChartInfoDateList) if err != nil { return } futureGoodMappingList := make([]*data_manage.ChartEdbInfoMapping, 0) for k, v := range futureGoodEdbInfoList { newMappingInfo := &data_manage.ChartEdbInfoMapping{ EdbInfoId: v.FutureGoodEdbInfoId, SourceName: v.Exchange, Source: 0, EdbCode: v.FutureGoodEdbCode, EdbName: v.FutureGoodEdbName, EdbAliasName: v.FutureGoodEdbName, EdbNameEn: v.FutureGoodEdbNameEn, EdbType: edbInfoMapping.EdbType, Frequency: edbInfoMapping.Frequency, FrequencyEn: edbInfoMapping.FrequencyEn, Unit: edbInfoMapping.Unit, UnitEn: edbInfoMapping.UnitEn, StartDate: v.StartDate, EndDate: v.EndDate, ModifyTime: v.ModifyTime.Format(utils.FormatDateTime), ChartEdbMappingId: v.FutureGoodEdbInfoId, ChartInfoId: edbInfoMapping.ChartInfoId, MaxData: v.MaxValue, MinData: v.MinValue, IsOrder: edbInfoMapping.IsOrder, IsAxis: edbInfoMapping.IsAxis, EdbInfoType: edbInfoMapping.EdbInfoType, EdbInfoCategoryType: edbInfoMapping.EdbInfoCategoryType, LeadValue: edbInfoMapping.LeadValue, LeadUnit: edbInfoMapping.LeadUnit, LeadUnitEn: edbInfoMapping.LeadUnitEn, ChartStyle: edbInfoMapping.ChartStyle, ChartColor: edbInfoMapping.ChartColor, PredictChartColor: edbInfoMapping.PredictChartColor, ChartWidth: edbInfoMapping.ChartWidth, ChartType: edbInfoMapping.ChartType, LatestDate: v.LatestDate.Format(utils.FormatDateTime), LatestValue: v.LatestValue, UniqueCode: futureGoodEdbInfoMapping.UniqueCode + strconv.Itoa(k), MinValue: v.MinValue, MaxValue: v.MaxValue, DataList: nil, IsNullData: false, } futureGoodMappingList = append(futureGoodMappingList, newMappingInfo) barConfigEdbInfoIdList = append(barConfigEdbInfoIdList, data_manage.BarChartInfoEdbItemReq{ EdbInfoId: newMappingInfo.EdbInfoId, Name: fmt.Sprint("M+", v.Month), NameEn: fmt.Sprint("M+", v.Month), Source: newMappingInfo.Source, }) } // 获取数据 for _, v := range futureGoodMappingList { dataList := make([]*data_manage.EdbDataList, 0) tmpDataList, tmpErr := future_good2.GetFutureGoodEdbDataListByDate(v.EdbInfoId, startDate, endDate) if tmpErr != nil { return } for _, tmpData := range tmpDataList { dataList = append(dataList, &data_manage.EdbDataList{ EdbDataId: tmpData.FutureGoodEdbDataId, EdbInfoId: tmpData.FutureGoodEdbInfoId, DataTime: tmpData.DataTime.Format(utils.FormatDate), DataTimestamp: tmpData.DataTimestamp, Value: tmpData.Close, }) } edbDataListMap[v.EdbInfoId] = dataList v.DataList = dataList } if regionType == `海外` { zlFutureGoodEdbMapping := &data_manage.ChartEdbInfoMapping{ EdbInfoId: zlFutureGoodEdbInfo.FutureGoodEdbInfoId, SourceName: zlFutureGoodEdbInfo.Exchange, Source: 0, EdbCode: zlFutureGoodEdbInfo.FutureGoodEdbCode, EdbName: zlFutureGoodEdbInfo.FutureGoodEdbName, EdbAliasName: zlFutureGoodEdbInfo.FutureGoodEdbName, EdbNameEn: zlFutureGoodEdbInfo.FutureGoodEdbNameEn, EdbType: edbInfoMapping.EdbType, Frequency: edbInfoMapping.Frequency, FrequencyEn: edbInfoMapping.FrequencyEn, Unit: edbInfoMapping.Unit, UnitEn: edbInfoMapping.UnitEn, StartDate: zlFutureGoodEdbInfo.StartDate, EndDate: zlFutureGoodEdbInfo.EndDate, ModifyTime: zlFutureGoodEdbInfo.ModifyTime.Format(utils.FormatDateTime), ChartEdbMappingId: zlFutureGoodEdbInfo.FutureGoodEdbInfoId, ChartInfoId: edbInfoMapping.ChartInfoId, MaxData: zlFutureGoodEdbInfo.MaxValue, MinData: zlFutureGoodEdbInfo.MinValue, IsOrder: edbInfoMapping.IsOrder, IsAxis: edbInfoMapping.IsAxis, EdbInfoType: edbInfoMapping.EdbInfoType, EdbInfoCategoryType: edbInfoMapping.EdbInfoCategoryType, LeadValue: edbInfoMapping.LeadValue, LeadUnit: edbInfoMapping.LeadUnit, LeadUnitEn: edbInfoMapping.LeadUnitEn, ChartStyle: edbInfoMapping.ChartStyle, ChartColor: edbInfoMapping.ChartColor, PredictChartColor: edbInfoMapping.PredictChartColor, ChartWidth: edbInfoMapping.ChartWidth, ChartType: edbInfoMapping.ChartType, LatestDate: zlFutureGoodEdbInfo.LatestDate.Format(utils.FormatDateTime), LatestValue: zlFutureGoodEdbInfo.LatestValue, UniqueCode: futureGoodEdbInfoMapping.UniqueCode + strconv.Itoa(0), MinValue: zlFutureGoodEdbInfo.MinValue, MaxValue: zlFutureGoodEdbInfo.MaxValue, DataList: nil, IsNullData: false, } edbList = append(edbList, zlFutureGoodEdbMapping) edbList = append(edbList, futureGoodMappingList...) } else { edbList = append(edbList, futureGoodMappingList...) } xEdbIdValue, yDataList, err = BarChartData(edbList[0], futureGoodEdbInfoList, edbDataListMap, barChartInfoDateList, regionType, latestDate) xDataList = []data_manage.XData{ { Name: "现货价", NameEn: "Spot Price", }, } //yDataList =make([]data_manage.YData,0) //data_manage.YData{ // Date: "", // Color: "", // Name: "", // NameEn: "", // Value: nil, // NoDataEdbList: nil, // XEdbInfoIdList: nil, //} futureGoodEdbInfoIndexMap := make(map[int]int) for index, v := range futureGoodEdbInfoList { futureGoodEdbInfoIndexMap[v.FutureGoodEdbInfoId] = index } nMap := make(map[int]int) maxIndex := 0 // 最大x轴的下标 for k, tmpYData := range yDataList { yDataMap := tmpYData.EdbValMap edbInfoIdList := make([]int, 0) noDataEdbInfoIdList := make([]int, 0) valueList := make([]float64, 0) noDataEdbIdMap := make(map[int]int) // 所有的N值 for _, n := range tmpYData.M { nMap[n] = n } // 基础指标 { baseEdbInfId := edbList[0].EdbInfoId edbInfoIdList = append(edbInfoIdList, baseEdbInfId) tmpVal, ok := yDataMap[baseEdbInfId] valueList = append(valueList, tmpVal) if !ok || tmpVal == 0 { noDataEdbInfoIdList = append(noDataEdbInfoIdList, baseEdbInfId) noDataEdbIdMap[baseEdbInfId] = baseEdbInfId } } for _, futureGoodEdbInfo := range futureGoodEdbInfoList { tmpEdbInfId := futureGoodEdbInfo.FutureGoodEdbInfoId edbInfoIdList = append(edbInfoIdList, tmpEdbInfId) tmpVal, ok := yDataMap[tmpEdbInfId] valueList = append(valueList, tmpVal) if !ok || tmpVal == 0 { noDataEdbInfoIdList = append(noDataEdbInfoIdList, tmpEdbInfId) noDataEdbIdMap[tmpEdbInfId] = tmpEdbInfId } } //tmpYData.Value = valueList tmpYData.NoDataEdbList = noDataEdbInfoIdList yDataList[k] = tmpYData lenEdbId := len(edbInfoIdList) tmpMaxIndex := lenEdbId - 1 // 当前数据的最大x轴的下标 for i := lenEdbId - 1; i >= 0; i-- { // 如果没有在无数据的指标列表中找到,那么就找到了最大x轴的下标 if _, ok := noDataEdbIdMap[edbInfoIdList[i]]; !ok { // 如果最大x轴的下标 小于 当前下标,那么就重新赋值 if maxIndex < i-1 { maxIndex = i - 1 } break } tmpMaxIndex = i - 1 } // 如果最大x轴的下标 小于 当前下标,那么就重新赋值 if maxIndex < tmpMaxIndex { maxIndex = tmpMaxIndex } } //xEdbIdValue = xEdbIdValue[0:maxIndex] // 找出所有的N值,并进行正序排列 nList := make([]int, 0) for _, n := range nMap { nList = append(nList, n) } sort.Slice(nList, func(i, j int) bool { return nList[i] < nList[j] }) for k, v := range yDataList { if len(v.XEdbInfoIdList) >= maxIndex+1 { yDataList[k].XEdbInfoIdList = v.XEdbInfoIdList[0 : maxIndex+1] } if len(v.Value) >= maxIndex+1 { yDataList[k].Value = v.Value[0 : maxIndex+1] } } tmpXDataList, newYDataList, err := handleResultData(regionType, futureGoodEdbType, yDataList, futureGoodEdbInfoList, maxIndex) if err != nil { return } xDataList = append(xDataList, tmpXDataList...) yDataList = newYDataList return } // BarChartData 获取数据 func BarChartData(edbInfoMapping *data_manage.ChartEdbInfoMapping, futureGoodMappingList []*future_good2.FutureGoodEdbInfo, edbDataListMap map[int][]*data_manage.EdbDataList, barChartInfoDateList []data_manage.BarChartInfoDateReq, regionType, latestDate string) (edbIdList []int, yDataList []data_manage.YData, err error) { // 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3}) edbDataMap := make(map[int]map[string]float64) for edbInfoId, edbDataList := range edbDataListMap { edbDateData := make(map[string]float64) for _, edbData := range edbDataList { edbDateData[edbData.DataTime] = edbData.Value } edbDataMap[edbInfoId] = edbDateData } // edbIdList 指标展示顺序;x轴的指标顺序 edbIdList = make([]int, 0) edbIdList = append(edbIdList, edbInfoMapping.EdbInfoId) for _, v := range futureGoodMappingList { edbIdList = append(edbIdList, v.FutureGoodEdbInfoId) } latestDateTime, _ := time.ParseInLocation(utils.FormatDate, latestDate, time.Local) yDataList = make([]data_manage.YData, 0) //y轴的数据列表 for _, barChartInfoDate := range barChartInfoDateList { yDataMap := make(map[int]float64) var maxDate time.Time var findDateTime time.Time switch barChartInfoDate.Type { case 1: //最新值 findDateTime = latestDateTime case 2: //近期几天 findDateTime = latestDateTime.AddDate(0, 0, -barChartInfoDate.Value) case 3: // 固定日期 //寻找固定日期的数据 tmpFindDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local) if tmpErr != nil { err = tmpErr return } findDateTime = tmpFindDateTime default: err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type)) return } if findDateTime.IsZero() { err = errors.New("错误的日期") return } findDataList := make([]float64, 0) // 当前日期的数据值 noDataIdList := make([]int, 0) // 没有数据的指标id noDataIdMap := make(map[int]int, 0) // 没有数据的指标map xEdbInfoIdList := make([]int, 0) // 当前数据的指标id列表 // 现货指标 realDateTime, findDataValue, isFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[edbInfoMapping.EdbInfoId], edbDataMap[edbInfoMapping.EdbInfoId]) if tmpErr != nil { err = tmpErr return } findDataList = append(findDataList, findDataValue) yDataMap[edbInfoMapping.EdbInfoId] = findDataValue if isFind { maxDate = realDateTime } else { noDataIdList = append(noDataIdList, edbInfoMapping.EdbInfoId) noDataIdMap[edbInfoMapping.EdbInfoId] = edbInfoMapping.EdbInfoId } currMonth := findDateTime.Month() // 当前月份 currYear := findDateTime.Year() // 当前年份 xEdbInfoIdList = append(xEdbInfoIdList, edbInfoMapping.EdbInfoId) mList := make([]int, 0) // 间隔月份 indexList := make([]int, 0) if regionType == `国内` { for i := currMonth + 1; i <= 12; i++ { indexList = append(indexList, int(i)) mList = append(mList, int(i-currMonth)) } for i := 1; i < int(currMonth); i++ { indexList = append(indexList, i) mList = append(mList, 12+i-int(currMonth)) } } else { for i, v := range futureGoodMappingList { if v.FutureGoodEdbType == 2 { if i == 0 { continue } indexList = append(indexList, i) mList = append(mList, v.Month) } else { if v.Year > currYear || (v.Year == currYear && v.Month > int(currMonth)) { indexList = append(indexList, i) mList = append(mList, (v.Year-currYear)*12+v.Month-int(currMonth)) } } } } for _, i := range indexList { futureGoodMapping := futureGoodMappingList[i] // 当前的期货指标 //tmpRealDateTime, tmpFindDataValue, tmpIsFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[futureGoodMapping.FutureGoodEdbInfoId], edbDataMap[futureGoodMapping.FutureGoodEdbInfoId]) //if tmpErr != nil { // err = tmpErr // return //} tmpRealDateTime := findDateTime tmpFindDataValue, tmpIsFind := edbDataMap[futureGoodMapping.FutureGoodEdbInfoId][findDateTime.Format(utils.FormatDate)] yDataMap[futureGoodMapping.FutureGoodEdbInfoId] = tmpFindDataValue findDataList = append(findDataList, tmpFindDataValue) if tmpIsFind { if maxDate.IsZero() || maxDate.Before(tmpRealDateTime) { maxDate = tmpRealDateTime } } else { noDataIdList = append(noDataIdList, futureGoodMapping.FutureGoodEdbInfoId) noDataIdMap[futureGoodMapping.FutureGoodEdbInfoId] = futureGoodMapping.FutureGoodEdbInfoId } // 当前期货合约的指标 xEdbInfoIdList = append(xEdbInfoIdList, futureGoodMapping.FutureGoodEdbInfoId) } yName := barChartInfoDate.Name yNameEn := barChartInfoDate.Name if yName == `` { if barChartInfoDate.Type == 2 { yName = strconv.Itoa(barChartInfoDate.Value) + "天前" if barChartInfoDate.Value == 1 { yNameEn = strconv.Itoa(barChartInfoDate.Value) + "day ago" } else { yNameEn = strconv.Itoa(barChartInfoDate.Value) + " days ago" } } else { yName = maxDate.Format(utils.FormatDate) yNameEn = maxDate.Format(utils.FormatDate) } } yDate := "0000-00-00" if !maxDate.IsZero() { yDate = maxDate.Format(utils.FormatDate) } // 数据处理,将没有数据的下标,赋值平均值 { hasDataIndexList := make([]int, 0) for dataK, edbInfoId := range xEdbInfoIdList { if _, ok := noDataIdMap[edbInfoId]; !ok { // 如果是没有数据的指标id hasDataIndexList = append(hasDataIndexList, dataK) } } lenHasDataIndex := len(hasDataIndexList) if lenHasDataIndex > 0 { for lenHasDataI := 1; lenHasDataI < lenHasDataIndex; lenHasDataI++ { perK := hasDataIndexList[lenHasDataI-1] //上一个有数据的指标下标 currK := hasDataIndexList[lenHasDataI] //当前有数据的指标下标 preVal := findDataList[perK] //上一个有数据的坐标的值 currVal := findDataList[currK] //当前有数据的指标的值 // 环差值 hcValDeci := decimal.NewFromFloat(currVal).Sub(decimal.NewFromFloat(preVal)).Div(decimal.NewFromInt(int64(currK - perK))) var tmpI int64 // 将两个中间的数据做平均值补全 for hcI := perK + 1; hcI < currK; hcI++ { tmpI++ findDataList[hcI], _ = decimal.NewFromFloat(preVal).Add(hcValDeci.Mul(decimal.NewFromInt(tmpI))).RoundCeil(4).Float64() } } } } yDataList = append(yDataList, data_manage.YData{ Date: yDate, ConfigDate: findDateTime, Value: findDataList, NoDataEdbList: noDataIdList, XEdbInfoIdList: xEdbInfoIdList, Color: barChartInfoDate.Color, Name: yName, NameEn: yNameEn, EdbValMap: yDataMap, M: mList, }) } return } // handleResultData 处理成最终的结果数据 func handleResultData(regionType string, futureGoodEdbType int, yDataList []data_manage.YData, futureGoodEdbInfoList []*future_good2.FutureGoodEdbInfo, maxIndex int) (xDataList []data_manage.XData, newYDataList []data_manage.YData, err error) { xDataList = make([]data_manage.XData, 0) newYDataList = yDataList if regionType == `国内` { for i := 1; i < 12; i++ { if i > maxIndex { break } xDataList = append(xDataList, data_manage.XData{ Name: fmt.Sprint("M+", i), NameEn: fmt.Sprint("M+", i), }) } return } futureGoodEdbInfoMap := make(map[int]*future_good2.FutureGoodEdbInfo) for _, v := range futureGoodEdbInfoList { futureGoodEdbInfoMap[v.FutureGoodEdbInfoId] = v } if futureGoodEdbType == 2 { // FutureGoodEdbType int `description:"指标类型,1:年月是固定的合约;2:只有M+N期的合约,未固定年月"` nList := []int{3, 15, 27} for _, i := range nList { xDataList = append(xDataList, data_manage.XData{ Name: fmt.Sprint("M+", i), NameEn: fmt.Sprint("M+", i), }) } for yIndex, yData := range yDataList { newYDataList[yIndex].XEdbInfoIdList = []int{} newYDataList[yIndex].Value = []float64{} tmpNList := nList //当前的主力合约 newYDataList[yIndex].XEdbInfoIdList = append(newYDataList[yIndex].XEdbInfoIdList, yData.XEdbInfoIdList[0]) newYDataList[yIndex].Value = append(newYDataList[yIndex].Value, yData.Value[0]) xEdbInfoIdList := yData.XEdbInfoIdList[1:] valIndex := 1 needNum := 0 for _, n := range tmpNList { if len(xEdbInfoIdList) > 0 { edbInfoId := xEdbInfoIdList[0] futureGoodEdbInfo, ok := futureGoodEdbInfoMap[edbInfoId] if !ok { err = errors.New("找不到指标") return } // 当前距离最早的日期相差的N数 if futureGoodEdbInfo.Month == n { if needNum > 0 { currVal := yData.Value[valIndex] preVal := yData.Value[valIndex-1] hcValDeci := decimal.NewFromFloat(currVal).Sub(decimal.NewFromFloat(preVal)).Div(decimal.NewFromInt(int64(needNum + 1))) for tmpNum := 0; tmpNum < needNum; tmpNum++ { newYDataList[yIndex].XEdbInfoIdList = append(newYDataList[yIndex].XEdbInfoIdList, 0) // 赋值平均值 tmpVal, _ := decimal.NewFromFloat(preVal).Add(hcValDeci.Mul(decimal.NewFromInt(int64(tmpNum + 1)))).RoundCeil(4).Float64() newYDataList[yIndex].Value = append(newYDataList[yIndex].Value, tmpVal) } } newYDataList[yIndex].XEdbInfoIdList = append(newYDataList[yIndex].XEdbInfoIdList, edbInfoId) newYDataList[yIndex].Value = append(newYDataList[yIndex].Value, yData.Value[valIndex]) valIndex++ needNum = 0 if len(xEdbInfoIdList) > 0 { xEdbInfoIdList = xEdbInfoIdList[1:] } } else { needNum++ } } } } maxI := 0 for _, yData := range newYDataList { lenEdb := len(yData.XEdbInfoIdList) for i := 0; i < lenEdb; i++ { if yData.XEdbInfoIdList[i] != 0 && !utils.InArrayByInt(yData.NoDataEdbList, yData.XEdbInfoIdList[i]) { if maxI < i { maxI = i } } } } xDataList = xDataList[0:maxI] for yIndex, yData := range newYDataList { if len(yData.XEdbInfoIdList) > maxI+1 { newYDataList[yIndex].XEdbInfoIdList = yData.XEdbInfoIdList[0 : maxI+1] } if len(yData.Value) > maxI+1 { newYDataList[yIndex].Value = yData.Value[0 : maxI+1] } } return } nMap := make(map[int]int) for _, v := range yDataList { findDateTime := v.ConfigDate currMonth := findDateTime.Month() // 当前月份 currYear := findDateTime.Year() // 当前年份 //v.XEdbInfoIdList for edbInfoIndex, edbInfoId := range v.XEdbInfoIdList { // 第一个不处理 if edbInfoIndex == 0 { continue } futureGoodEdbInfo, ok := futureGoodEdbInfoMap[edbInfoId] if !ok { err = errors.New("找不到指标") return } n := (futureGoodEdbInfo.Year-currYear)*12 + futureGoodEdbInfo.Month - int(currMonth) nMap[n] = n } } // 找出所有的N值,并进行正序排列 nList := make([]int, 0) for _, n := range nMap { nList = append(nList, n) } sort.Slice(nList, func(i, j int) bool { return nList[i] < nList[j] }) //prevMonth := 1 for _, n := range nList { xDataList = append(xDataList, data_manage.XData{ Name: fmt.Sprint("M+", n), NameEn: fmt.Sprint("M+", n), }) } for yIndex, yData := range yDataList { newYDataList[yIndex].XEdbInfoIdList = []int{} newYDataList[yIndex].Value = []float64{} tmpNList := nList //当前的主力合约 newYDataList[yIndex].XEdbInfoIdList = append(newYDataList[yIndex].XEdbInfoIdList, yData.XEdbInfoIdList[0]) newYDataList[yIndex].Value = append(newYDataList[yIndex].Value, yData.Value[0]) xEdbInfoIdList := yData.XEdbInfoIdList[1:] currDataTime := yData.ConfigDate valIndex := 1 needNum := 0 for _, n := range tmpNList { if len(xEdbInfoIdList) > 0 { edbInfoId := xEdbInfoIdList[0] futureGoodEdbInfo, ok := futureGoodEdbInfoMap[edbInfoId] if !ok { err = errors.New("找不到指标") return } // 当前距离最早的日期相差的N数 divMonth := (futureGoodEdbInfo.Year-currDataTime.Year())*12 + (futureGoodEdbInfo.Month - int(currDataTime.Month())) if divMonth == n { if needNum > 0 { currVal := yData.Value[valIndex] preVal := yData.Value[valIndex-1] hcValDeci := decimal.NewFromFloat(currVal).Sub(decimal.NewFromFloat(preVal)).Div(decimal.NewFromInt(int64(needNum + 1))) for tmpNum := 0; tmpNum < needNum; tmpNum++ { newYDataList[yIndex].XEdbInfoIdList = append(newYDataList[yIndex].XEdbInfoIdList, 0) // 赋值平均值 tmpVal, _ := decimal.NewFromFloat(preVal).Add(hcValDeci.Mul(decimal.NewFromInt(int64(tmpNum + 1)))).RoundCeil(4).Float64() newYDataList[yIndex].Value = append(newYDataList[yIndex].Value, tmpVal) } } newYDataList[yIndex].XEdbInfoIdList = append(newYDataList[yIndex].XEdbInfoIdList, edbInfoId) newYDataList[yIndex].Value = append(newYDataList[yIndex].Value, yData.Value[valIndex]) valIndex++ needNum = 0 if len(xEdbInfoIdList) > 0 { xEdbInfoIdList = xEdbInfoIdList[1:] } } else { needNum++ } } } } maxI := 0 for _, yData := range newYDataList { lenEdb := len(yData.XEdbInfoIdList) for i := 0; i < lenEdb; i++ { if yData.XEdbInfoIdList[i] != 0 && !utils.InArrayByInt(yData.NoDataEdbList, yData.XEdbInfoIdList[i]) { if maxI < i { maxI = i } } } } xDataList = xDataList[0:maxI] for yIndex, yData := range newYDataList { if len(yData.XEdbInfoIdList) > maxI+1 { newYDataList[yIndex].XEdbInfoIdList = yData.XEdbInfoIdList[0 : maxI+1] } if len(yData.Value) > maxI+1 { newYDataList[yIndex].Value = yData.Value[0 : maxI+1] } } return } // getFutureGoodEdbInfoList 获取适用的指标列表 func getFutureGoodEdbInfoList(latestDateTime time.Time, tmpFutureGoodEdbInfoList []*future_good2.FutureGoodEdbInfo, barChartInfoDateList []data_manage.BarChartInfoDateReq) (earliestDateTime time.Time, futureGoodEdbInfoList []*future_good2.FutureGoodEdbInfo, err error) { maxM := 36 //最大36期合约 futureGoodEdbInfoList = make([]*future_good2.FutureGoodEdbInfo, 0) earliestDateTime = latestDateTime // 数据的最早日期,目的是为了找出最早的合约 for _, barChartInfoDate := range barChartInfoDateList { var findDateTime time.Time switch barChartInfoDate.Type { case 1: //最新值 findDateTime = latestDateTime case 2: //近期几天 findDateTime = latestDateTime.AddDate(0, 0, -barChartInfoDate.Value) case 3: // 固定日期 //寻找固定日期的数据 tmpFindDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local) if tmpErr != nil { err = tmpErr return } findDateTime = tmpFindDateTime default: err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type)) return } if findDateTime.IsZero() { err = errors.New("错误的日期") return } if findDateTime.Before(earliestDateTime) { earliestDateTime = findDateTime } } for _, v := range tmpFutureGoodEdbInfoList { if v.RegionType == `国内` { futureGoodEdbInfoList = append(futureGoodEdbInfoList, v) continue } //海外的连续日期,目前 if v.FutureGoodEdbType == 2 { if v.Month <= maxM { //addMonth := int(earliestDateTime.Month()) + v.Month //v.Year = earliestDateTime.Year() + addMonth/12 //realMonth := addMonth % 12 //if realMonth == 0 { // realMonth = 12 //} //v.Month = realMonth futureGoodEdbInfoList = append(futureGoodEdbInfoList, v) } continue } if v.Year < earliestDateTime.Year() { continue } // 小于等于当前年,那么就肯定是ok的 if v.Year <= earliestDateTime.Year() { futureGoodEdbInfoList = append(futureGoodEdbInfoList, v) continue } // 如果(当前年-最新日期的年份) * 12个月 + (当前月-最新日期的月份) 小于总月份 if (v.Year-earliestDateTime.Year())*12+(v.Month-int(earliestDateTime.Month())) <= maxM { futureGoodEdbInfoList = append(futureGoodEdbInfoList, v) continue } } return } // GetNeedDateData 获取合约内需要的日期数据 func GetNeedDateData(needDateTime time.Time, dataList []*data_manage.EdbDataList, edbDataMap map[string]float64) (findDateTime time.Time, findDataValue float64, isFind bool, err error) { //dataList := edbDataListMap[edbInfoId] //指标的所有数据值 if len(dataList) <= 0 { // 没有数据的指标id return } //最早的日期 minDateTime, err := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local) if err != nil { return } for tmpDateTime := needDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) { tmpDate := tmpDateTime.Format(utils.FormatDate) if tmpValue, ok := edbDataMap[tmpDate]; ok { //如果能找到数据,那么就返回 // 数据为0,也直接返回,做无值处理 if tmpValue == 0 { return } findDateTime, _ = time.ParseInLocation(utils.FormatDate, tmpDate, time.Local) findDataValue = tmpValue isFind = true return } } return } // FutureGoodChartInfoRefresh // @author Roc // @datetime 2023-2-2 18:44:46 // @description 商品价格曲线图表刷新 func FutureGoodChartInfoRefresh(chartInfoId int) (err error) { var errMsg string defer func() { if err != nil { go alarm_msg.SendAlarmMsg("ChartInfoRefresh:"+errMsg, 3) fmt.Println("ChartInfoRefresh Err:" + errMsg) } }() edbInfoMapping, err := data_manage.GetEtaEdbChartEdbMapping(chartInfoId) if err != nil { errMsg = "获取需要刷新的ETA指标失败:Err:" + err.Error() return } // 获取期货指标 futureGoodEdbInfoMapping, err := data_manage.GetFutureGoodEdbChartEdbMapping(chartInfoId) if err != nil { errMsg = "获取需要刷新的商品期货指标失败:Err:" + err.Error() return } // 获取期货指标以及期货数据 futureGoodEdbInfoList, err := future_good2.GetFutureGoodEdbInfoListByParentId(futureGoodEdbInfoMapping.EdbInfoId) if err != nil { return } // 批量刷新ETA指标 err = data.EdbInfoRefreshAllFromBaseV3([]int{edbInfoMapping.EdbInfoId}, false) if err != nil { return } // 批量刷新期货指标 err = FutureGoodEdbInfoRefreshAllFromBase(futureGoodEdbInfoList, false) if err != nil { return } return }