predict_edb_info_rule.go 51 KB

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