chart_info.go 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878
  1. package future_good
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/shopspring/decimal"
  6. "hongze/hongze_ETA_mobile_api/models/data_manage"
  7. future_good2 "hongze/hongze_ETA_mobile_api/models/data_manage/future_good"
  8. "hongze/hongze_ETA_mobile_api/services/data"
  9. "hongze/hongze_ETA_mobile_api/utils"
  10. "sort"
  11. "strconv"
  12. "time"
  13. )
  14. // GetChartEdbData 获取图表的指标数据
  15. func GetChartEdbData(chartInfoId int, startDate, endDate string, edbInfoMapping, futureGoodEdbInfoMapping *data_manage.ChartEdbInfoMapping, barChartInfoDateList []data_manage.BarChartInfoDateReq, barChartInfoSort data_manage.BarChartInfoSortReq) (barConfigEdbInfoIdList []data_manage.BarChartInfoEdbItemReq, edbList []*data_manage.ChartEdbInfoMapping, xEdbIdValue []int, xDataList []data_manage.XData, yDataList []data_manage.YData, err error) {
  16. edbList = make([]*data_manage.ChartEdbInfoMapping, 0)
  17. if futureGoodEdbInfoMapping == nil {
  18. err = errors.New("商品指标未选取")
  19. return
  20. }
  21. if edbInfoMapping == nil {
  22. err = errors.New("ETA指标未选取")
  23. return
  24. }
  25. // 指标对应的所有数据
  26. edbDataListMap := make(map[int][]*data_manage.EdbDataList)
  27. item := new(data_manage.ChartEdbInfoMapping)
  28. edbInfoMapping.FrequencyEn = data.GetFrequencyEn(edbInfoMapping.Frequency)
  29. if edbInfoMapping.Unit == `无` {
  30. edbInfoMapping.Unit = ``
  31. }
  32. if futureGoodEdbInfoMapping.Unit == `无` {
  33. futureGoodEdbInfoMapping.Unit = ``
  34. }
  35. if chartInfoId <= 0 {
  36. edbInfoMapping.IsAxis = 1
  37. edbInfoMapping.LeadValue = 0
  38. edbInfoMapping.LeadUnit = ""
  39. edbInfoMapping.ChartEdbMappingId = 0
  40. edbInfoMapping.ChartInfoId = 0
  41. edbInfoMapping.IsOrder = false
  42. edbInfoMapping.EdbInfoType = 1
  43. edbInfoMapping.ChartStyle = ""
  44. edbInfoMapping.ChartColor = ""
  45. edbInfoMapping.ChartWidth = 0
  46. futureGoodEdbInfoMapping.IsAxis = 1
  47. futureGoodEdbInfoMapping.LeadValue = 0
  48. futureGoodEdbInfoMapping.LeadUnit = ""
  49. futureGoodEdbInfoMapping.ChartEdbMappingId = 0
  50. futureGoodEdbInfoMapping.ChartInfoId = 0
  51. futureGoodEdbInfoMapping.IsOrder = false
  52. futureGoodEdbInfoMapping.EdbInfoType = 1
  53. futureGoodEdbInfoMapping.ChartStyle = ""
  54. futureGoodEdbInfoMapping.ChartColor = ""
  55. futureGoodEdbInfoMapping.ChartWidth = 0
  56. } else {
  57. edbInfoMapping.LeadUnitEn = data.GetLeadUnitEn(edbInfoMapping.LeadUnit)
  58. futureGoodEdbInfoMapping.LeadUnitEn = data.GetLeadUnitEn(futureGoodEdbInfoMapping.LeadUnit)
  59. }
  60. // 普通的指标数据
  61. {
  62. dataList := make([]*data_manage.EdbDataList, 0)
  63. dataList, err = data_manage.GetEdbDataList(edbInfoMapping.Source, edbInfoMapping.EdbInfoId, startDate, endDate)
  64. edbDataListMap[edbInfoMapping.EdbInfoId] = dataList
  65. item.DataList = dataList
  66. edbList = append(edbList, edbInfoMapping)
  67. barConfigEdbInfoIdList = append(barConfigEdbInfoIdList, data_manage.BarChartInfoEdbItemReq{
  68. EdbInfoId: edbInfoMapping.EdbInfoId,
  69. //Name: edbInfoMapping.EdbName,
  70. Name: "现货价",
  71. NameEn: "Spot Price",
  72. Source: edbInfoMapping.Source,
  73. })
  74. }
  75. // 获取主力合约和最新日期
  76. var zlFutureGoodEdbInfo *future_good2.FutureGoodEdbInfo
  77. var latestDate string // 最新日期是这个
  78. var regionType string // 交易所来源:“国内”,“海外”
  79. var futureGoodEdbType int
  80. {
  81. // 寻找主力合约
  82. zlFutureGoodEdbInfo, err = future_good2.GetFutureGoodEdbInfo(futureGoodEdbInfoMapping.EdbInfoId)
  83. if err != nil {
  84. return
  85. }
  86. regionType = zlFutureGoodEdbInfo.RegionType
  87. futureGoodEdbType = zlFutureGoodEdbInfo.FutureGoodEdbType
  88. // 如果当前合约配置的 "画图时,日期来源的指标id" 并不是自己的话,那么就去查找对应配置的合约
  89. if zlFutureGoodEdbInfo.DateSourceId != zlFutureGoodEdbInfo.FutureGoodEdbInfoId {
  90. sourceDateFutureGoodEdbInfo, tmpErr := future_good2.GetFutureGoodEdbInfo(zlFutureGoodEdbInfo.DateSourceId)
  91. if tmpErr != nil {
  92. err = tmpErr
  93. return
  94. }
  95. latestDate = sourceDateFutureGoodEdbInfo.EndDate // 最新日期是这个
  96. } else {
  97. latestDate = zlFutureGoodEdbInfo.EndDate // 最新日期是这个
  98. }
  99. if latestDate == `0000-00-00` {
  100. err = errors.New("日期异常")
  101. return
  102. }
  103. }
  104. // 获取期货指标以及期货数据
  105. tmpFutureGoodEdbInfoList, err := future_good2.GetFutureGoodEdbInfoListByParentId(futureGoodEdbInfoMapping.EdbInfoId)
  106. if err != nil {
  107. return
  108. }
  109. latestDateTime, _ := time.ParseInLocation(utils.FormatDate, latestDate, time.Local)
  110. _, futureGoodEdbInfoList, err := getFutureGoodEdbInfoList(latestDateTime, tmpFutureGoodEdbInfoList, barChartInfoDateList)
  111. if err != nil {
  112. return
  113. }
  114. futureGoodMappingList := make([]*data_manage.ChartEdbInfoMapping, 0)
  115. for k, v := range futureGoodEdbInfoList {
  116. newMappingInfo := &data_manage.ChartEdbInfoMapping{
  117. EdbInfoId: v.FutureGoodEdbInfoId,
  118. SourceName: v.Exchange,
  119. Source: 0,
  120. EdbCode: v.FutureGoodEdbCode,
  121. EdbName: v.FutureGoodEdbName,
  122. EdbAliasName: v.FutureGoodEdbName,
  123. EdbNameEn: v.FutureGoodEdbNameEn,
  124. EdbType: edbInfoMapping.EdbType,
  125. Frequency: edbInfoMapping.Frequency,
  126. FrequencyEn: edbInfoMapping.FrequencyEn,
  127. Unit: edbInfoMapping.Unit,
  128. UnitEn: edbInfoMapping.UnitEn,
  129. StartDate: v.StartDate,
  130. EndDate: v.EndDate,
  131. ModifyTime: v.ModifyTime.Format(utils.FormatDateTime),
  132. ChartEdbMappingId: v.FutureGoodEdbInfoId,
  133. ChartInfoId: edbInfoMapping.ChartInfoId,
  134. MaxData: v.MaxValue,
  135. MinData: v.MinValue,
  136. IsOrder: edbInfoMapping.IsOrder,
  137. IsAxis: edbInfoMapping.IsAxis,
  138. EdbInfoType: edbInfoMapping.EdbInfoType,
  139. EdbInfoCategoryType: edbInfoMapping.EdbInfoCategoryType,
  140. LeadValue: edbInfoMapping.LeadValue,
  141. LeadUnit: edbInfoMapping.LeadUnit,
  142. LeadUnitEn: edbInfoMapping.LeadUnitEn,
  143. ChartStyle: edbInfoMapping.ChartStyle,
  144. ChartColor: edbInfoMapping.ChartColor,
  145. PredictChartColor: edbInfoMapping.PredictChartColor,
  146. ChartWidth: edbInfoMapping.ChartWidth,
  147. ChartType: edbInfoMapping.ChartType,
  148. LatestDate: v.LatestDate.Format(utils.FormatDateTime),
  149. LatestValue: v.LatestValue,
  150. UniqueCode: futureGoodEdbInfoMapping.UniqueCode + strconv.Itoa(k),
  151. MinValue: v.MinValue,
  152. MaxValue: v.MaxValue,
  153. DataList: nil,
  154. IsNullData: false,
  155. }
  156. futureGoodMappingList = append(futureGoodMappingList, newMappingInfo)
  157. barConfigEdbInfoIdList = append(barConfigEdbInfoIdList, data_manage.BarChartInfoEdbItemReq{
  158. EdbInfoId: newMappingInfo.EdbInfoId,
  159. Name: fmt.Sprint("M+", v.Month),
  160. NameEn: fmt.Sprint("M+", v.Month),
  161. Source: newMappingInfo.Source,
  162. })
  163. }
  164. // 获取数据
  165. for _, v := range futureGoodMappingList {
  166. dataList := make([]*data_manage.EdbDataList, 0)
  167. tmpDataList, tmpErr := future_good2.GetFutureGoodEdbDataListByDate(v.EdbInfoId, startDate, endDate)
  168. if tmpErr != nil {
  169. return
  170. }
  171. for _, tmpData := range tmpDataList {
  172. dataList = append(dataList, &data_manage.EdbDataList{
  173. EdbDataId: tmpData.FutureGoodEdbDataId,
  174. EdbInfoId: tmpData.FutureGoodEdbInfoId,
  175. DataTime: tmpData.DataTime.Format(utils.FormatDate),
  176. DataTimestamp: tmpData.DataTimestamp,
  177. Value: tmpData.Close,
  178. })
  179. }
  180. edbDataListMap[v.EdbInfoId] = dataList
  181. v.DataList = dataList
  182. }
  183. if regionType == `海外` {
  184. zlFutureGoodEdbMapping := &data_manage.ChartEdbInfoMapping{
  185. EdbInfoId: zlFutureGoodEdbInfo.FutureGoodEdbInfoId,
  186. SourceName: zlFutureGoodEdbInfo.Exchange,
  187. Source: 0,
  188. EdbCode: zlFutureGoodEdbInfo.FutureGoodEdbCode,
  189. EdbName: zlFutureGoodEdbInfo.FutureGoodEdbName,
  190. EdbAliasName: zlFutureGoodEdbInfo.FutureGoodEdbName,
  191. EdbNameEn: zlFutureGoodEdbInfo.FutureGoodEdbNameEn,
  192. EdbType: edbInfoMapping.EdbType,
  193. Frequency: edbInfoMapping.Frequency,
  194. FrequencyEn: edbInfoMapping.FrequencyEn,
  195. Unit: edbInfoMapping.Unit,
  196. UnitEn: edbInfoMapping.UnitEn,
  197. StartDate: zlFutureGoodEdbInfo.StartDate,
  198. EndDate: zlFutureGoodEdbInfo.EndDate,
  199. ModifyTime: zlFutureGoodEdbInfo.ModifyTime.Format(utils.FormatDateTime),
  200. ChartEdbMappingId: zlFutureGoodEdbInfo.FutureGoodEdbInfoId,
  201. ChartInfoId: edbInfoMapping.ChartInfoId,
  202. MaxData: zlFutureGoodEdbInfo.MaxValue,
  203. MinData: zlFutureGoodEdbInfo.MinValue,
  204. IsOrder: edbInfoMapping.IsOrder,
  205. IsAxis: edbInfoMapping.IsAxis,
  206. EdbInfoType: edbInfoMapping.EdbInfoType,
  207. EdbInfoCategoryType: edbInfoMapping.EdbInfoCategoryType,
  208. LeadValue: edbInfoMapping.LeadValue,
  209. LeadUnit: edbInfoMapping.LeadUnit,
  210. LeadUnitEn: edbInfoMapping.LeadUnitEn,
  211. ChartStyle: edbInfoMapping.ChartStyle,
  212. ChartColor: edbInfoMapping.ChartColor,
  213. PredictChartColor: edbInfoMapping.PredictChartColor,
  214. ChartWidth: edbInfoMapping.ChartWidth,
  215. ChartType: edbInfoMapping.ChartType,
  216. LatestDate: zlFutureGoodEdbInfo.LatestDate.Format(utils.FormatDateTime),
  217. LatestValue: zlFutureGoodEdbInfo.LatestValue,
  218. UniqueCode: futureGoodEdbInfoMapping.UniqueCode + strconv.Itoa(0),
  219. MinValue: zlFutureGoodEdbInfo.MinValue,
  220. MaxValue: zlFutureGoodEdbInfo.MaxValue,
  221. DataList: nil,
  222. IsNullData: false,
  223. }
  224. edbList = append(edbList, zlFutureGoodEdbMapping)
  225. edbList = append(edbList, futureGoodMappingList...)
  226. } else {
  227. edbList = append(edbList, futureGoodMappingList...)
  228. }
  229. xEdbIdValue, yDataList, err = BarChartData(edbList[0], futureGoodEdbInfoList, edbDataListMap, barChartInfoDateList, regionType, latestDate)
  230. xDataList = []data_manage.XData{
  231. {
  232. Name: "现货价",
  233. NameEn: "Spot Price",
  234. },
  235. }
  236. //yDataList =make([]data_manage.YData,0)
  237. //data_manage.YData{
  238. // Date: "",
  239. // Color: "",
  240. // Name: "",
  241. // NameEn: "",
  242. // Value: nil,
  243. // NoDataEdbList: nil,
  244. // XEdbInfoIdList: nil,
  245. //}
  246. futureGoodEdbInfoIndexMap := make(map[int]int)
  247. for index, v := range futureGoodEdbInfoList {
  248. futureGoodEdbInfoIndexMap[v.FutureGoodEdbInfoId] = index
  249. }
  250. nMap := make(map[int]int)
  251. maxIndex := 0 // 最大x轴的下标
  252. for k, tmpYData := range yDataList {
  253. yDataMap := tmpYData.EdbValMap
  254. edbInfoIdList := make([]int, 0)
  255. noDataEdbInfoIdList := make([]int, 0)
  256. valueList := make([]float64, 0)
  257. noDataEdbIdMap := make(map[int]int)
  258. // 所有的N值
  259. for _, n := range tmpYData.M {
  260. nMap[n] = n
  261. }
  262. // 基础指标
  263. {
  264. baseEdbInfId := edbList[0].EdbInfoId
  265. edbInfoIdList = append(edbInfoIdList, baseEdbInfId)
  266. tmpVal, ok := yDataMap[baseEdbInfId]
  267. valueList = append(valueList, tmpVal)
  268. if !ok || tmpVal == 0 {
  269. noDataEdbInfoIdList = append(noDataEdbInfoIdList, baseEdbInfId)
  270. noDataEdbIdMap[baseEdbInfId] = baseEdbInfId
  271. }
  272. }
  273. for _, futureGoodEdbInfo := range futureGoodEdbInfoList {
  274. tmpEdbInfId := futureGoodEdbInfo.FutureGoodEdbInfoId
  275. edbInfoIdList = append(edbInfoIdList, tmpEdbInfId)
  276. tmpVal, ok := yDataMap[tmpEdbInfId]
  277. valueList = append(valueList, tmpVal)
  278. if !ok || tmpVal == 0 {
  279. noDataEdbInfoIdList = append(noDataEdbInfoIdList, tmpEdbInfId)
  280. noDataEdbIdMap[tmpEdbInfId] = tmpEdbInfId
  281. }
  282. }
  283. //tmpYData.Value = valueList
  284. tmpYData.NoDataEdbList = noDataEdbInfoIdList
  285. yDataList[k] = tmpYData
  286. lenEdbId := len(edbInfoIdList)
  287. tmpMaxIndex := lenEdbId - 1 // 当前数据的最大x轴的下标
  288. for i := lenEdbId - 1; i >= 0; i-- {
  289. // 如果没有在无数据的指标列表中找到,那么就找到了最大x轴的下标
  290. if _, ok := noDataEdbIdMap[edbInfoIdList[i]]; !ok {
  291. // 如果最大x轴的下标 小于 当前下标,那么就重新赋值
  292. if maxIndex < i-1 {
  293. maxIndex = i - 1
  294. }
  295. break
  296. }
  297. tmpMaxIndex = i - 1
  298. }
  299. // 如果最大x轴的下标 小于 当前下标,那么就重新赋值
  300. if maxIndex < tmpMaxIndex {
  301. maxIndex = tmpMaxIndex
  302. }
  303. }
  304. //xEdbIdValue = xEdbIdValue[0:maxIndex]
  305. // 找出所有的N值,并进行正序排列
  306. nList := make([]int, 0)
  307. for _, n := range nMap {
  308. nList = append(nList, n)
  309. }
  310. sort.Slice(nList, func(i, j int) bool {
  311. return nList[i] < nList[j]
  312. })
  313. for k, v := range yDataList {
  314. if len(v.XEdbInfoIdList) >= maxIndex+1 {
  315. yDataList[k].XEdbInfoIdList = v.XEdbInfoIdList[0 : maxIndex+1]
  316. }
  317. if len(v.Value) >= maxIndex+1 {
  318. yDataList[k].Value = v.Value[0 : maxIndex+1]
  319. }
  320. }
  321. tmpXDataList, newYDataList, err := handleResultData(regionType, futureGoodEdbType, yDataList, futureGoodEdbInfoList, maxIndex)
  322. if err != nil {
  323. return
  324. }
  325. xDataList = append(xDataList, tmpXDataList...)
  326. yDataList = newYDataList
  327. return
  328. }
  329. // BarChartData 获取数据
  330. func BarChartData(edbInfoMapping *data_manage.ChartEdbInfoMapping, futureGoodMappingList []*future_good2.FutureGoodEdbInfo, edbDataListMap map[int][]*data_manage.EdbDataList, barChartInfoDateList []data_manage.BarChartInfoDateReq, regionType, latestDate string) (edbIdList []int, yDataList []data_manage.YData, err error) {
  331. // 指标数据数组(10086:{"2022-12-02":100.01,"2022-12-01":102.3})
  332. edbDataMap := make(map[int]map[string]float64)
  333. for edbInfoId, edbDataList := range edbDataListMap {
  334. edbDateData := make(map[string]float64)
  335. for _, edbData := range edbDataList {
  336. edbDateData[edbData.DataTime] = edbData.Value
  337. }
  338. edbDataMap[edbInfoId] = edbDateData
  339. }
  340. // edbIdList 指标展示顺序;x轴的指标顺序
  341. edbIdList = make([]int, 0)
  342. edbIdList = append(edbIdList, edbInfoMapping.EdbInfoId)
  343. for _, v := range futureGoodMappingList {
  344. edbIdList = append(edbIdList, v.FutureGoodEdbInfoId)
  345. }
  346. latestDateTime, _ := time.ParseInLocation(utils.FormatDate, latestDate, time.Local)
  347. yDataList = make([]data_manage.YData, 0) //y轴的数据列表
  348. for _, barChartInfoDate := range barChartInfoDateList {
  349. yDataMap := make(map[int]float64)
  350. var maxDate time.Time
  351. var findDateTime time.Time
  352. switch barChartInfoDate.Type {
  353. case 1: //最新值
  354. findDateTime = latestDateTime
  355. case 2: //近期几天
  356. findDateTime = latestDateTime.AddDate(0, 0, -barChartInfoDate.Value)
  357. case 3: // 固定日期
  358. //寻找固定日期的数据
  359. tmpFindDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local)
  360. if tmpErr != nil {
  361. err = tmpErr
  362. return
  363. }
  364. findDateTime = tmpFindDateTime
  365. default:
  366. err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type))
  367. return
  368. }
  369. if findDateTime.IsZero() {
  370. err = errors.New("错误的日期")
  371. return
  372. }
  373. findDataList := make([]float64, 0) // 当前日期的数据值
  374. noDataIdList := make([]int, 0) // 没有数据的指标id
  375. noDataIdMap := make(map[int]int, 0) // 没有数据的指标map
  376. xEdbInfoIdList := make([]int, 0) // 当前数据的指标id列表
  377. // 现货指标
  378. realDateTime, findDataValue, isFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[edbInfoMapping.EdbInfoId], edbDataMap[edbInfoMapping.EdbInfoId])
  379. if tmpErr != nil {
  380. err = tmpErr
  381. return
  382. }
  383. findDataList = append(findDataList, findDataValue)
  384. yDataMap[edbInfoMapping.EdbInfoId] = findDataValue
  385. if isFind {
  386. maxDate = realDateTime
  387. } else {
  388. noDataIdList = append(noDataIdList, edbInfoMapping.EdbInfoId)
  389. noDataIdMap[edbInfoMapping.EdbInfoId] = edbInfoMapping.EdbInfoId
  390. }
  391. currMonth := findDateTime.Month() // 当前月份
  392. currYear := findDateTime.Year() // 当前年份
  393. xEdbInfoIdList = append(xEdbInfoIdList, edbInfoMapping.EdbInfoId)
  394. mList := make([]int, 0) // 间隔月份
  395. indexList := make([]int, 0)
  396. if regionType == `国内` {
  397. for i := currMonth + 1; i <= 12; i++ {
  398. indexList = append(indexList, int(i))
  399. mList = append(mList, int(i-currMonth))
  400. }
  401. for i := 1; i < int(currMonth); i++ {
  402. indexList = append(indexList, i)
  403. mList = append(mList, 12+i-int(currMonth))
  404. }
  405. } else {
  406. for i, v := range futureGoodMappingList {
  407. if v.FutureGoodEdbType == 2 {
  408. if i == 0 {
  409. continue
  410. }
  411. indexList = append(indexList, i)
  412. mList = append(mList, v.Month)
  413. } else {
  414. if v.Year > currYear || (v.Year == currYear && v.Month > int(currMonth)) {
  415. indexList = append(indexList, i)
  416. mList = append(mList, (v.Year-currYear)*12+v.Month-int(currMonth))
  417. }
  418. }
  419. }
  420. }
  421. for _, i := range indexList {
  422. futureGoodMapping := futureGoodMappingList[i] // 当前的期货指标
  423. //tmpRealDateTime, tmpFindDataValue, tmpIsFind, tmpErr := GetNeedDateData(findDateTime, edbDataListMap[futureGoodMapping.FutureGoodEdbInfoId], edbDataMap[futureGoodMapping.FutureGoodEdbInfoId])
  424. //if tmpErr != nil {
  425. // err = tmpErr
  426. // return
  427. //}
  428. tmpRealDateTime := findDateTime
  429. tmpFindDataValue, tmpIsFind := edbDataMap[futureGoodMapping.FutureGoodEdbInfoId][findDateTime.Format(utils.FormatDate)]
  430. yDataMap[futureGoodMapping.FutureGoodEdbInfoId] = tmpFindDataValue
  431. findDataList = append(findDataList, tmpFindDataValue)
  432. if tmpIsFind {
  433. if maxDate.IsZero() || maxDate.Before(tmpRealDateTime) {
  434. maxDate = tmpRealDateTime
  435. }
  436. } else {
  437. noDataIdList = append(noDataIdList, futureGoodMapping.FutureGoodEdbInfoId)
  438. noDataIdMap[futureGoodMapping.FutureGoodEdbInfoId] = futureGoodMapping.FutureGoodEdbInfoId
  439. }
  440. // 当前期货合约的指标
  441. xEdbInfoIdList = append(xEdbInfoIdList, futureGoodMapping.FutureGoodEdbInfoId)
  442. }
  443. yName := barChartInfoDate.Name
  444. yNameEn := barChartInfoDate.Name
  445. if yName == `` {
  446. if barChartInfoDate.Type == 2 {
  447. yName = strconv.Itoa(barChartInfoDate.Value) + "天前"
  448. if barChartInfoDate.Value == 1 {
  449. yNameEn = strconv.Itoa(barChartInfoDate.Value) + "day ago"
  450. } else {
  451. yNameEn = strconv.Itoa(barChartInfoDate.Value) + " days ago"
  452. }
  453. } else {
  454. yName = maxDate.Format(utils.FormatDate)
  455. yNameEn = maxDate.Format(utils.FormatDate)
  456. }
  457. }
  458. yDate := "0000-00-00"
  459. if !maxDate.IsZero() {
  460. yDate = maxDate.Format(utils.FormatDate)
  461. }
  462. // 数据处理,将没有数据的下标,赋值平均值
  463. {
  464. hasDataIndexList := make([]int, 0)
  465. for dataK, edbInfoId := range xEdbInfoIdList {
  466. if _, ok := noDataIdMap[edbInfoId]; !ok { // 如果是没有数据的指标id
  467. hasDataIndexList = append(hasDataIndexList, dataK)
  468. }
  469. }
  470. lenHasDataIndex := len(hasDataIndexList)
  471. if lenHasDataIndex > 0 {
  472. for lenHasDataI := 1; lenHasDataI < lenHasDataIndex; lenHasDataI++ {
  473. perK := hasDataIndexList[lenHasDataI-1] //上一个有数据的指标下标
  474. currK := hasDataIndexList[lenHasDataI] //当前有数据的指标下标
  475. preVal := findDataList[perK] //上一个有数据的坐标的值
  476. currVal := findDataList[currK] //当前有数据的指标的值
  477. // 环差值
  478. hcValDeci := decimal.NewFromFloat(currVal).Sub(decimal.NewFromFloat(preVal)).Div(decimal.NewFromInt(int64(currK - perK)))
  479. var tmpI int64
  480. // 将两个中间的数据做平均值补全
  481. for hcI := perK + 1; hcI < currK; hcI++ {
  482. tmpI++
  483. findDataList[hcI], _ = decimal.NewFromFloat(preVal).Add(hcValDeci.Mul(decimal.NewFromInt(tmpI))).RoundCeil(4).Float64()
  484. }
  485. }
  486. }
  487. }
  488. yDataList = append(yDataList, data_manage.YData{
  489. Date: yDate,
  490. ConfigDate: findDateTime,
  491. Value: findDataList,
  492. NoDataEdbList: noDataIdList,
  493. XEdbInfoIdList: xEdbInfoIdList,
  494. Color: barChartInfoDate.Color,
  495. Name: yName,
  496. NameEn: yNameEn,
  497. EdbValMap: yDataMap,
  498. M: mList,
  499. })
  500. }
  501. return
  502. }
  503. // handleResultData 处理成最终的结果数据
  504. func handleResultData(regionType string, futureGoodEdbType int, yDataList []data_manage.YData, futureGoodEdbInfoList []*future_good2.FutureGoodEdbInfo, maxIndex int) (xDataList []data_manage.XData, newYDataList []data_manage.YData, err error) {
  505. xDataList = make([]data_manage.XData, 0)
  506. newYDataList = yDataList
  507. if regionType == `国内` {
  508. for i := 1; i < 12; i++ {
  509. if i > maxIndex {
  510. break
  511. }
  512. xDataList = append(xDataList, data_manage.XData{
  513. Name: fmt.Sprint("M+", i),
  514. NameEn: fmt.Sprint("M+", i),
  515. })
  516. }
  517. return
  518. }
  519. futureGoodEdbInfoMap := make(map[int]*future_good2.FutureGoodEdbInfo)
  520. for _, v := range futureGoodEdbInfoList {
  521. futureGoodEdbInfoMap[v.FutureGoodEdbInfoId] = v
  522. }
  523. if futureGoodEdbType == 2 { // FutureGoodEdbType int `description:"指标类型,1:年月是固定的合约;2:只有M+N期的合约,未固定年月"`
  524. nList := []int{3, 15, 27}
  525. for _, i := range nList {
  526. xDataList = append(xDataList, data_manage.XData{
  527. Name: fmt.Sprint("M+", i),
  528. NameEn: fmt.Sprint("M+", i),
  529. })
  530. }
  531. for yIndex, yData := range yDataList {
  532. newYDataList[yIndex].XEdbInfoIdList = []int{}
  533. newYDataList[yIndex].Value = []float64{}
  534. tmpNList := nList
  535. //当前的主力合约
  536. newYDataList[yIndex].XEdbInfoIdList = append(newYDataList[yIndex].XEdbInfoIdList, yData.XEdbInfoIdList[0])
  537. newYDataList[yIndex].Value = append(newYDataList[yIndex].Value, yData.Value[0])
  538. xEdbInfoIdList := yData.XEdbInfoIdList[1:]
  539. valIndex := 1
  540. needNum := 0
  541. for _, n := range tmpNList {
  542. if len(xEdbInfoIdList) > 0 {
  543. edbInfoId := xEdbInfoIdList[0]
  544. futureGoodEdbInfo, ok := futureGoodEdbInfoMap[edbInfoId]
  545. if !ok {
  546. err = errors.New("找不到指标")
  547. return
  548. }
  549. // 当前距离最早的日期相差的N数
  550. if futureGoodEdbInfo.Month == n {
  551. if needNum > 0 {
  552. currVal := yData.Value[valIndex]
  553. preVal := yData.Value[valIndex-1]
  554. hcValDeci := decimal.NewFromFloat(currVal).Sub(decimal.NewFromFloat(preVal)).Div(decimal.NewFromInt(int64(needNum + 1)))
  555. for tmpNum := 0; tmpNum < needNum; tmpNum++ {
  556. newYDataList[yIndex].XEdbInfoIdList = append(newYDataList[yIndex].XEdbInfoIdList, 0)
  557. // 赋值平均值
  558. tmpVal, _ := decimal.NewFromFloat(preVal).Add(hcValDeci.Mul(decimal.NewFromInt(int64(tmpNum + 1)))).RoundCeil(4).Float64()
  559. newYDataList[yIndex].Value = append(newYDataList[yIndex].Value, tmpVal)
  560. }
  561. }
  562. newYDataList[yIndex].XEdbInfoIdList = append(newYDataList[yIndex].XEdbInfoIdList, edbInfoId)
  563. newYDataList[yIndex].Value = append(newYDataList[yIndex].Value, yData.Value[valIndex])
  564. valIndex++
  565. needNum = 0
  566. if len(xEdbInfoIdList) > 0 {
  567. xEdbInfoIdList = xEdbInfoIdList[1:]
  568. }
  569. } else {
  570. needNum++
  571. }
  572. }
  573. }
  574. }
  575. maxI := 0
  576. for _, yData := range newYDataList {
  577. lenEdb := len(yData.XEdbInfoIdList)
  578. for i := 0; i < lenEdb; i++ {
  579. if yData.XEdbInfoIdList[i] != 0 && !utils.InArrayByInt(yData.NoDataEdbList, yData.XEdbInfoIdList[i]) {
  580. if maxI < i {
  581. maxI = i
  582. }
  583. }
  584. }
  585. }
  586. xDataList = xDataList[0:maxI]
  587. for yIndex, yData := range newYDataList {
  588. if len(yData.XEdbInfoIdList) > maxI+1 {
  589. newYDataList[yIndex].XEdbInfoIdList = yData.XEdbInfoIdList[0 : maxI+1]
  590. }
  591. if len(yData.Value) > maxI+1 {
  592. newYDataList[yIndex].Value = yData.Value[0 : maxI+1]
  593. }
  594. }
  595. return
  596. }
  597. nMap := make(map[int]int)
  598. for _, v := range yDataList {
  599. findDateTime := v.ConfigDate
  600. currMonth := findDateTime.Month() // 当前月份
  601. currYear := findDateTime.Year() // 当前年份
  602. //v.XEdbInfoIdList
  603. for edbInfoIndex, edbInfoId := range v.XEdbInfoIdList {
  604. // 第一个不处理
  605. if edbInfoIndex == 0 {
  606. continue
  607. }
  608. futureGoodEdbInfo, ok := futureGoodEdbInfoMap[edbInfoId]
  609. if !ok {
  610. err = errors.New("找不到指标")
  611. return
  612. }
  613. n := (futureGoodEdbInfo.Year-currYear)*12 + futureGoodEdbInfo.Month - int(currMonth)
  614. nMap[n] = n
  615. }
  616. }
  617. // 找出所有的N值,并进行正序排列
  618. nList := make([]int, 0)
  619. for _, n := range nMap {
  620. nList = append(nList, n)
  621. }
  622. sort.Slice(nList, func(i, j int) bool {
  623. return nList[i] < nList[j]
  624. })
  625. //prevMonth := 1
  626. for _, n := range nList {
  627. xDataList = append(xDataList, data_manage.XData{
  628. Name: fmt.Sprint("M+", n),
  629. NameEn: fmt.Sprint("M+", n),
  630. })
  631. }
  632. for yIndex, yData := range yDataList {
  633. newYDataList[yIndex].XEdbInfoIdList = []int{}
  634. newYDataList[yIndex].Value = []float64{}
  635. tmpNList := nList
  636. //当前的主力合约
  637. newYDataList[yIndex].XEdbInfoIdList = append(newYDataList[yIndex].XEdbInfoIdList, yData.XEdbInfoIdList[0])
  638. newYDataList[yIndex].Value = append(newYDataList[yIndex].Value, yData.Value[0])
  639. xEdbInfoIdList := yData.XEdbInfoIdList[1:]
  640. currDataTime := yData.ConfigDate
  641. valIndex := 1
  642. needNum := 0
  643. for _, n := range tmpNList {
  644. if len(xEdbInfoIdList) > 0 {
  645. edbInfoId := xEdbInfoIdList[0]
  646. futureGoodEdbInfo, ok := futureGoodEdbInfoMap[edbInfoId]
  647. if !ok {
  648. err = errors.New("找不到指标")
  649. return
  650. }
  651. // 当前距离最早的日期相差的N数
  652. divMonth := (futureGoodEdbInfo.Year-currDataTime.Year())*12 + (futureGoodEdbInfo.Month - int(currDataTime.Month()))
  653. if divMonth == n {
  654. if needNum > 0 {
  655. currVal := yData.Value[valIndex]
  656. preVal := yData.Value[valIndex-1]
  657. hcValDeci := decimal.NewFromFloat(currVal).Sub(decimal.NewFromFloat(preVal)).Div(decimal.NewFromInt(int64(needNum + 1)))
  658. for tmpNum := 0; tmpNum < needNum; tmpNum++ {
  659. newYDataList[yIndex].XEdbInfoIdList = append(newYDataList[yIndex].XEdbInfoIdList, 0)
  660. // 赋值平均值
  661. tmpVal, _ := decimal.NewFromFloat(preVal).Add(hcValDeci.Mul(decimal.NewFromInt(int64(tmpNum + 1)))).RoundCeil(4).Float64()
  662. newYDataList[yIndex].Value = append(newYDataList[yIndex].Value, tmpVal)
  663. }
  664. }
  665. newYDataList[yIndex].XEdbInfoIdList = append(newYDataList[yIndex].XEdbInfoIdList, edbInfoId)
  666. newYDataList[yIndex].Value = append(newYDataList[yIndex].Value, yData.Value[valIndex])
  667. valIndex++
  668. needNum = 0
  669. if len(xEdbInfoIdList) > 0 {
  670. xEdbInfoIdList = xEdbInfoIdList[1:]
  671. }
  672. } else {
  673. needNum++
  674. }
  675. }
  676. }
  677. }
  678. maxI := 0
  679. for _, yData := range newYDataList {
  680. lenEdb := len(yData.XEdbInfoIdList)
  681. for i := 0; i < lenEdb; i++ {
  682. if yData.XEdbInfoIdList[i] != 0 && !utils.InArrayByInt(yData.NoDataEdbList, yData.XEdbInfoIdList[i]) {
  683. if maxI < i {
  684. maxI = i
  685. }
  686. }
  687. }
  688. }
  689. xDataList = xDataList[0:maxI]
  690. for yIndex, yData := range newYDataList {
  691. if len(yData.XEdbInfoIdList) > maxI+1 {
  692. newYDataList[yIndex].XEdbInfoIdList = yData.XEdbInfoIdList[0 : maxI+1]
  693. }
  694. if len(yData.Value) > maxI+1 {
  695. newYDataList[yIndex].Value = yData.Value[0 : maxI+1]
  696. }
  697. }
  698. return
  699. }
  700. // getFutureGoodEdbInfoList 获取适用的指标列表
  701. func getFutureGoodEdbInfoList(latestDateTime time.Time, tmpFutureGoodEdbInfoList []*future_good2.FutureGoodEdbInfo, barChartInfoDateList []data_manage.BarChartInfoDateReq) (earliestDateTime time.Time, futureGoodEdbInfoList []*future_good2.FutureGoodEdbInfo, err error) {
  702. maxM := 32 //最大32期合约
  703. futureGoodEdbInfoList = make([]*future_good2.FutureGoodEdbInfo, 0)
  704. earliestDateTime = latestDateTime // 数据的最早日期,目的是为了找出最早的合约
  705. for _, barChartInfoDate := range barChartInfoDateList {
  706. var findDateTime time.Time
  707. switch barChartInfoDate.Type {
  708. case 1: //最新值
  709. findDateTime = latestDateTime
  710. case 2: //近期几天
  711. findDateTime = latestDateTime.AddDate(0, 0, -barChartInfoDate.Value)
  712. case 3: // 固定日期
  713. //寻找固定日期的数据
  714. tmpFindDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, barChartInfoDate.Date, time.Local)
  715. if tmpErr != nil {
  716. err = tmpErr
  717. return
  718. }
  719. findDateTime = tmpFindDateTime
  720. default:
  721. err = errors.New(fmt.Sprint("日期类型异常,Type:", barChartInfoDate.Type))
  722. return
  723. }
  724. if findDateTime.IsZero() {
  725. err = errors.New("错误的日期")
  726. return
  727. }
  728. if findDateTime.Before(earliestDateTime) {
  729. earliestDateTime = findDateTime
  730. }
  731. }
  732. for _, v := range tmpFutureGoodEdbInfoList {
  733. if v.RegionType == `国内` {
  734. futureGoodEdbInfoList = append(futureGoodEdbInfoList, v)
  735. continue
  736. }
  737. //海外的连续日期,目前
  738. if v.FutureGoodEdbType == 2 {
  739. if v.Month <= maxM {
  740. //addMonth := int(earliestDateTime.Month()) + v.Month
  741. //v.Year = earliestDateTime.Year() + addMonth/12
  742. //realMonth := addMonth % 12
  743. //if realMonth == 0 {
  744. // realMonth = 12
  745. //}
  746. //v.Month = realMonth
  747. futureGoodEdbInfoList = append(futureGoodEdbInfoList, v)
  748. }
  749. continue
  750. }
  751. if v.Year < earliestDateTime.Year() {
  752. continue
  753. }
  754. // 小于等于当前年,那么就肯定是ok的
  755. if v.Year <= earliestDateTime.Year() {
  756. futureGoodEdbInfoList = append(futureGoodEdbInfoList, v)
  757. continue
  758. }
  759. // 如果(当前年-最新日期的年份) * 12个月 + (当前月-最新日期的月份) 小于总月份
  760. if (v.Year-earliestDateTime.Year())*12+(v.Month-int(earliestDateTime.Month())) <= maxM {
  761. futureGoodEdbInfoList = append(futureGoodEdbInfoList, v)
  762. continue
  763. }
  764. }
  765. return
  766. }
  767. // GetNeedDateData 获取合约内需要的日期数据
  768. func GetNeedDateData(needDateTime time.Time, dataList []*data_manage.EdbDataList, edbDataMap map[string]float64) (findDateTime time.Time, findDataValue float64, isFind bool, err error) {
  769. //dataList := edbDataListMap[edbInfoId] //指标的所有数据值
  770. if len(dataList) <= 0 {
  771. // 没有数据的指标id
  772. return
  773. }
  774. //最早的日期
  775. minDateTime, err := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  776. if err != nil {
  777. return
  778. }
  779. for tmpDateTime := needDateTime; tmpDateTime.After(minDateTime) || tmpDateTime.Equal(minDateTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  780. tmpDate := tmpDateTime.Format(utils.FormatDate)
  781. if tmpValue, ok := edbDataMap[tmpDate]; ok { //如果能找到数据,那么就返回
  782. // 数据为0,也直接返回,做无值处理
  783. if tmpValue == 0 {
  784. return
  785. }
  786. findDateTime, _ = time.ParseInLocation(utils.FormatDate, tmpDate, time.Local)
  787. findDataValue = tmpValue
  788. isFind = true
  789. return
  790. }
  791. }
  792. return
  793. }