factor_edb_series.go 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816
  1. package data_manage
  2. import (
  3. "encoding/json"
  4. "eta/eta_api/controllers"
  5. "eta/eta_api/models"
  6. "eta/eta_api/models/data_manage"
  7. "eta/eta_api/models/data_manage/request"
  8. "eta/eta_api/services/data"
  9. correlationServ "eta/eta_api/services/data/correlation"
  10. "eta/eta_api/utils"
  11. "fmt"
  12. "sort"
  13. "strconv"
  14. "strings"
  15. "sync"
  16. "time"
  17. )
  18. // FactorEdbSeriesController 因子指标系列
  19. type FactorEdbSeriesController struct {
  20. controllers.BaseAuthController
  21. }
  22. // CalculateFuncList
  23. // @Title 计算方式列表
  24. // @Description 计算方式列表
  25. // @Param EdbInfoType query int false "指标计算类型: 0-普通指标; 1-预测指标"
  26. // @Success Ret=200 操作成功
  27. // @router /factor_edb_series/calculate_func/list [get]
  28. func (this *FactorEdbSeriesController) CalculateFuncList() {
  29. br := new(models.BaseResponse).Init()
  30. defer func() {
  31. if br.ErrMsg == "" {
  32. br.IsSendEmail = false
  33. }
  34. this.Data["json"] = br
  35. this.ServeJSON()
  36. }()
  37. sysUser := this.SysUser
  38. if sysUser == nil {
  39. br.Msg = "请登录"
  40. br.ErrMsg = "请登录,SysUser Is Empty"
  41. br.Ret = 408
  42. return
  43. }
  44. edbInfoType, _ := this.GetInt("EdbInfoType", 0)
  45. funcOb := new(data_manage.FactorEdbSeriesCalculateFunc)
  46. cond := fmt.Sprintf(` AND %s = ?`, funcOb.Cols().EdbInfoType)
  47. pars := make([]interface{}, 0)
  48. pars = append(pars, edbInfoType)
  49. list, e := funcOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", funcOb.Cols().PrimaryId))
  50. if e != nil {
  51. br.Msg = "获取失败"
  52. br.ErrMsg = fmt.Sprintf("获取计算方式列表失败, Err: %v", e)
  53. return
  54. }
  55. resp := make([]*data_manage.FactorEdbSeriesCalculateFuncItem, 0)
  56. for _, v := range list {
  57. resp = append(resp, v.Format2Item())
  58. }
  59. br.Data = resp
  60. br.Ret = 200
  61. br.Success = true
  62. br.Msg = "获取成功"
  63. }
  64. // Add
  65. // @Title 新增
  66. // @Description 新增
  67. // @Param request body request.AddFactorEdbSeriesReq true "type json string"
  68. // @Success Ret=200 操作成功
  69. // @router /factor_edb_series/add [post]
  70. func (this *FactorEdbSeriesController) Add() {
  71. br := new(models.BaseResponse).Init()
  72. defer func() {
  73. if br.ErrMsg == "" {
  74. br.IsSendEmail = false
  75. }
  76. this.Data["json"] = br
  77. this.ServeJSON()
  78. }()
  79. sysUser := this.SysUser
  80. if sysUser == nil {
  81. br.Msg = "请登录"
  82. br.ErrMsg = "请登录,SysUser Is Empty"
  83. br.Ret = 408
  84. return
  85. }
  86. var req request.AddFactorEdbSeriesReq
  87. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  88. br.Msg = "参数解析异常"
  89. br.ErrMsg = fmt.Sprintf("参数解析异常, Err: %v", e)
  90. return
  91. }
  92. req.SeriesName = strings.TrimSpace(req.SeriesName)
  93. if req.SeriesName == "" {
  94. br.Msg = "请输入指标系列名称"
  95. return
  96. }
  97. if len(req.EdbInfoIds) <= 0 {
  98. br.Msg = "请选择因子指标系列"
  99. return
  100. }
  101. if len(req.EdbInfoIds) > 100 {
  102. br.Msg = "添加指标总数量不得超过100"
  103. return
  104. }
  105. calculateLen := len(req.Calculates)
  106. if calculateLen > 5 {
  107. br.Msg = "计算公式不可超过5个"
  108. return
  109. }
  110. var calculatesJson string
  111. if calculateLen > 0 {
  112. b, e := json.Marshal(req.Calculates)
  113. if e != nil {
  114. br.Msg = "计算方式格式有误"
  115. br.ErrMsg = "解析计算方式参数失败, Err: " + e.Error()
  116. return
  117. }
  118. calculatesJson = string(b)
  119. for _, v := range req.Calculates {
  120. switch v.Source {
  121. case utils.EdbBaseCalculateNszydpjjs, utils.EdbBaseCalculateHbz, utils.EdbBaseCalculateHcz, utils.EdbBaseCalculateCjjx:
  122. if v.Formula == nil {
  123. br.Msg = "请输入N值"
  124. return
  125. }
  126. formula, ok := v.Formula.(string)
  127. if !ok {
  128. br.Msg = "N值格式有误"
  129. return
  130. }
  131. formulaInt, _ := strconv.Atoi(formula)
  132. if formulaInt <= 0 {
  133. br.Msg = "N值不可小于0, 重新输入"
  134. return
  135. }
  136. case utils.EdbBaseCalculateExponentialSmoothing:
  137. if v.Formula == nil {
  138. br.Msg = "请填写alpha值"
  139. return
  140. }
  141. formula, ok := v.Formula.(string)
  142. if !ok {
  143. br.Msg = "alpha值格式有误"
  144. return
  145. }
  146. alpha, _ := strconv.ParseFloat(formula, 64)
  147. if alpha <= 0 || alpha >= 1 {
  148. br.Msg = "alpha值应在0-1之间, 请重新输入"
  149. return
  150. }
  151. }
  152. }
  153. }
  154. edbArr, e := data_manage.GetEdbInfoByIdList(req.EdbInfoIds)
  155. if e != nil {
  156. br.Msg = "操作失败"
  157. br.ErrMsg = "获取指标列表失败, Err: " + e.Error()
  158. return
  159. }
  160. if len(edbArr) == 0 {
  161. br.Msg = "因子指标系列有误"
  162. br.ErrMsg = "因子指标系列长度为0"
  163. return
  164. }
  165. // 新增指标系列
  166. seriesItem := new(data_manage.FactorEdbSeries)
  167. seriesItem.SeriesName = req.SeriesName
  168. seriesItem.EdbInfoType = req.EdbInfoType
  169. seriesItem.CreateTime = time.Now().Local()
  170. seriesItem.ModifyTime = time.Now().Local()
  171. if calculateLen > 0 {
  172. seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculating
  173. seriesItem.CalculateStep = calculatesJson
  174. }
  175. mappings := make([]*data_manage.FactorEdbSeriesMapping, 0)
  176. for _, v := range edbArr {
  177. mappings = append(mappings, &data_manage.FactorEdbSeriesMapping{
  178. EdbInfoId: v.EdbInfoId,
  179. EdbCode: v.EdbCode,
  180. CreateTime: time.Now().Local(),
  181. ModifyTime: time.Now().Local(),
  182. })
  183. }
  184. seriesId, e := seriesItem.CreateSeriesAndMapping(seriesItem, mappings)
  185. if e != nil {
  186. br.Msg = "操作失败"
  187. br.ErrMsg = "新增因子指标系列失败, Err: " + e.Error()
  188. return
  189. }
  190. // 计算指标数据
  191. var calculateResp data_manage.FactorEdbSeriesStepCalculateResp
  192. if calculateLen > 0 {
  193. calculateResp, e = data.FactorEdbStepCalculate(seriesId, edbArr, req.Calculates, this.Lang, false)
  194. if e != nil {
  195. br.Msg = "操作失败"
  196. br.ErrMsg = "计算因子指标失败, Err: " + e.Error()
  197. return
  198. }
  199. // 更新系列计算状态
  200. cols := []string{seriesItem.Cols().CalculateState, seriesItem.Cols().ModifyTime}
  201. seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculated
  202. seriesItem.ModifyTime = time.Now().Local()
  203. if e = seriesItem.Update(cols); e != nil {
  204. br.Msg = "操作失败"
  205. br.ErrMsg = "更新因子指标系列计算状态失败, Err: " + e.Error()
  206. return
  207. }
  208. } else {
  209. for _, v := range edbArr {
  210. calculateResp.Success = append(calculateResp.Success, data_manage.FactorEdbSeriesStepCalculateResult{
  211. EdbInfoId: v.EdbInfoId,
  212. EdbCode: v.EdbCode,
  213. Msg: "保存成功",
  214. })
  215. }
  216. }
  217. calculateResp.SeriesId = seriesId
  218. br.Data = calculateResp
  219. br.Ret = 200
  220. br.Success = true
  221. br.Msg = "操作成功"
  222. br.IsAddLog = true
  223. }
  224. // Edit
  225. // @Title 编辑
  226. // @Description 编辑
  227. // @Param request body request.EditFactorEdbSeriesReq true "type json string"
  228. // @Success Ret=200 操作成功
  229. // @router /factor_edb_series/edit [post]
  230. func (this *FactorEdbSeriesController) Edit() {
  231. br := new(models.BaseResponse).Init()
  232. defer func() {
  233. if br.ErrMsg == "" {
  234. br.IsSendEmail = false
  235. }
  236. this.Data["json"] = br
  237. this.ServeJSON()
  238. }()
  239. sysUser := this.SysUser
  240. if sysUser == nil {
  241. br.Msg = "请登录"
  242. br.ErrMsg = "请登录,SysUser Is Empty"
  243. br.Ret = 408
  244. return
  245. }
  246. var req request.EditFactorEdbSeriesReq
  247. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  248. br.Msg = "参数解析异常"
  249. br.ErrMsg = fmt.Sprintf("参数解析异常, Err: %v", e)
  250. return
  251. }
  252. if req.SeriesId <= 0 {
  253. br.Msg = "参数有误"
  254. br.ErrMsg = fmt.Sprintf("参数有误, SeriesId: %d", req.SeriesId)
  255. return
  256. }
  257. req.SeriesName = strings.TrimSpace(req.SeriesName)
  258. if req.SeriesName == "" {
  259. br.Msg = "请输入指标系列名称"
  260. return
  261. }
  262. if len(req.EdbInfoIds) <= 0 {
  263. br.Msg = "请选择因子指标系列"
  264. return
  265. }
  266. if len(req.EdbInfoIds) > 100 {
  267. br.Msg = "添加指标总数量不得超过100"
  268. return
  269. }
  270. calculateLen := len(req.Calculates)
  271. if calculateLen > 5 {
  272. br.Msg = "计算公式不可超过5个"
  273. return
  274. }
  275. var calculatesJson string
  276. if calculateLen > 0 {
  277. b, e := json.Marshal(req.Calculates)
  278. if e != nil {
  279. br.Msg = "计算方式格式有误"
  280. br.ErrMsg = "解析计算方式参数失败, Err: " + e.Error()
  281. return
  282. }
  283. calculatesJson = string(b)
  284. for _, v := range req.Calculates {
  285. switch v.Source {
  286. case utils.EdbBaseCalculateNszydpjjs, utils.EdbBaseCalculateHbz, utils.EdbBaseCalculateHcz, utils.EdbBaseCalculateCjjx:
  287. if v.Formula == nil {
  288. br.Msg = "请输入N值"
  289. return
  290. }
  291. formula, ok := v.Formula.(string)
  292. if !ok {
  293. br.Msg = "N值格式有误"
  294. return
  295. }
  296. formulaInt, _ := strconv.Atoi(formula)
  297. if formulaInt <= 0 {
  298. br.Msg = "N值不可小于0, 重新输入"
  299. return
  300. }
  301. case utils.EdbBaseCalculateExponentialSmoothing:
  302. if v.Formula == nil {
  303. br.Msg = "请填写alpha值"
  304. return
  305. }
  306. formula, ok := v.Formula.(string)
  307. if !ok {
  308. br.Msg = "alpha值格式有误"
  309. return
  310. }
  311. alpha, _ := strconv.ParseFloat(formula, 64)
  312. if alpha <= 0 || alpha >= 1 {
  313. br.Msg = "alpha值应在0-1之间, 请重新输入"
  314. return
  315. }
  316. }
  317. }
  318. }
  319. seriesOb := new(data_manage.FactorEdbSeries)
  320. seriesItem, e := seriesOb.GetItemById(req.SeriesId)
  321. if e != nil {
  322. if e.Error() == utils.ErrNoRow() {
  323. br.Msg = "该因子指标系列不存在"
  324. return
  325. }
  326. br.Msg = "获取失败"
  327. br.ErrMsg = "获取因子指标系列失败, Err: " + e.Error()
  328. return
  329. }
  330. edbArr, e := data_manage.GetEdbInfoByIdList(req.EdbInfoIds)
  331. if e != nil {
  332. br.Msg = "操作失败"
  333. br.ErrMsg = "获取指标列表失败, Err: " + e.Error()
  334. return
  335. }
  336. if len(edbArr) == 0 {
  337. br.Msg = "因子指标系列有误"
  338. br.ErrMsg = "因子指标系列长度为0"
  339. return
  340. }
  341. var calculateResp data_manage.FactorEdbSeriesStepCalculateResp
  342. calculateResp.SeriesId = seriesItem.FactorEdbSeriesId
  343. // 如果不需要进行重新计算(比如只改了系列名称)那么只更新指标系列
  344. seriesItem.SeriesName = req.SeriesName
  345. seriesItem.EdbInfoType = req.EdbInfoType
  346. seriesItem.ModifyTime = time.Now().Local()
  347. updateCols := []string{seriesOb.Cols().SeriesName, seriesOb.Cols().EdbInfoType, seriesOb.Cols().ModifyTime}
  348. if !req.Recalculate {
  349. if e = seriesItem.Update(updateCols); e != nil {
  350. br.Msg = "操作成功"
  351. br.ErrMsg = "更新因子指标系列信息失败, Err: " + e.Error()
  352. return
  353. }
  354. for _, v := range edbArr {
  355. calculateResp.Success = append(calculateResp.Success, data_manage.FactorEdbSeriesStepCalculateResult{
  356. EdbInfoId: v.EdbInfoId,
  357. EdbCode: v.EdbCode,
  358. Msg: "保存成功",
  359. })
  360. }
  361. br.Data = calculateResp
  362. br.Ret = 200
  363. br.Success = true
  364. br.Msg = "操作成功"
  365. return
  366. }
  367. // 更新系列信息和指标关联
  368. if calculateLen > 0 {
  369. seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculating
  370. seriesItem.CalculateStep = calculatesJson
  371. updateCols = append(updateCols, seriesOb.Cols().CalculateState, seriesOb.Cols().CalculateStep)
  372. }
  373. mappings := make([]*data_manage.FactorEdbSeriesMapping, 0)
  374. for _, v := range edbArr {
  375. mappings = append(mappings, &data_manage.FactorEdbSeriesMapping{
  376. EdbInfoId: v.EdbInfoId,
  377. EdbCode: v.EdbCode,
  378. CreateTime: time.Now().Local(),
  379. ModifyTime: time.Now().Local(),
  380. })
  381. }
  382. if e = seriesItem.EditSeriesAndMapping(seriesItem, mappings, updateCols); e != nil {
  383. br.Msg = "操作失败"
  384. br.ErrMsg = "编辑因子指标系列失败, Err: " + e.Error()
  385. return
  386. }
  387. // 重新计算
  388. calculateResp, e = data.FactorEdbStepCalculate(seriesItem.FactorEdbSeriesId, edbArr, req.Calculates, this.Lang, req.Recalculate)
  389. if e != nil {
  390. br.Msg = "操作失败"
  391. br.ErrMsg = "计算因子指标失败, Err: " + e.Error()
  392. return
  393. }
  394. // 更新系列计算状态
  395. cols := []string{seriesItem.Cols().CalculateState, seriesItem.Cols().ModifyTime}
  396. seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculated
  397. seriesItem.ModifyTime = time.Now().Local()
  398. if e = seriesItem.Update(cols); e != nil {
  399. br.Msg = "操作失败"
  400. br.ErrMsg = "更新因子指标系列计算状态失败, Err: " + e.Error()
  401. return
  402. }
  403. br.Data = calculateResp
  404. br.Ret = 200
  405. br.Success = true
  406. br.Msg = "操作成功"
  407. br.IsAddLog = true
  408. }
  409. // Detail
  410. // @Title 详情
  411. // @Description 详情
  412. // @Param SeriesId query int false "多因子指标系列ID"
  413. // @Success 200 {object} data_manage.FactorEdbSeriesDetail
  414. // @router /factor_edb_series/detail [get]
  415. func (this *FactorEdbSeriesController) Detail() {
  416. br := new(models.BaseResponse).Init()
  417. defer func() {
  418. if br.ErrMsg == "" {
  419. br.IsSendEmail = false
  420. }
  421. this.Data["json"] = br
  422. this.ServeJSON()
  423. }()
  424. sysUser := this.SysUser
  425. if sysUser == nil {
  426. br.Msg = "请登录"
  427. br.ErrMsg = "请登录,SysUser Is Empty"
  428. br.Ret = 408
  429. return
  430. }
  431. seriesId, _ := this.GetInt("SeriesId", 0)
  432. if seriesId <= 0 {
  433. br.Msg = "参数有误"
  434. br.ErrMsg = fmt.Sprintf("参数有误, SeriesId: %d", seriesId)
  435. return
  436. }
  437. seriesOb := new(data_manage.FactorEdbSeries)
  438. series, e := seriesOb.GetItemById(seriesId)
  439. if e != nil {
  440. if e.Error() == utils.ErrNoRow() {
  441. br.Msg = "该因子指标系列不存在"
  442. return
  443. }
  444. br.Msg = "获取失败"
  445. br.ErrMsg = "获取因子指标系列失败, Err: " + e.Error()
  446. return
  447. }
  448. mappingOb := new(data_manage.FactorEdbSeriesMapping)
  449. cond := fmt.Sprintf(" AND %s = ?", mappingOb.Cols().FactorEdbSeriesId)
  450. pars := make([]interface{}, 0)
  451. pars = append(pars, seriesId)
  452. mappings, e := mappingOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", mappingOb.Cols().CreateTime))
  453. if e != nil {
  454. br.Msg = "获取失败"
  455. br.ErrMsg = "获取因子指标系列关联失败, Err: " + e.Error()
  456. return
  457. }
  458. resp := new(data_manage.FactorEdbSeriesDetail)
  459. resp.FactorEdbSeriesItem = series.Format2Item()
  460. for _, m := range mappings {
  461. resp.EdbMappings = append(resp.EdbMappings, m.Format2Item())
  462. }
  463. br.Data = resp
  464. br.Ret = 200
  465. br.Success = true
  466. br.Msg = "获取成功"
  467. }
  468. // CorrelationMatrix
  469. // @Title 因子指标系列-相关性矩阵
  470. // @Description 因子指标系列-相关性矩阵
  471. // @Param request body request.FactorEdbSeriesCorrelationMatrixReq true "type json string"
  472. // @Success 200 {object} data_manage.FactorEdbSeriesCorrelationMatrixItem
  473. // @router /factor_edb_series/correlation/matrix [post]
  474. func (this *FactorEdbSeriesController) CorrelationMatrix() {
  475. br := new(models.BaseResponse).Init()
  476. defer func() {
  477. if br.ErrMsg == "" {
  478. br.IsSendEmail = false
  479. }
  480. this.Data["json"] = br
  481. this.ServeJSON()
  482. }()
  483. sysUser := this.SysUser
  484. if sysUser == nil {
  485. br.Msg = "请登录"
  486. br.ErrMsg = "请登录,SysUser Is Empty"
  487. br.Ret = 408
  488. return
  489. }
  490. var req request.FactorEdbSeriesCorrelationMatrixReq
  491. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  492. br.Msg = "参数解析异常"
  493. br.ErrMsg = fmt.Sprintf("参数解析异常, Err: %v", e)
  494. return
  495. }
  496. if req.BaseEdbInfoId <= 0 {
  497. br.Msg = "请选择标的指标"
  498. return
  499. }
  500. if len(req.SeriesIds) == 0 {
  501. br.Msg = "请选择因子指标系列"
  502. return
  503. }
  504. if req.Correlation.LeadValue <= 0 {
  505. br.Msg = "分析周期不允许设置为负数或0"
  506. return
  507. }
  508. if req.Correlation.LeadUnit == "" {
  509. br.Msg = "请选择分析周期频度"
  510. return
  511. }
  512. leadUnitDays, ok := utils.FrequencyDaysMap[req.Correlation.LeadUnit]
  513. if !ok {
  514. br.Msg = "错误的分析周期频度"
  515. br.ErrMsg = fmt.Sprintf("分析周期频度有误: %s", req.Correlation.LeadUnit)
  516. return
  517. }
  518. if req.Correlation.CalculateUnit == "" {
  519. br.Msg = "请选择计算窗口频度"
  520. return
  521. }
  522. calculateUnitDays, ok := utils.FrequencyDaysMap[req.Correlation.CalculateUnit]
  523. if !ok {
  524. br.Msg = "错误的计算窗口频度"
  525. br.ErrMsg = fmt.Sprintf("计算窗口频度有误: %s", req.Correlation.CalculateUnit)
  526. return
  527. }
  528. leadDays := 2 * req.Correlation.LeadValue * leadUnitDays
  529. calculateDays := req.Correlation.CalculateValue * calculateUnitDays
  530. if calculateDays < leadDays {
  531. br.Msg = "计算窗口必须≥2*分析周期"
  532. return
  533. }
  534. // 获取标的指标信息及数据
  535. baseEdb, e := data_manage.GetEdbInfoById(req.BaseEdbInfoId)
  536. if e != nil {
  537. if e.Error() == utils.ErrNoRow() {
  538. br.Msg = "标的指标不存在"
  539. return
  540. }
  541. br.Msg = "获取失败"
  542. br.ErrMsg = "获取标的指标信息失败, Err: " + e.Error()
  543. return
  544. }
  545. dataListA := make([]*data_manage.EdbDataList, 0)
  546. {
  547. // 标的指标数据日期区间
  548. startDate := time.Now().AddDate(0, 0, -calculateDays).Format(utils.FormatDate)
  549. endDate := time.Now().Format(utils.FormatDate)
  550. startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  551. startDate = startDateTime.AddDate(0, 0, 1).Format(utils.FormatDate) // 不包含第一天
  552. switch baseEdb.EdbInfoType {
  553. case 0:
  554. dataListA, e = data_manage.GetEdbDataList(baseEdb.Source, baseEdb.SubSource, baseEdb.EdbInfoId, startDate, endDate)
  555. case 1:
  556. _, dataListA, _, _, e, _ = data.GetPredictDataListByPredictEdbInfoId(baseEdb.EdbInfoId, startDate, endDate, false)
  557. default:
  558. br.Msg = "获取失败"
  559. br.ErrMsg = fmt.Sprintf("标的指标类型异常: %d", baseEdb.EdbInfoType)
  560. return
  561. }
  562. if e != nil {
  563. br.Msg = "获取失败"
  564. br.ErrMsg = "获取标的指标数据失败, Err:" + e.Error()
  565. return
  566. }
  567. }
  568. // 获取因子系列
  569. seriesIdItem := make(map[int]*data_manage.FactorEdbSeries)
  570. {
  571. ob := new(data_manage.FactorEdbSeries)
  572. cond := fmt.Sprintf(" AND %s IN (%s)", ob.Cols().PrimaryId, utils.GetOrmInReplace(len(req.SeriesIds)))
  573. pars := make([]interface{}, 0)
  574. pars = append(pars, req.SeriesIds)
  575. items, e := ob.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", ob.Cols().PrimaryId))
  576. if e != nil {
  577. br.Msg = "获取失败"
  578. br.ErrMsg = "获取因子指标系列失败, Err: " + e.Error()
  579. return
  580. }
  581. if len(items) != len(req.SeriesIds) {
  582. br.Msg = "获取失败"
  583. br.ErrMsg = "因子指标系列数量有误"
  584. return
  585. }
  586. for _, v := range items {
  587. seriesIdItem[v.FactorEdbSeriesId] = v
  588. }
  589. }
  590. // 获取因子指标
  591. edbMappings := make([]*data_manage.FactorEdbSeriesMapping, 0)
  592. edbInfoIds := make([]int, 0)
  593. {
  594. ob := new(data_manage.FactorEdbSeriesMapping)
  595. cond := fmt.Sprintf(" AND %s IN (%s)", ob.Cols().FactorEdbSeriesId, utils.GetOrmInReplace(len(req.SeriesIds)))
  596. pars := make([]interface{}, 0)
  597. pars = append(pars, req.SeriesIds)
  598. order := fmt.Sprintf("%s ASC, %s ASC", ob.Cols().FactorEdbSeriesId, ob.Cols().EdbInfoId)
  599. items, e := ob.GetItemsByCondition(cond, pars, []string{}, order)
  600. if e != nil {
  601. br.Msg = "获取失败"
  602. br.ErrMsg = "获取因子指标关联失败, Err: " + e.Error()
  603. return
  604. }
  605. for _, v := range items {
  606. edbInfoIds = append(edbInfoIds, v.EdbInfoId)
  607. }
  608. edbMappings = items
  609. }
  610. edbIdItem := make(map[int]*data_manage.EdbInfo)
  611. edbItems, e := data_manage.GetEdbInfoByIdList(edbInfoIds)
  612. if e != nil {
  613. br.Msg = "获取失败"
  614. br.ErrMsg = "获取因子指标失败, Err: " + e.Error()
  615. return
  616. }
  617. for _, v := range edbItems {
  618. edbIdItem[v.EdbInfoId] = v
  619. }
  620. // 获取因子指标数据, 计算相关性
  621. resp := new(data_manage.FactorEdbSeriesCorrelationMatrixResp)
  622. calculateDataOb := new(data_manage.FactorEdbSeriesCalculateData)
  623. calculateWorkers := make(chan struct{}, 10)
  624. wg := sync.WaitGroup{}
  625. edbExists := make(map[string]bool)
  626. chartKeyMap := make(map[string]*data_manage.FactorEdbSeriesChartMapping)
  627. for _, v := range edbMappings {
  628. existsKey := fmt.Sprintf("%d-%d", v.FactorEdbSeriesId, v.EdbInfoId)
  629. if edbExists[existsKey] {
  630. continue
  631. }
  632. edbExists[existsKey] = true
  633. edbItem := edbIdItem[v.EdbInfoId]
  634. if edbItem == nil {
  635. continue
  636. }
  637. seriesItem := seriesIdItem[v.FactorEdbSeriesId]
  638. if seriesItem == nil {
  639. continue
  640. }
  641. wg.Add(1)
  642. go func(mapping *data_manage.FactorEdbSeriesMapping, edb *data_manage.EdbInfo, series *data_manage.FactorEdbSeries) {
  643. defer func() {
  644. wg.Done()
  645. <-calculateWorkers
  646. }()
  647. calculateWorkers <- struct{}{}
  648. var item data_manage.FactorEdbSeriesCorrelationMatrixItem
  649. item.SeriesId = series.FactorEdbSeriesId
  650. item.EdbInfoId = edb.EdbInfoId
  651. item.EdbCode = edb.EdbCode
  652. item.EdbName = edb.EdbName
  653. // 指标来源
  654. edbList := make([]*data_manage.ChartEdbInfoMapping, 0)
  655. edbList = append(edbList, &data_manage.ChartEdbInfoMapping{
  656. EdbInfoId: edb.EdbInfoId,
  657. EdbInfoCategoryType: edb.EdbInfoType,
  658. EdbType: edb.EdbType,
  659. Source: edb.Source,
  660. SourceName: edb.SourceName,
  661. })
  662. sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList)
  663. item.SourceName = strings.Join(sourceNameList, ",")
  664. item.SourceNameEn = strings.Join(sourceNameEnList, ",")
  665. // 获取指标数据
  666. dataListB := make([]*data_manage.EdbDataList, 0)
  667. if series.CalculateState == data_manage.FactorEdbSeriesCalculated {
  668. cond := fmt.Sprintf(" AND %s = ? AND %s = ?", calculateDataOb.Cols().FactorEdbSeriesId, calculateDataOb.Cols().EdbInfoId)
  669. pars := make([]interface{}, 0)
  670. pars = append(pars, mapping.FactorEdbSeriesId, mapping.EdbInfoId)
  671. dataItems, e := calculateDataOb.GetItemsByCondition(cond, pars, []string{calculateDataOb.Cols().DataTime, calculateDataOb.Cols().Value}, fmt.Sprintf("%s ASC", calculateDataOb.Cols().DataTime))
  672. if e != nil {
  673. item.Msg = fmt.Sprintf("计算失败")
  674. item.ErrMsg = fmt.Sprintf("获取计算数据失败, err: %v", e)
  675. resp.Fail = append(resp.Fail, item)
  676. return
  677. }
  678. dataListB = data_manage.TransEdbSeriesCalculateData2EdbDataList(dataItems)
  679. } else {
  680. switch edb.EdbInfoType {
  681. case 0:
  682. dataListB, e = data_manage.GetEdbDataList(edb.Source, edb.SubSource, edb.EdbInfoId, "", "")
  683. case 1:
  684. _, dataListB, _, _, e, _ = data.GetPredictDataListByPredictEdbInfoId(edb.EdbInfoId, "", "", false)
  685. default:
  686. item.Msg = fmt.Sprintf("计算失败")
  687. item.ErrMsg = fmt.Sprintf("指标类型异常, edbType: %d", edb.EdbInfoType)
  688. resp.Fail = append(resp.Fail, item)
  689. return
  690. }
  691. }
  692. // 计算相关性
  693. xEdbIdValue, yDataList, e := correlationServ.CalculateCorrelation(req.Correlation.LeadValue, req.Correlation.LeadUnit, baseEdb.Frequency, edb.Frequency, dataListA, dataListB)
  694. if e != nil {
  695. item.Msg = fmt.Sprintf("计算失败")
  696. item.ErrMsg = fmt.Sprintf("相关性计算失败, err: %v", e)
  697. resp.Fail = append(resp.Fail, item)
  698. return
  699. }
  700. // X及Y轴数据
  701. yData := yDataList[0].Value
  702. yLen := len(yData)
  703. values := make([]data_manage.FactorEdbSeriesCorrelationMatrixValues, len(xEdbIdValue))
  704. for k, x := range xEdbIdValue {
  705. var y float64
  706. if k >= 0 && k < yLen {
  707. y = yData[k]
  708. }
  709. y = utils.SubFloatToFloat(y, 2)
  710. values[k] = data_manage.FactorEdbSeriesCorrelationMatrixValues{
  711. XData: x, YData: y,
  712. }
  713. }
  714. // 图表关联-此处添加的chart_info_id=0
  715. newMapping := new(data_manage.FactorEdbSeriesChartMapping)
  716. newMapping.CalculateType = data_manage.FactorEdbSeriesChartCalculateTypeCorrelation
  717. // 计算参数
  718. var calculatePars data_manage.FactorEdbSeriesChartCalculateCorrelationReq
  719. calculatePars.BaseEdbInfoId = req.BaseEdbInfoId
  720. calculatePars.LeadValue = req.Correlation.LeadValue
  721. calculatePars.LeadUnit = req.Correlation.LeadUnit
  722. calculatePars.CalculateValue = req.Correlation.CalculateValue
  723. calculatePars.CalculateUnit = req.Correlation.CalculateUnit
  724. bc, e := json.Marshal(calculatePars)
  725. if e != nil {
  726. item.Msg = fmt.Sprintf("计算失败")
  727. item.ErrMsg = fmt.Sprintf("计算参数JSON格式化失败, err: %v", e)
  728. resp.Fail = append(resp.Fail, item)
  729. return
  730. }
  731. newMapping.CalculatePars = string(bc)
  732. // 计算结果, 注此处保存的是排序前的顺序
  733. bv, e := json.Marshal(values)
  734. if e != nil {
  735. item.Msg = fmt.Sprintf("计算失败")
  736. item.ErrMsg = fmt.Sprintf("计算结果JSON格式化失败, err: %v", e)
  737. resp.Fail = append(resp.Fail, item)
  738. return
  739. }
  740. newMapping.CalculateData = string(bv)
  741. newMapping.FactorEdbSeriesId = mapping.FactorEdbSeriesId
  742. newMapping.EdbInfoId = mapping.EdbInfoId
  743. newMapping.CreateTime = time.Now().Local()
  744. newMapping.ModifyTime = time.Now().Local()
  745. chartKeyMap[existsKey] = newMapping
  746. // 按照固定规则排期数[0 1 2 3 -1 -2 -3], 仅矩阵展示为此顺序
  747. sort.Sort(data_manage.FactorEdbSeriesCorrelationMatrixOrder(values))
  748. item.Msg = "计算成功"
  749. item.Values = values
  750. resp.Success = append(resp.Success, item)
  751. }(v, edbItem, seriesItem)
  752. }
  753. wg.Wait()
  754. // 新增图表关联, 此处按照顺序添加
  755. chartMappings := make([]*data_manage.FactorEdbSeriesChartMapping, 0)
  756. for _, v := range edbMappings {
  757. k := fmt.Sprintf("%d-%d", v.FactorEdbSeriesId, v.EdbInfoId)
  758. item := chartKeyMap[k]
  759. if item == nil {
  760. continue
  761. }
  762. chartMappings = append(chartMappings, item)
  763. }
  764. chartMappingOb := new(data_manage.FactorEdbSeriesChartMapping)
  765. if e = chartMappingOb.ClearAndCreateMapping(req.SeriesIds, chartMappings); e != nil {
  766. br.Msg = "获取失败"
  767. br.ErrMsg = fmt.Sprintf("新增图表关联失败, Err: %v", e)
  768. return
  769. }
  770. br.Data = resp
  771. br.Ret = 200
  772. br.Success = true
  773. br.Msg = "获取成功"
  774. }