factor_edb_series.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546
  1. package data_manage
  2. import (
  3. "encoding/json"
  4. "eta_gn/eta_api/controllers"
  5. "eta_gn/eta_api/models"
  6. "eta_gn/eta_api/models/data_manage"
  7. "eta_gn/eta_api/models/data_manage/request"
  8. "eta_gn/eta_api/services/data"
  9. correlationServ "eta_gn/eta_api/services/data/correlation"
  10. "eta_gn/eta_api/utils"
  11. "fmt"
  12. "strconv"
  13. "strings"
  14. "time"
  15. )
  16. type FactorEdbSeriesController struct {
  17. controllers.BaseAuthController
  18. }
  19. // @router /factor_edb_series/calculate_func/list [get]
  20. func (this *FactorEdbSeriesController) CalculateFuncList() {
  21. br := new(models.BaseResponse).Init()
  22. defer func() {
  23. if br.ErrMsg == "" {
  24. br.IsSendEmail = false
  25. }
  26. this.Data["json"] = br
  27. this.ServeJSON()
  28. }()
  29. sysUser := this.SysUser
  30. if sysUser == nil {
  31. br.Msg = "请登录"
  32. br.ErrMsg = "请登录,SysUser Is Empty"
  33. br.Ret = 408
  34. return
  35. }
  36. edbInfoType, _ := this.GetInt("EdbInfoType", 0)
  37. funcOb := new(data_manage.FactorEdbSeriesCalculateFunc)
  38. cond := fmt.Sprintf(` AND %s = ?`, funcOb.Cols().EdbInfoType)
  39. pars := make([]interface{}, 0)
  40. pars = append(pars, edbInfoType)
  41. list, e := funcOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", funcOb.Cols().PrimaryId))
  42. if e != nil {
  43. br.Msg = "获取失败"
  44. br.ErrMsg = fmt.Sprintf("获取计算方式列表失败, Err: %v", e)
  45. return
  46. }
  47. resp := make([]*data_manage.FactorEdbSeriesCalculateFuncItem, 0)
  48. for _, v := range list {
  49. resp = append(resp, v.Format2Item())
  50. }
  51. br.Data = resp
  52. br.Ret = 200
  53. br.Success = true
  54. br.Msg = "获取成功"
  55. }
  56. // @router /factor_edb_series/add [post]
  57. func (this *FactorEdbSeriesController) Add() {
  58. br := new(models.BaseResponse).Init()
  59. defer func() {
  60. if br.ErrMsg == "" {
  61. br.IsSendEmail = false
  62. }
  63. this.Data["json"] = br
  64. this.ServeJSON()
  65. }()
  66. sysUser := this.SysUser
  67. if sysUser == nil {
  68. br.Msg = "请登录"
  69. br.ErrMsg = "请登录,SysUser Is Empty"
  70. br.Ret = 408
  71. return
  72. }
  73. var req request.AddFactorEdbSeriesReq
  74. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  75. br.Msg = "参数解析异常"
  76. br.ErrMsg = fmt.Sprintf("参数解析异常, Err: %v", e)
  77. return
  78. }
  79. req.SeriesName = strings.TrimSpace(req.SeriesName)
  80. if req.SeriesName == "" {
  81. br.Msg = "请输入指标系列名称"
  82. return
  83. }
  84. if len(req.EdbInfoIds) <= 0 {
  85. br.Msg = "请选择因子指标系列"
  86. return
  87. }
  88. if len(req.EdbInfoIds) > 100 {
  89. br.Msg = "添加指标总数量不得超过100"
  90. return
  91. }
  92. calculateLen := len(req.Calculates)
  93. if calculateLen > 5 {
  94. br.Msg = "计算公式不可超过5个"
  95. return
  96. }
  97. var calculatesJson string
  98. if calculateLen > 0 {
  99. b, e := json.Marshal(req.Calculates)
  100. if e != nil {
  101. br.Msg = "计算方式格式有误"
  102. br.ErrMsg = "解析计算方式参数失败, Err: " + e.Error()
  103. return
  104. }
  105. calculatesJson = string(b)
  106. for _, v := range req.Calculates {
  107. switch v.Source {
  108. case utils.EdbBaseCalculateNszydpjjs, utils.EdbBaseCalculateHbz, utils.EdbBaseCalculateHcz, utils.EdbBaseCalculateCjjx:
  109. if v.Formula == nil {
  110. br.Msg = "请输入N值"
  111. return
  112. }
  113. formula, ok := v.Formula.(string)
  114. if !ok {
  115. br.Msg = "N值格式有误"
  116. return
  117. }
  118. formulaInt, _ := strconv.Atoi(formula)
  119. if formulaInt <= 0 {
  120. br.Msg = "N值不可小于0, 重新输入"
  121. return
  122. }
  123. case utils.EdbBaseCalculateExponentialSmoothing:
  124. if v.Formula == nil {
  125. br.Msg = "请填写alpha值"
  126. return
  127. }
  128. formula, ok := v.Formula.(string)
  129. if !ok {
  130. br.Msg = "alpha值格式有误"
  131. return
  132. }
  133. alpha, _ := strconv.ParseFloat(formula, 64)
  134. if alpha <= 0 || alpha >= 1 {
  135. br.Msg = "alpha值应在0-1之间, 请重新输入"
  136. return
  137. }
  138. }
  139. }
  140. }
  141. edbArr, e := data_manage.GetEdbInfoByIdList(req.EdbInfoIds)
  142. if e != nil {
  143. br.Msg = "操作失败"
  144. br.ErrMsg = "获取指标列表失败, Err: " + e.Error()
  145. return
  146. }
  147. if len(edbArr) == 0 {
  148. br.Msg = "因子指标系列有误"
  149. br.ErrMsg = "因子指标系列长度为0"
  150. return
  151. }
  152. seriesItem := new(data_manage.FactorEdbSeries)
  153. seriesItem.SeriesName = req.SeriesName
  154. seriesItem.EdbInfoType = req.EdbInfoType
  155. seriesItem.CreateTime = time.Now().Local()
  156. seriesItem.ModifyTime = time.Now().Local()
  157. if calculateLen > 0 {
  158. seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculating
  159. seriesItem.CalculateStep = calculatesJson
  160. }
  161. mappings := make([]*data_manage.FactorEdbSeriesMapping, 0)
  162. for _, v := range edbArr {
  163. mappings = append(mappings, &data_manage.FactorEdbSeriesMapping{
  164. EdbInfoId: v.EdbInfoId,
  165. EdbCode: v.EdbCode,
  166. CreateTime: time.Now().Local(),
  167. ModifyTime: time.Now().Local(),
  168. })
  169. }
  170. seriesId, e := seriesItem.CreateSeriesAndMapping(seriesItem, mappings)
  171. if e != nil {
  172. br.Msg = "操作失败"
  173. br.ErrMsg = "新增因子指标系列失败, Err: " + e.Error()
  174. return
  175. }
  176. var calculateResp data_manage.FactorEdbSeriesStepCalculateResp
  177. if calculateLen > 0 {
  178. calculateResp, e = data.FactorEdbStepCalculate(seriesId, edbArr, req.Calculates, this.Lang, false)
  179. if e != nil {
  180. br.Msg = "操作失败"
  181. br.ErrMsg = "计算因子指标失败, Err: " + e.Error()
  182. return
  183. }
  184. cols := []string{seriesItem.Cols().CalculateState, seriesItem.Cols().ModifyTime}
  185. seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculated
  186. seriesItem.ModifyTime = time.Now().Local()
  187. if e = seriesItem.Update(cols); e != nil {
  188. br.Msg = "操作失败"
  189. br.ErrMsg = "更新因子指标系列计算状态失败, Err: " + e.Error()
  190. return
  191. }
  192. } else {
  193. for _, v := range edbArr {
  194. calculateResp.Success = append(calculateResp.Success, data_manage.FactorEdbSeriesStepCalculateResult{
  195. EdbInfoId: v.EdbInfoId,
  196. EdbCode: v.EdbCode,
  197. Msg: "保存成功",
  198. })
  199. }
  200. }
  201. calculateResp.SeriesId = seriesId
  202. br.Data = calculateResp
  203. br.Ret = 200
  204. br.Success = true
  205. br.Msg = "操作成功"
  206. br.IsAddLog = true
  207. }
  208. // @router /factor_edb_series/edit [post]
  209. func (this *FactorEdbSeriesController) Edit() {
  210. br := new(models.BaseResponse).Init()
  211. defer func() {
  212. if br.ErrMsg == "" {
  213. br.IsSendEmail = false
  214. }
  215. this.Data["json"] = br
  216. this.ServeJSON()
  217. }()
  218. sysUser := this.SysUser
  219. if sysUser == nil {
  220. br.Msg = "请登录"
  221. br.ErrMsg = "请登录,SysUser Is Empty"
  222. br.Ret = 408
  223. return
  224. }
  225. var req request.EditFactorEdbSeriesReq
  226. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  227. br.Msg = "参数解析异常"
  228. br.ErrMsg = fmt.Sprintf("参数解析异常, Err: %v", e)
  229. return
  230. }
  231. if req.SeriesId <= 0 {
  232. br.Msg = "参数有误"
  233. br.ErrMsg = fmt.Sprintf("参数有误, SeriesId: %d", req.SeriesId)
  234. return
  235. }
  236. req.SeriesName = strings.TrimSpace(req.SeriesName)
  237. if req.SeriesName == "" {
  238. br.Msg = "请输入指标系列名称"
  239. return
  240. }
  241. if len(req.EdbInfoIds) <= 0 {
  242. br.Msg = "请选择因子指标系列"
  243. return
  244. }
  245. if len(req.EdbInfoIds) > 100 {
  246. br.Msg = "添加指标总数量不得超过100"
  247. return
  248. }
  249. calculateLen := len(req.Calculates)
  250. if calculateLen > 5 {
  251. br.Msg = "计算公式不可超过5个"
  252. return
  253. }
  254. var calculatesJson string
  255. if calculateLen > 0 {
  256. b, e := json.Marshal(req.Calculates)
  257. if e != nil {
  258. br.Msg = "计算方式格式有误"
  259. br.ErrMsg = "解析计算方式参数失败, Err: " + e.Error()
  260. return
  261. }
  262. calculatesJson = string(b)
  263. for _, v := range req.Calculates {
  264. switch v.Source {
  265. case utils.EdbBaseCalculateNszydpjjs, utils.EdbBaseCalculateHbz, utils.EdbBaseCalculateHcz, utils.EdbBaseCalculateCjjx:
  266. if v.Formula == nil {
  267. br.Msg = "请输入N值"
  268. return
  269. }
  270. formula, ok := v.Formula.(string)
  271. if !ok {
  272. br.Msg = "N值格式有误"
  273. return
  274. }
  275. formulaInt, _ := strconv.Atoi(formula)
  276. if formulaInt <= 0 {
  277. br.Msg = "N值不可小于0, 重新输入"
  278. return
  279. }
  280. case utils.EdbBaseCalculateExponentialSmoothing:
  281. if v.Formula == nil {
  282. br.Msg = "请填写alpha值"
  283. return
  284. }
  285. formula, ok := v.Formula.(string)
  286. if !ok {
  287. br.Msg = "alpha值格式有误"
  288. return
  289. }
  290. alpha, _ := strconv.ParseFloat(formula, 64)
  291. if alpha <= 0 || alpha >= 1 {
  292. br.Msg = "alpha值应在0-1之间, 请重新输入"
  293. return
  294. }
  295. }
  296. }
  297. }
  298. seriesOb := new(data_manage.FactorEdbSeries)
  299. seriesItem, e := seriesOb.GetItemById(req.SeriesId)
  300. if e != nil {
  301. if utils.IsErrNoRow(e) {
  302. br.Msg = "该因子指标系列不存在"
  303. return
  304. }
  305. br.Msg = "获取失败"
  306. br.ErrMsg = "获取因子指标系列失败, Err: " + e.Error()
  307. return
  308. }
  309. originCalculateState := seriesItem.CalculateState
  310. edbArr, e := data_manage.GetEdbInfoByIdList(req.EdbInfoIds)
  311. if e != nil {
  312. br.Msg = "操作失败"
  313. br.ErrMsg = "获取指标列表失败, Err: " + e.Error()
  314. return
  315. }
  316. if len(edbArr) == 0 {
  317. br.Msg = "因子指标系列有误"
  318. br.ErrMsg = "因子指标系列长度为0"
  319. return
  320. }
  321. var calculateResp data_manage.FactorEdbSeriesStepCalculateResp
  322. calculateResp.SeriesId = seriesItem.FactorEdbSeriesId
  323. seriesItem.SeriesName = req.SeriesName
  324. seriesItem.EdbInfoType = req.EdbInfoType
  325. seriesItem.ModifyTime = time.Now().Local()
  326. updateCols := []string{seriesOb.Cols().SeriesName, seriesOb.Cols().EdbInfoType, seriesOb.Cols().ModifyTime}
  327. if !req.Recalculate {
  328. if e = seriesItem.Update(updateCols); e != nil {
  329. br.Msg = "操作成功"
  330. br.ErrMsg = "更新因子指标系列信息失败, Err: " + e.Error()
  331. return
  332. }
  333. for _, v := range edbArr {
  334. calculateResp.Success = append(calculateResp.Success, data_manage.FactorEdbSeriesStepCalculateResult{
  335. EdbInfoId: v.EdbInfoId,
  336. EdbCode: v.EdbCode,
  337. Msg: "保存成功",
  338. })
  339. }
  340. br.Data = calculateResp
  341. br.Ret = 200
  342. br.Success = true
  343. br.Msg = "操作成功"
  344. return
  345. }
  346. seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculateNone
  347. if calculateLen > 0 {
  348. seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculating
  349. seriesItem.CalculateStep = calculatesJson
  350. updateCols = append(updateCols, seriesOb.Cols().CalculateState, seriesOb.Cols().CalculateStep)
  351. }
  352. mappings := make([]*data_manage.FactorEdbSeriesMapping, 0)
  353. for _, v := range edbArr {
  354. mappings = append(mappings, &data_manage.FactorEdbSeriesMapping{
  355. EdbInfoId: v.EdbInfoId,
  356. EdbCode: v.EdbCode,
  357. CreateTime: time.Now().Local(),
  358. ModifyTime: time.Now().Local(),
  359. })
  360. }
  361. if e = seriesItem.EditSeriesAndMapping(seriesItem, mappings, updateCols); e != nil {
  362. br.Msg = "操作失败"
  363. br.ErrMsg = "编辑因子指标系列失败, Err: " + e.Error()
  364. return
  365. }
  366. calculateResp, e = data.FactorEdbStepCalculate(seriesItem.FactorEdbSeriesId, edbArr, req.Calculates, this.Lang, req.Recalculate)
  367. if e != nil {
  368. br.Msg = "操作失败"
  369. br.ErrMsg = "计算因子指标失败, Err: " + e.Error()
  370. return
  371. }
  372. if seriesItem.CalculateState == data_manage.FactorEdbSeriesCalculating {
  373. seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculated
  374. }
  375. if originCalculateState != seriesItem.CalculateState {
  376. cols := []string{seriesItem.Cols().CalculateState, seriesItem.Cols().ModifyTime}
  377. seriesItem.ModifyTime = time.Now().Local()
  378. if e = seriesItem.Update(cols); e != nil {
  379. br.Msg = "操作失败"
  380. br.ErrMsg = "更新因子指标系列计算状态失败, Err: " + e.Error()
  381. return
  382. }
  383. }
  384. br.Data = calculateResp
  385. br.Ret = 200
  386. br.Success = true
  387. br.Msg = "操作成功"
  388. br.IsAddLog = true
  389. }
  390. // @router /factor_edb_series/detail [get]
  391. func (this *FactorEdbSeriesController) Detail() {
  392. br := new(models.BaseResponse).Init()
  393. defer func() {
  394. if br.ErrMsg == "" {
  395. br.IsSendEmail = false
  396. }
  397. this.Data["json"] = br
  398. this.ServeJSON()
  399. }()
  400. sysUser := this.SysUser
  401. if sysUser == nil {
  402. br.Msg = "请登录"
  403. br.ErrMsg = "请登录,SysUser Is Empty"
  404. br.Ret = 408
  405. return
  406. }
  407. seriesId, _ := this.GetInt("SeriesId", 0)
  408. if seriesId <= 0 {
  409. br.Msg = "参数有误"
  410. br.ErrMsg = fmt.Sprintf("参数有误, SeriesId: %d", seriesId)
  411. return
  412. }
  413. seriesOb := new(data_manage.FactorEdbSeries)
  414. series, e := seriesOb.GetItemById(seriesId)
  415. if e != nil {
  416. if utils.IsErrNoRow(e) {
  417. br.Msg = "该因子指标系列不存在"
  418. return
  419. }
  420. br.Msg = "获取失败"
  421. br.ErrMsg = "获取因子指标系列失败, Err: " + e.Error()
  422. return
  423. }
  424. mappingOb := new(data_manage.FactorEdbSeriesMapping)
  425. cond := fmt.Sprintf(" AND %s = ?", mappingOb.Cols().FactorEdbSeriesId)
  426. pars := make([]interface{}, 0)
  427. pars = append(pars, seriesId)
  428. mappings, e := mappingOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", mappingOb.Cols().CreateTime))
  429. if e != nil {
  430. br.Msg = "获取失败"
  431. br.ErrMsg = "获取因子指标系列关联失败, Err: " + e.Error()
  432. return
  433. }
  434. resp := new(data_manage.FactorEdbSeriesDetail)
  435. resp.FactorEdbSeriesItem = series.Format2Item()
  436. for _, m := range mappings {
  437. resp.EdbMappings = append(resp.EdbMappings, m.Format2Item())
  438. }
  439. br.Data = resp
  440. br.Ret = 200
  441. br.Success = true
  442. br.Msg = "获取成功"
  443. }
  444. // @router /factor_edb_series/correlation/matrix [post]
  445. func (this *FactorEdbSeriesController) CorrelationMatrix() {
  446. br := new(models.BaseResponse).Init()
  447. defer func() {
  448. if br.ErrMsg == "" {
  449. br.IsSendEmail = false
  450. }
  451. this.Data["json"] = br
  452. this.ServeJSON()
  453. }()
  454. sysUser := this.SysUser
  455. if sysUser == nil {
  456. br.Msg = "请登录"
  457. br.ErrMsg = "请登录,SysUser Is Empty"
  458. br.Ret = 408
  459. return
  460. }
  461. var req request.FactorEdbSeriesCorrelationMatrixReq
  462. if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil {
  463. br.Msg = "参数解析异常"
  464. br.ErrMsg = fmt.Sprintf("参数解析异常, Err: %v", e)
  465. return
  466. }
  467. if req.BaseEdbInfoId <= 0 {
  468. br.Msg = "请选择标的指标"
  469. return
  470. }
  471. if len(req.SeriesIds) == 0 {
  472. br.Msg = "请选择因子指标系列"
  473. return
  474. }
  475. if req.Correlation.LeadValue <= 0 {
  476. br.Msg = "分析周期不允许设置为负数或0"
  477. return
  478. }
  479. if req.Correlation.LeadUnit == "" {
  480. br.Msg = "请选择分析周期频度"
  481. return
  482. }
  483. leadUnitDays, ok := utils.FrequencyDaysMap[req.Correlation.LeadUnit]
  484. if !ok {
  485. br.Msg = "错误的分析周期频度"
  486. br.ErrMsg = fmt.Sprintf("分析周期频度有误: %s", req.Correlation.LeadUnit)
  487. return
  488. }
  489. if req.Correlation.CalculateUnit == "" {
  490. br.Msg = "请选择计算窗口频度"
  491. return
  492. }
  493. calculateUnitDays, ok := utils.FrequencyDaysMap[req.Correlation.CalculateUnit]
  494. if !ok {
  495. br.Msg = "错误的计算窗口频度"
  496. br.ErrMsg = fmt.Sprintf("计算窗口频度有误: %s", req.Correlation.CalculateUnit)
  497. return
  498. }
  499. leadDays := 2 * req.Correlation.LeadValue * leadUnitDays
  500. calculateDays := req.Correlation.CalculateValue * calculateUnitDays
  501. if calculateDays < leadDays {
  502. br.Msg = "计算窗口必须≥2*分析周期"
  503. return
  504. }
  505. var calculatePars data_manage.CalculateCorrelationMatrixPars
  506. calculatePars.BaseEdbInfoId = req.BaseEdbInfoId
  507. calculatePars.SeriesIds = req.SeriesIds
  508. calculatePars.Correlation = req.Correlation
  509. resp, _, e := correlationServ.CalculateCorrelationMatrix(calculatePars)
  510. if e != nil {
  511. br.Msg = "计算失败"
  512. br.ErrMsg = fmt.Sprintf("计算相关性矩阵失败, %v", e)
  513. return
  514. }
  515. br.Data = resp
  516. br.Ret = 200
  517. br.Success = true
  518. br.Msg = "获取成功"
  519. }