predict_edb_info.go 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. package data
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "eta_gn/eta_chart_lib/models"
  6. "eta_gn/eta_chart_lib/models/data_manage"
  7. "eta_gn/eta_chart_lib/utils"
  8. "strconv"
  9. "time"
  10. "github.com/shopspring/decimal"
  11. )
  12. func getPredictEdbDayList(startDate, endDate time.Time, frequency, dataDateType string) (dayList []time.Time) {
  13. if dataDateType == `` {
  14. dataDateType = `交易日`
  15. }
  16. switch frequency {
  17. case "日度":
  18. for currDate := startDate.AddDate(0, 0, 1); currDate.Before(endDate) || currDate.Equal(endDate); currDate = currDate.AddDate(0, 0, 1) {
  19. if dataDateType == `交易日` && (currDate.Weekday() == time.Sunday || currDate.Weekday() == time.Saturday) {
  20. continue
  21. }
  22. dayList = append(dayList, currDate)
  23. }
  24. case "周度":
  25. for currDate := startDate.AddDate(0, 0, 7); currDate.Before(endDate) || currDate.Equal(endDate); currDate = currDate.AddDate(0, 0, 7) {
  26. dayList = append(dayList, currDate)
  27. }
  28. case "旬度":
  29. for currDate := startDate.AddDate(0, 0, 1); currDate.Before(endDate) || currDate.Equal(endDate); {
  30. nextDate := currDate.AddDate(0, 0, 1)
  31. if nextDate.Day() == 11 || nextDate.Day() == 21 || nextDate.Day() == 1 {
  32. dayList = append(dayList, currDate)
  33. }
  34. currDate = nextDate
  35. }
  36. case "月度":
  37. for currDate := startDate; currDate.Before(endDate) || currDate.Equal(endDate); {
  38. currDate = time.Date(currDate.Year(), currDate.Month(), 1, 0, 0, 0, 0, time.Now().Location()).AddDate(0, 1, -1)
  39. if !currDate.After(endDate) && !currDate.Equal(startDate) {
  40. dayList = append(dayList, currDate)
  41. }
  42. currDate = currDate.AddDate(0, 0, 1)
  43. }
  44. case "季度":
  45. for currDate := startDate; currDate.Before(endDate) || currDate.Equal(endDate); {
  46. currDate = time.Date(currDate.Year(), currDate.Month(), 1, 0, 0, 0, 0, time.Now().Location()).AddDate(0, 1, -1)
  47. if !currDate.After(endDate) && !currDate.Equal(startDate) {
  48. if currDate.Month() == 3 || currDate.Month() == 6 || currDate.Month() == 9 || currDate.Month() == 12 {
  49. dayList = append(dayList, currDate)
  50. }
  51. }
  52. currDate = currDate.AddDate(0, 0, 1)
  53. }
  54. case "半年度":
  55. for currDate := startDate; currDate.Before(endDate) || currDate.Equal(endDate); {
  56. currDate = time.Date(currDate.Year(), currDate.Month(), 1, 0, 0, 0, 0, time.Now().Location()).AddDate(0, 1, -1)
  57. if !currDate.After(endDate) && !currDate.Equal(startDate) {
  58. if currDate.Month() == 6 || currDate.Month() == 12 {
  59. dayList = append(dayList, currDate)
  60. }
  61. }
  62. currDate = currDate.AddDate(0, 0, 1)
  63. }
  64. case "年度":
  65. for currDate := startDate; currDate.Before(endDate) || currDate.Equal(endDate); {
  66. currDate = time.Date(currDate.Year()+1, 12, 31, 0, 0, 0, 0, time.Now().Location())
  67. if !currDate.After(endDate) && !currDate.Equal(startDate) {
  68. dayList = append(dayList, currDate)
  69. }
  70. }
  71. }
  72. return
  73. }
  74. func GetPredictDataListByPredictEdbInfoId(edbInfoId int, startDate, endDate string, isTimeBetween bool) (edbInfo *data_manage.EdbInfo, dataList []*models.EdbDataList, sourceEdbInfoItem *data_manage.EdbInfo, predictEdbConf *data_manage.PredictEdbConf, err error, errMsg string) {
  75. edbInfo, err = data_manage.GetEdbInfoById(edbInfoId)
  76. if err != nil {
  77. errMsg = `获取预测指标信息失败`
  78. return
  79. }
  80. dataList, sourceEdbInfoItem, predictEdbConf, err, errMsg = GetPredictDataListByPredictEdbInfo(edbInfo, startDate, endDate, isTimeBetween)
  81. return
  82. }
  83. func GetPredictDataListByPredictEdbInfo(edbInfo *data_manage.EdbInfo, startDate, endDate string, isTimeBetween bool) (dataList []*models.EdbDataList, sourceEdbInfoItem *data_manage.EdbInfo, predictEdbConf *data_manage.PredictEdbConf, err error, errMsg string) {
  84. if edbInfo.EdbType != 1 {
  85. if !isTimeBetween {
  86. endDate = ``
  87. }
  88. return GetPredictCalculateDataListByPredictEdbInfo(edbInfo, startDate, endDate)
  89. }
  90. predictEdbConfList, err := data_manage.GetPredictEdbConfListById(edbInfo.EdbInfoId)
  91. if err != nil && !utils.IsErrNoRow(err) {
  92. errMsg = "获取预测指标配置信息失败"
  93. return
  94. }
  95. if len(predictEdbConfList) == 0 {
  96. errMsg = "获取预测指标配置信息失败"
  97. err = errors.New(errMsg)
  98. return
  99. }
  100. predictEdbConf = predictEdbConfList[0]
  101. if predictEdbConf == nil {
  102. errMsg = "获取预测指标配置信息失败"
  103. err = errors.New(errMsg)
  104. return
  105. }
  106. sourceEdbInfoItem, err = data_manage.GetEdbInfoById(predictEdbConf.SourceEdbInfoId)
  107. if err != nil {
  108. if utils.IsErrNoRow(err) {
  109. errMsg = "找不到来源指标信息"
  110. err = errors.New(errMsg)
  111. }
  112. return
  113. }
  114. allDataList := make([]*models.EdbDataList, 0)
  115. dataList, err = models.GetEdbDataList(sourceEdbInfoItem.Source, sourceEdbInfoItem.SubSource, sourceEdbInfoItem.EdbInfoId, startDate, endDate)
  116. if err != nil {
  117. return
  118. }
  119. if startDate != `` {
  120. allDataList, err = models.GetEdbDataList(sourceEdbInfoItem.Source, sourceEdbInfoItem.SubSource, sourceEdbInfoItem.EdbInfoId, "", "")
  121. if err != nil {
  122. return
  123. }
  124. } else {
  125. allDataList = dataList
  126. }
  127. predictDataList := make([]*models.EdbDataList, 0)
  128. endDateStr := edbInfo.EndDate //预测指标的结束日期
  129. if isTimeBetween && endDate != `` { //如果是时间区间,同时截止日期不为空的情况,那么
  130. reqEndDateTime, _ := time.ParseInLocation(utils.FormatDate, endDate, time.Local)
  131. endDateTime, _ := time.ParseInLocation(utils.FormatDate, edbInfo.EndDate, time.Local)
  132. if reqEndDateTime.Before(endDateTime) {
  133. endDateStr = endDate
  134. }
  135. }
  136. var predictMinValue, predictMaxValue float64
  137. predictDataList, predictMinValue, predictMaxValue, err = GetChartPredictEdbInfoDataListByConfList(predictEdbConfList, startDate, sourceEdbInfoItem.LatestDate, endDateStr, edbInfo.Frequency, edbInfo.DataDateType, allDataList)
  138. if err != nil {
  139. return
  140. }
  141. dataList = append(dataList, predictDataList...)
  142. if len(predictDataList) > 0 {
  143. if edbInfo.MinValue > predictMinValue {
  144. edbInfo.MinValue = predictMinValue
  145. }
  146. if edbInfo.MaxValue < predictMaxValue {
  147. edbInfo.MaxValue = predictMaxValue
  148. }
  149. }
  150. return
  151. }
  152. func GetPredictCalculateDataListByPredictEdbInfo(edbInfo *data_manage.EdbInfo, startDate, endDate string) (dataList []*models.EdbDataList, sourceEdbInfoItem *data_manage.EdbInfo, predictEdbConf *data_manage.PredictEdbConf, err error, errMsg string) {
  153. dataList, err = models.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, startDate, endDate)
  154. return
  155. }
  156. func GetChartPredictEdbInfoDataListByConfList(predictEdbConfList []*data_manage.PredictEdbConf, filtrateStartDateStr, latestDateStr, endDateStr, frequency, dataDateType string, realPredictEdbInfoData []*models.EdbDataList) (predictEdbInfoData []*models.EdbDataList, minValue, maxValue float64, err error) {
  157. endDate, err := time.ParseInLocation(utils.FormatDate, endDateStr, time.Local)
  158. if err != nil {
  159. return
  160. }
  161. latestDate, err := time.ParseInLocation(utils.FormatDate, latestDateStr, time.Local)
  162. if err != nil {
  163. return
  164. }
  165. startDate := latestDate
  166. if filtrateStartDateStr != `` {
  167. filtrateStartDate, tmpErr := time.ParseInLocation(utils.FormatDate, filtrateStartDateStr, time.Local)
  168. if tmpErr != nil {
  169. err = tmpErr
  170. return
  171. }
  172. if filtrateStartDate.After(latestDate) {
  173. startDate = filtrateStartDate.AddDate(0, 0, -1)
  174. }
  175. }
  176. existMap := make(map[string]float64)
  177. for _, v := range realPredictEdbInfoData {
  178. existMap[v.DataTime] = v.Value
  179. }
  180. predictEdbInfoData = make([]*models.EdbDataList, 0)
  181. for _, predictEdbConf := range predictEdbConfList {
  182. dataEndTime := endDate
  183. if predictEdbConf.EndDate.Before(dataEndTime) {
  184. dataEndTime = predictEdbConf.EndDate
  185. }
  186. var tmpMinValue, tmpMaxValue float64 // 当前预测结果中的最大/最小值
  187. dayList := getPredictEdbDayList(startDate, dataEndTime, frequency, dataDateType)
  188. if len(dayList) <= 0 { // 如果未来没有日期的话,那么就退出当前循环,进入下一个循环
  189. continue
  190. }
  191. switch predictEdbConf.RuleType {
  192. case 1: //1:最新
  193. var lastDataValue float64 //最新值
  194. tmpAllData := make([]*models.EdbDataList, 0)
  195. tmpAllData = append(tmpAllData, realPredictEdbInfoData...)
  196. tmpAllData = append(tmpAllData, predictEdbInfoData...)
  197. lenTmpAllData := len(tmpAllData)
  198. if lenTmpAllData > 0 {
  199. lastDataValue = tmpAllData[lenTmpAllData-1].Value
  200. }
  201. predictEdbInfoData = GetChartPredictEdbInfoDataListByRule1(predictEdbConf.PredictEdbInfoId, lastDataValue, dayList, predictEdbInfoData, existMap)
  202. tmpMaxValue = lastDataValue
  203. tmpMinValue = lastDataValue
  204. case 2: //2:固定值
  205. tmpValDecimal, tmpErr := decimal.NewFromString(predictEdbConf.Value)
  206. if tmpErr != nil {
  207. err = tmpErr
  208. return
  209. }
  210. dataValue, _ := tmpValDecimal.Float64()
  211. predictEdbInfoData = GetChartPredictEdbInfoDataListByRule1(predictEdbConf.PredictEdbInfoId, dataValue, dayList, predictEdbInfoData, existMap)
  212. tmpMaxValue = dataValue
  213. tmpMinValue = dataValue
  214. case 3: //3:同比
  215. tmpValDecimal, tmpErr := decimal.NewFromString(predictEdbConf.Value)
  216. if tmpErr != nil {
  217. err = tmpErr
  218. return
  219. }
  220. tbValue, _ := tmpValDecimal.Float64()
  221. predictEdbInfoData, tmpMinValue, tmpMaxValue = GetChartPredictEdbInfoDataListByRuleTb(predictEdbConf.PredictEdbInfoId, tbValue, dayList, frequency, realPredictEdbInfoData, predictEdbInfoData, existMap)
  222. case 4: //4:同差
  223. tmpValDecimal, tmpErr := decimal.NewFromString(predictEdbConf.Value)
  224. if tmpErr != nil {
  225. err = tmpErr
  226. return
  227. }
  228. tcValue, _ := tmpValDecimal.Float64()
  229. predictEdbInfoData, tmpMinValue, tmpMaxValue = GetChartPredictEdbInfoDataListByRuleTc(predictEdbConf.PredictEdbInfoId, tcValue, dayList, frequency, realPredictEdbInfoData, predictEdbInfoData, existMap)
  230. case 5: //5:环比
  231. tmpValDecimal, tmpErr := decimal.NewFromString(predictEdbConf.Value)
  232. if tmpErr != nil {
  233. err = tmpErr
  234. return
  235. }
  236. hbValue, _ := tmpValDecimal.Float64()
  237. predictEdbInfoData, tmpMinValue, tmpMaxValue = GetChartPredictEdbInfoDataListByRuleHb(predictEdbConf.PredictEdbInfoId, hbValue, dayList, realPredictEdbInfoData, predictEdbInfoData, existMap)
  238. case 6: //6:环差
  239. tmpValDecimal, tmpErr := decimal.NewFromString(predictEdbConf.Value)
  240. if tmpErr != nil {
  241. err = tmpErr
  242. return
  243. }
  244. hcValue, _ := tmpValDecimal.Float64()
  245. predictEdbInfoData, tmpMinValue, tmpMaxValue = GetChartPredictEdbInfoDataListByRuleHc(predictEdbConf.PredictEdbInfoId, hcValue, dayList, realPredictEdbInfoData, predictEdbInfoData, existMap)
  246. case 7: //7:N期移动均值
  247. nValue, tmpErr := strconv.Atoi(predictEdbConf.Value)
  248. if tmpErr != nil {
  249. err = tmpErr
  250. return
  251. }
  252. predictEdbInfoData, tmpMinValue, tmpMaxValue = GetChartPredictEdbInfoDataListByRuleNMoveMeanValue(predictEdbConf.PredictEdbInfoId, nValue, dayList, realPredictEdbInfoData, predictEdbInfoData, existMap)
  253. case 8: //8:N期段线性外推值
  254. nValue, tmpErr := strconv.Atoi(predictEdbConf.Value)
  255. if tmpErr != nil {
  256. err = tmpErr
  257. return
  258. }
  259. predictEdbInfoData, tmpMinValue, tmpMaxValue = GetChartPredictEdbInfoDataListByRuleNLinearRegression(predictEdbConf.PredictEdbInfoId, nValue, dayList, realPredictEdbInfoData, predictEdbInfoData, existMap)
  260. case 9: //9:动态环差”预测规则;
  261. predictEdbInfoData, tmpMinValue, tmpMaxValue = GetChartPredictEdbInfoDataListByRuleTrendsHC(predictEdbConf.PredictEdbInfoId, predictEdbConf.ConfigId, startDate, dataEndTime, dayList, realPredictEdbInfoData, predictEdbInfoData, existMap)
  262. case 10: //10:根据 给定终值后插值 规则获取预测数据
  263. tmpValDecimal, tmpErr := decimal.NewFromString(predictEdbConf.Value)
  264. if tmpErr != nil {
  265. err = tmpErr
  266. return
  267. }
  268. finalValue, _ := tmpValDecimal.Float64()
  269. predictEdbInfoData, tmpMinValue, tmpMaxValue = GetChartPredictEdbInfoDataListByRuleFinalValueHc(predictEdbConf.PredictEdbInfoId, finalValue, dayList, realPredictEdbInfoData, predictEdbInfoData, existMap)
  270. case 11: //11:根据 季节性 规则获取预测数据
  271. var seasonConf SeasonConf
  272. tmpErr := json.Unmarshal([]byte(predictEdbConf.Value), &seasonConf)
  273. if tmpErr != nil {
  274. err = errors.New("季节性配置信息异常:" + tmpErr.Error())
  275. return
  276. }
  277. calendar := "公历"
  278. if seasonConf.Calendar == "农历" {
  279. calendar = "农历"
  280. }
  281. yearList := make([]int, 0)
  282. if seasonConf.YearType == 1 {
  283. if seasonConf.NValue < 1 {
  284. err = errors.New("连续N年不允许小于1")
  285. return
  286. }
  287. currYear := time.Now().Year()
  288. for i := 0; i < seasonConf.NValue; i++ {
  289. yearList = append(yearList, currYear-i-1)
  290. }
  291. } else {
  292. yearList = seasonConf.YearList
  293. }
  294. predictEdbInfoData, tmpMinValue, tmpMaxValue, err = GetChartPredictEdbInfoDataListByRuleSeason(predictEdbConf.PredictEdbInfoId, yearList, calendar, dayList, realPredictEdbInfoData, predictEdbInfoData, existMap)
  295. if err != nil {
  296. return
  297. }
  298. case 12: //12:根据 移动平均同比 规则获取预测数据
  299. var moveAverageConf MoveAverageConf
  300. tmpErr := json.Unmarshal([]byte(predictEdbConf.Value), &moveAverageConf)
  301. if tmpErr != nil {
  302. err = errors.New("季节性配置信息异常:" + tmpErr.Error())
  303. return
  304. }
  305. predictEdbInfoData, tmpMinValue, tmpMaxValue, err = GetChartPredictEdbInfoDataListByRuleMoveAverageTb(predictEdbConf.PredictEdbInfoId, moveAverageConf.NValue, moveAverageConf.Year, dayList, realPredictEdbInfoData, predictEdbInfoData, existMap)
  306. if err != nil {
  307. return
  308. }
  309. case 13: //13:根据 同比增速差值 规则获取预测数据
  310. tmpValDecimal, tmpErr := decimal.NewFromString(predictEdbConf.Value)
  311. if tmpErr != nil {
  312. err = tmpErr
  313. return
  314. }
  315. tbEndValue, _ := tmpValDecimal.Float64()
  316. predictEdbInfoData, tmpMinValue, tmpMaxValue = GetChartPredictEdbInfoDataListByRuleTbzscz(predictEdbConf.PredictEdbInfoId, tbEndValue, dayList, frequency, realPredictEdbInfoData, predictEdbInfoData, existMap)
  317. case 14: //14:根据 一元线性拟合 规则获取预测数据
  318. var ruleConf RuleLineNhConf
  319. err = json.Unmarshal([]byte(predictEdbConf.Value), &ruleConf)
  320. if err != nil {
  321. err = errors.New("一元线性拟合配置信息异常:" + err.Error())
  322. return
  323. }
  324. newNhccDataMap := make(map[string]float64)
  325. if predictEdbConf.PredictEdbInfoId > 0 { //已经生成的动态数据
  326. tmpPredictEdbRuleDataList, tmpErr := data_manage.GetPredictEdbRuleDataList(predictEdbConf.PredictEdbInfoId, predictEdbConf.ConfigId, "", "")
  327. if tmpErr != nil {
  328. err = tmpErr
  329. return
  330. }
  331. for _, v := range tmpPredictEdbRuleDataList {
  332. newNhccDataMap[v.DataTime] = v.Value
  333. }
  334. } else { //未生成的动态数据,需要使用外部传入的数据进行计算
  335. newNhccDataMap, err = getCalculateNhccData(append(realPredictEdbInfoData, predictEdbInfoData...), ruleConf)
  336. if err != nil {
  337. return
  338. }
  339. }
  340. predictEdbInfoData, tmpMinValue, tmpMaxValue, err = GetChartPredictEdbInfoDataListByRuleLineNh(predictEdbConf.PredictEdbInfoId, dayList, realPredictEdbInfoData, predictEdbInfoData, newNhccDataMap, existMap)
  341. if err != nil {
  342. return
  343. }
  344. case 15: //15:N年均值:过去N年同期均值。过去N年可以连续或者不连续,指标数据均用线性插值补全为日度数据后计算;
  345. predictEdbInfoData, tmpMinValue, tmpMaxValue, err = GetChartPredictEdbInfoDataListByRuleNAnnualAverage(predictEdbConf.PredictEdbInfoId, predictEdbConf.Value, dayList, realPredictEdbInfoData, predictEdbInfoData, existMap)
  346. if err != nil {
  347. return
  348. }
  349. case 16: //16:年度值倒推
  350. predictEdbInfoData, tmpMinValue, tmpMaxValue, err = GetChartPredictEdbInfoDataListByRuleAnnualValueInversion(predictEdbConf.PredictEdbInfoId, predictEdbConf.Value, dayList, frequency, realPredictEdbInfoData, predictEdbInfoData, existMap)
  351. if err != nil {
  352. return
  353. }
  354. }
  355. {
  356. lenPredictEdbInfoData := len(predictEdbInfoData)
  357. if lenPredictEdbInfoData > 0 {
  358. tmpDataEndTime, _ := time.ParseInLocation(utils.FormatDate, predictEdbInfoData[lenPredictEdbInfoData-1].DataTime, time.Local)
  359. if startDate.Before(tmpDataEndTime) {
  360. startDate = tmpDataEndTime
  361. }
  362. }
  363. }
  364. if tmpMinValue < minValue {
  365. minValue = tmpMinValue
  366. }
  367. if tmpMaxValue < maxValue {
  368. maxValue = tmpMaxValue
  369. }
  370. }
  371. return
  372. }