chart_info.go 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  1. package future_good
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/shopspring/decimal"
  6. "hongze/hongze_chart_lib/models"
  7. "hongze/hongze_chart_lib/models/data_manage"
  8. "hongze/hongze_chart_lib/models/data_manage/future_good"
  9. "hongze/hongze_chart_lib/services/alarm_msg"
  10. "hongze/hongze_chart_lib/services/data"
  11. "hongze/hongze_chart_lib/utils"
  12. "strconv"
  13. "time"
  14. )
  15. // GetChartEdbData 获取图表的指标数据
  16. func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping, futureGoodEdbInfoMapping *models.ChartEdbInfoMapping, barChartInfoDateList []data_manage.BarChartInfoDateReq, barChartInfoSort data_manage.BarChartInfoSortReq) (barConfigEdbInfoIdList []data_manage.BarChartInfoEdbItemReq, edbList []*models.ChartEdbInfoMapping, xEdbIdValue []int, xDataList []models.XData, yDataList []models.YData, err error) {
  17. edbList = make([]*models.ChartEdbInfoMapping, 0)
  18. if futureGoodEdbInfoMapping == nil {
  19. err = errors.New("商品指标未选取")
  20. return
  21. }
  22. if edbInfoMapping == nil {
  23. err = errors.New("ETA指标未选取")
  24. return
  25. }
  26. // 指标对应的所有数据
  27. edbDataListMap := make(map[int][]*models.EdbDataList)
  28. item := new(data_manage.ChartEdbInfoMapping)
  29. edbInfoMapping.FrequencyEn = data.GetFrequencyEn(edbInfoMapping.Frequency)
  30. if edbInfoMapping.Unit == `无` {
  31. edbInfoMapping.Unit = ``
  32. }
  33. if futureGoodEdbInfoMapping.Unit == `无` {
  34. futureGoodEdbInfoMapping.Unit = ``
  35. }
  36. if chartInfoId <= 0 {
  37. edbInfoMapping.IsAxis = 1
  38. edbInfoMapping.LeadValue = 0
  39. edbInfoMapping.LeadUnit = ""
  40. edbInfoMapping.ChartEdbMappingId = 0
  41. edbInfoMapping.ChartInfoId = 0
  42. edbInfoMapping.IsOrder = false
  43. edbInfoMapping.EdbInfoType = 1
  44. edbInfoMapping.ChartStyle = ""
  45. edbInfoMapping.ChartColor = ""
  46. edbInfoMapping.ChartWidth = 0
  47. futureGoodEdbInfoMapping.IsAxis = 1
  48. futureGoodEdbInfoMapping.LeadValue = 0
  49. futureGoodEdbInfoMapping.LeadUnit = ""
  50. futureGoodEdbInfoMapping.ChartEdbMappingId = 0
  51. futureGoodEdbInfoMapping.ChartInfoId = 0
  52. futureGoodEdbInfoMapping.IsOrder = false
  53. futureGoodEdbInfoMapping.EdbInfoType = 1
  54. futureGoodEdbInfoMapping.ChartStyle = ""
  55. futureGoodEdbInfoMapping.ChartColor = ""
  56. futureGoodEdbInfoMapping.ChartWidth = 0
  57. } else {
  58. edbInfoMapping.LeadUnitEn = data.GetLeadUnitEn(edbInfoMapping.LeadUnit)
  59. futureGoodEdbInfoMapping.LeadUnitEn = data.GetLeadUnitEn(futureGoodEdbInfoMapping.LeadUnit)
  60. }
  61. // 普通的指标数据
  62. {
  63. dataList := make([]*models.EdbDataList, 0)
  64. dataList, err = models.GetEdbDataList(edbInfoMapping.Source, edbInfoMapping.EdbInfoId, startDate, endDate)
  65. edbDataListMap[edbInfoMapping.EdbInfoId] = dataList
  66. item.DataList = dataList
  67. edbList = append(edbList, edbInfoMapping)
  68. barConfigEdbInfoIdList = append(barConfigEdbInfoIdList, data_manage.BarChartInfoEdbItemReq{
  69. EdbInfoId: edbInfoMapping.EdbInfoId,
  70. //Name: edbInfoMapping.EdbName,
  71. Name: "现货价",
  72. NameEn: "Spot Price",
  73. Source: edbInfoMapping.Source,
  74. })
  75. }
  76. // 获取主力合约和最新日期
  77. var zlFutureGoodEdbInfo *future_good.FutureGoodEdbInfo
  78. var latestDate string // 最新日期是这个
  79. var regionType string // 交易所来源:“国内”,“海外”
  80. {
  81. // 寻找主力合约
  82. zlFutureGoodEdbInfo, err = future_good.GetFutureGoodEdbInfo(futureGoodEdbInfoMapping.EdbInfoId)
  83. if err != nil {
  84. return
  85. }
  86. regionType = zlFutureGoodEdbInfo.RegionType
  87. // 如果当前合约配置的 "画图时,日期来源的指标id" 并不是自己的话,那么就去查找对应配置的合约
  88. if zlFutureGoodEdbInfo.DateSourceId != zlFutureGoodEdbInfo.FutureGoodEdbInfoId {
  89. sourceDateFutureGoodEdbInfo, tmpErr := future_good.GetFutureGoodEdbInfo(zlFutureGoodEdbInfo.DateSourceId)
  90. if tmpErr != nil {
  91. err = tmpErr
  92. return
  93. }
  94. latestDate = sourceDateFutureGoodEdbInfo.EndDate // 最新日期是这个
  95. } else {
  96. latestDate = zlFutureGoodEdbInfo.EndDate // 最新日期是这个
  97. }
  98. if latestDate == `0000-00-00` {
  99. err = errors.New("日期异常")
  100. return
  101. }
  102. }
  103. // 获取期货指标以及期货数据
  104. futureGoodEdbInfoList, err := future_good.GetFutureGoodEdbInfoListByParentId(futureGoodEdbInfoMapping.EdbInfoId)
  105. if err != nil {
  106. return
  107. }
  108. maxM := 36
  109. tmpFutureGoodEdbInfoList := make([]*future_good.FutureGoodEdbInfo, 0)
  110. latestDateTime, _ := time.ParseInLocation(utils.FormatDate, latestDate, time.Local)
  111. for _, v := range tmpFutureGoodEdbInfoList {
  112. if v.RegionType == `国内` {
  113. futureGoodEdbInfoList = append(futureGoodEdbInfoList, v)
  114. continue
  115. }
  116. //海外的连续日期,目前
  117. if v.FutureGoodEdbType == 2 {
  118. if v.Month <= maxM {
  119. addMonth := int(latestDateTime.Month()) + v.Month
  120. v.Year = latestDateTime.Year() + addMonth/12
  121. realMonth := addMonth % 12
  122. if realMonth == 0 {
  123. realMonth = 12
  124. }
  125. v.Month = realMonth
  126. futureGoodEdbInfoList = append(futureGoodEdbInfoList, v)
  127. }
  128. continue
  129. }
  130. // 小于等于当前年,那么就肯定是ok的
  131. if v.Year <= latestDateTime.Year() {
  132. futureGoodEdbInfoList = append(futureGoodEdbInfoList, v)
  133. continue
  134. }
  135. // 如果(当前年-最新日期的年份) * 12个月 + (当前月-最新日期的月份) 小于总月份
  136. if (v.Year-latestDateTime.Year())*12+(v.Month-int(latestDateTime.Month())) <= maxM {
  137. futureGoodEdbInfoList = append(futureGoodEdbInfoList, v)
  138. continue
  139. }
  140. }
  141. futureGoodMappingList := make([]*models.ChartEdbInfoMapping, 0)
  142. for k, v := range futureGoodEdbInfoList {
  143. newMappingInfo := &models.ChartEdbInfoMapping{
  144. EdbInfoId: v.FutureGoodEdbInfoId,
  145. SourceName: v.Exchange,
  146. Source: 0,
  147. EdbCode: v.FutureGoodEdbCode,
  148. EdbName: v.FutureGoodEdbName,
  149. EdbAliasName: v.FutureGoodEdbName,
  150. EdbNameEn: v.FutureGoodEdbNameEn,
  151. EdbType: edbInfoMapping.EdbType,
  152. Frequency: edbInfoMapping.Frequency,
  153. FrequencyEn: edbInfoMapping.FrequencyEn,
  154. Unit: edbInfoMapping.Unit,
  155. UnitEn: edbInfoMapping.UnitEn,
  156. StartDate: v.StartDate,
  157. EndDate: v.EndDate,
  158. ModifyTime: v.ModifyTime.Format(utils.FormatDateTime),
  159. ChartEdbMappingId: v.FutureGoodEdbInfoId,
  160. ChartInfoId: edbInfoMapping.ChartInfoId,
  161. MaxData: v.MaxValue,
  162. MinData: v.MinValue,
  163. IsOrder: edbInfoMapping.IsOrder,
  164. IsAxis: edbInfoMapping.IsAxis,
  165. EdbInfoType: edbInfoMapping.EdbInfoType,
  166. EdbInfoCategoryType: edbInfoMapping.EdbInfoCategoryType,
  167. LeadValue: edbInfoMapping.LeadValue,
  168. LeadUnit: edbInfoMapping.LeadUnit,
  169. LeadUnitEn: edbInfoMapping.LeadUnitEn,
  170. ChartStyle: edbInfoMapping.ChartStyle,
  171. ChartColor: edbInfoMapping.ChartColor,
  172. PredictChartColor: edbInfoMapping.PredictChartColor,
  173. ChartWidth: edbInfoMapping.ChartWidth,
  174. ChartType: edbInfoMapping.ChartType,
  175. LatestDate: v.LatestDate.Format(utils.FormatDateTime),
  176. LatestValue: v.LatestValue,
  177. UniqueCode: futureGoodEdbInfoMapping.UniqueCode + strconv.Itoa(k),
  178. MinValue: v.MinValue,
  179. MaxValue: v.MaxValue,
  180. DataList: nil,
  181. IsNullData: false,
  182. }
  183. futureGoodMappingList = append(futureGoodMappingList, newMappingInfo)
  184. barConfigEdbInfoIdList = append(barConfigEdbInfoIdList, data_manage.BarChartInfoEdbItemReq{
  185. EdbInfoId: newMappingInfo.EdbInfoId,
  186. Name: fmt.Sprint("M+", v.Month),
  187. NameEn: fmt.Sprint("M+", v.Month),
  188. Source: newMappingInfo.Source,
  189. })
  190. }
  191. // 获取数据
  192. for _, v := range futureGoodMappingList {
  193. dataList := make([]*models.EdbDataList, 0)
  194. tmpDataList, tmpErr := future_good.GetFutureGoodEdbDataListByDate(v.EdbInfoId, startDate, endDate)
  195. if tmpErr != nil {
  196. return
  197. }
  198. for _, tmpData := range tmpDataList {
  199. dataList = append(dataList, &models.EdbDataList{
  200. EdbDataId: tmpData.FutureGoodEdbDataId,
  201. EdbInfoId: tmpData.FutureGoodEdbInfoId,
  202. DataTime: tmpData.DataTime.Format(utils.FormatDate),
  203. DataTimestamp: tmpData.DataTimestamp,
  204. Value: tmpData.Close,
  205. })
  206. }
  207. edbDataListMap[v.EdbInfoId] = dataList
  208. v.DataList = dataList
  209. }
  210. edbList = append(edbList, futureGoodMappingList...)
  211. xEdbIdValue, yDataList, err = BarChartData(edbList[0], futureGoodEdbInfoList, edbDataListMap, barChartInfoDateList, regionType, latestDate)
  212. xDataList = []models.XData{
  213. {
  214. Name: "现货价",
  215. NameEn: "Spot Price",
  216. },
  217. }
  218. if regionType == `国内` {
  219. for i := range futureGoodEdbInfoList {
  220. xDataList = append(xDataList, models.XData{
  221. Name: fmt.Sprint("M+", i),
  222. NameEn: fmt.Sprint("M+ ", i),
  223. })
  224. }
  225. } else {
  226. for _, v := range futureGoodEdbInfoList {
  227. divMonth := (v.Year-latestDateTime.Year())*12 + (v.Month - int(latestDateTime.Month()))
  228. xDataList = append(xDataList, models.XData{
  229. Name: fmt.Sprint("M+", divMonth),
  230. NameEn: fmt.Sprint("M+ ", divMonth),
  231. })
  232. }
  233. }
  234. return
  235. }
  236. // BarChartData 柱方图的数据处理
  237. //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) {
  238. // // 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
  239. // edbDataMap := make(map[int]map[string]float64)
  240. // for edbInfoId, edbDataList := range edbDataListMap {
  241. // edbDateData := make(map[string]float64)
  242. // for _, edbData := range edbDataList {
  243. // edbDateData[edbData.DataTime] = edbData.Value
  244. // }
  245. // edbDataMap[edbInfoId] = edbDateData
  246. // }
  247. //
  248. // // edbIdList 指标展示顺序;x轴的指标顺序
  249. // edbIdList = make([]int, 0)
  250. // edbIdList = append(edbIdList, edbInfoMapping.EdbInfoId)
  251. // if barChartInfoSort.Sort == 0 {
  252. // for _, v := range futureGoodMappingList {
  253. // edbIdList = append(edbIdList, v.EdbInfoId)
  254. // }
  255. // }
  256. //
  257. // //固定取螺纹期货主力合约的时间序列,最新值为该合约最新日期、N天前为该合约最新日期N天前
  258. // rbzlInfo, err := future_good.GetFutureGoodEdbInfoByCode("RBZL.SHF")
  259. // if err != nil {
  260. // return
  261. // }
  262. // latestDate := rbzlInfo.EndDate // 最新日期是这个
  263. // if rbzlInfo.EndDate == `0000-00-00` {
  264. // err = errors.New("日期异常")
  265. // return
  266. // }
  267. // latestDateTime, _ := time.ParseInLocation(utils.FormatDate, latestDate, time.Local)
  268. //
  269. // yDataList = make([]models.YData, 0) //y轴的数据列表
  270. //
  271. // for _, barChartInfoDate := range barChartInfoDateList {
  272. // var maxDate time.Time
  273. // var findDateTime time.Time
  274. // switch barChartInfoDate.Type {
  275. // case 1: //最新值
  276. // findDateTime = latestDateTime
  277. // case 2: //近期几天
  278. // findDateTime = latestDateTime.AddDate(0, 0, -barChartInfoDate.Value)
  279. // case 3: // 固定日期
  280. // //寻找固定日期的数据
  281. // tmpFindDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local)
  282. // if tmpErr != nil {
  283. // err = tmpErr
  284. // return
  285. // }
  286. // findDateTime = tmpFindDateTime
  287. // default:
  288. // err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type))
  289. // return
  290. // }
  291. // if findDateTime.IsZero() {
  292. // err = errors.New("错误的日期")
  293. // return
  294. // }
  295. //
  296. // findDataList := make([]float64, 0) // 当前日期的数据值
  297. // noDataIdList := make([]int, 0) // 没有数据的指标id
  298. // noDataIdMap := make(map[int]int, 0) // 没有数据的指标map
  299. // xEdbInfoIdList := make([]int, 0) // 当前数据的指标id列表
  300. //
  301. // // 现货指标
  302. // realDateTime, findDataValue, isFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[edbInfoMapping.EdbInfoId], edbDataMap[edbInfoMapping.EdbInfoId])
  303. // if tmpErr != nil {
  304. // err = tmpErr
  305. // return
  306. // }
  307. // findDataList = append(findDataList, findDataValue)
  308. // if isFind {
  309. // maxDate = realDateTime
  310. // } else {
  311. // noDataIdList = append(noDataIdList, edbInfoMapping.EdbInfoId)
  312. // noDataIdMap[edbInfoMapping.EdbInfoId] = edbInfoMapping.EdbInfoId
  313. // }
  314. // currMonth := findDateTime.Month() // 当前月份
  315. // xEdbInfoIdList = append(xEdbInfoIdList, edbInfoMapping.EdbInfoId)
  316. //
  317. // // 当前月的后面月份合约的数据
  318. // for i := currMonth; i < 12; i++ {
  319. // futureGoodMapping := futureGoodMappingList[i] // 当前的期货指标
  320. // tmpRealDateTime, tmpFindDataValue, tmpIsFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[futureGoodMapping.EdbInfoId], edbDataMap[futureGoodMapping.EdbInfoId])
  321. // if tmpErr != nil {
  322. // err = tmpErr
  323. // return
  324. // }
  325. // findDataList = append(findDataList, tmpFindDataValue)
  326. // if tmpIsFind {
  327. // if maxDate.IsZero() || maxDate.Before(tmpRealDateTime) {
  328. // maxDate = tmpRealDateTime
  329. // }
  330. // } else {
  331. // noDataIdList = append(noDataIdList, futureGoodMapping.EdbInfoId)
  332. // noDataIdMap[futureGoodMapping.EdbInfoId] = futureGoodMapping.EdbInfoId
  333. // }
  334. // // 当前期货合约的指标
  335. // xEdbInfoIdList = append(xEdbInfoIdList, futureGoodMapping.EdbInfoId)
  336. // }
  337. //
  338. // // 当前月的前面月份合约的数据
  339. // for i := 1; i < int(currMonth); i++ {
  340. // futureGoodMapping := futureGoodMappingList[i-1] // 当前的期货指标
  341. // tmpRealDateTime, tmpFindDataValue, tmpIsFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[futureGoodMapping.EdbInfoId], edbDataMap[futureGoodMapping.EdbInfoId])
  342. // if tmpErr != nil {
  343. // err = tmpErr
  344. // return
  345. // }
  346. // findDataList = append(findDataList, tmpFindDataValue)
  347. // if tmpIsFind {
  348. // if maxDate.IsZero() || maxDate.Before(tmpRealDateTime) {
  349. // maxDate = tmpRealDateTime
  350. // }
  351. // } else {
  352. // noDataIdList = append(noDataIdList, futureGoodMapping.EdbInfoId)
  353. // noDataIdMap[futureGoodMapping.EdbInfoId] = futureGoodMapping.EdbInfoId
  354. // }
  355. // // 当前期货合约的指标
  356. // xEdbInfoIdList = append(xEdbInfoIdList, futureGoodMapping.EdbInfoId)
  357. // }
  358. //
  359. // yName := barChartInfoDate.Name
  360. // yNameEn := barChartInfoDate.Name
  361. // if yName == `` {
  362. // if barChartInfoDate.Type == 2 {
  363. // yName = strconv.Itoa(barChartInfoDate.Value) + "天前"
  364. // if barChartInfoDate.Value == 1 {
  365. // yNameEn = strconv.Itoa(barChartInfoDate.Value) + "day ago"
  366. // } else {
  367. // yNameEn = strconv.Itoa(barChartInfoDate.Value) + " days ago"
  368. // }
  369. // } else {
  370. // yName = maxDate.Format(utils.FormatDate)
  371. // yNameEn = maxDate.Format(utils.FormatDate)
  372. // }
  373. // }
  374. // yDate := "0000-00-00"
  375. // if !maxDate.IsZero() {
  376. // yDate = maxDate.Format(utils.FormatDate)
  377. // }
  378. //
  379. // // 数据处理,将没有数据的下标,赋值平均值
  380. // {
  381. // hasDataIndexList := make([]int, 0)
  382. // for dataK, edbInfoId := range xEdbInfoIdList {
  383. // if _, ok := noDataIdMap[edbInfoId]; !ok { // 如果是没有数据的指标id
  384. // hasDataIndexList = append(hasDataIndexList, dataK)
  385. // }
  386. // }
  387. // lenHasDataIndex := len(hasDataIndexList)
  388. // if lenHasDataIndex > 0 {
  389. // for lenHasDataI := 1; lenHasDataI < lenHasDataIndex; lenHasDataI++ {
  390. // perK := hasDataIndexList[lenHasDataI-1] //上一个有数据的指标下标
  391. // currK := hasDataIndexList[lenHasDataI] //当前有数据的指标下标
  392. // preVal := findDataList[perK] //上一个有数据的坐标的值
  393. // currVal := findDataList[currK] //当前有数据的指标的值
  394. //
  395. // // 环差值
  396. // hcValDeci := decimal.NewFromFloat(currVal).Sub(decimal.NewFromFloat(preVal)).Div(decimal.NewFromInt(int64(currK - perK)))
  397. // var tmpI int64
  398. // // 将两个中间的数据做平均值补全
  399. // for hcI := perK + 1; hcI < currK; hcI++ {
  400. // tmpI++
  401. // findDataList[hcI], _ = decimal.NewFromFloat(preVal).Add(hcValDeci.Mul(decimal.NewFromInt(tmpI))).RoundCeil(4).Float64()
  402. // }
  403. // }
  404. // }
  405. // }
  406. //
  407. // yDataList = append(yDataList, models.YData{
  408. // Date: yDate,
  409. // Value: findDataList,
  410. // NoDataEdbList: noDataIdList,
  411. // XEdbInfoIdList: xEdbInfoIdList,
  412. // Color: barChartInfoDate.Color,
  413. // Name: yName,
  414. // NameEn: yNameEn,
  415. // })
  416. // }
  417. //
  418. // return
  419. //}
  420. // BarChartData 柱方图的数据处理
  421. 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) {
  422. // 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
  423. edbDataMap := make(map[int]map[string]float64)
  424. for edbInfoId, edbDataList := range edbDataListMap {
  425. edbDateData := make(map[string]float64)
  426. for _, edbData := range edbDataList {
  427. edbDateData[edbData.DataTime] = edbData.Value
  428. }
  429. edbDataMap[edbInfoId] = edbDateData
  430. }
  431. // edbIdList 指标展示顺序;x轴的指标顺序
  432. edbIdList = make([]int, 0)
  433. edbIdList = append(edbIdList, edbInfoMapping.EdbInfoId)
  434. for _, v := range futureGoodMappingList {
  435. edbIdList = append(edbIdList, v.FutureGoodEdbInfoId)
  436. }
  437. latestDateTime, _ := time.ParseInLocation(utils.FormatDate, latestDate, time.Local)
  438. yDataList = make([]models.YData, 0) //y轴的数据列表
  439. for _, barChartInfoDate := range barChartInfoDateList {
  440. var maxDate time.Time
  441. var findDateTime time.Time
  442. switch barChartInfoDate.Type {
  443. case 1: //最新值
  444. findDateTime = latestDateTime
  445. case 2: //近期几天
  446. findDateTime = latestDateTime.AddDate(0, 0, -barChartInfoDate.Value)
  447. case 3: // 固定日期
  448. //寻找固定日期的数据
  449. tmpFindDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local)
  450. if tmpErr != nil {
  451. err = tmpErr
  452. return
  453. }
  454. findDateTime = tmpFindDateTime
  455. default:
  456. err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type))
  457. return
  458. }
  459. if findDateTime.IsZero() {
  460. err = errors.New("错误的日期")
  461. return
  462. }
  463. findDataList := make([]float64, 0) // 当前日期的数据值
  464. noDataIdList := make([]int, 0) // 没有数据的指标id
  465. noDataIdMap := make(map[int]int, 0) // 没有数据的指标map
  466. xEdbInfoIdList := make([]int, 0) // 当前数据的指标id列表
  467. // 现货指标
  468. realDateTime, findDataValue, isFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[edbInfoMapping.EdbInfoId], edbDataMap[edbInfoMapping.EdbInfoId])
  469. if tmpErr != nil {
  470. err = tmpErr
  471. return
  472. }
  473. findDataList = append(findDataList, findDataValue)
  474. if isFind {
  475. maxDate = realDateTime
  476. } else {
  477. noDataIdList = append(noDataIdList, edbInfoMapping.EdbInfoId)
  478. noDataIdMap[edbInfoMapping.EdbInfoId] = edbInfoMapping.EdbInfoId
  479. }
  480. currMonth := findDateTime.Month() // 当前月份
  481. currYear := findDateTime.Year() // 当前年份
  482. xEdbInfoIdList = append(xEdbInfoIdList, edbInfoMapping.EdbInfoId)
  483. indexList := make([]int, 0)
  484. if regionType == `国内` {
  485. for i := currMonth; i < 12; i++ {
  486. indexList = append(indexList, int(i))
  487. }
  488. for i := 1; i < int(currMonth); i++ {
  489. indexList = append(indexList, i)
  490. }
  491. } else {
  492. for i, v := range futureGoodMappingList {
  493. if v.Year > currYear || (v.Year == currYear && v.Month >= int(currMonth)) {
  494. indexList = append(indexList, i)
  495. }
  496. }
  497. }
  498. for _, i := range indexList {
  499. futureGoodMapping := futureGoodMappingList[i] // 当前的期货指标
  500. tmpRealDateTime, tmpFindDataValue, tmpIsFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[futureGoodMapping.FutureGoodEdbInfoId], edbDataMap[futureGoodMapping.FutureGoodEdbInfoId])
  501. if tmpErr != nil {
  502. err = tmpErr
  503. return
  504. }
  505. findDataList = append(findDataList, tmpFindDataValue)
  506. if tmpIsFind {
  507. if maxDate.IsZero() || maxDate.Before(tmpRealDateTime) {
  508. maxDate = tmpRealDateTime
  509. }
  510. } else {
  511. noDataIdList = append(noDataIdList, futureGoodMapping.FutureGoodEdbInfoId)
  512. noDataIdMap[futureGoodMapping.FutureGoodEdbInfoId] = futureGoodMapping.FutureGoodEdbInfoId
  513. }
  514. // 当前期货合约的指标
  515. xEdbInfoIdList = append(xEdbInfoIdList, futureGoodMapping.FutureGoodEdbInfoId)
  516. }
  517. yName := barChartInfoDate.Name
  518. yNameEn := barChartInfoDate.Name
  519. if yName == `` {
  520. if barChartInfoDate.Type == 2 {
  521. yName = strconv.Itoa(barChartInfoDate.Value) + "天前"
  522. if barChartInfoDate.Value == 1 {
  523. yNameEn = strconv.Itoa(barChartInfoDate.Value) + "day ago"
  524. } else {
  525. yNameEn = strconv.Itoa(barChartInfoDate.Value) + " days ago"
  526. }
  527. } else {
  528. yName = maxDate.Format(utils.FormatDate)
  529. yNameEn = maxDate.Format(utils.FormatDate)
  530. }
  531. }
  532. yDate := "0000-00-00"
  533. if !maxDate.IsZero() {
  534. yDate = maxDate.Format(utils.FormatDate)
  535. }
  536. // 数据处理,将没有数据的下标,赋值平均值
  537. {
  538. hasDataIndexList := make([]int, 0)
  539. for dataK, edbInfoId := range xEdbInfoIdList {
  540. if _, ok := noDataIdMap[edbInfoId]; !ok { // 如果是没有数据的指标id
  541. hasDataIndexList = append(hasDataIndexList, dataK)
  542. }
  543. }
  544. lenHasDataIndex := len(hasDataIndexList)
  545. if lenHasDataIndex > 0 {
  546. for lenHasDataI := 1; lenHasDataI < lenHasDataIndex; lenHasDataI++ {
  547. perK := hasDataIndexList[lenHasDataI-1] //上一个有数据的指标下标
  548. currK := hasDataIndexList[lenHasDataI] //当前有数据的指标下标
  549. preVal := findDataList[perK] //上一个有数据的坐标的值
  550. currVal := findDataList[currK] //当前有数据的指标的值
  551. // 环差值
  552. hcValDeci := decimal.NewFromFloat(currVal).Sub(decimal.NewFromFloat(preVal)).Div(decimal.NewFromInt(int64(currK - perK)))
  553. var tmpI int64
  554. // 将两个中间的数据做平均值补全
  555. for hcI := perK + 1; hcI < currK; hcI++ {
  556. tmpI++
  557. findDataList[hcI], _ = decimal.NewFromFloat(preVal).Add(hcValDeci.Mul(decimal.NewFromInt(tmpI))).RoundCeil(4).Float64()
  558. }
  559. }
  560. }
  561. }
  562. yDataList = append(yDataList, models.YData{
  563. Date: yDate,
  564. Value: findDataList,
  565. NoDataEdbList: noDataIdList,
  566. XEdbInfoIdList: xEdbInfoIdList,
  567. Color: barChartInfoDate.Color,
  568. Name: yName,
  569. NameEn: yNameEn,
  570. })
  571. }
  572. return
  573. }
  574. // GetNeedDateData 获取合约内需要的日期数据
  575. func GetNeedDateData(needDateTime time.Time, dataList []*models.EdbDataList, edbDataMap map[string]float64) (findDateTime time.Time, findDataValue float64, isFind bool, err error) {
  576. //dataList := edbDataListMap[edbInfoId] //指标的所有数据值
  577. if len(dataList) <= 0 {
  578. // 没有数据的指标id
  579. return
  580. }
  581. //最早的日期
  582. minDateTime, err := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  583. if err != nil {
  584. return
  585. }
  586. for tmpDateTime := needDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  587. tmpDate := tmpDateTime.Format(utils.FormatDate)
  588. if tmpValue, ok := edbDataMap[tmpDate]; ok { //如果能找到数据,那么就返回
  589. // 数据为0,也直接返回,做无值处理
  590. if tmpValue == 0 {
  591. return
  592. }
  593. findDateTime, _ = time.ParseInLocation(utils.FormatDate, tmpDate, time.Local)
  594. findDataValue = tmpValue
  595. isFind = true
  596. return
  597. }
  598. }
  599. return
  600. }
  601. // FutureGoodChartInfoRefresh
  602. // @author Roc
  603. // @datetime 2023-2-2 18:44:46
  604. // @description 商品价格曲线图表刷新
  605. func FutureGoodChartInfoRefresh(chartInfoId int) (err error) {
  606. var errMsg string
  607. defer func() {
  608. if err != nil {
  609. go alarm_msg.SendAlarmMsg("ChartInfoRefresh:"+errMsg, 3)
  610. fmt.Println("ChartInfoRefresh Err:" + errMsg)
  611. }
  612. }()
  613. edbInfoMapping, err := models.GetEtaEdbChartEdbMapping(chartInfoId)
  614. if err != nil {
  615. errMsg = "获取需要刷新的ETA指标失败:Err:" + err.Error()
  616. return
  617. }
  618. // 获取期货指标
  619. futureGoodEdbInfoMapping, err := models.GetFutureGoodEdbChartEdbMapping(chartInfoId)
  620. if err != nil {
  621. errMsg = "获取需要刷新的商品期货指标失败:Err:" + err.Error()
  622. return
  623. }
  624. // 获取期货指标以及期货数据
  625. futureGoodEdbInfoList, err := future_good.GetFutureGoodEdbInfoListByParentId(futureGoodEdbInfoMapping.EdbInfoId)
  626. if err != nil {
  627. return
  628. }
  629. // 批量刷新ETA指标
  630. err, _ = data.EdbInfoRefreshAllFromBase([]int{edbInfoMapping.EdbInfoId}, false)
  631. if err != nil {
  632. return
  633. }
  634. // 批量刷新期货指标
  635. err = FutureGoodEdbInfoRefreshAllFromBase(futureGoodEdbInfoList, false)
  636. if err != nil {
  637. return
  638. }
  639. return
  640. }