Преглед изворни кода

fix:商品价格曲线,增加海外交易所

Roc пре 1 година
родитељ
комит
ad292e6e77

+ 4 - 0
models/data_manage/future_good/future_good_edb_info.go

@@ -12,7 +12,11 @@ type FutureGoodEdbInfo struct {
 	FutureGoodEdbName   string    `description:"期货指标名称"`
 	FutureGoodEdbNameEn string    `description:"期货指标英文名称"`
 	ParentId            int       `description:"上级期货id"`
+	RegionType          string    `description:"交易所来源,海外还是国内"`
 	Exchange            string    `description:"所属交易所"`
+	FutureGoodEdbType   int       `description:"指标类型,1:年月是固定的合约;2:只有M+N期的合约,未固定年月"`
+	DateSourceId        int       `description:"画图时,日期来源的指标id"`
+	Year                int       `description:"所属年份"`
 	Month               int       `description:"所属月份"`
 	StartDate           string    `description:"起始日期"`
 	EndDate             string    `description:"终止日期"`

+ 295 - 50
services/data/future_good/chart_info.go

@@ -6,7 +6,7 @@ import (
 	"github.com/shopspring/decimal"
 	"hongze/hongze_chart_lib/models"
 	"hongze/hongze_chart_lib/models/data_manage"
-	efuture_good "hongze/hongze_chart_lib/models/data_manage/future_good"
+	"hongze/hongze_chart_lib/models/data_manage/future_good"
 	"hongze/hongze_chart_lib/services/alarm_msg"
 	"hongze/hongze_chart_lib/services/data"
 	"hongze/hongze_chart_lib/utils"
@@ -85,18 +85,84 @@ func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping,
 		})
 	}
 
+	// 获取主力合约和最新日期
+	var zlFutureGoodEdbInfo *future_good.FutureGoodEdbInfo
+	var latestDate string // 最新日期是这个
+	var regionType string // 交易所来源:“国内”,“海外”
+	{
+		// 寻找主力合约
+		zlFutureGoodEdbInfo, err = future_good.GetFutureGoodEdbInfo(futureGoodEdbInfoMapping.EdbInfoId)
+		if err != nil {
+			return
+		}
+		regionType = zlFutureGoodEdbInfo.RegionType
+
+		// 如果当前合约配置的 "画图时,日期来源的指标id" 并不是自己的话,那么就去查找对应配置的合约
+		if zlFutureGoodEdbInfo.DateSourceId != zlFutureGoodEdbInfo.FutureGoodEdbInfoId {
+			sourceDateFutureGoodEdbInfo, tmpErr := future_good.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
+		}
+	}
+
 	// 获取期货指标以及期货数据
-	futureGoodEdbInfoList, err := efuture_good.GetFutureGoodEdbInfoListByParentId(futureGoodEdbInfoMapping.EdbInfoId)
+	futureGoodEdbInfoList, err := future_good.GetFutureGoodEdbInfoListByParentId(futureGoodEdbInfoMapping.EdbInfoId)
 	if err != nil {
 		return
 	}
 
