factor_edb_series.go 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822
  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. originCalculateState := seriesItem.CalculateState
  331. edbArr, e := data_manage.GetEdbInfoByIdList(req.EdbInfoIds)
  332. if e != nil {
  333. br.Msg = "操作失败"
  334. br.ErrMsg = "获取指标列表失败, Err: " + e.Error()
  335. return
  336. }
  337. if len(edbArr) == 0 {
  338. br.Msg = "因子指标系列有误"
  339. br.ErrMsg = "因子指标系列长度为0"
  340. return
  341. }
  342. var calculateResp data_manage.FactorEdbSeriesStepCalculateResp
  343. calculateResp.SeriesId = seriesItem.FactorEdbSeriesId
  344. // 如果不需要进行重新计算(比如只改了系列名称)那么只更新指标系列
  345. seriesItem.SeriesName = req.SeriesName
  346. seriesItem.EdbInfoType = req.EdbInfoType
  347. seriesItem.ModifyTime = time.Now().Local()
  348. updateCols := []string{seriesOb.Cols().SeriesName, seriesOb.Cols().EdbInfoType, seriesOb.Cols().ModifyTime}
  349. if !req.Recalculate {
  350. if e = seriesItem.Update(updateCols); e != nil {
  351. br.Msg = "操作成功"
  352. br.ErrMsg = "更新因子指标系列信息失败, Err: " + e.Error()
  353. return
  354. }
  355. for _, v := range edbArr {
  356. calculateResp.Success = append(calculateResp.Success, data_manage.FactorEdbSeriesStepCalculateResult{
  357. EdbInfoId: v.EdbInfoId,
  358. EdbCode: v.EdbCode,
  359. Msg: "保存成功",
  360. })
  361. }
  362. br.Data = calculateResp
  363. br.Ret = 200
  364. br.Success = true
  365. br.Msg = "操作成功"
  366. return
  367. }
  368. // 更新系列信息和指标关联
  369. seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculateNone
  370. if calculateLen > 0 {
  371. seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculating
  372. seriesItem.CalculateStep = calculatesJson
  373. updateCols = append(updateCols, seriesOb.Cols().CalculateState, seriesOb.Cols().CalculateStep)
  374. }
  375. mappings := make([]*data_manage.FactorEdbSeriesMapping, 0)
  376. for _, v := range edbArr {
  377. mappings = append(mappings, &data_manage.FactorEdbSeriesMapping{
  378. EdbInfoId: v.EdbInfoId,
  379. EdbCode: v.EdbCode,
  380. CreateTime: time.Now().Local(),
  381. ModifyTime: time.Now().Local(),
  382. })
  383. }
  384. if e = seriesItem.EditSeriesAndMapping(seriesItem, mappings, updateCols); e != nil {
  385. br.Msg = "操作失败"
  386. br.ErrMsg = "编辑因子指标系列失败, Err: " + e.Error()
  387. return
  388. }
  389. // 重新计算
  390. calculateResp, e = data.FactorEdbStepCalculate(seriesItem.FactorEdbSeriesId, edbArr, req.Calculates, this.Lang, req.Recalculate)
  391. if e != nil {
  392. br.Msg = "操作失败"
  393. br.ErrMsg = "计算因子指标失败, Err: " + e.Error()
  394. return
  395. }
  396. if seriesItem.CalculateState == data_manage.FactorEdbSeriesCalculating {
  397. seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculated
  398. }
  399. // 若原状态不一致, 更新状态
  400. if originCalculateState != seriesItem.CalculateState {
  401. cols := []string{seriesItem.Cols().CalculateState, seriesItem.Cols().ModifyTime}
  402. seriesItem.ModifyTime = time.Now().Local()
  403. if e = seriesItem.Update(cols); e != nil {
  404. br.Msg = "操作失败"
  405. br.ErrMsg = "更新因子指标系列计算状态失败, Err: " + e.Error()
  406. return
  407. }
  408. }
  409. br.Data = calculateResp
  410. br.Ret = 200
  411. br.Success = true
  412. br.Msg = "操作成功"
  413. br.IsAddLog = true
  414. }
  415. // Detail
  416. // @Title 详情
  417. // @Description 详情
  418. // @Param SeriesId query int false "多因子指标系列ID"
  419. // @Success 200 {object} data_manage.FactorEdbSeriesDetail
  420. // @router /factor_edb_series/detail [get]
  421. func (this *FactorEdbSeriesController) Detail() {
  422. br := new(models.BaseResponse).Init()
  423. defer func() {
  424. if br.ErrMsg == "" {
  425. br.IsSendEmail = false
  426. }
  427. this.Data["json"] = br
  428. this.ServeJSON()
  429. }()
  430. sysUser := this.SysUser
  431. if sysUser == nil {
  432. br.Msg = "请登录"
  433. br.ErrMsg = "请登录,SysUser Is Empty"
  434. br.Ret = 408
  435. return
  436. }
  437. seriesId, _ := this.GetInt("SeriesId", 0)
  438. if seriesId <= 0 {
  439. br.Msg = "参数有误"
  440. br.ErrMsg = fmt.Sprintf("参数有误, SeriesId: %d", seriesId)
  441. return
  442. }
  443. seriesOb := new(data_manage.FactorEdbSeries)
  444. series, e := seriesOb.GetItemById(seriesId)
  445. if e != nil {
  446. if e.Error() == utils.ErrNoRow() {
  447. br.Msg = "该因子指标系列不存在"
  448. return
  449. }
  450. br.Msg = "获取失败"
  451. br.ErrMsg = "获取因子指标系列失败, Err: " + e.Error()
  452. return
  453. }
  454. mappingOb := new(data_manage.FactorEdbSeriesMapping)
  455. cond := fmt.Sprintf(" AND %s = ?", mappingOb.Cols().FactorEdbSeriesId)
  456. pars := make([]interface{}, 0)
  457. pars = append(pars, seriesId)
  458. mappings, e := mappingOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", mappingOb.Cols().CreateTime))
  459. if e != nil {
  460. br.Msg = "获取失败"
  461. br.ErrMsg = "获取因子指标系列关联失败, Err: " + e.Error()
  462. return
  463. }
  464. resp := new(data_manage.FactorEdbSeriesDetail)
  465. resp.FactorEdbSeriesItem = series.Format2Item()
  466. for _, m := range mappings {
  467. resp.EdbMappings = append(resp.EdbMappings, m.Format2Item())
  468. }
  469. br.Data = resp
  470. br.Ret = 200
  471. br.Success = true
  472. br.Msg = "获取成功"
  473. }
  474. // CorrelationMatrix
  475. // @Title 因子指标系列-相关性矩阵
  476. // @Description 因子指标系列-相关性矩阵
  477. // @Param request body request.FactorEdbSeriesCorrelationMatrixReq true "type json string"
  478. // @Success 200 {object} data_manage.FactorEdbSeriesCorrelationMatrixItem
  479. // @router /factor_edb_series/correlation/matrix [post]
  480. func (this *FactorEdbSeriesController) CorrelationMatrix() {
  481. br := new(models.BaseResponse).Init()
  482. defer func() {
  483. if br.ErrMsg == "" {
  484. br.IsSendEmail = false
  485. }
  486. this.Data["json"] = br
  487. this.ServeJSON()
  488. }()
  489. sysUser := this.SysUser
  490. if sysUser == nil {
  491. br.Msg = "请登录"
  492. br.ErrMsg = "请登录,SysUser Is Empty"
  493. br.Ret = 408
  494. return
  495. }
  496. var req request.FactorEdbSeriesCorrelationMatrixReq
  497. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  498. br.Msg = "参数解析异常"
  499. br.ErrMsg = fmt.Sprintf("参数解析异常, Err: %v", e)
  500. return
  501. }
  502. if req.BaseEdbInfoId <= 0 {
  503. br.Msg = "请选择标的指标"
  504. return
  505. }
  506. if len(req.SeriesIds) == 0 {
  507. br.Msg = "请选择因子指标系列"
  508. return
  509. }
  510. if req.Correlation.LeadValue <= 0 {
  511. br.Msg = "分析周期不允许设置为负数或0"
  512. return
  513. }
  514. if req.Correlation.LeadUnit == "" {
  515. br.Msg = "请选择分析周期频度"
  516. return
  517. }
  518. leadUnitDays, ok := utils.FrequencyDaysMap[req.Correlation.LeadUnit]
  519. if !ok {
  520. br.Msg = "错误的分析周期频度"
  521. br.ErrMsg = fmt.Sprintf("分析周期频度有误: %s", req.Correlation.LeadUnit)
  522. return
  523. }
  524. if req.Correlation.CalculateUnit == "" {
  525. br.Msg = "请选择计算窗口频度"
  526. return
  527. }
  528. calculateUnitDays, ok := utils.FrequencyDaysMap[req.Correlation.CalculateUnit]
  529. if !ok {
  530. br.Msg = "错误的计算窗口频度"
  531. br.ErrMsg = fmt.Sprintf("计算窗口频度有误: %s", req.Correlation.CalculateUnit)
  532. return
  533. }
  534. leadDays := 2 * req.Correlation.LeadValue * leadUnitDays
  535. calculateDays := req.Correlation.CalculateValue * calculateUnitDays
  536. if calculateDays < leadDays {
  537. br.Msg = "计算窗口必须≥2*分析周期"
  538. return
  539. }
  540. // 获取标的指标信息及数据
  541. baseEdb, e := data_manage.GetEdbInfoById(req.BaseEdbInfoId)
  542. if e != nil {
  543. if e.Error() == utils.ErrNoRow() {
  544. br.Msg = "标的指标不存在"
  545. return
  546. }
  547. br.Msg = "获取失败"
  548. br.ErrMsg = "获取标的指标信息失败, Err: " + e.Error()
  549. return
  550. }
  551. dataListA := make([]*data_manage.EdbDataList, 0)
  552. {
  553. // 标的指标数据日期区间
  554. startDate := time.Now().AddDate(0, 0, -calculateDays).Format(utils.FormatDate)
  555. endDate := time.Now().Format(utils.FormatDate)
  556. startDateTime, _ := time.ParseInLocation(utils.FormatDate, startDate, time.Local)
  557. startDate = startDateTime.AddDate(0, 0, 1).Format(utils.FormatDate) // 不包含第一天
  558. switch baseEdb.EdbInfoType {
  559. case 0:
  560. dataListA, e = data_manage.GetEdbDataList(baseEdb.Source, baseEdb.SubSource, baseEdb.EdbInfoId, startDate, endDate)
  561. case 1:
  562. _, dataListA, _, _, e, _ = data.GetPredictDataListByPredictEdbInfoId(baseEdb.EdbInfoId, startDate, endDate, false)
  563. default:
  564. br.Msg = "获取失败"
  565. br.ErrMsg = fmt.Sprintf("标的指标类型异常: %d", baseEdb.EdbInfoType)
  566. return
  567. }
  568. if e != nil {
  569. br.Msg = "获取失败"
  570. br.ErrMsg = "获取标的指标数据失败, Err:" + e.Error()
  571. return
  572. }
  573. }
  574. // 获取因子系列
  575. seriesIdItem := make(map[int]*data_manage.FactorEdbSeries)
  576. {
  577. ob := new(data_manage.FactorEdbSeries)
  578. cond := fmt.Sprintf(" AND %s IN (%s)", ob.Cols().PrimaryId, utils.GetOrmInReplace(len(req.SeriesIds)))
  579. pars := make([]interface{}, 0)
  580. pars = append(pars, req.SeriesIds)
  581. items, e := ob.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", ob.Cols().PrimaryId))
  582. if e != nil {
  583. br.Msg = "获取失败"
  584. br.ErrMsg = "获取因子指标系列失败, Err: " + e.Error()
  585. return
  586. }
  587. if len(items) != len(req.SeriesIds) {
  588. br.Msg = "获取失败"
  589. br.ErrMsg = "因子指标系列数量有误"
  590. return
  591. }
  592. for _, v := range items {
  593. seriesIdItem[v.FactorEdbSeriesId] = v
  594. }
  595. }
  596. // 获取因子指标
  597. edbMappings := make([]*data_manage.FactorEdbSeriesMapping, 0)
  598. edbInfoIds := make([]int, 0)
  599. {
  600. ob := new(data_manage.FactorEdbSeriesMapping)
  601. cond := fmt.Sprintf(" AND %s IN (%s)", ob.Cols().FactorEdbSeriesId, utils.GetOrmInReplace(len(req.SeriesIds)))
  602. pars := make([]interface{}, 0)
  603. pars = append(pars, req.SeriesIds)
  604. order := fmt.Sprintf("%s ASC, %s ASC", ob.Cols().FactorEdbSeriesId, ob.Cols().EdbInfoId)
  605. items, e := ob.GetItemsByCondition(cond, pars, []string{}, order)
  606. if e != nil {
  607. br.Msg = "获取失败"
  608. br.ErrMsg = "获取因子指标关联失败, Err: " + e.Error()
  609. return
  610. }
  611. for _, v := range items {
  612. edbInfoIds = append(edbInfoIds, v.EdbInfoId)
  613. }
  614. edbMappings = items
  615. }
  616. edbIdItem := make(map[int]*data_manage.EdbInfo)
  617. edbItems, e := data_manage.GetEdbInfoByIdList(edbInfoIds)
  618. if e != nil {
  619. br.Msg = "获取失败"
  620. br.ErrMsg = "获取因子指标失败, Err: " + e.Error()
  621. return
  622. }
  623. for _, v := range edbItems {
  624. edbIdItem[v.EdbInfoId] = v
  625. }
  626. // 获取因子指标数据, 计算相关性
  627. resp := new(data_manage.FactorEdbSeriesCorrelationMatrixResp)
  628. calculateDataOb := new(data_manage.FactorEdbSeriesCalculateData)
  629. calculateWorkers := make(chan struct{}, 10)
  630. wg := sync.WaitGroup{}
  631. edbExists := make(map[string]bool)
  632. chartKeyMap := make(map[string]*data_manage.FactorEdbSeriesChartMapping)
  633. for _, v := range edbMappings {
  634. existsKey := fmt.Sprintf("%d-%d", v.FactorEdbSeriesId, v.EdbInfoId)
  635. if edbExists[existsKey] {
  636. continue
  637. }
  638. edbExists[existsKey] = true
  639. edbItem := edbIdItem[v.EdbInfoId]
  640. if edbItem == nil {
  641. continue
  642. }
  643. seriesItem := seriesIdItem[v.FactorEdbSeriesId]
  644. if seriesItem == nil {
  645. continue
  646. }
  647. wg.Add(1)
  648. go func(mapping *data_manage.FactorEdbSeriesMapping, edb *data_manage.EdbInfo, series *data_manage.FactorEdbSeries) {
  649. defer func() {
  650. wg.Done()
  651. <-calculateWorkers
  652. }()
  653. calculateWorkers <- struct{}{}
  654. var item data_manage.FactorEdbSeriesCorrelationMatrixItem
  655. item.SeriesId = series.FactorEdbSeriesId
  656. item.EdbInfoId = edb.EdbInfoId
  657. item.EdbCode = edb.EdbCode
  658. item.EdbName = edb.EdbName
  659. // 指标来源
  660. edbList := make([]*data_manage.ChartEdbInfoMapping, 0)
  661. edbList = append(edbList, &data_manage.ChartEdbInfoMapping{
  662. EdbInfoId: edb.EdbInfoId,
  663. EdbInfoCategoryType: edb.EdbInfoType,
  664. EdbType: edb.EdbType,
  665. Source: edb.Source,
  666. SourceName: edb.SourceName,
  667. })
  668. sourceNameList, sourceNameEnList := data.GetEdbSourceByEdbInfoIdList(edbList)
  669. item.SourceName = strings.Join(sourceNameList, ",")
  670. item.SourceNameEn = strings.Join(sourceNameEnList, ",")
  671. // 获取指标数据
  672. dataListB := make([]*data_manage.EdbDataList, 0)
  673. if series.CalculateState == data_manage.FactorEdbSeriesCalculated {
  674. cond := fmt.Sprintf(" AND %s = ? AND %s = ?", calculateDataOb.Cols().FactorEdbSeriesId, calculateDataOb.Cols().EdbInfoId)
  675. pars := make([]interface{}, 0)
  676. pars = append(pars, mapping.FactorEdbSeriesId, mapping.EdbInfoId)
  677. dataItems, e := calculateDataOb.GetItemsByCondition(cond, pars, []string{calculateDataOb.Cols().DataTime, calculateDataOb.Cols().Value}, fmt.Sprintf("%s ASC", calculateDataOb.Cols().DataTime))
  678. if e != nil {
  679. item.Msg = fmt.Sprintf("计算失败")
  680. item.ErrMsg = fmt.Sprintf("获取计算数据失败, err: %v", e)
  681. resp.Fail = append(resp.Fail, item)
  682. return
  683. }
  684. dataListB = data_manage.TransEdbSeriesCalculateData2EdbDataList(dataItems)
  685. } else {
  686. switch edb.EdbInfoType {
  687. case 0:
  688. dataListB, e = data_manage.GetEdbDataList(edb.Source, edb.SubSource, edb.EdbInfoId, "", "")
  689. case 1:
  690. _, dataListB, _, _, e, _ = data.GetPredictDataListByPredictEdbInfoId(edb.EdbInfoId, "", "", false)
  691. default:
  692. item.Msg = fmt.Sprintf("计算失败")
  693. item.ErrMsg = fmt.Sprintf("指标类型异常, edbType: %d", edb.EdbInfoType)
  694. resp.Fail = append(resp.Fail, item)
  695. return
  696. }
  697. }
  698. // 计算相关性
  699. xEdbIdValue, yDataList, e := correlationServ.CalculateCorrelation(req.Correlation.LeadValue, req.Correlation.LeadUnit, baseEdb.Frequency, edb.Frequency, dataListA, dataListB)
  700. if e != nil {
  701. item.Msg = fmt.Sprintf("计算失败")
  702. item.ErrMsg = fmt.Sprintf("相关性计算失败, err: %v", e)
  703. resp.Fail = append(resp.Fail, item)
  704. return
  705. }
  706. // X及Y轴数据
  707. yData := yDataList[0].Value
  708. yLen := len(yData)
  709. values := make([]data_manage.FactorEdbSeriesCorrelationMatrixValues, len(xEdbIdValue))
  710. for k, x := range xEdbIdValue {
  711. var y float64
  712. if k >= 0 && k < yLen {
  713. y = yData[k]
  714. }
  715. y = utils.SubFloatToFloat(y, 2)
  716. values[k] = data_manage.FactorEdbSeriesCorrelationMatrixValues{
  717. XData: x, YData: y,
  718. }
  719. }
  720. // 图表关联-此处添加的chart_info_id=0
  721. newMapping := new(data_manage.FactorEdbSeriesChartMapping)
  722. newMapping.CalculateType = data_manage.FactorEdbSeriesChartCalculateTypeCorrelation
  723. // 计算参数
  724. var calculatePars data_manage.FactorEdbSeriesChartCalculateCorrelationReq
  725. calculatePars.BaseEdbInfoId = req.BaseEdbInfoId
  726. calculatePars.LeadValue = req.Correlation.LeadValue
  727. calculatePars.LeadUnit = req.Correlation.LeadUnit
  728. calculatePars.CalculateValue = req.Correlation.CalculateValue
  729. calculatePars.CalculateUnit = req.Correlation.CalculateUnit
  730. bc, e := json.Marshal(calculatePars)
  731. if e != nil {
  732. item.Msg = fmt.Sprintf("计算失败")
  733. item.ErrMsg = fmt.Sprintf("计算参数JSON格式化失败, err: %v", e)
  734. resp.Fail = append(resp.Fail, item)
  735. return
  736. }
  737. newMapping.CalculatePars = string(bc)
  738. // 计算结果, 注此处保存的是排序前的顺序
  739. bv, e := json.Marshal(values)
  740. if e != nil {
  741. item.Msg = fmt.Sprintf("计算失败")
  742. item.ErrMsg = fmt.Sprintf("计算结果JSON格式化失败, err: %v", e)
  743. resp.Fail = append(resp.Fail, item)
  744. return
  745. }
  746. newMapping.CalculateData = string(bv)
  747. newMapping.FactorEdbSeriesId = mapping.FactorEdbSeriesId
  748. newMapping.EdbInfoId = mapping.EdbInfoId
  749. newMapping.CreateTime = time.Now().Local()
  750. newMapping.ModifyTime = time.Now().Local()
  751. chartKeyMap[existsKey] = newMapping
  752. // 按照固定规则排期数[0 1 2 3 -1 -2 -3], 仅矩阵展示为此顺序
  753. sort.Sort(data_manage.FactorEdbSeriesCorrelationMatrixOrder(values))
  754. item.Msg = "计算成功"
  755. item.Values = values
  756. resp.Success = append(resp.Success, item)
  757. }(v, edbItem, seriesItem)
  758. }
  759. wg.Wait()
  760. // 新增图表关联, 此处按照顺序添加
  761. chartMappings := make([]*data_manage.FactorEdbSeriesChartMapping, 0)
  762. for _, v := range edbMappings {
  763. k := fmt.Sprintf("%d-%d", v.FactorEdbSeriesId, v.EdbInfoId)
  764. item := chartKeyMap[k]
  765. if item == nil {
  766. continue
  767. }
  768. chartMappings = append(chartMappings, item)
  769. }
  770. chartMappingOb := new(data_manage.FactorEdbSeriesChartMapping)
  771. if e = chartMappingOb.ClearAndCreateMapping(req.SeriesIds, chartMappings); e != nil {
  772. br.Msg = "获取失败"
  773. br.ErrMsg = fmt.Sprintf("新增图表关联失败, Err: %v", e)
  774. return
  775. }
  776. br.Data = resp
  777. br.Ret = 200
  778. br.Success = true
  779. br.Msg = "获取成功"
  780. }