123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895 |
- package future_good
- import (
- "errors"
- "fmt"
- "github.com/shopspring/decimal"
- "hongze/hongze_yb/models/request"
- "hongze/hongze_yb/models/response/chart_info"
- chartEdbMappingModel "hongze/hongze_yb/models/tables/chart_edb_mapping"
- edbDataModel "hongze/hongze_yb/models/tables/edb_data"
- "hongze/hongze_yb/models/tables/future_good_edb_data"
- "hongze/hongze_yb/models/tables/future_good_edb_info"
- "hongze/hongze_yb/services/alarm_msg"
- "hongze/hongze_yb/services/chart"
- "hongze/hongze_yb/utils"
- "sort"
- "strconv"
- "time"
- )
- // GetChartEdbData 获取图表的指标数据
- func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping, futureGoodEdbInfoMapping *chartEdbMappingModel.ChartEdbInfoMappingList, barChartInfoDateList []request.BarChartInfoDateReq) (barConfigEdbInfoIdList []request.BarChartInfoEdbItemReq, edbList []*chartEdbMappingModel.ChartEdbInfoMappingList, xEdbIdValue []int, xDataList []chart_info.XData, yDataList []chart_info.YData, sourceArr []string, err error) {
- edbList = make([]*chartEdbMappingModel.ChartEdbInfoMappingList, 0)
- sourceArr = make([]string, 0)
- if futureGoodEdbInfoMapping == nil {
- err = errors.New("商品指标未选取")
- return
- }
- if edbInfoMapping == nil {
- err = errors.New("ETA指标未选取")
- return
- }
- // 指标对应的所有数据
- edbDataListMap := make(map[int][]*edbDataModel.EdbDataList)
- item := new(chartEdbMappingModel.ChartEdbInfoMappingList)
- edbInfoMapping.FrequencyEn = chart.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 = chart.GetLeadUnitEn(edbInfoMapping.LeadUnit)
- futureGoodEdbInfoMapping.LeadUnitEn = chart.GetLeadUnitEn(futureGoodEdbInfoMapping.LeadUnit)
- }
- // 普通的指标数据
- {
- dataList := make([]*edbDataModel.EdbDataList, 0)
- dataList, err = edbDataModel.GetEdbDataList(edbInfoMapping.Source, edbInfoMapping.SubSource, edbInfoMapping.EdbInfoId, startDate, endDate)
- edbDataListMap[edbInfoMapping.EdbInfoId] = dataList
- item.DataList = dataList
- edbList = append(edbList, edbInfoMapping)
- barConfigEdbInfoIdList = append(barConfigEdbInfoIdList, request.BarChartInfoEdbItemReq{
- EdbInfoId: edbInfoMapping.EdbInfoId,
- //Name: edbInfoMapping.EdbName,
- Name: "现货价",
- NameEn: "Spot Price",
- Source: edbInfoMapping.Source,
- })
- if !utils.InArray(edbInfoMapping.Source, utils.SystemSourceList) { //来源于系统的指标,都展示为弘则研究
- if !utils.InArray(edbInfoMapping.SourceName, sourceArr) {
- sourceArr = append(sourceArr, edbInfoMapping.SourceName)
- }
- }
- }
- // 获取主力合约和最新日期
- var zlFutureGoodEdbInfo *future_good_edb_info.FutureGoodEdbInfo
- var latestDate string // 最新日期是这个
- var regionType string // 交易所来源:“国内”,“海外”
- var futureGoodEdbType int
- {
- // 寻找主力合约
- zlFutureGoodEdbInfo, err = future_good_edb_info.GetFutureGoodEdbInfo(futureGoodEdbInfoMapping.EdbInfoId)
- if err != nil {
- return
- }
- regionType = zlFutureGoodEdbInfo.RegionType
- futureGoodEdbType = int(zlFutureGoodEdbInfo.FutureGoodEdbType)
- // 如果当前合约配置的 "画图时,日期来源的指标id" 并不是自己的话,那么就去查找对应配置的合约
- if uint64(zlFutureGoodEdbInfo.DateSourceID) != zlFutureGoodEdbInfo.FutureGoodEdbInfoID {
- sourceDateFutureGoodEdbInfo, tmpErr := future_good_edb_info.GetFutureGoodEdbInfo(int(zlFutureGoodEdbInfo.DateSourceID))
- if tmpErr != nil {
- err = tmpErr
- return
- }
- latestDate = sourceDateFutureGoodEdbInfo.EndDate.Format(utils.FormatDate) // 最新日期是这个
- } else {
- latestDate = zlFutureGoodEdbInfo.EndDate.Format(utils.FormatDate) // 最新日期是这个
- }
- if latestDate == `0000-00-00` {
- err = errors.New("日期异常")
- return
- }
- }
- // 获取期货指标以及期货数据
- tmpFutureGoodEdbInfoList, err := future_good_edb_info.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([]*chartEdbMappingModel.ChartEdbInfoMappingList, 0)
- for k, v := range futureGoodEdbInfoList {
- newMappingInfo := &chartEdbMappingModel.ChartEdbInfoMappingList{
- ChartEdbInfoMapping: chartEdbMappingModel.ChartEdbInfoMapping{
- EdbInfoId: int(v.FutureGoodEdbInfoID),
- SourceName: v.Exchange,
- Source: utils.CHART_SOURCE_FUTURE_GOOD,
- 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.Format(utils.FormatDateTime),
- EndDate: v.EndDate.Format(utils.FormatDateTime),
- ModifyTime: v.ModifyTime.Format(utils.FormatDateTime),
- ChartEdbMappingId: int(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,
- LatestValue: v.LatestValue,
- UniqueCode: futureGoodEdbInfoMapping.UniqueCode + "1" + strconv.Itoa(k),
- MinValue: v.MinValue,
- MaxValue: v.MaxValue,
- },
- DataList: nil,
- IsNullData: false,
- }
- futureGoodMappingList = append(futureGoodMappingList, newMappingInfo)
- barConfigEdbInfoIdList = append(barConfigEdbInfoIdList, request.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([]*edbDataModel.EdbDataList, 0)
- tmpDataList, tmpErr := future_good_edb_data.GetFutureGoodEdbDataListByDate(v.EdbInfoId, startDate, endDate)
- if tmpErr != nil {
- return
- }
- for _, tmpData := range tmpDataList {
- dataList = append(dataList, &edbDataModel.EdbDataList{
- EdbDataId: int(tmpData.FutureGoodEdbDataID),
- EdbInfoId: int(tmpData.FutureGoodEdbInfoID),
- DataTime: tmpData.DataTime.Format(utils.FormatDate),
- DataTimestamp: tmpData.DataTimestamp,
- Value: tmpData.Close,
- })
- }
- edbDataListMap[v.EdbInfoId] = dataList
- v.DataList = dataList
- }
- edbList = append(edbList, futureGoodMappingList...)
- xEdbIdValue, yDataList, err = BarChartData(edbList[0], futureGoodEdbInfoList, edbDataListMap, barChartInfoDateList, regionType, edbInfoMapping.EndDate)
- xDataList = []chart_info.XData{
- {
- Name: "现货价",
- NameEn: "Spot Price",
- },
- }
- //yDataList =make([]chart_info.YData,0)
- //chart_info.YData{
- // Date: "",
- // Color: "",
- // Name: "",
- // NameEn: "",
- // Value: nil,
- // NoDataEdbList: nil,
- // XEdbInfoIdList: nil,
- //}
- futureGoodEdbInfoIndexMap := make(map[int]int)
- for index, v := range futureGoodEdbInfoList {
- futureGoodEdbInfoIndexMap[int(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 := int(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 *chartEdbMappingModel.ChartEdbInfoMappingList, futureGoodMappingList []*future_good_edb_info.FutureGoodEdbInfo, edbDataListMap map[int][]*edbDataModel.EdbDataList, barChartInfoDateList []request.BarChartInfoDateReq, regionType, latestDate string) (edbIdList []int, yDataList []chart_info.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, int(v.FutureGoodEdbInfoID))
- }
- latestDateTime, _ := time.ParseInLocation(utils.FormatDate, latestDate, time.Local)
- yDataList = make([]chart_info.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, int(v.Month))
- } else {
- if v.Year > currYear || (v.Year == currYear && int(v.Month) > int(currMonth)) {
- indexList = append(indexList, i)
- mList = append(mList, (v.Year-currYear)*12+int(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 // 按照配置找到的日期
- tmpRealDateTime := realDateTime // 实际现货的日期
- tmpFindDataValue, tmpIsFind := edbDataMap[int(futureGoodMapping.FutureGoodEdbInfoID)][tmpRealDateTime.Format(utils.FormatDate)]
- yDataMap[int(futureGoodMapping.FutureGoodEdbInfoID)] = tmpFindDataValue
- findDataList = append(findDataList, tmpFindDataValue)
- if tmpIsFind {
- if maxDate.IsZero() || maxDate.Before(tmpRealDateTime) {
- maxDate = tmpRealDateTime
- }
- } else {
- noDataIdList = append(noDataIdList, int(futureGoodMapping.FutureGoodEdbInfoID))
- noDataIdMap[int(futureGoodMapping.FutureGoodEdbInfoID)] = int(futureGoodMapping.FutureGoodEdbInfoID)
- }
- // 当前期货合约的指标
- xEdbInfoIdList = append(xEdbInfoIdList, int(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, chart_info.YData{
- Date: yDate,
- ConfigDate: realDateTime,
- Value: findDataList,
- NoDataEdbList: noDataIdList,
- XEdbInfoIdList: xEdbInfoIdList,
- Color: barChartInfoDate.Color,
- Name: yName,
- NameEn: yNameEn,
- EdbValMap: yDataMap,
- M: mList,
- })
- }
- return
- }
- // GetNeedDateData 获取合约内需要的日期数据
- func GetNeedDateData(needDateTime time.Time, dataList []*edbDataModel.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 := chartEdbMappingModel.GetEtaEdbChartEdbMapping(chartInfoId)
- if err != nil {
- errMsg = "获取需要刷新的ETA指标失败:Err:" + err.Error()
- return
- }
- // 获取期货指标
- futureGoodEdbInfoMapping, err := chartEdbMappingModel.GetFutureGoodEdbChartEdbMapping(chartInfoId)
- if err != nil {
- errMsg = "获取需要刷新的商品期货指标失败:Err:" + err.Error()
- return
- }
- // 获取期货指标以及期货数据
- futureGoodEdbInfoList, err := future_good_edb_info.GetFutureGoodEdbInfoListByParentId(futureGoodEdbInfoMapping.EdbInfoId)
- if err != nil {
- return
- }
- // 批量刷新ETA指标
- err, _ = chart.EdbInfoRefreshAllFromBase([]int{edbInfoMapping.EdbInfoId}, false)
- if err != nil {
- return
- }
- // 批量刷新期货指标
- err = FutureGoodEdbInfoRefreshAllFromBase(futureGoodEdbInfoList, false)
- if err != nil {
- return
- }
- return
- }
- // handleResultData 处理成最终的结果数据
- func handleResultData(regionType string, futureGoodEdbType int, yDataList []chart_info.YData, futureGoodEdbInfoList []*future_good_edb_info.FutureGoodEdbInfo, maxIndex int) (xDataList []chart_info.XData, newYDataList []chart_info.YData, err error) {
- xDataList = make([]chart_info.XData, 0)
- newYDataList = yDataList
- if regionType == `国内` {
- for i := 1; i < 12; i++ {
- if i > maxIndex {
- break
- }
- xDataList = append(xDataList, chart_info.XData{
- Name: fmt.Sprint("M+", i),
- NameEn: fmt.Sprint("M+", i),
- })
- }
- return
- }
- futureGoodEdbInfoMap := make(map[int]*future_good_edb_info.FutureGoodEdbInfo)
- for _, v := range futureGoodEdbInfoList {
- futureGoodEdbInfoMap[int(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, chart_info.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 int(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 + int(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, chart_info.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 + (int(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_good_edb_info.FutureGoodEdbInfo, barChartInfoDateList []request.BarChartInfoDateReq) (earliestDateTime time.Time, futureGoodEdbInfoList []*future_good_edb_info.FutureGoodEdbInfo, err error) {
- maxM := 36 //最大36期合约
- futureGoodEdbInfoList = make([]*future_good_edb_info.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 int(v.Month) <= maxM {
- //addMonth := int(earliestDateTime.Month()) + int(v.Month)
- //v.Year = earliestDateTime.Year() + addMonth/12
- //realMonth := addMonth % 12
- //if realMonth == 0 {
- // realMonth = 12
- //}
- //v.Month = uint32(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+(int(v.Month)-int(earliestDateTime.Month())) <= maxM {
- futureGoodEdbInfoList = append(futureGoodEdbInfoList, v)
- continue
- }
- }
- return
- }
|