edb_data_calculate_phase_shift.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. package models
  2. import (
  3. "errors"
  4. "eta/eta_index_lib/global"
  5. "eta/eta_index_lib/utils"
  6. "fmt"
  7. "gorm.io/gorm"
  8. "strconv"
  9. "strings"
  10. "time"
  11. )
  12. // AddCalculatePhaseShift 期数移位
  13. func AddCalculatePhaseShift(req *EdbInfoCalculateBatchSaveReq, fromEdbInfo *EdbInfo, edbCode, uniqueCode string, sysUserId int, sysUserRealName string) (edbInfo *EdbInfo, err error) {
  14. to := global.DEFAULT_DB.Begin()
  15. defer func() {
  16. if err != nil {
  17. to.Rollback()
  18. } else {
  19. to.Commit()
  20. }
  21. }()
  22. // 前端那边让后端处理。。。
  23. if req.Frequency == "日度" && req.MoveFrequency == "" {
  24. return nil, errors.New("日度指标,移动频率不能为空")
  25. }
  26. switch req.Frequency {
  27. case "周度":
  28. req.MoveFrequency = "周"
  29. case "旬度":
  30. req.MoveFrequency = "旬"
  31. case "月度":
  32. req.MoveFrequency = "月"
  33. case "季度":
  34. req.MoveFrequency = "季"
  35. case "半年度":
  36. req.MoveFrequency = "半年"
  37. case "年度":
  38. req.MoveFrequency = "年"
  39. }
  40. if req.EdbInfoId <= 0 {
  41. edbInfo = new(EdbInfo)
  42. edbInfo.Source = utils.DATA_SOURCE_CALCULATE_PHASE_SHIFT
  43. edbInfo.SourceName = "期数移位"
  44. edbInfo.EdbCode = edbCode
  45. edbInfo.EdbName = req.EdbName
  46. edbInfo.EdbNameSource = req.EdbName
  47. edbInfo.Frequency = req.Frequency
  48. edbInfo.Unit = req.Unit
  49. edbInfo.ClassifyId = req.ClassifyId
  50. edbInfo.SysUserId = sysUserId
  51. edbInfo.SysUserRealName = sysUserRealName
  52. edbInfo.CreateTime = time.Now()
  53. edbInfo.ModifyTime = time.Now()
  54. edbInfo.UniqueCode = uniqueCode
  55. edbInfo.CalculateFormula = req.Formula
  56. edbInfo.EdbNameEn = req.EdbName
  57. edbInfo.UnitEn = req.Unit
  58. edbInfo.EdbType = 2
  59. edbInfo.Sort = GetAddEdbMaxSortByClassifyId(req.ClassifyId, utils.EDB_INFO_TYPE)
  60. edbInfo.MoveType = req.MoveType
  61. edbInfo.MoveFrequency = req.MoveFrequency
  62. tmpErr := to.Create(edbInfo).Error
  63. if tmpErr != nil {
  64. err = tmpErr
  65. return
  66. }
  67. //关联关系
  68. {
  69. calculateMappingItem := new(EdbInfoCalculateMapping)
  70. calculateMappingItem.CreateTime = time.Now()
  71. calculateMappingItem.ModifyTime = time.Now()
  72. calculateMappingItem.Sort = 1
  73. calculateMappingItem.EdbCode = edbCode
  74. calculateMappingItem.EdbInfoId = edbInfo.EdbInfoId
  75. calculateMappingItem.FromEdbInfoId = fromEdbInfo.EdbInfoId
  76. calculateMappingItem.FromEdbCode = fromEdbInfo.EdbCode
  77. calculateMappingItem.FromEdbName = fromEdbInfo.EdbName
  78. calculateMappingItem.FromSource = fromEdbInfo.Source
  79. calculateMappingItem.FromSourceName = fromEdbInfo.SourceName
  80. calculateMappingItem.FromTag = ""
  81. calculateMappingItem.Source = edbInfo.Source
  82. calculateMappingItem.SourceName = edbInfo.SourceName
  83. calculateMappingItem.FromSubSource = edbInfo.SubSource
  84. err = to.Create(calculateMappingItem).Error
  85. if err != nil {
  86. return
  87. }
  88. }
  89. } else {
  90. edbInfo, err = GetEdbInfoById(req.EdbInfoId)
  91. if err != nil {
  92. return
  93. }
  94. dataTableName := GetEdbDataTableName(utils.DATA_SOURCE_CALCULATE_PHASE_SHIFT, utils.DATA_SUB_SOURCE_EDB)
  95. fmt.Println("dataTableName:" + dataTableName)
  96. deleteSql := ` DELETE FROM %s WHERE edb_info_id=? `
  97. deleteSql = fmt.Sprintf(deleteSql, dataTableName)
  98. err = to.Exec(deleteSql, req.EdbInfoId).Error
  99. if err != nil {
  100. return
  101. }
  102. }
  103. formulaInt, _ := strconv.Atoi(req.Formula)
  104. //计算数据
  105. err = refreshAllCalculatePhaseShift(to, edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, formulaInt, edbInfo.MoveType, fromEdbInfo, edbInfo.EdbCode, "", "", edbInfo.MoveFrequency)
  106. return
  107. }
  108. // EditCalculatePhaseShift 修改期数移位
  109. func EditCalculatePhaseShift(edbInfo *EdbInfo, req *EdbInfoCalculateBatchEditReq, fromEdbInfo *EdbInfo) (err error) {
  110. to := global.DEFAULT_DB.Begin()
  111. defer func() {
  112. if err != nil {
  113. to.Rollback()
  114. } else {
  115. to.Commit()
  116. }
  117. }()
  118. switch req.Frequency {
  119. case "周度":
  120. req.MoveFrequency = "周"
  121. case "旬度":
  122. req.MoveFrequency = "旬"
  123. case "月度":
  124. req.MoveFrequency = "月"
  125. case "季度":
  126. req.MoveFrequency = "季"
  127. case "半年度":
  128. req.MoveFrequency = "半年"
  129. case "年度":
  130. req.MoveFrequency = "年"
  131. }
  132. oldEdbInfo := *edbInfo //旧的指标信息
  133. //修改指标信息
  134. edbInfo.EdbName = req.EdbName
  135. edbInfo.EdbNameSource = req.EdbName
  136. edbInfo.Frequency = req.Frequency
  137. edbInfo.Unit = req.Unit
  138. edbInfo.ClassifyId = req.ClassifyId
  139. edbInfo.MoveType = req.MoveType
  140. edbInfo.MoveFrequency = req.MoveFrequency
  141. edbInfo.CalculateFormula = req.Formula
  142. edbInfo.EdbNameEn = req.EdbNameEn
  143. edbInfo.UnitEn = req.UnitEn
  144. edbInfo.ModifyTime = time.Now()
  145. err = to.Model(edbInfo).Select([]string{"EdbName", "EdbNameSource", "Frequency", "Unit", "ClassifyId", "MoveType", "MoveFrequency", "CalculateFormula", "ModifyTime", "EdbNameEn", "UnitEn"}).Updates(edbInfo).Error
  146. if err != nil {
  147. return
  148. }
  149. //判断计算指标是否被更换
  150. var existCondition string
  151. var existPars []interface{}
  152. existCondition += " AND edb_info_id=? AND from_edb_info_id=? "
  153. existPars = append(existPars, edbInfo.EdbInfoId, req.FromEdbInfoId)
  154. count, err := GetEdbInfoCalculateCountByCondition(existCondition, existPars)
  155. if err != nil {
  156. err = errors.New("判断指标是否改变失败,Err:" + err.Error())
  157. return
  158. }
  159. if count <= 0 || req.MoveType != oldEdbInfo.MoveType || req.MoveFrequency != oldEdbInfo.MoveFrequency || req.Formula != oldEdbInfo.CalculateFormula {
  160. //如果是依赖指标变更,那么需要删除对应的关联指标,并添加新的关系
  161. if count <= 0 {
  162. //删除,计算指标关联的,基础指标的关联关系
  163. sql := ` DELETE FROM edb_info_calculate_mapping WHERE edb_info_id = ? `
  164. err = to.Exec(sql, edbInfo.EdbInfoId).Error
  165. if err != nil {
  166. err = errors.New("删除计算指标关联关系失败,Err:" + err.Error())
  167. return
  168. }
  169. //关联关系
  170. {
  171. calculateMappingItem := &EdbInfoCalculateMapping{
  172. EdbInfoCalculateMappingId: 0,
  173. EdbInfoId: edbInfo.EdbInfoId,
  174. Source: utils.DATA_SOURCE_CALCULATE_PHASE_SHIFT,
  175. SourceName: "期数移位",
  176. EdbCode: edbInfo.EdbCode,
  177. FromEdbInfoId: fromEdbInfo.EdbInfoId,
  178. FromEdbCode: fromEdbInfo.EdbCode,
  179. FromEdbName: fromEdbInfo.EdbName,
  180. FromSource: fromEdbInfo.Source,
  181. FromSourceName: fromEdbInfo.SourceName,
  182. FromTag: "",
  183. Sort: 1,
  184. CreateTime: time.Now(),
  185. ModifyTime: time.Now(),
  186. FromSubSource: fromEdbInfo.SubSource,
  187. }
  188. err = to.Create(calculateMappingItem).Error
  189. if err != nil {
  190. return
  191. }
  192. }
  193. }
  194. //清空原有数据
  195. sql := ` DELETE FROM edb_data_calculate_phase_shift WHERE edb_info_id = ? `
  196. err = to.Exec(sql, edbInfo.EdbInfoId).Error
  197. if err != nil {
  198. return
  199. }
  200. //计算数据
  201. formulaInt, _ := strconv.Atoi(req.Formula)
  202. err = refreshAllCalculatePhaseShift(to, edbInfo.EdbInfoId, edbInfo.Source, edbInfo.SubSource, formulaInt, edbInfo.MoveType, fromEdbInfo, edbInfo.EdbCode, "", "", edbInfo.MoveFrequency)
  203. }
  204. return
  205. }
  206. // RefreshAllCalculatePhaseShift 刷新所有时间移位数据
  207. func RefreshAllCalculatePhaseShift(edbInfoId, source, subSource, formulaInt, moveType int, fromEdbInfo *EdbInfo, edbCode, startDate, endDate, moveFrequency string) (err error) {
  208. to := global.DEFAULT_DB.Begin()
  209. defer func() {
  210. if err != nil {
  211. to.Rollback()
  212. } else {
  213. to.Commit()
  214. }
  215. }()
  216. //清空原有数据
  217. sql := ` DELETE FROM edb_data_calculate_phase_shift WHERE edb_info_id = ? `
  218. err = to.Exec(sql, edbInfoId).Error
  219. if err != nil {
  220. return
  221. }
  222. //计算数据
  223. err = refreshAllCalculatePhaseShift(to, edbInfoId, source, subSource, formulaInt, moveType, fromEdbInfo, edbCode, startDate, endDate, moveFrequency)
  224. return
  225. }
  226. // refreshAllCalculatePhaseShift 刷新所有时间移位数据
  227. func refreshAllCalculatePhaseShift(to *gorm.DB, edbInfoId, source, subSource, formulaInt, moveType int, fromEdbInfo *EdbInfo, edbCode, startDate, endDate, moveFrequency string) (err error) {
  228. edbInfoIdStr := strconv.Itoa(edbInfoId)
  229. //计算数据
  230. dataList, err := GetEdbDataListAllByTo(to, fromEdbInfo.Source, fromEdbInfo.SubSource, FindEdbDataListAllCond{
  231. EdbInfoId: fromEdbInfo.EdbInfoId,
  232. StartDataTime: startDate,
  233. StartDataTimeCond: ">=",
  234. }, 0)
  235. if err != nil {
  236. return err
  237. }
  238. var dateArr []string
  239. dataMap := make(map[string]*EdbInfoSearchData)
  240. for _, v := range dataList {
  241. dateArr = append(dateArr, v.DataTime)
  242. dataMap[v.DataTime] = v
  243. }
  244. fmt.Println("source:", source)
  245. //获取指标所有数据
  246. existDataList, err := GetAllEdbDataListByTo(to, edbInfoId, source, subSource)
  247. if err != nil {
  248. return
  249. }
  250. existDataMap := make(map[string]string)
  251. removeDateMap := make(map[string]string)
  252. for _, v := range existDataList {
  253. existDataMap[v.DataTime] = v.Value
  254. removeDateMap[v.DataTime] = ``
  255. }
  256. fmt.Println("existDataMap:", existDataMap)
  257. addSql := ` INSERT INTO edb_data_calculate_phase_shift(edb_info_id,edb_code,data_time,value,create_time,modify_time,data_timestamp) values `
  258. var isAdd bool
  259. resultMap := make(map[string]float64)
  260. dataLen := len(dataList)
  261. var moveNum int
  262. for i := 0; i < dataLen; i++ {
  263. // step_1 如果 领先/滞后 之后时间key存在,将该key为目标key,填充
  264. currentIndex := dataList[i]
  265. // 领先
  266. if moveType != 2 {
  267. periods := dataLen - i + formulaInt - 1
  268. if periods < dataLen {
  269. newIndex := dataList[dataLen-periods-1]
  270. resultMap[newIndex.DataTime] = currentIndex.Value
  271. } else {
  272. moveNum = formulaInt - i
  273. // 新数据须根据频度补充key
  274. currentDate, _ := time.ParseInLocation(utils.FormatDate, dataList[0].DataTime, time.Local)
  275. shiftDay := CalculateIntervalDays(moveFrequency, moveNum, currentDate, resultMap, moveType)
  276. var newDate time.Time
  277. if moveFrequency == "年" {
  278. newDate = currentDate.AddDate(moveNum, 0, 0)
  279. } else {
  280. newDate = currentDate.AddDate(0, 0, shiftDay)
  281. }
  282. format := newDate.Format(utils.FormatDate)
  283. resultMap[format] = currentIndex.Value
  284. }
  285. } else {
  286. // 滞后
  287. periods := dataLen - i - formulaInt
  288. if periods > 0 {
  289. newIndex := dataList[dataLen-periods]
  290. resultMap[newIndex.DataTime] = currentIndex.Value
  291. } else {
  292. moveNum = formulaInt + 1 - (dataLen - i)
  293. // 新数据须根据频度补充key
  294. currentDate, _ := time.ParseInLocation(utils.FormatDate, dataList[dataLen-1].DataTime, time.Local)
  295. shiftDay := CalculateIntervalDays(moveFrequency, moveNum, currentDate, resultMap, moveType)
  296. var newDate time.Time
  297. if moveFrequency == "年" {
  298. newDate = currentDate.AddDate(-moveNum, 0, 0)
  299. } else {
  300. newDate = currentDate.AddDate(0, 0, -shiftDay)
  301. }
  302. format := newDate.Format(utils.FormatDate)
  303. resultMap[format] = currentIndex.Value
  304. }
  305. }
  306. }
  307. for key, value := range resultMap {
  308. currentDate, _ := time.ParseInLocation(utils.FormatDate, key, time.Local)
  309. timestamp := currentDate.UnixNano() / 1e6
  310. timestampStr := fmt.Sprintf("%d", timestamp)
  311. addSql += GetAddSql(edbInfoIdStr, edbCode, key, timestampStr, fmt.Sprintf("%f", value))
  312. isAdd = true
  313. }
  314. if isAdd {
  315. addSql = strings.TrimRight(addSql, ",")
  316. err = to.Exec(addSql).Error
  317. if err != nil {
  318. return
  319. }
  320. }
  321. return
  322. }
  323. func CalculateIntervalDays(moveFrequency string, formulaInt int, baseDate time.Time, resultMap map[string]float64, moveType int) int {
  324. var shiftDay int
  325. switch moveFrequency {
  326. case "自然日":
  327. shiftDay = formulaInt
  328. case "交易日":
  329. shiftDay = utils.CalculateTradingDays(baseDate, formulaInt, resultMap, moveType)
  330. case "周":
  331. shiftDay = formulaInt * 7
  332. case "旬":
  333. shiftDay = utils.CalculateDekadTime(baseDate, formulaInt, moveType)
  334. case "月":
  335. shiftDay = utils.CalculateEndOfMonth(baseDate, formulaInt, moveType)
  336. case "季":
  337. shiftDay = utils.CalculateEndOfQuarter(baseDate, formulaInt, moveType)
  338. case "半年":
  339. shiftDay = utils.CalculateEndOfHalfYear(baseDate, formulaInt, moveType)
  340. case "年":
  341. shiftDay = utils.CalculateEndOfYear(baseDate, formulaInt, moveType)
  342. default:
  343. shiftDay = formulaInt
  344. }
  345. return shiftDay
  346. }