predict_edb_info_rule.go 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582
  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. "fmt"
  9. "github.com/nosixtools/solarlunar"
  10. "github.com/shopspring/decimal"
  11. "math"
  12. "strings"
  13. "time"
  14. )
  15. func GetChartPredictEdbInfoDataListByRule1(edbInfoId int, dataValue float64, dayList []time.Time, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList) {
  16. newPredictEdbInfoData = predictEdbInfoData
  17. predictEdbInfoData = make([]*models.EdbDataList, 0)
  18. for k, v := range dayList {
  19. newPredictEdbInfoData = append(newPredictEdbInfoData, &models.EdbDataList{
  20. EdbDataId: edbInfoId + 10000000000 + k,
  21. EdbInfoId: edbInfoId,
  22. DataTime: v.Format(utils.FormatDate),
  23. Value: dataValue,
  24. DataTimestamp: v.UnixNano() / 1e6,
  25. })
  26. existMap[v.Format(utils.FormatDate)] = dataValue
  27. }
  28. return
  29. }
  30. func GetChartPredictEdbInfoDataListByRuleTb(edbInfoId int, tbValue float64, dayList []time.Time, frequency string, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64) {
  31. allDataList := make([]*models.EdbDataList, 0)
  32. allDataList = append(allDataList, realPredictEdbInfoData...)
  33. allDataList = append(allDataList, predictEdbInfoData...)
  34. newPredictEdbInfoData = predictEdbInfoData
  35. index := len(allDataList)
  36. predictEdbInfoData = make([]*models.EdbDataList, 0)
  37. for k, currentDate := range dayList {
  38. tmpData := &models.EdbDataList{
  39. EdbDataId: edbInfoId + 10000000000 + index + k,
  40. EdbInfoId: edbInfoId,
  41. DataTime: currentDate.Format(utils.FormatDate),
  42. DataTimestamp: currentDate.UnixNano() / 1e6,
  43. }
  44. var val float64
  45. var calculateStatus bool //计算结果
  46. preDate := currentDate.AddDate(-1, 0, 0)
  47. preDateStr := preDate.Format(utils.FormatDate)
  48. if preValue, ok := existMap[preDateStr]; ok { //上一年同期找到
  49. val = TbzDiv(preValue, tbValue)
  50. calculateStatus = true
  51. } else {
  52. switch frequency {
  53. case "月度":
  54. nextDateDay := preDate
  55. preDateDay := preDate
  56. for i := 0; i <= 35; i++ {
  57. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  58. if preValue, ok := existMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
  59. val = TbzDiv(preValue, tbValue)
  60. calculateStatus = true
  61. break
  62. } else {
  63. preDateDayStr := preDateDay.Format(utils.FormatDate)
  64. if preValue, ok := existMap[preDateDayStr]; ok { //上一年同期->上一个月找到
  65. val = TbzDiv(preValue, tbValue)
  66. calculateStatus = true
  67. break
  68. }
  69. }
  70. nextDateDay = nextDateDay.AddDate(0, 0, 1)
  71. preDateDay = preDateDay.AddDate(0, 0, -1)
  72. }
  73. case "季度", "年度":
  74. if preValue, ok := existMap[preDateStr]; ok { //上一年同期->下一个月找到
  75. val = TbzDiv(preValue, tbValue)
  76. calculateStatus = true
  77. break
  78. }
  79. default:
  80. nextDateDay := preDate
  81. preDateDay := preDate
  82. for i := 0; i < 35; i++ {
  83. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  84. if preValue, ok := existMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
  85. val = TbzDiv(preValue, tbValue)
  86. calculateStatus = true
  87. break
  88. } else {
  89. preDateDayStr := preDateDay.Format(utils.FormatDate)
  90. if preValue, ok := existMap[preDateDayStr]; ok { //上一年同期->上一个月找到
  91. val = TbzDiv(preValue, tbValue)
  92. calculateStatus = true
  93. break
  94. } else {
  95. }
  96. }
  97. nextDateDay = nextDateDay.AddDate(0, 0, 1)
  98. preDateDay = preDateDay.AddDate(0, 0, -1)
  99. }
  100. }
  101. }
  102. if calculateStatus {
  103. tmpData.Value = val
  104. newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
  105. allDataList = append(allDataList, tmpData)
  106. existMap[tmpData.DataTime] = val
  107. if val < minValue {
  108. minValue = val
  109. }
  110. if val > maxValue {
  111. maxValue = val
  112. }
  113. }
  114. }
  115. return
  116. }
  117. func TbzDiv(a, b float64) (result float64) {
  118. af := decimal.NewFromFloat(a)
  119. bf := decimal.NewFromFloat(b)
  120. cf := decimal.NewFromFloat(1)
  121. val := bf.Add(cf)
  122. result, _ = val.Mul(af).RoundCeil(4).Float64()
  123. return
  124. }
  125. func GetChartPredictEdbInfoDataListByRuleTc(edbInfoId int, tcValue float64, dayList []time.Time, frequency string, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64) {
  126. allDataList := make([]*models.EdbDataList, 0)
  127. allDataList = append(allDataList, realPredictEdbInfoData...)
  128. allDataList = append(allDataList, predictEdbInfoData...)
  129. newPredictEdbInfoData = predictEdbInfoData
  130. index := len(allDataList)
  131. predictEdbInfoData = make([]*models.EdbDataList, 0)
  132. for k, currentDate := range dayList {
  133. tmpData := &models.EdbDataList{
  134. EdbDataId: edbInfoId + 10000000000 + index + k,
  135. EdbInfoId: edbInfoId,
  136. DataTime: currentDate.Format(utils.FormatDate),
  137. DataTimestamp: currentDate.UnixNano() / 1e6,
  138. }
  139. var val float64
  140. var calculateStatus bool //计算结果
  141. preDate := currentDate.AddDate(-1, 0, 0)
  142. preDateStr := preDate.Format(utils.FormatDate)
  143. if preValue, ok := existMap[preDateStr]; ok { //上一年同期找到
  144. val = TczDiv(preValue, tcValue)
  145. calculateStatus = true
  146. } else {
  147. switch frequency {
  148. case "月度":
  149. nextDateDay := preDate
  150. preDateDay := preDate
  151. for i := 0; i <= 35; i++ {
  152. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  153. if preValue, ok := existMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
  154. val = TczDiv(preValue, tcValue)
  155. calculateStatus = true
  156. break
  157. } else {
  158. preDateDayStr := preDateDay.Format(utils.FormatDate)
  159. if preValue, ok := existMap[preDateDayStr]; ok { //上一年同期->上一个月找到
  160. val = TczDiv(preValue, tcValue)
  161. calculateStatus = true
  162. break
  163. }
  164. }
  165. nextDateDay = nextDateDay.AddDate(0, 0, 1)
  166. preDateDay = preDateDay.AddDate(0, 0, -1)
  167. }
  168. case "季度", "年度":
  169. if preValue, ok := existMap[preDateStr]; ok { //上一年同期->下一个月找到
  170. val = TczDiv(preValue, tcValue)
  171. calculateStatus = true
  172. break
  173. }
  174. default:
  175. nextDateDay := preDate
  176. preDateDay := preDate
  177. for i := 0; i < 35; i++ {
  178. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  179. if preValue, ok := existMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
  180. val = TczDiv(preValue, tcValue)
  181. calculateStatus = true
  182. break
  183. } else {
  184. preDateDayStr := preDateDay.Format(utils.FormatDate)
  185. if preValue, ok := existMap[preDateDayStr]; ok { //上一年同期->上一个月找到
  186. val = TczDiv(preValue, tcValue)
  187. calculateStatus = true
  188. break
  189. } else {
  190. }
  191. }
  192. nextDateDay = nextDateDay.AddDate(0, 0, 1)
  193. preDateDay = preDateDay.AddDate(0, 0, -1)
  194. }
  195. }
  196. }
  197. if calculateStatus {
  198. tmpData.Value = val
  199. newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
  200. allDataList = append(allDataList, tmpData)
  201. existMap[tmpData.DataTime] = val
  202. if val < minValue {
  203. minValue = val
  204. }
  205. if val > maxValue {
  206. maxValue = val
  207. }
  208. }
  209. }
  210. return
  211. }
  212. func TczDiv(a, b float64) (result float64) {
  213. if b != 0 {
  214. af := decimal.NewFromFloat(a)
  215. bf := decimal.NewFromFloat(b)
  216. result, _ = af.Add(bf).RoundCeil(4).Float64()
  217. } else {
  218. result = 0
  219. }
  220. return
  221. }
  222. func GetChartPredictEdbInfoDataListByRuleHb(edbInfoId int, hbValue float64, dayList []time.Time, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64) {
  223. allDataList := make([]*models.EdbDataList, 0)
  224. allDataList = append(allDataList, realPredictEdbInfoData...)
  225. allDataList = append(allDataList, predictEdbInfoData...)
  226. newPredictEdbInfoData = predictEdbInfoData
  227. index := len(allDataList)
  228. for k, currentDate := range dayList {
  229. tmpK := index + k - 1 //上1期的值
  230. val := HbzDiv(allDataList[tmpK].Value, hbValue)
  231. currentDateStr := currentDate.Format(utils.FormatDate)
  232. tmpData := &models.EdbDataList{
  233. EdbDataId: edbInfoId + 10000000000 + index + k,
  234. EdbInfoId: edbInfoId,
  235. DataTime: currentDateStr,
  236. Value: val,
  237. DataTimestamp: currentDate.UnixNano() / 1e6,
  238. }
  239. newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
  240. allDataList = append(allDataList, tmpData)
  241. existMap[currentDateStr] = val
  242. if val < minValue {
  243. minValue = val
  244. }
  245. if val > maxValue {
  246. maxValue = val
  247. }
  248. }
  249. return
  250. }
  251. func HbzDiv(a, b float64) (result float64) {
  252. if b != 0 {
  253. af := decimal.NewFromFloat(a)
  254. bf := decimal.NewFromFloat(b)
  255. cf := decimal.NewFromFloat(1)
  256. val := bf.Add(cf)
  257. result, _ = val.Mul(af).RoundCeil(4).Float64()
  258. } else {
  259. result = 0
  260. }
  261. return
  262. }
  263. func GetChartPredictEdbInfoDataListByRuleHc(edbInfoId int, hcValue float64, dayList []time.Time, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64) {
  264. allDataList := make([]*models.EdbDataList, 0)
  265. allDataList = append(allDataList, realPredictEdbInfoData...)
  266. allDataList = append(allDataList, predictEdbInfoData...)
  267. newPredictEdbInfoData = predictEdbInfoData
  268. index := len(allDataList)
  269. for k, currentDate := range dayList {
  270. tmpK := index + k - 1 //上1期的值
  271. val := HczDiv(allDataList[tmpK].Value, hcValue)
  272. currentDateStr := currentDate.Format(utils.FormatDate)
  273. tmpData := &models.EdbDataList{
  274. EdbDataId: edbInfoId + 10000000000 + index + k,
  275. EdbInfoId: edbInfoId,
  276. DataTime: currentDateStr,
  277. Value: val,
  278. DataTimestamp: currentDate.UnixNano() / 1e6,
  279. }
  280. newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
  281. allDataList = append(allDataList, tmpData)
  282. existMap[currentDateStr] = val
  283. if val < minValue {
  284. minValue = val
  285. }
  286. if val > maxValue {
  287. maxValue = val
  288. }
  289. }
  290. return
  291. }
  292. func HczDiv(a, b float64) (result float64) {
  293. if b != 0 {
  294. af := decimal.NewFromFloat(a)
  295. bf := decimal.NewFromFloat(b)
  296. result, _ = af.Add(bf).RoundCeil(4).Float64()
  297. } else {
  298. result = 0
  299. }
  300. return
  301. }
  302. func GetChartPredictEdbInfoDataListByRuleNMoveMeanValue(edbInfoId int, nValue int, dayList []time.Time, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64) {
  303. allDataList := make([]*models.EdbDataList, 0)
  304. allDataList = append(allDataList, realPredictEdbInfoData...)
  305. allDataList = append(allDataList, predictEdbInfoData...)
  306. newPredictEdbInfoData = predictEdbInfoData
  307. lenAllData := len(allDataList)
  308. if lenAllData < nValue || lenAllData <= 0 {
  309. return
  310. }
  311. if nValue <= 0 {
  312. return
  313. }
  314. decimalN := decimal.NewFromInt(int64(nValue))
  315. for k, currentDate := range dayList {
  316. tmpIndex := lenAllData + k - 1 //上1期的值
  317. tmpDecimalVal := decimal.NewFromFloat(allDataList[tmpIndex].Value)
  318. for tmpK := 2; tmpK <= nValue; tmpK++ {
  319. tmpIndex2 := tmpIndex - tmpK //上N期的值
  320. tmpDecimalVal2 := decimal.NewFromFloat(allDataList[tmpIndex2].Value)
  321. tmpDecimalVal = tmpDecimalVal.Add(tmpDecimalVal2)
  322. }
  323. val, _ := tmpDecimalVal.Div(decimalN).RoundCeil(4).Float64()
  324. currentDateStr := currentDate.Format(utils.FormatDate)
  325. tmpData := &models.EdbDataList{
  326. EdbDataId: edbInfoId + 10000000000 + lenAllData + k,
  327. EdbInfoId: edbInfoId,
  328. DataTime: currentDateStr,
  329. Value: val,
  330. DataTimestamp: currentDate.UnixNano() / 1e6,
  331. }
  332. newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
  333. allDataList = append(allDataList, tmpData)
  334. existMap[currentDateStr] = val
  335. if val < minValue {
  336. minValue = val
  337. }
  338. if val > maxValue {
  339. maxValue = val
  340. }
  341. }
  342. return
  343. }
  344. func GetChartPredictEdbInfoDataListByRuleNLinearRegression(edbInfoId int, nValue int, dayList []time.Time, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64) {
  345. allDataList := make([]*models.EdbDataList, 0)
  346. allDataList = append(allDataList, realPredictEdbInfoData...)
  347. allDataList = append(allDataList, predictEdbInfoData...)
  348. newPredictEdbInfoData = predictEdbInfoData
  349. lenAllData := len(allDataList)
  350. if lenAllData < nValue || lenAllData <= 0 {
  351. return
  352. }
  353. if nValue <= 1 {
  354. return
  355. }
  356. coordinateData := make([]Coordinate, 0)
  357. for tmpK := nValue; tmpK > 0; tmpK-- {
  358. tmpIndex2 := lenAllData - tmpK //上N期的值
  359. tmpCoordinate := Coordinate{
  360. X: float64(nValue - tmpK + 1),
  361. Y: allDataList[tmpIndex2].Value,
  362. }
  363. coordinateData = append(coordinateData, tmpCoordinate)
  364. }
  365. a, b := getLinearResult(coordinateData)
  366. for k, currentDate := range dayList {
  367. tmpK := nValue + k + 1
  368. aDecimal := decimal.NewFromFloat(a)
  369. xDecimal := decimal.NewFromInt(int64(tmpK))
  370. bDecimal := decimal.NewFromFloat(b)
  371. val, _ := aDecimal.Mul(xDecimal).Add(bDecimal).RoundCeil(4).Float64()
  372. currentDateStr := currentDate.Format(utils.FormatDate)
  373. tmpData := &models.EdbDataList{
  374. EdbDataId: edbInfoId + 10000000000 + lenAllData + k,
  375. EdbInfoId: edbInfoId,
  376. DataTime: currentDateStr,
  377. Value: val,
  378. DataTimestamp: currentDate.UnixNano() / 1e6,
  379. }
  380. newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
  381. allDataList = append(allDataList, tmpData)
  382. existMap[currentDateStr] = val
  383. if val < minValue {
  384. minValue = val
  385. }
  386. if val > maxValue {
  387. maxValue = val
  388. }
  389. }
  390. return
  391. }
  392. type Series []Coordinate
  393. type Coordinate struct {
  394. X, Y float64
  395. }
  396. func getLinearResult(s []Coordinate) (gradient, intercept float64) {
  397. if len(s) <= 1 {
  398. return
  399. }
  400. var sum [5]float64
  401. i := 0
  402. for ; i < len(s); i++ {
  403. sum[0] += s[i].X
  404. sum[1] += s[i].Y
  405. sum[2] += s[i].X * s[i].X
  406. sum[3] += s[i].X * s[i].Y
  407. sum[4] += s[i].Y * s[i].Y
  408. }
  409. f := float64(i)
  410. gradient = (f*sum[3] - sum[0]*sum[1]) / (f*sum[2] - sum[0]*sum[0])
  411. intercept = (sum[1] / f) - (gradient * sum[0] / f)
  412. return
  413. }
  414. func GetChartPredictEdbInfoDataListByRuleTrendsHC(edbInfoId, configId int, startDate, endDate time.Time, dayList []time.Time, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64) {
  415. allDataList := make([]*models.EdbDataList, 0)
  416. allDataList = append(allDataList, realPredictEdbInfoData...)
  417. allDataList = append(allDataList, predictEdbInfoData...)
  418. newPredictEdbInfoData = predictEdbInfoData
  419. lenAllData := len(allDataList)
  420. if lenAllData <= 0 {
  421. return
  422. }
  423. hcDataMap := make(map[string]float64) //规则计算的环差值map
  424. tmpPredictEdbRuleDataList, err := data_manage.GetPredictEdbRuleDataList(edbInfoId, configId, startDate.Format(utils.FormatDate), endDate.Format(utils.FormatDate))
  425. if err != nil {
  426. return
  427. }
  428. for _, v := range tmpPredictEdbRuleDataList {
  429. hcDataMap[v.DataTime] = v.Value
  430. }
  431. for k, currentDate := range dayList {
  432. tmpLenAllDataList := len(allDataList)
  433. lastValue := allDataList[tmpLenAllDataList-1].Value
  434. currentDateStr := currentDate.Format(utils.FormatDate)
  435. hcVal, ok := hcDataMap[currentDateStr]
  436. if !ok {
  437. continue
  438. }
  439. lastValueDecimal := decimal.NewFromFloat(lastValue)
  440. hcValDecimal := decimal.NewFromFloat(hcVal)
  441. val, _ := lastValueDecimal.Add(hcValDecimal).RoundCeil(4).Float64()
  442. tmpData := &models.EdbDataList{
  443. EdbDataId: edbInfoId + 10000000000 + lenAllData + k,
  444. EdbInfoId: edbInfoId,
  445. DataTime: currentDateStr,
  446. Value: val,
  447. DataTimestamp: currentDate.UnixNano() / 1e6,
  448. }
  449. newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
  450. allDataList = append(allDataList, tmpData)
  451. existMap[currentDateStr] = val
  452. if val < minValue {
  453. minValue = val
  454. }
  455. if val > maxValue {
  456. maxValue = val
  457. }
  458. }
  459. return
  460. }
  461. func GetChartPredictEdbInfoDataListByRuleFinalValueHc(edbInfoId int, finalValue float64, dayList []time.Time, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64) {
  462. allDataList := make([]*models.EdbDataList, 0)
  463. allDataList = append(allDataList, realPredictEdbInfoData...)
  464. allDataList = append(allDataList, predictEdbInfoData...)
  465. newPredictEdbInfoData = predictEdbInfoData
  466. index := len(allDataList)
  467. lenDay := len(dayList)
  468. if lenDay <= 0 {
  469. return
  470. }
  471. var hcValue float64
  472. lastValueDeciamal := decimal.NewFromFloat(allDataList[index-1].Value) // 实际数据的最后一个值
  473. finalValueDeciamal := decimal.NewFromFloat(finalValue) // 给定的终止数据
  474. dayDecimal := decimal.NewFromInt(int64(lenDay)) // 需要作为分母的期数
  475. hcValue, _ = finalValueDeciamal.Sub(lastValueDeciamal).Div(dayDecimal).Float64() // 计算出来的环差值
  476. predictEdbInfoData = make([]*models.EdbDataList, 0)
  477. lastK := lenDay - 1 // 最后的日期
  478. for k, currentDate := range dayList {
  479. tmpK := index + k - 1 //上1期的值
  480. var val float64
  481. if k == lastK { //如果是最后一天,那么就用最终值,否则就计算
  482. val = finalValue
  483. } else {
  484. val = HczDiv(allDataList[tmpK].Value, hcValue)
  485. }
  486. currentDateStr := currentDate.Format(utils.FormatDate)
  487. tmpData := &models.EdbDataList{
  488. EdbDataId: edbInfoId + 10000000000 + index + k,
  489. EdbInfoId: edbInfoId,
  490. DataTime: currentDateStr,
  491. Value: val,
  492. DataTimestamp: currentDate.UnixNano() / 1e6,
  493. }
  494. newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
  495. allDataList = append(allDataList, tmpData)
  496. existMap[currentDateStr] = val
  497. if val < minValue {
  498. minValue = val
  499. }
  500. if val > maxValue {
  501. maxValue = val
  502. }
  503. }
  504. return
  505. }
  506. type SeasonConf struct {
  507. Calendar string `description:"公历、农历"`
  508. YearType int `description:"选择方式,1:连续N年;2:指定年份"`
  509. NValue int `description:"连续N年"`
  510. YearList []int `description:"指定年份列表"`
  511. }
  512. func GetChartPredictEdbInfoDataListByRuleSeason(edbInfoId int, yearsList []int, calendar string, dayList []time.Time, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64, err error) {
  513. allDataList := make([]*models.EdbDataList, 0)
  514. allDataList = append(allDataList, realPredictEdbInfoData...)
  515. allDataList = append(allDataList, predictEdbInfoData...)
  516. newPredictEdbInfoData = predictEdbInfoData
  517. handleDataMap := make(map[string]float64)
  518. err = HandleDataByLinearRegression(allDataList, handleDataMap)
  519. if err != nil {
  520. return
  521. }
  522. moveDayMap := make(map[int]int, 0) // 每个年份的春节公历
  523. {
  524. if calendar == "公历" {
  525. for _, year := range yearsList {
  526. moveDayMap[year] = 0 //公历就不平移了
  527. }
  528. } else {
  529. currentDay := time.Now()
  530. if currentDay.Month() >= 11 { //如果大于等于11月份,那么用的是下一年的春节
  531. currentDay = currentDay.AddDate(1, 0, 0)
  532. }
  533. currentYear := currentDay.Year()
  534. currentYearCjnl := fmt.Sprintf("%d-01-01", currentYear) //当年的春节农历
  535. currentYearCjgl := solarlunar.LunarToSolar(currentYearCjnl, false) //当年的春节公历
  536. currentYearCjglTime, tmpErr := time.ParseInLocation(utils.FormatDate, currentYearCjgl, time.Local)
  537. if tmpErr != nil {
  538. err = errors.New("当前春节公历日期转换失败:" + tmpErr.Error())
  539. return
  540. }
  541. for _, year := range yearsList {
  542. tmpYearCjnl := fmt.Sprintf("%d-01-01", year) //指定年的春节农历
  543. tmpYearCjgl := solarlunar.LunarToSolar(tmpYearCjnl, false) //指定年的春节公历
  544. tmpYearCjglTime, tmpErr := time.ParseInLocation(utils.FormatDate, tmpYearCjgl, time.Local)
  545. if tmpErr != nil {
  546. err = errors.New(fmt.Sprintf("%d公历日期转换失败:%s", year, tmpErr.Error()))
  547. return
  548. }
  549. tmpCurrentYearCjglTime := currentYearCjglTime.AddDate(year-currentYear, 0, 0)
  550. moveDay := utils.GetTimeSubDay(tmpYearCjglTime, tmpCurrentYearCjglTime)
  551. moveDayMap[year] = moveDay //公历平移
  552. }
  553. }
  554. }
  555. index := len(allDataList)
  556. predictEdbInfoData = make([]*models.EdbDataList, 0)
  557. for k, currentDate := range dayList {
  558. if strings.Contains(currentDate.Format(utils.FormatDate), "02-29") {
  559. continue
  560. }
  561. tmpHistoryVal := decimal.NewFromFloat(0) //往期的差值总和
  562. tmpHistoryValNum := 0 // 往期差值计算的数量
  563. tmpLenAllDataList := len(allDataList)
  564. tmpK := tmpLenAllDataList - 1 //上1期数据的下标
  565. lastDayData := allDataList[tmpK] // 上1期的数据
  566. lastDayStr := lastDayData.DataTime
  567. lastDayVal := lastDayData.Value
  568. lastDay, tmpErr := time.ParseInLocation(utils.FormatDate, lastDayStr, time.Local)
  569. if tmpErr != nil {
  570. err = errors.New("获取上期日期转换失败:" + tmpErr.Error())
  571. }
  572. for _, year := range yearsList {
  573. moveDay := moveDayMap[year] //需要移动的天数
  574. var tmpHistoryCurrentVal, tmpHistoryLastVal float64
  575. var isFindHistoryCurrent, isFindHistoryLast bool //是否找到前几年的数据
  576. tmpHistoryCurrentDate := currentDate.AddDate(year-currentDate.Year(), 0, -moveDay)
  577. for i := 0; i <= 35; i++ { // 前后35天找数据,找到最近的值,先向后面找,再往前面找
  578. tmpDate := tmpHistoryCurrentDate.AddDate(0, 0, i)
  579. if val, ok := handleDataMap[tmpDate.Format(utils.FormatDate)]; ok {
  580. tmpHistoryCurrentVal = val
  581. isFindHistoryCurrent = true
  582. break
  583. } else {
  584. tmpDate := tmpHistoryCurrentDate.AddDate(0, 0, -i)
  585. if val, ok := handleDataMap[tmpDate.Format(utils.FormatDate)]; ok {
  586. tmpHistoryCurrentVal = val
  587. isFindHistoryCurrent = true
  588. break
  589. }
  590. }
  591. }
  592. tmpHistoryLastDate := lastDay.AddDate(year-lastDay.Year(), 0, -moveDay)
  593. for i := 0; i <= 35; i++ { // 前后35天找数据,找到最近的值,先向后面找,再往前面找
  594. tmpDate := tmpHistoryLastDate.AddDate(0, 0, i)
  595. if val, ok := handleDataMap[tmpDate.Format(utils.FormatDate)]; ok {
  596. tmpHistoryLastVal = val
  597. isFindHistoryLast = true
  598. break
  599. } else {
  600. tmpDate := tmpHistoryLastDate.AddDate(0, 0, -i)
  601. if val, ok := handleDataMap[tmpDate.Format(utils.FormatDate)]; ok {
  602. tmpHistoryLastVal = val
  603. isFindHistoryLast = true
  604. break
  605. }
  606. }
  607. }
  608. if isFindHistoryCurrent && isFindHistoryLast {
  609. af := decimal.NewFromFloat(tmpHistoryCurrentVal)
  610. bf := decimal.NewFromFloat(tmpHistoryLastVal)
  611. tmpHistoryVal = tmpHistoryVal.Add(af.Sub(bf))
  612. tmpHistoryValNum++
  613. }
  614. }
  615. if tmpHistoryValNum != len(yearsList) {
  616. continue
  617. }
  618. lastDayValDec := decimal.NewFromFloat(lastDayVal)
  619. val, _ := tmpHistoryVal.Div(decimal.NewFromInt(int64(tmpHistoryValNum))).Add(lastDayValDec).RoundCeil(4).Float64()
  620. currentDateStr := currentDate.Format(utils.FormatDate)
  621. tmpData := &models.EdbDataList{
  622. EdbDataId: edbInfoId + 10000000000 + index + k,
  623. EdbInfoId: edbInfoId,
  624. DataTime: currentDateStr,
  625. Value: val,
  626. DataTimestamp: currentDate.UnixNano() / 1e6,
  627. }
  628. newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
  629. allDataList = append(allDataList, tmpData)
  630. existMap[currentDateStr] = val
  631. err = HandleDataByLinearRegression([]*models.EdbDataList{
  632. lastDayData, tmpData,
  633. }, handleDataMap)
  634. if err != nil {
  635. return
  636. }
  637. if val < minValue {
  638. minValue = val
  639. }
  640. if val > maxValue {
  641. maxValue = val
  642. }
  643. }
  644. return
  645. }
  646. type MoveAverageConf struct {
  647. Year int `description:"指定年份"`
  648. NValue int `description:"N期的数据"`
  649. }
  650. func GetChartPredictEdbInfoDataListByRuleMoveAverageTb(edbInfoId int, nValue, year int, dayList []time.Time, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64, err error) {
  651. allDataList := make([]*models.EdbDataList, 0)
  652. allDataList = append(allDataList, realPredictEdbInfoData...)
  653. allDataList = append(allDataList, predictEdbInfoData...)
  654. newPredictEdbInfoData = predictEdbInfoData
  655. lenAllData := len(allDataList)
  656. if lenAllData < nValue || lenAllData <= 0 {
  657. return
  658. }
  659. if nValue <= 0 {
  660. return
  661. }
  662. decimalN := decimal.NewFromInt(int64(nValue))
  663. if len(dayList) <= 0 {
  664. return
  665. }
  666. subYear := year - dayList[0].Year()
  667. for k, currentDate := range dayList {
  668. tmpLenAllDataList := len(allDataList)
  669. tmpIndex := tmpLenAllDataList - 1 //上1期数据的下标
  670. averageDateList := make([]string, 0) //计算平均数的日期
  671. tmpDecimalVal := decimal.NewFromFloat(allDataList[tmpIndex].Value)
  672. averageDateList = append(averageDateList, allDataList[tmpIndex].DataTime)
  673. for tmpK := 1; tmpK < nValue; tmpK++ {
  674. tmpIndex2 := tmpIndex - tmpK //上N期的值
  675. tmpDecimalVal2 := decimal.NewFromFloat(allDataList[tmpIndex2].Value)
  676. tmpDecimalVal = tmpDecimalVal.Add(tmpDecimalVal2)
  677. averageDateList = append(averageDateList, allDataList[tmpIndex2].DataTime)
  678. }
  679. tmpAverageVal := tmpDecimalVal.Div(decimalN)
  680. var tmpHistoryCurrentVal float64 // 前几年当日的数据值
  681. var isFindHistoryCurrent, isFindHistoryLast bool //是否找到前几年的数据
  682. tmpHistoryDecimalVal := decimal.NewFromFloat(0) //前几年N期数据总值
  683. {
  684. tmpHistoryValNum := 0
  685. {
  686. tmpHistoryCurrentDate := currentDate.AddDate(subYear, 0, 0)
  687. for i := 0; i <= 35; i++ { // 前后35天找数据,找到最近的值,先向后面找,再往前面找
  688. tmpDate := tmpHistoryCurrentDate.AddDate(0, 0, i)
  689. if val, ok := existMap[tmpDate.Format(utils.FormatDate)]; ok {
  690. tmpHistoryCurrentVal = val
  691. isFindHistoryCurrent = true
  692. break
  693. } else {
  694. tmpDate := tmpHistoryCurrentDate.AddDate(0, 0, -i)
  695. if val, ok := existMap[tmpDate.Format(utils.FormatDate)]; ok {
  696. tmpHistoryCurrentVal = val
  697. isFindHistoryCurrent = true
  698. break
  699. }
  700. }
  701. }
  702. }
  703. for _, averageDate := range averageDateList {
  704. lastDay, tmpErr := time.ParseInLocation(utils.FormatDate, averageDate, time.Local)
  705. if tmpErr != nil {
  706. err = tmpErr
  707. return
  708. }
  709. tmpHistoryLastDate := lastDay.AddDate(subYear, 0, 0)
  710. for i := 0; i <= 35; i++ { // 前后35天找数据,找到最近的值,先向后面找,再往前面找
  711. tmpDate := tmpHistoryLastDate.AddDate(0, 0, i)
  712. if val, ok := existMap[tmpDate.Format(utils.FormatDate)]; ok {
  713. tmpDecimalVal2 := decimal.NewFromFloat(val)
  714. tmpHistoryDecimalVal = tmpHistoryDecimalVal.Add(tmpDecimalVal2)
  715. tmpHistoryValNum++
  716. break
  717. } else {
  718. tmpDate := tmpHistoryLastDate.AddDate(0, 0, -i)
  719. if val, ok := existMap[tmpDate.Format(utils.FormatDate)]; ok {
  720. tmpDecimalVal2 := decimal.NewFromFloat(val)
  721. tmpHistoryDecimalVal = tmpHistoryDecimalVal.Add(tmpDecimalVal2)
  722. tmpHistoryValNum++
  723. break
  724. }
  725. }
  726. }
  727. }
  728. if tmpHistoryValNum == nValue {
  729. isFindHistoryLast = true
  730. }
  731. }
  732. if !isFindHistoryLast || !isFindHistoryCurrent {
  733. continue
  734. }
  735. tmpHistoryAverageVal := tmpHistoryDecimalVal.Div(decimalN)
  736. tbVal := tmpAverageVal.Div(tmpHistoryAverageVal)
  737. val, _ := decimal.NewFromFloat(tmpHistoryCurrentVal).Mul(tbVal).RoundCeil(4).Float64()
  738. currentDateStr := currentDate.Format(utils.FormatDate)
  739. tmpData := &models.EdbDataList{
  740. EdbDataId: edbInfoId + 10000000000 + lenAllData + k,
  741. EdbInfoId: edbInfoId,
  742. DataTime: currentDateStr,
  743. Value: val,
  744. DataTimestamp: currentDate.UnixNano() / 1e6,
  745. }
  746. newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
  747. allDataList = append(allDataList, tmpData)
  748. existMap[currentDateStr] = val
  749. if val < minValue {
  750. minValue = val
  751. }
  752. if val > maxValue {
  753. maxValue = val
  754. }
  755. }
  756. return
  757. }
  758. func GetChartPredictEdbInfoDataListByRuleTbzscz(edbInfoId int, tbEndValue float64, dayList []time.Time, frequency string, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64) {
  759. allDataList := make([]*models.EdbDataList, 0)
  760. allDataList = append(allDataList, realPredictEdbInfoData...)
  761. allDataList = append(allDataList, predictEdbInfoData...)
  762. newPredictEdbInfoData = predictEdbInfoData
  763. index := len(allDataList)
  764. if index <= 0 {
  765. return
  766. }
  767. lastData := allDataList[index-1]
  768. lastDayTime, _ := time.ParseInLocation(utils.FormatDate, lastData.DataTime, time.Local)
  769. var lastTb decimal.Decimal // 计算最新数据与上一期的数据同比值
  770. {
  771. preDate := lastDayTime.AddDate(-1, 0, 0)
  772. preDateStr := preDate.Format(utils.FormatDate)
  773. if preValue, ok := existMap[preDateStr]; ok { //上一年同期找到
  774. lastTb = (decimal.NewFromFloat(lastData.Value)).Sub(decimal.NewFromFloat(preValue)).Div(decimal.NewFromFloat(preValue))
  775. } else {
  776. switch frequency {
  777. case "月度":
  778. nextDateDay := preDate
  779. preDateDay := preDate
  780. for i := 0; i <= 35; i++ {
  781. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  782. if preValue, ok := existMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
  783. lastTb = (decimal.NewFromFloat(lastData.Value)).Sub(decimal.NewFromFloat(preValue)).Div(decimal.NewFromFloat(preValue))
  784. break
  785. } else {
  786. preDateDayStr := preDateDay.Format(utils.FormatDate)
  787. if preValue, ok := existMap[preDateDayStr]; ok { //上一年同期->上一个月找到
  788. lastTb = (decimal.NewFromFloat(lastData.Value)).Sub(decimal.NewFromFloat(preValue)).Div(decimal.NewFromFloat(preValue))
  789. break
  790. }
  791. }
  792. nextDateDay = nextDateDay.AddDate(0, 0, 1)
  793. preDateDay = preDateDay.AddDate(0, 0, -1)
  794. }
  795. case "季度", "年度":
  796. if preValue, ok := existMap[preDateStr]; ok { //上一年同期->下一个月找到
  797. lastTb = (decimal.NewFromFloat(lastData.Value)).Sub(decimal.NewFromFloat(preValue)).Div(decimal.NewFromFloat(preValue))
  798. break
  799. }
  800. default:
  801. nextDateDay := preDate
  802. preDateDay := preDate
  803. for i := 0; i < 35; i++ {
  804. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  805. if preValue, ok := existMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
  806. lastTb = (decimal.NewFromFloat(lastData.Value)).Sub(decimal.NewFromFloat(preValue)).Div(decimal.NewFromFloat(preValue))
  807. break
  808. } else {
  809. preDateDayStr := preDateDay.Format(utils.FormatDate)
  810. if preValue, ok := existMap[preDateDayStr]; ok { //上一年同期->上一个月找到
  811. lastTb = (decimal.NewFromFloat(lastData.Value)).Sub(decimal.NewFromFloat(preValue)).Div(decimal.NewFromFloat(preValue))
  812. break
  813. } else {
  814. }
  815. }
  816. nextDateDay = nextDateDay.AddDate(0, 0, 1)
  817. preDateDay = preDateDay.AddDate(0, 0, -1)
  818. }
  819. }
  820. }
  821. }
  822. lenDay := len(dayList)
  823. tbEndValueDecimal := decimal.NewFromFloat(tbEndValue)
  824. avgTbVal := tbEndValueDecimal.Sub(lastTb).Div(decimal.NewFromInt(int64(lenDay)))
  825. predictEdbInfoData = make([]*models.EdbDataList, 0)
  826. for k, currentDate := range dayList {
  827. var tbValue decimal.Decimal
  828. if k == lenDay-1 { // 如果是最后的日期了,那么就用终值去计算
  829. tbValue = tbEndValueDecimal.Add(decimal.NewFromInt(1))
  830. } else { // 最近数据的同比值 + (平均增值乘以当前期数)
  831. tbValue = lastTb.Add(avgTbVal.Mul(decimal.NewFromInt(int64(k + 1)))).Add(decimal.NewFromInt(1))
  832. }
  833. tmpData := &models.EdbDataList{
  834. EdbDataId: edbInfoId + 100000 + index + k,
  835. EdbInfoId: edbInfoId,
  836. DataTime: currentDate.Format(utils.FormatDate),
  837. DataTimestamp: currentDate.UnixNano() / 1e6,
  838. }
  839. var val float64
  840. var calculateStatus bool //计算结果
  841. preDate := currentDate.AddDate(-1, 0, 0)
  842. preDateStr := preDate.Format(utils.FormatDate)
  843. if preValue, ok := existMap[preDateStr]; ok { //上一年同期找到
  844. val, _ = decimal.NewFromFloat(preValue).Mul(tbValue).RoundCeil(4).Float64()
  845. calculateStatus = true
  846. } else {
  847. switch frequency {
  848. case "月度":
  849. nextDateDay := preDate
  850. preDateDay := preDate
  851. for i := 0; i <= 35; i++ {
  852. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  853. if preValue, ok := existMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
  854. val, _ = decimal.NewFromFloat(preValue).Mul(tbValue).RoundCeil(4).Float64()
  855. calculateStatus = true
  856. break
  857. } else {
  858. preDateDayStr := preDateDay.Format(utils.FormatDate)
  859. if preValue, ok := existMap[preDateDayStr]; ok { //上一年同期->上一个月找到
  860. val, _ = decimal.NewFromFloat(preValue).Mul(tbValue).RoundCeil(4).Float64()
  861. calculateStatus = true
  862. break
  863. }
  864. }
  865. nextDateDay = nextDateDay.AddDate(0, 0, 1)
  866. preDateDay = preDateDay.AddDate(0, 0, -1)
  867. }
  868. case "季度", "年度":
  869. if preValue, ok := existMap[preDateStr]; ok { //上一年同期->下一个月找到
  870. val, _ = decimal.NewFromFloat(preValue).Mul(tbValue).RoundCeil(4).Float64()
  871. calculateStatus = true
  872. break
  873. }
  874. default:
  875. nextDateDay := preDate
  876. preDateDay := preDate
  877. for i := 0; i < 35; i++ {
  878. nextDateDayStr := nextDateDay.Format(utils.FormatDate)
  879. if preValue, ok := existMap[nextDateDayStr]; ok { //上一年同期->下一个月找到
  880. val, _ = decimal.NewFromFloat(preValue).Mul(tbValue).RoundCeil(4).Float64()
  881. calculateStatus = true
  882. break
  883. } else {
  884. preDateDayStr := preDateDay.Format(utils.FormatDate)
  885. if preValue, ok := existMap[preDateDayStr]; ok { //上一年同期->上一个月找到
  886. val, _ = decimal.NewFromFloat(preValue).Mul(tbValue).RoundCeil(4).Float64()
  887. calculateStatus = true
  888. break
  889. } else {
  890. }
  891. }
  892. nextDateDay = nextDateDay.AddDate(0, 0, 1)
  893. preDateDay = preDateDay.AddDate(0, 0, -1)
  894. }
  895. }
  896. }
  897. if calculateStatus {
  898. tmpData.Value = val
  899. newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
  900. allDataList = append(allDataList, tmpData)
  901. existMap[tmpData.DataTime] = val
  902. if val < minValue {
  903. minValue = val
  904. }
  905. if val > maxValue {
  906. maxValue = val
  907. }
  908. }
  909. }
  910. return
  911. }
  912. type RuleLineNhConf struct {
  913. StartDate string `description:"开始日期"`
  914. EndDate string `description:"结束日期"`
  915. MoveDay int `description:"移动天数"`
  916. EdbInfoId int `description:"指标id"`
  917. }
  918. func GetChartPredictEdbInfoDataListByRuleLineNh(edbInfoId int, dayList []time.Time, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, newNhccDataMap, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64, err error) {
  919. allDataList := make([]*models.EdbDataList, 0)
  920. allDataList = append(allDataList, realPredictEdbInfoData...)
  921. allDataList = append(allDataList, predictEdbInfoData...)
  922. newPredictEdbInfoData = predictEdbInfoData
  923. lenAllData := len(allDataList)
  924. if lenAllData <= 0 {
  925. return
  926. }
  927. for k, currentDate := range dayList {
  928. currentDateStr := currentDate.Format(utils.FormatDate)
  929. val, ok := newNhccDataMap[currentDateStr]
  930. if !ok {
  931. continue
  932. }
  933. tmpData := &models.EdbDataList{
  934. EdbDataId: edbInfoId + 100000 + lenAllData + k,
  935. EdbInfoId: edbInfoId,
  936. DataTime: currentDateStr,
  937. Value: val,
  938. DataTimestamp: currentDate.UnixNano() / 1e6,
  939. }
  940. newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
  941. allDataList = append(allDataList, tmpData)
  942. existMap[currentDateStr] = val
  943. if val < minValue {
  944. minValue = val
  945. }
  946. if val > maxValue {
  947. maxValue = val
  948. }
  949. }
  950. return
  951. }
  952. func getCalculateNhccData(secondDataList []*models.EdbDataList, ruleConf RuleLineNhConf) (newBDataMap map[string]float64, err error) {
  953. firstEdbInfoId := ruleConf.EdbInfoId
  954. moveDay := ruleConf.MoveDay
  955. startDate, _ := time.ParseInLocation(utils.FormatDate, ruleConf.StartDate, time.Local)
  956. endDate, _ := time.ParseInLocation(utils.FormatDate, ruleConf.EndDate, time.Local)
  957. edbInfo, err := data_manage.GetEdbInfoById(firstEdbInfoId)
  958. if err != nil {
  959. return
  960. }
  961. aDataList := make([]models.EdbDataList, 0)
  962. aDataMap := make(map[string]float64)
  963. {
  964. var firstDataList []*models.EdbDataList
  965. switch edbInfo.EdbInfoType {
  966. case 0:
  967. firstDataList, err = models.GetEdbDataList(edbInfo.Source, edbInfo.SubSource, edbInfo.EdbInfoId, ``, ``)
  968. case 1:
  969. _, firstDataList, _, _, err, _ = GetPredictDataListByPredictEdbInfoId(edbInfo.EdbInfoId, ``, ``, false)
  970. default:
  971. err = errors.New(fmt.Sprint("获取失败,指标类型异常", edbInfo.EdbInfoType))
  972. }
  973. if err != nil {
  974. return
  975. }
  976. aDataList, aDataMap = handleNhccData(firstDataList, moveDay)
  977. }
  978. bDataList := make([]models.EdbDataList, 0)
  979. bDataMap := make(map[string]float64)
  980. {
  981. bDataList, bDataMap = handleNhccData(secondDataList, 0)
  982. }
  983. if len(aDataList) <= 0 {
  984. err = errors.New("指标A没有数据")
  985. return
  986. }
  987. if len(bDataList) <= 0 {
  988. err = errors.New("指标B没有数据")
  989. return
  990. }
  991. {
  992. endAData := aDataList[len(aDataList)-1]
  993. tmpEndDate, tmpErr := time.ParseInLocation(utils.FormatDate, endAData.DataTime, time.Local)
  994. if tmpErr != nil {
  995. err = tmpErr
  996. return
  997. }
  998. if tmpEndDate.Before(endDate) {
  999. endDate = tmpEndDate
  1000. }
  1001. endBData := bDataList[len(bDataList)-1]
  1002. tmpEndDate, tmpErr = time.ParseInLocation(utils.FormatDate, endBData.DataTime, time.Local)
  1003. if tmpErr != nil {
  1004. err = tmpErr
  1005. return
  1006. }
  1007. if tmpEndDate.Before(endDate) {
  1008. endDate = tmpEndDate
  1009. }
  1010. }
  1011. var a, b float64
  1012. {
  1013. coordinateData := make([]utils.Coordinate, 0)
  1014. for i := startDate; i.Before(endDate) || i.Equal(endDate); i = i.AddDate(0, 0, 1) {
  1015. dateStr := i.Format(utils.FormatDate)
  1016. xValue, ok := aDataMap[dateStr]
  1017. if !ok {
  1018. err = errors.New("指标A日期:" + dateStr + "数据异常,导致计算线性方程公式失败")
  1019. return
  1020. }
  1021. yValue, ok := bDataMap[dateStr]
  1022. if !ok {
  1023. err = errors.New("指标B日期:" + dateStr + "数据异常,导致计算线性方程公式失败")
  1024. return
  1025. }
  1026. tmpCoordinate := utils.Coordinate{
  1027. X: xValue,
  1028. Y: yValue,
  1029. }
  1030. coordinateData = append(coordinateData, tmpCoordinate)
  1031. }
  1032. a, b = utils.GetLinearResult(coordinateData)
  1033. }
  1034. if math.IsNaN(a) || math.IsNaN(b) {
  1035. err = errors.New("线性方程公式生成失败")
  1036. return
  1037. }
  1038. newBDataMap = make(map[string]float64)
  1039. {
  1040. aDecimal := decimal.NewFromFloat(a)
  1041. bDecimal := decimal.NewFromFloat(b)
  1042. for _, aData := range aDataList {
  1043. xDecimal := decimal.NewFromFloat(aData.Value)
  1044. val, _ := aDecimal.Mul(xDecimal).Add(bDecimal).RoundCeil(4).Float64()
  1045. newBDataMap[aData.DataTime] = val
  1046. }
  1047. }
  1048. return
  1049. }
  1050. func handleNhccData(dataList []*models.EdbDataList, moveDay int) (newDataList []models.EdbDataList, dateDataMap map[string]float64) {
  1051. dateMap := make(map[time.Time]float64)
  1052. var minDate, maxDate time.Time
  1053. dateDataMap = make(map[string]float64)
  1054. for _, v := range dataList {
  1055. currDate, _ := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  1056. if minDate.IsZero() || currDate.Before(minDate) {
  1057. minDate = currDate
  1058. }
  1059. if maxDate.IsZero() || currDate.After(maxDate) {
  1060. maxDate = currDate
  1061. }
  1062. dateMap[currDate] = v.Value
  1063. }
  1064. newDateMap := make(map[time.Time]float64)
  1065. for currDate, value := range dateMap {
  1066. newDate := currDate.AddDate(0, 0, moveDay)
  1067. newDateMap[newDate] = value
  1068. }
  1069. minDate = minDate.AddDate(0, 0, moveDay)
  1070. maxDate = maxDate.AddDate(0, 0, moveDay)
  1071. dayNum := utils.GetTimeSubDay(minDate, maxDate)
  1072. for i := 0; i <= dayNum; i++ {
  1073. currDate := minDate.AddDate(0, 0, i)
  1074. tmpValue, ok := newDateMap[currDate]
  1075. if !ok {
  1076. if len(newDataList) <= 0 {
  1077. continue
  1078. }
  1079. tmpValue = newDataList[len(newDataList)-1].Value
  1080. }
  1081. tmpData := models.EdbDataList{
  1082. DataTime: currDate.Format(utils.FormatDate),
  1083. Value: tmpValue,
  1084. }
  1085. dateDataMap[tmpData.DataTime] = tmpData.Value
  1086. newDataList = append(newDataList, tmpData)
  1087. }
  1088. return
  1089. }
  1090. func GetChartPredictEdbInfoDataListByRuleNAnnualAverage(edbInfoId int, configValue string, dayList []time.Time, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64, err error) {
  1091. yearList, _, err := getYearListBySeasonConf(configValue)
  1092. if err != nil {
  1093. return
  1094. }
  1095. allDataList := make([]*models.EdbDataList, 0)
  1096. allDataList = append(allDataList, realPredictEdbInfoData...)
  1097. allDataList = append(allDataList, predictEdbInfoData...)
  1098. newPredictEdbInfoData = predictEdbInfoData
  1099. handleDataMap := make(map[string]float64)
  1100. err = HandleDataByLinearRegression(allDataList, handleDataMap)
  1101. if err != nil {
  1102. return
  1103. }
  1104. index := len(allDataList)
  1105. predictEdbInfoData = make([]*models.EdbDataList, 0)
  1106. for k, currentDate := range dayList {
  1107. if strings.Contains(currentDate.Format(utils.FormatDate), "02-29") {
  1108. continue
  1109. }
  1110. tmpK := len(allDataList) - 1 //上1期数据的下标
  1111. lastDayData := allDataList[tmpK] // 上1期的数据
  1112. tmpHistoryVal := decimal.NewFromFloat(0) //往期的差值总和
  1113. tmpHistoryValNum := 0 // 往期差值计算的数量
  1114. for _, year := range yearList {
  1115. tmpHistoryCurrentDate := currentDate.AddDate(year-currentDate.Year(), 0, 0)
  1116. if val, ok := handleDataMap[tmpHistoryCurrentDate.Format(utils.FormatDate)]; ok {
  1117. tmpHistoryVal = tmpHistoryVal.Add(decimal.NewFromFloat(val))
  1118. tmpHistoryValNum++
  1119. }
  1120. }
  1121. if tmpHistoryValNum != len(yearList) {
  1122. continue
  1123. }
  1124. val, _ := tmpHistoryVal.Div(decimal.NewFromInt(int64(tmpHistoryValNum))).RoundCeil(4).Float64()
  1125. currentDateStr := currentDate.Format(utils.FormatDate)
  1126. tmpData := &models.EdbDataList{
  1127. EdbDataId: edbInfoId + 100000 + index + k,
  1128. EdbInfoId: edbInfoId,
  1129. DataTime: currentDateStr,
  1130. Value: val,
  1131. DataTimestamp: currentDate.UnixNano() / 1e6,
  1132. }
  1133. newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
  1134. allDataList = append(allDataList, tmpData)
  1135. existMap[currentDateStr] = val
  1136. err = HandleDataByLinearRegression([]*models.EdbDataList{
  1137. lastDayData, tmpData,
  1138. }, handleDataMap)
  1139. if err != nil {
  1140. return
  1141. }
  1142. if val < minValue {
  1143. minValue = val
  1144. }
  1145. if val > maxValue {
  1146. maxValue = val
  1147. }
  1148. }
  1149. return
  1150. }
  1151. type AnnualValueInversionConf struct {
  1152. Value float64 `description:"年度值"`
  1153. Type int `description:"分配方式,1:均值法;2:同比法"`
  1154. Year int `description:"同比年份"`
  1155. }
  1156. func GetChartPredictEdbInfoDataListByRuleAnnualValueInversion(edbInfoId int, configValue string, dayList []time.Time, frequency string, realPredictEdbInfoData, predictEdbInfoData []*models.EdbDataList, existMap map[string]float64) (newPredictEdbInfoData []*models.EdbDataList, minValue, maxValue float64, err error) {
  1157. if frequency == "年度" {
  1158. err = errors.New("当前指标频度是年度,不允许配置年度值倒推")
  1159. return
  1160. }
  1161. var annualValueInversionConf AnnualValueInversionConf
  1162. err = json.Unmarshal([]byte(configValue), &annualValueInversionConf)
  1163. if err != nil {
  1164. err = errors.New("年度值倒推配置信息异常:" + err.Error())
  1165. return
  1166. }
  1167. allDataList := make([]*models.EdbDataList, 0)
  1168. allDataList = append(allDataList, realPredictEdbInfoData...)
  1169. allDataList = append(allDataList, predictEdbInfoData...)
  1170. newPredictEdbInfoData = predictEdbInfoData
  1171. index := len(allDataList)
  1172. yearValueConfig := annualValueInversionConf.Value
  1173. currDayTime, err := time.ParseInLocation(utils.FormatDate, allDataList[index-1].DataTime, time.Local)
  1174. if err != nil {
  1175. return
  1176. }
  1177. lastDayTime := dayList[len(dayList)-1]
  1178. if currDayTime.Year() != lastDayTime.Year() {
  1179. err = errors.New("年度值倒推不支持跨年预测")
  1180. return
  1181. }
  1182. if annualValueInversionConf.Type == 1 {
  1183. currYearN := 0
  1184. var currYearVal float64
  1185. {
  1186. if frequency != "周度" {
  1187. for _, v := range allDataList {
  1188. currTime, tmpErr := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  1189. if tmpErr != nil {
  1190. err = tmpErr
  1191. return
  1192. }
  1193. if currTime.Year() != currDayTime.Year() {
  1194. continue
  1195. }
  1196. currYearN++
  1197. currYearVal = currYearVal + v.Value
  1198. }
  1199. } else {
  1200. tmpDataList := make([]*models.EdbDataList, 0)
  1201. var lastData *models.EdbDataList
  1202. isFirst := true
  1203. for _, v := range allDataList {
  1204. currTime, tmpErr := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  1205. if tmpErr != nil {
  1206. err = tmpErr
  1207. return
  1208. }
  1209. if currTime.Year() != currDayTime.Year() {
  1210. lastData = v
  1211. continue
  1212. }
  1213. if isFirst {
  1214. tmpDataList = append(tmpDataList, lastData)
  1215. }
  1216. isFirst = false
  1217. tmpDataList = append(tmpDataList, v)
  1218. currYearN++
  1219. }
  1220. tmpHandleDataMap := make(map[string]float64)
  1221. err = HandleDataByLinearRegression(tmpDataList, tmpHandleDataMap)
  1222. if err != nil {
  1223. return
  1224. }
  1225. for tmpDate, val := range tmpHandleDataMap {
  1226. tmpDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, tmpDate, time.Local)
  1227. if tmpErr != nil {
  1228. err = tmpErr
  1229. return
  1230. }
  1231. if tmpDateTime.Year() != currDayTime.Year() {
  1232. continue
  1233. }
  1234. currYearVal = currYearVal + val
  1235. }
  1236. currYearVal = currYearVal / 7
  1237. }
  1238. }
  1239. var averageVal float64
  1240. switch frequency {
  1241. case "半年度":
  1242. averageVal, _ = (decimal.NewFromFloat(yearValueConfig).Sub(decimal.NewFromFloat(currYearVal))).Div(decimal.NewFromInt(int64(2 - currYearN))).Float64()
  1243. case "季度":
  1244. averageVal, _ = (decimal.NewFromFloat(yearValueConfig).Sub(decimal.NewFromFloat(currYearVal))).Div(decimal.NewFromInt(int64(4 - currYearN))).Float64()
  1245. case "月度":
  1246. averageVal, _ = (decimal.NewFromFloat(yearValueConfig).Sub(decimal.NewFromFloat(currYearVal))).Div(decimal.NewFromInt(int64(12 - currYearN))).Float64()
  1247. case "旬度":
  1248. averageVal, _ = (decimal.NewFromFloat(yearValueConfig).Sub(decimal.NewFromFloat(currYearVal))).Div(decimal.NewFromInt(int64(36 - currYearN))).Float64()
  1249. case "周度", "日度":
  1250. yearFirstDay := time.Date(currDayTime.Year(), 1, 1, 0, 0, 0, 0, time.Local)
  1251. subDay := utils.GetTimeSubDay(yearFirstDay, currDayTime) + 1
  1252. yearLastDay := time.Date(currDayTime.Year(), 12, 31, 0, 0, 0, 0, time.Local)
  1253. subDay2 := utils.GetTimeSubDay(yearFirstDay, yearLastDay) + 1
  1254. surplusN := decimal.NewFromInt(int64(subDay2 - subDay)).Div(decimal.NewFromInt(int64(subDay))).Mul(decimal.NewFromInt(int64(currYearN)))
  1255. balance := decimal.NewFromFloat(annualValueInversionConf.Value).Sub(decimal.NewFromFloat(currYearVal))
  1256. averageVal, _ = balance.Div(surplusN).Round(4).Float64()
  1257. }
  1258. averageVal, _ = decimal.NewFromFloat(averageVal).Round(4).Float64()
  1259. for k, currentDate := range dayList {
  1260. currentDateStr := currentDate.Format(utils.FormatDate)
  1261. tmpData := &models.EdbDataList{
  1262. EdbDataId: edbInfoId + 100000 + index + k,
  1263. EdbInfoId: edbInfoId,
  1264. DataTime: currentDateStr,
  1265. Value: averageVal,
  1266. DataTimestamp: currentDate.UnixNano() / 1e6,
  1267. }
  1268. newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
  1269. allDataList = append(allDataList, tmpData)
  1270. existMap[currentDateStr] = averageVal
  1271. }
  1272. if averageVal < minValue {
  1273. minValue = averageVal
  1274. }
  1275. if averageVal > maxValue {
  1276. maxValue = averageVal
  1277. }
  1278. return
  1279. }
  1280. dateTotalMap := make(map[time.Time]float64)
  1281. yearTotalMap := make(map[int]float64)
  1282. for _, v := range allDataList {
  1283. currTime, tmpErr := time.ParseInLocation(utils.FormatDate, v.DataTime, time.Local)
  1284. if tmpErr != nil {
  1285. err = tmpErr
  1286. return
  1287. }
  1288. yearVal := yearTotalMap[currTime.Year()]
  1289. yearVal = yearVal + v.Value
  1290. yearTotalMap[currTime.Year()] = yearVal
  1291. dateTotalMap[currTime] = yearVal
  1292. }
  1293. for k, currentDate := range dayList {
  1294. currYearBalance := yearValueConfig - yearTotalMap[currentDate.Year()] // 当年的余额
  1295. prevDateStr := allDataList[len(allDataList)-1].DataTime
  1296. prevDateTime, tmpErr := time.ParseInLocation(utils.FormatDate, prevDateStr, time.Local)
  1297. if tmpErr != nil {
  1298. err = tmpErr
  1299. return
  1300. }
  1301. lastYear := annualValueInversionConf.Year + (currentDate.Year() - currDayTime.Year())
  1302. var lastPrevDateTime, lastDateTime time.Time
  1303. switch frequency {
  1304. case "半年度", "季度":
  1305. lastDateTime = time.Date(lastYear, currentDate.Month(), currentDate.Day(), 0, 0, 0, 0, currentDate.Location())
  1306. lastPrevDateTime = time.Date(lastYear, prevDateTime.Month(), prevDateTime.Day(), 0, 0, 0, 0, prevDateTime.Location())
  1307. case "月度":
  1308. lastDateTime = time.Date(lastYear, currentDate.Month()+1, 1, 0, 0, 0, 0, currentDate.Location()).AddDate(0, 0, -1)
  1309. lastPrevDateTime = time.Date(lastYear, prevDateTime.Month()+1, 1, 0, 0, 0, 0, prevDateTime.Location()).AddDate(0, 0, -1)
  1310. case "旬度":
  1311. if prevDateTime.Day() == 10 || prevDateTime.Day() == 20 {
  1312. lastDateTime = time.Date(lastYear, currentDate.Month(), currentDate.Day(), 0, 0, 0, 0, currentDate.Location())
  1313. lastPrevDateTime = time.Date(lastYear, prevDateTime.Month(), prevDateTime.Day(), 0, 0, 0, 0, prevDateTime.Location())
  1314. } else {
  1315. lastDateTime = time.Date(lastYear, currentDate.Month()+1, 1, 0, 0, 0, 0, currentDate.Location()).AddDate(0, 0, -1)
  1316. lastPrevDateTime = time.Date(lastYear, prevDateTime.Month()+1, 1, 0, 0, 0, 0, prevDateTime.Location()).AddDate(0, 0, -1)
  1317. }
  1318. case "周度", "日度":
  1319. lastDateTime = time.Date(lastYear, currentDate.Month(), currentDate.Day(), 0, 0, 0, 0, currentDate.Location())
  1320. lastPrevDateTime = time.Date(lastYear, prevDateTime.Month(), prevDateTime.Day(), 0, 0, 0, 0, prevDateTime.Location())
  1321. }
  1322. var dateTotal float64
  1323. dateTotal, ok := dateTotalMap[lastPrevDateTime]
  1324. if !ok { //如果没有找到这个日期,那么就往前面找,一直到找到这个累计值,或者找完这一年
  1325. yearFirstDayTime := time.Date(lastPrevDateTime.Year(), 1, 1, 0, 0, 0, 0, lastDateTime.Location())
  1326. for tmpDateTime := lastPrevDateTime.AddDate(0, 0, -1); tmpDateTime.After(yearFirstDayTime) || tmpDateTime.Equal(yearFirstDayTime); tmpDateTime = tmpDateTime.AddDate(0, 0, -1) {
  1327. dateTotal, ok = dateTotalMap[tmpDateTime]
  1328. if ok {
  1329. break
  1330. }
  1331. }
  1332. }
  1333. lastYearDateBalance := yearTotalMap[lastPrevDateTime.Year()] - dateTotal
  1334. if lastYearDateBalance == 0 {
  1335. continue
  1336. }
  1337. tbVal := decimal.NewFromFloat(currYearBalance).Div(decimal.NewFromFloat(lastYearDateBalance))
  1338. if lastDateVal, ok := existMap[lastDateTime.Format(utils.FormatDate)]; ok {
  1339. tmpVal, _ := decimal.NewFromFloat(lastDateVal).Mul(tbVal).Round(4).Float64()
  1340. currentDateStr := currentDate.Format(utils.FormatDate)
  1341. tmpData := &models.EdbDataList{
  1342. EdbDataId: edbInfoId + 100000 + index + k,
  1343. EdbInfoId: edbInfoId,
  1344. DataTime: currentDateStr,
  1345. Value: tmpVal,
  1346. DataTimestamp: currentDate.UnixNano() / 1e6,
  1347. }
  1348. newPredictEdbInfoData = append(newPredictEdbInfoData, tmpData)
  1349. allDataList = append(allDataList, tmpData)
  1350. existMap[currentDateStr] = tmpVal
  1351. yearVal := yearTotalMap[currentDate.Year()]
  1352. yearVal = yearVal + tmpVal
  1353. yearTotalMap[currentDate.Year()] = yearVal
  1354. dateTotalMap[currentDate] = yearVal
  1355. if tmpVal < minValue {
  1356. minValue = tmpVal
  1357. }
  1358. if tmpVal > maxValue {
  1359. maxValue = tmpVal
  1360. }
  1361. }
  1362. }
  1363. return
  1364. }
  1365. func getYearListBySeasonConf(configValue string) (yearList []int, seasonConf SeasonConf, err error) {
  1366. tmpErr := json.Unmarshal([]byte(configValue), &seasonConf)
  1367. if tmpErr != nil {
  1368. err = errors.New("年份配置信息异常:" + tmpErr.Error())
  1369. return
  1370. }
  1371. if seasonConf.YearType == 1 {
  1372. if seasonConf.NValue < 1 {
  1373. err = errors.New("连续N年不允许小于1")
  1374. return
  1375. }
  1376. currYear := time.Now().Year()
  1377. for i := 0; i < seasonConf.NValue; i++ {
  1378. yearList = append(yearList, currYear-i-1)
  1379. }
  1380. } else {
  1381. yearList = seasonConf.YearList
  1382. }
  1383. return
  1384. }