+	maxM := 36
+	tmpFutureGoodEdbInfoList := make([]*future_good.FutureGoodEdbInfo, 0)
+	latestDateTime, _ := time.ParseInLocation(utils.FormatDate, latestDate, time.Local)
+
+	for _, v := range tmpFutureGoodEdbInfoList {
+		if v.RegionType == `国内` {
+			futureGoodEdbInfoList = append(futureGoodEdbInfoList, v)
+			continue
+		}
+		//海外的连续日期,目前
+		if v.FutureGoodEdbType == 2 {
+			if v.Month <= maxM {
+				addMonth := int(latestDateTime.Month()) + v.Month
+				v.Year = latestDateTime.Year() + addMonth/12
+				realMonth := addMonth % 12
+				if realMonth == 0 {
+					realMonth = 12
+				}
+				v.Month = realMonth
+				futureGoodEdbInfoList = append(futureGoodEdbInfoList, v)
+			}
+			continue
+		}
+
+		// 小于等于当前年,那么就肯定是ok的
+		if v.Year <= latestDateTime.Year() {
+			futureGoodEdbInfoList = append(futureGoodEdbInfoList, v)
+			continue
+		}
+		// 如果(当前年-最新日期的年份) * 12个月 + (当前月-最新日期的月份) 小于总月份
+		if (v.Year-latestDateTime.Year())*12+(v.Month-int(latestDateTime.Month())) <= maxM {
+			futureGoodEdbInfoList = append(futureGoodEdbInfoList, v)
+			continue
+		}
+
+	}
+
 	futureGoodMappingList := make([]*models.ChartEdbInfoMapping, 0)
 	for k, v := range futureGoodEdbInfoList {
 		newMappingInfo := &models.ChartEdbInfoMapping{
 			EdbInfoId:           v.FutureGoodEdbInfoId,
 			SourceName:          v.Exchange,
-			Source:              utils.CHART_SOURCE_FUTURE_GOOD,
+			Source:              0,
 			EdbCode:             v.FutureGoodEdbCode,
 			EdbName:             v.FutureGoodEdbName,
 			EdbAliasName:        v.FutureGoodEdbName,
@@ -147,7 +213,7 @@ func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping,
 	for _, v := range futureGoodMappingList {
 		dataList := make([]*models.EdbDataList, 0)
 
-		tmpDataList, tmpErr := efuture_good.GetFutureGoodEdbDataListByDate(v.EdbInfoId, startDate, endDate)
+		tmpDataList, tmpErr := future_good.GetFutureGoodEdbDataListByDate(v.EdbInfoId, startDate, endDate)
 		if tmpErr != nil {
 			return
 		}
@@ -165,7 +231,7 @@ func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping,
 	}
 
 	edbList = append(edbList, futureGoodMappingList...)
-	xEdbIdValue, yDataList, err = BarChartData(edbList[0], futureGoodMappingList, edbDataListMap, barChartInfoDateList, barChartInfoSort)
+	xEdbIdValue, yDataList, err = BarChartData(edbList[0], futureGoodEdbInfoList, edbDataListMap, barChartInfoDateList, regionType, latestDate)
 
 	xDataList = []models.XData{
 		{
@@ -173,18 +239,213 @@ func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping,
 			NameEn: "Spot Price",
 		},
 	}
-
-	for i := 1; i <= 11; i++ {
-		xDataList = append(xDataList, models.XData{
-			Name:   fmt.Sprint("M+", i),
-			NameEn: fmt.Sprint("M+", i),
-		})
+	if regionType == `国内` {
+		for i := range futureGoodEdbInfoList {
+			xDataList = append(xDataList, models.XData{
+				Name:   fmt.Sprint("M+", i),
+				NameEn: fmt.Sprint("M+ ", i),
+			})
+		}
+	} else {
+		for _, v := range futureGoodEdbInfoList {
+			divMonth := (v.Year-latestDateTime.Year())*12 + (v.Month - int(latestDateTime.Month()))
+			xDataList = append(xDataList, models.XData{
+				Name:   fmt.Sprint("M+", divMonth),
+				NameEn: fmt.Sprint("M+ ", divMonth),
+			})
+		}
 	}
+
 	return
 }
 
 // BarChartData 柱方图的数据处理
-func BarChartData(edbInfoMapping *models.ChartEdbInfoMapping, futureGoodMappingList []*models.ChartEdbInfoMapping, edbDataListMap map[int][]*models.EdbDataList, barChartInfoDateList []data_manage.BarChartInfoDateReq, barChartInfoSort data_manage.BarChartInfoSortReq) (edbIdList []int, yDataList []models.YData, err error) {
+//func BarChartData(edbInfoMapping *models.ChartEdbInfoMapping, futureGoodMappingList []*models.ChartEdbInfoMapping, edbDataListMap map[int][]*models.EdbDataList, barChartInfoDateList []data_manage.BarChartInfoDateReq, barChartInfoSort data_manage.BarChartInfoSortReq) (edbIdList []int, yDataList []models.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)
+//	if barChartInfoSort.Sort == 0 {
+//		for _, v := range futureGoodMappingList {
+//			edbIdList = append(edbIdList, v.EdbInfoId)
+//		}
+//	}
+//
+//	//固定取螺纹期货主力合约的时间序列,最新值为该合约最新日期、N天前为该合约最新日期N天前
+//	rbzlInfo, err := future_good.GetFutureGoodEdbInfoByCode("RBZL.SHF")
+//	if err != nil {
+//		return
+//	}
+//	latestDate := rbzlInfo.EndDate // 最新日期是这个
+//	if rbzlInfo.EndDate == `0000-00-00` {
+//		err = errors.New("日期异常")
+//		return
+//	}
+//	latestDateTime, _ := time.ParseInLocation(utils.FormatDate, latestDate, time.Local)
+//
+//	yDataList = make([]models.YData, 0) //y轴的数据列表
+//
+//	for _, barChartInfoDate := range barChartInfoDateList {
+//		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)
+//		if isFind {
+//			maxDate = realDateTime
+//		} else {
+//			noDataIdList = append(noDataIdList, edbInfoMapping.EdbInfoId)
+//			noDataIdMap[edbInfoMapping.EdbInfoId] = edbInfoMapping.EdbInfoId
+//		}
+//		currMonth := findDateTime.Month() // 当前月份
+//		xEdbInfoIdList = append(xEdbInfoIdList, edbInfoMapping.EdbInfoId)
+//
+//		// 当前月的后面月份合约的数据
+//		for i := currMonth; i < 12; i++ {
+//			futureGoodMapping := futureGoodMappingList[i] // 当前的期货指标
+//			tmpRealDateTime, tmpFindDataValue, tmpIsFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[futureGoodMapping.EdbInfoId], edbDataMap[futureGoodMapping.EdbInfoId])
+//			if tmpErr != nil {
+//				err = tmpErr
+//				return
+//			}
+//			findDataList = append(findDataList, tmpFindDataValue)
+//			if tmpIsFind {
+//				if maxDate.IsZero() || maxDate.Before(tmpRealDateTime) {
+//					maxDate = tmpRealDateTime
+//				}
+//			} else {
+//				noDataIdList = append(noDataIdList, futureGoodMapping.EdbInfoId)
+//				noDataIdMap[futureGoodMapping.EdbInfoId] = futureGoodMapping.EdbInfoId
+//			}
+//			// 当前期货合约的指标
+//			xEdbInfoIdList = append(xEdbInfoIdList, futureGoodMapping.EdbInfoId)
+//		}
+//
+//		// 当前月的前面月份合约的数据
+//		for i := 1; i < int(currMonth); i++ {
+//			futureGoodMapping := futureGoodMappingList[i-1] // 当前的期货指标
+//			tmpRealDateTime, tmpFindDataValue, tmpIsFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[futureGoodMapping.EdbInfoId], edbDataMap[futureGoodMapping.EdbInfoId])
+//			if tmpErr != nil {
+//				err = tmpErr
+//				return
+//			}
+//			findDataList = append(findDataList, tmpFindDataValue)
+//			if tmpIsFind {
+//				if maxDate.IsZero() || maxDate.Before(tmpRealDateTime) {
+//					maxDate = tmpRealDateTime
+//				}
+//			} else {
+//				noDataIdList = append(noDataIdList, futureGoodMapping.EdbInfoId)
+//				noDataIdMap[futureGoodMapping.EdbInfoId] = futureGoodMapping.EdbInfoId
+//			}
+//			// 当前期货合约的指标
+//			xEdbInfoIdList = append(xEdbInfoIdList, futureGoodMapping.EdbInfoId)
+//		}
+//
+//		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, models.YData{
+//			Date:           yDate,
+//			Value:          findDataList,
+//			NoDataEdbList:  noDataIdList,
+//			XEdbInfoIdList: xEdbInfoIdList,
+//			Color:          barChartInfoDate.Color,
+//			Name:           yName,
+//			NameEn:         yNameEn,
+//		})
+//	}
+//
+//	return
+//}
+
+// BarChartData 柱方图的数据处理
+func BarChartData(edbInfoMapping *models.ChartEdbInfoMapping, futureGoodMappingList []*future_good.FutureGoodEdbInfo, edbDataListMap map[int][]*models.EdbDataList, barChartInfoDateList []data_manage.BarChartInfoDateReq, regionType, latestDate string) (edbIdList []int, yDataList []models.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 {
@@ -198,28 +459,17 @@ func BarChartData(edbInfoMapping *models.ChartEdbInfoMapping, futureGoodMappingL
 	// edbIdList 指标展示顺序;x轴的指标顺序
 	edbIdList = make([]int, 0)
 	edbIdList = append(edbIdList, edbInfoMapping.EdbInfoId)
-	if barChartInfoSort.Sort == 0 {
-		for _, v := range futureGoodMappingList {
-			edbIdList = append(edbIdList, v.EdbInfoId)
-		}
+	for _, v := range futureGoodMappingList {
+		edbIdList = append(edbIdList, v.FutureGoodEdbInfoId)
 	}
 
-	//固定取螺纹期货主力合约的时间序列,最新值为该合约最新日期、N天前为该合约最新日期N天前
-	rbzlInfo, err := efuture_good.GetFutureGoodEdbInfoByCode("RBZL.SHF")
-	if err != nil {
-		return
-	}
-	latestDate := rbzlInfo.EndDate // 最新日期是这个
-	if rbzlInfo.EndDate == `0000-00-00` {
-		err = errors.New("日期异常")
-		return
-	}
 	latestDateTime, _ := time.ParseInLocation(utils.FormatDate, latestDate, time.Local)
 
 	yDataList = make([]models.YData, 0) //y轴的数据列表
 
 	for _, barChartInfoDate := range barChartInfoDateList {
 		var maxDate time.Time
+
 		var findDateTime time.Time
 		switch barChartInfoDate.Type {
 		case 1: //最新值
@@ -262,33 +512,28 @@ func BarChartData(edbInfoMapping *models.ChartEdbInfoMapping, futureGoodMappingL
 			noDataIdMap[edbInfoMapping.EdbInfoId] = edbInfoMapping.EdbInfoId
 		}
 		currMonth := findDateTime.Month() // 当前月份
+		currYear := findDateTime.Year()   // 当前年份
 		xEdbInfoIdList = append(xEdbInfoIdList, edbInfoMapping.EdbInfoId)
 
-		// 当前月的后面月份合约的数据
-		for i := currMonth; i < 12; i++ {
-			futureGoodMapping := futureGoodMappingList[i] // 当前的期货指标
-			tmpRealDateTime, tmpFindDataValue, tmpIsFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[futureGoodMapping.EdbInfoId], edbDataMap[futureGoodMapping.EdbInfoId])
-			if tmpErr != nil {
-				err = tmpErr
-				return
+		indexList := make([]int, 0)
+		if regionType == `国内` {
+			for i := currMonth; i < 12; i++ {
+				indexList = append(indexList, int(i))
 			}
-			findDataList = append(findDataList, tmpFindDataValue)
-			if tmpIsFind {
-				if maxDate.IsZero() || maxDate.Before(tmpRealDateTime) {
-					maxDate = tmpRealDateTime
+			for i := 1; i < int(currMonth); i++ {
+				indexList = append(indexList, i)
+			}
+		} else {
+			for i, v := range futureGoodMappingList {
+				if v.Year > currYear || (v.Year == currYear && v.Month >= int(currMonth)) {
+					indexList = append(indexList, i)
 				}
-			} else {
-				noDataIdList = append(noDataIdList, futureGoodMapping.EdbInfoId)
-				noDataIdMap[futureGoodMapping.EdbInfoId] = futureGoodMapping.EdbInfoId
 			}
-			// 当前期货合约的指标
-			xEdbInfoIdList = append(xEdbInfoIdList, futureGoodMapping.EdbInfoId)
 		}
 
-		// 当前月的前面月份合约的数据
-		for i := 1; i < int(currMonth); i++ {
-			futureGoodMapping := futureGoodMappingList[i-1] // 当前的期货指标
-			tmpRealDateTime, tmpFindDataValue, tmpIsFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[futureGoodMapping.EdbInfoId], edbDataMap[futureGoodMapping.EdbInfoId])
+		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
@@ -299,11 +544,11 @@ func BarChartData(edbInfoMapping *models.ChartEdbInfoMapping, futureGoodMappingL
 					maxDate = tmpRealDateTime
 				}
 			} else {
-				noDataIdList = append(noDataIdList, futureGoodMapping.EdbInfoId)
-				noDataIdMap[futureGoodMapping.EdbInfoId] = futureGoodMapping.EdbInfoId
+				noDataIdList = append(noDataIdList, futureGoodMapping.FutureGoodEdbInfoId)
+				noDataIdMap[futureGoodMapping.FutureGoodEdbInfoId] = futureGoodMapping.FutureGoodEdbInfoId
 			}
 			// 当前期货合约的指标
-			xEdbInfoIdList = append(xEdbInfoIdList, futureGoodMapping.EdbInfoId)
+			xEdbInfoIdList = append(xEdbInfoIdList, futureGoodMapping.FutureGoodEdbInfoId)
 		}
 
 		yName := barChartInfoDate.Name
@@ -425,7 +670,7 @@ func FutureGoodChartInfoRefresh(chartInfoId int) (err error) {
 	}
 
 	// 获取期货指标以及期货数据
-	futureGoodEdbInfoList, err := efuture_good.GetFutureGoodEdbInfoListByParentId(futureGoodEdbInfoMapping.EdbInfoId)
+	futureGoodEdbInfoList, err := future_good.GetFutureGoodEdbInfoListByParentId(futureGoodEdbInfoMapping.EdbInfoId)
 	if err != nil {
 		return
 	}