package future_good import ( "errors" "eta_gn/eta_api/models/data_manage" future_good2 "eta_gn/eta_api/models/data_manage/future_good" "eta_gn/eta_api/services/alarm_msg" "eta_gn/eta_api/services/data" "eta_gn/eta_api/utils" "fmt" "github.com/shopspring/decimal" "sort" "strconv" "time" ) func GetChartEdbData(chartInfoId int, startDate, endDate string, baseEdbInfoMapping *data_manage.ChartEdbInfoMapping, edbInfoMappingList []*data_manage.ChartEdbInfoMapping, futureGoodEdbInfoMapping *data_manage.ChartEdbInfoMapping, barChartInfoConf data_manage.FutureGoodBarChartInfoReq, needData bool) (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) barChartInfoDateList := barChartInfoConf.DateList if futureGoodEdbInfoMapping == nil { err = errors.New("商品指标未选取") return } if len(edbInfoMappingList) == 0 { err = errors.New("ETA指标未选取") return } edbDataListMap := make(map[int][]*data_manage.EdbDataList) if futureGoodEdbInfoMapping.Unit == `无` { futureGoodEdbInfoMapping.Unit = `` } if chartInfoId <= 0 { for k, edbInfoMapping := range edbInfoMappingList { edbInfoMapping.FrequencyEn = data.GetFrequencyEn(edbInfoMapping.Frequency) if edbInfoMapping.Unit == `无` { edbInfoMapping.Unit = `` } 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 edbInfoMappingList[k] = edbInfoMapping } 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 { for k, edbInfoMapping := range edbInfoMappingList { edbInfoMapping.FrequencyEn = data.GetFrequencyEn(edbInfoMapping.Frequency) if edbInfoMapping.Unit == `无` { edbInfoMapping.Unit = `` } edbInfoMapping.LeadUnitEn = data.GetLeadUnitEn(edbInfoMapping.LeadUnit) edbInfoMappingList[k] = edbInfoMapping } futureGoodEdbInfoMapping.LeadUnitEn = data.GetLeadUnitEn(futureGoodEdbInfoMapping.LeadUnit) } xDataItemMap := make(map[int]data_manage.XData) for k, v := range barChartInfoConf.XDataList { xDataItemMap[k] = v } { edbList = edbInfoMappingList for k, edbInfoMapping := range edbInfoMappingList { tmp := data_manage.BarChartInfoEdbItemReq{ EdbInfoId: edbInfoMapping.EdbInfoId, Name: edbInfoMapping.EdbName, NameEn: edbInfoMapping.EdbNameEn, Source: edbInfoMapping.Source, } xItem, ok := xDataItemMap[k] if ok && xItem.Name != "" { tmp.Name = xItem.Name tmp.NameEn = xItem.NameEn tmp.IsHide = xItem.IsHide } barConfigEdbInfoIdList = append(barConfigEdbInfoIdList, tmp) } } var zlFutureGoodEdbInfo *future_good2.FutureGoodEdbInfo var latestDate string // 最新日期是这个 var regionType string // 交易所来源:“国内”,“海外” var futureGoodEdbType int { zlFutureGoodEdbInfo, err = future_good2.GetFutureGoodEdbInfo(futureGoodEdbInfoMapping.EdbInfoId) if err != nil { err = fmt.Errorf("查不到期货指标,GetFutureGoodEdbInfo err: %v", err) return } regionType = zlFutureGoodEdbInfo.RegionType futureGoodEdbType = zlFutureGoodEdbInfo.FutureGoodEdbType if zlFutureGoodEdbInfo.DateSourceId != zlFutureGoodEdbInfo.FutureGoodEdbInfoId { sourceDateFutureGoodEdbInfo, tmpErr := future_good2.GetFutureGoodEdbInfo(zlFutureGoodEdbInfo.DateSourceId) if tmpErr != nil { err = fmt.Errorf("获取期货指标 %d 的日期来源的指标信息失败,错误:%s", zlFutureGoodEdbInfo.DateSourceId, tmpErr.Error()) 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 { err = fmt.Errorf("获取期货指标列表失败,getFutureGoodEdbInfoList 错误:%s", err.Error()) 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: baseEdbInfoMapping.EdbType, Frequency: baseEdbInfoMapping.Frequency, FrequencyEn: baseEdbInfoMapping.FrequencyEn, Unit: baseEdbInfoMapping.Unit, UnitEn: baseEdbInfoMapping.UnitEn, StartDate: v.StartDate, EndDate: v.EndDate, ModifyTime: v.ModifyTime.Format(utils.FormatDateTime), ChartEdbMappingId: v.FutureGoodEdbInfoId, ChartInfoId: baseEdbInfoMapping.ChartInfoId, MaxData: v.MaxValue, MinData: v.MinValue, IsOrder: baseEdbInfoMapping.IsOrder, IsAxis: baseEdbInfoMapping.IsAxis, EdbInfoType: baseEdbInfoMapping.EdbInfoType, EdbInfoCategoryType: baseEdbInfoMapping.EdbInfoCategoryType, LeadValue: baseEdbInfoMapping.LeadValue, LeadUnit: baseEdbInfoMapping.LeadUnit, LeadUnitEn: baseEdbInfoMapping.LeadUnitEn, ChartStyle: baseEdbInfoMapping.ChartStyle, ChartColor: baseEdbInfoMapping.ChartColor, PredictChartColor: baseEdbInfoMapping.PredictChartColor, ChartWidth: baseEdbInfoMapping.ChartWidth, ChartType: baseEdbInfoMapping.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) tmp := data_manage.BarChartInfoEdbItemReq{ EdbInfoId: newMappingInfo.EdbInfoId, Name: fmt.Sprint("M+", v.Month), NameEn: fmt.Sprint("M+", v.Month), Source: newMappingInfo.Source, } xItem, ok := xDataItemMap[k] if ok && xItem.Name != "" { tmp.Name = xItem.Name tmp.NameEn = xItem.NameEn tmp.IsHide = xItem.IsHide } barConfigEdbInfoIdList = append(barConfigEdbInfoIdList, tmp) } 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: baseEdbInfoMapping.EdbType, Frequency: baseEdbInfoMapping.Frequency, FrequencyEn: baseEdbInfoMapping.FrequencyEn, Unit: baseEdbInfoMapping.Unit, UnitEn: baseEdbInfoMapping.UnitEn, StartDate: zlFutureGoodEdbInfo.StartDate, EndDate: zlFutureGoodEdbInfo.EndDate, ModifyTime: zlFutureGoodEdbInfo.ModifyTime.Format(utils.FormatDateTime), ChartEdbMappingId: zlFutureGoodEdbInfo.FutureGoodEdbInfoId, ChartInfoId: baseEdbInfoMapping.ChartInfoId, MaxData: zlFutureGoodEdbInfo.MaxValue, MinData: zlFutureGoodEdbInfo.MinValue, IsOrder: baseEdbInfoMapping.IsOrder, IsAxis: baseEdbInfoMapping.IsAxis, EdbInfoType: baseEdbInfoMapping.EdbInfoType, EdbInfoCategoryType: baseEdbInfoMapping.EdbInfoCategoryType, LeadValue: baseEdbInfoMapping.LeadValue, LeadUnit: baseEdbInfoMapping.LeadUnit, LeadUnitEn: baseEdbInfoMapping.LeadUnitEn, ChartStyle: baseEdbInfoMapping.ChartStyle, ChartColor: baseEdbInfoMapping.ChartColor, PredictChartColor: baseEdbInfoMapping.PredictChartColor, ChartWidth: baseEdbInfoMapping.ChartWidth, ChartType: baseEdbInfoMapping.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...) } if !needData { return } for _, edbInfoMapping := range edbInfoMappingList { dataList := make([]*data_manage.EdbDataList, 0) dataList, err = data_manage.GetEdbDataList(edbInfoMapping.Source, edbInfoMapping.SubSource, edbInfoMapping.EdbInfoId, startDate, endDate) if err != nil { return } edbDataListMap[edbInfoMapping.EdbInfoId] = dataList } futureEdbInfoIds := make([]int, 0) for _, v := range futureGoodMappingList { futureEdbInfoIds = append(futureEdbInfoIds, v.EdbInfoId) } tmpDataListMap := make(map[int][]*future_good2.FutureGoodEdbData) if len(futureEdbInfoIds) > 0 { tmpDataList, tmpErr := future_good2.GetFutureGoodEdbDataListByIdsAndDate(futureEdbInfoIds, startDate, endDate) if tmpErr != nil { err = tmpErr return } for _, v := range tmpDataList { if _, ok := tmpDataListMap[v.FutureGoodEdbInfoId]; !ok { tmpDataListMap[v.FutureGoodEdbInfoId] = make([]*future_good2.FutureGoodEdbData, 0) } tmpDataListMap[v.FutureGoodEdbInfoId] = append(tmpDataListMap[v.FutureGoodEdbInfoId], v) } } for _, v := range futureGoodMappingList { dataList := make([]*data_manage.EdbDataList, 0) tmpDataList, ok := tmpDataListMap[v.EdbInfoId] if !ok { continue } 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 } xEdbIdValue, yDataList, err = BarChartData(baseEdbInfoMapping, edbInfoMappingList, futureGoodEdbInfoList, edbDataListMap, barChartInfoDateList, regionType, baseEdbInfoMapping.EndDate) if len(barChartInfoConf.XDataList) > 0 { xDataList = barChartInfoConf.XDataList } else { for _, v := range edbInfoMappingList { xDataList = append(xDataList, data_manage.XData{ Name: v.EdbName, NameEn: v.EdbNameEn, IsHide: 0, }) } } 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) for _, n := range tmpYData.M { nMap[n] = n } baseEdbIds := make([]int, 0) for _, tmp := range edbInfoMappingList { edbInfoIdList = append(edbInfoIdList, tmp.EdbInfoId) baseEdbIds = append(baseEdbIds, tmp.EdbInfoId) tmpVal, ok := yDataMap[tmp.EdbInfoId] valueList = append(valueList, tmpVal) if !ok || tmpVal == 0 { noDataEdbInfoIdList = append(noDataEdbInfoIdList, tmp.EdbInfoId) noDataEdbIdMap[tmp.EdbInfoId] = tmp.EdbInfoId } } 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.NoDataEdbList = noDataEdbInfoIdList yDataList[k] = tmpYData lenEdbId := len(edbInfoIdList) tmpMaxIndex := lenEdbId - 1 // 当前数据的最大x轴的下标 for i := lenEdbId - 1; i >= 0; i-- { if _, ok := noDataEdbIdMap[edbInfoIdList[i]]; !ok || utils.InArrayByInt(baseEdbIds, edbInfoIdList[i]) { //以往的逻辑是碰到第一个无数据的期货指标,那后续的月份都是无数据的,因此需要特殊处理,改成多个现货指标之后需要排除无值的现货指标 if maxIndex < i-1 { maxIndex = i - 1 } break } tmpMaxIndex = i - 1 } if maxIndex < tmpMaxIndex { maxIndex = tmpMaxIndex } } 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] } } baseEdbLen := len(edbInfoMappingList) tmpXDataList, newYDataList, err := handleResultData(regionType, futureGoodEdbType, baseEdbLen, yDataList, futureGoodEdbInfoList, maxIndex) if err != nil { return } if len(barChartInfoConf.XDataList) == 0 { xDataList = append(xDataList, tmpXDataList...) } yDataList = newYDataList return } func BarChartData(baseEdbInfoMapping *data_manage.ChartEdbInfoMapping, edbInfoMappingList []*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) { baseEdbDataMap := make(map[int]map[string]float64) edbInfoMappingMap := make(map[int]struct{}) for _, v := range edbInfoMappingList { edbInfoMappingMap[v.EdbInfoId] = struct{}{} } for edbInfoId, edbDataList := range edbDataListMap { if _, ok1 := edbInfoMappingMap[edbInfoId]; ok1 { edbDateData := make(map[string]float64) for _, edbData := range edbDataList { edbDateData[edbData.DataTime] = edbData.Value } baseEdbDataMap[edbInfoId] = edbDateData } } edbDataMap := make(map[int]map[string]float64) for edbInfoId, edbDataList := range edbDataListMap { if _, ok := edbInfoMappingMap[edbInfoId]; ok { continue } edbDateData := make(map[string]float64) for _, edbData := range edbDataList { edbDateData[edbData.DataTime] = edbData.Value } edbDataMap[edbInfoId] = edbDateData } edbIdList = make([]int, 0) for _, v := range edbInfoMappingList { edbIdList = append(edbIdList, v.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列表 var realDateTime time.Time realDateTime, findDataValue, isFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[baseEdbInfoMapping.EdbInfoId], baseEdbDataMap[baseEdbInfoMapping.EdbInfoId], edbDataMap) if tmpErr != nil { err = tmpErr return } for _, v := range edbInfoMappingList { if v.EdbInfoId == baseEdbInfoMapping.EdbInfoId { findDataList = append(findDataList, findDataValue) yDataMap[baseEdbInfoMapping.EdbInfoId] = findDataValue if isFind { maxDate = realDateTime } else { noDataIdList = append(noDataIdList, baseEdbInfoMapping.EdbInfoId) noDataIdMap[baseEdbInfoMapping.EdbInfoId] = baseEdbInfoMapping.EdbInfoId } xEdbInfoIdList = append(xEdbInfoIdList, v.EdbInfoId) continue } findDataValueTmp, isFindTmp := baseEdbDataMap[v.EdbInfoId][realDateTime.Format(utils.FormatDate)] findDataList = append(findDataList, findDataValueTmp) yDataMap[v.EdbInfoId] = findDataValueTmp if !isFindTmp { noDataIdList = append(noDataIdList, v.EdbInfoId) noDataIdMap[v.EdbInfoId] = v.EdbInfoId } xEdbInfoIdList = append(xEdbInfoIdList, v.EdbInfoId) } currMonth := realDateTime.Month() // 当前月份 currYear := realDateTime.Year() // 当前年份 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 := realDateTime // 实际现货的日期 tmpFindDataValue, tmpIsFind := edbDataMap[futureGoodMapping.FutureGoodEdbInfoId][tmpRealDateTime.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: realDateTime, Value: findDataList, NoDataEdbList: noDataIdList, XEdbInfoIdList: xEdbInfoIdList, Color: barChartInfoDate.Color, Name: yName, NameEn: yNameEn, EdbValMap: yDataMap, M: mList, }) } return } func handleResultData(regionType string, futureGoodEdbType, baseEdbLen 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:baseEdbLen]...) newYDataList[yIndex].Value = append(newYDataList[yIndex].Value, yData.Value[0:baseEdbLen]...) xEdbInfoIdList := yData.XEdbInfoIdList[baseEdbLen:] valIndex := baseEdbLen needNum := 0 for _, n := range tmpNList { if len(xEdbInfoIdList) > 0 { edbInfoId := xEdbInfoIdList[0] futureGoodEdbInfo, ok := futureGoodEdbInfoMap[edbInfoId] if !ok { err = errors.New("找不到指标") return } 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() // 当前年份 for edbInfoIndex, edbInfoId := range v.XEdbInfoIdList { if edbInfoIndex <= baseEdbLen-1 { continue } futureGoodEdbInfo, ok := futureGoodEdbInfoMap[edbInfoId] if !ok { err = errors.New("找不到指标") return } n := (futureGoodEdbInfo.Year-currYear)*12 + futureGoodEdbInfo.Month - int(currMonth) nMap[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] }) 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:baseEdbLen]...) newYDataList[yIndex].Value = append(newYDataList[yIndex].Value, yData.Value[0:baseEdbLen]...) xEdbInfoIdList := yData.XEdbInfoIdList[baseEdbLen:] currDataTime := yData.ConfigDate valIndex := baseEdbLen needNum := 0 for _, n := range tmpNList { if len(xEdbInfoIdList) > 0 { edbInfoId := xEdbInfoIdList[0] futureGoodEdbInfo, ok := futureGoodEdbInfoMap[edbInfoId] if !ok { err = errors.New("找不到指标") return } 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 } 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 { futureGoodEdbInfoList = append(futureGoodEdbInfoList, v) } continue } if v.Year < earliestDateTime.Year() { continue } if v.Year <= earliestDateTime.Year() { futureGoodEdbInfoList = append(futureGoodEdbInfoList, v) continue } if (v.Year-earliestDateTime.Year())*12+(v.Month-int(earliestDateTime.Month())) <= maxM { futureGoodEdbInfoList = append(futureGoodEdbInfoList, v) continue } } return } func GetNeedDateData(needDateTime time.Time, dataList []*data_manage.EdbDataList, edbDataMap map[string]float64, allEdbDataMap map[int]map[string]float64) (findDateTime time.Time, findDataValue float64, isFind bool, err error) { if len(dataList) <= 0 { return } minDateTime, err := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local) if err != nil { return } maxCount := 1 for tmpDateTime := needDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) { tmpDate := tmpDateTime.Format(utils.FormatDate) tmpValue, ok := edbDataMap[tmpDate] if !ok { continue } count := 0 for _, currEdbDataMap := range allEdbDataMap { _, tmpIsFind := currEdbDataMap[tmpDate] if tmpIsFind { count++ if count >= maxCount { continue } } } if count < maxCount { continue } if tmpValue == 0 { return } findDateTime, _ = time.ParseInLocation(utils.FormatDate, tmpDate, time.Local) findDataValue = tmpValue isFind = true return } return } 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) } }() edbInfoMappingList, err := data_manage.GetEtaEdbChartEdbMappingList(chartInfoId) if err != nil { errMsg = "获取需要刷新的ETA指标失败:Err:" + err.Error() return } edbInfoIds := make([]int, 0) for _, edbInfoMapping := range edbInfoMappingList { edbInfoIds = append(edbInfoIds, edbInfoMapping.EdbInfoId) } 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 } err, _ = data.EdbInfoRefreshAllFromBaseV3(edbInfoIds, false, true, false) if err != nil { return } err = FutureGoodEdbInfoRefreshAllFromBase(futureGoodEdbInfoList, false) if err != nil { return } return }