package data_manage import ( "encoding/json" "eta_gn/eta_api/controllers" "eta_gn/eta_api/models" "eta_gn/eta_api/models/data_manage" "eta_gn/eta_api/models/data_manage/request" "eta_gn/eta_api/services/data" correlationServ "eta_gn/eta_api/services/data/correlation" "eta_gn/eta_api/utils" "fmt" "strconv" "strings" "time" ) type FactorEdbSeriesController struct { controllers.BaseAuthController } // @router /factor_edb_series/calculate_func/list [get] func (this *FactorEdbSeriesController) CalculateFuncList() { br := new(models.BaseResponse).Init() defer func() { if br.ErrMsg == "" { br.IsSendEmail = false } this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } edbInfoType, _ := this.GetInt("EdbInfoType", 0) funcOb := new(data_manage.FactorEdbSeriesCalculateFunc) cond := fmt.Sprintf(` AND %s = ?`, funcOb.Cols().EdbInfoType) pars := make([]interface{}, 0) pars = append(pars, edbInfoType) list, e := funcOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", funcOb.Cols().PrimaryId)) if e != nil { br.Msg = "获取失败" br.ErrMsg = fmt.Sprintf("获取计算方式列表失败, Err: %v", e) return } resp := make([]*data_manage.FactorEdbSeriesCalculateFuncItem, 0) for _, v := range list { resp = append(resp, v.Format2Item()) } br.Data = resp br.Ret = 200 br.Success = true br.Msg = "获取成功" } // @router /factor_edb_series/add [post] func (this *FactorEdbSeriesController) Add() { br := new(models.BaseResponse).Init() defer func() { if br.ErrMsg == "" { br.IsSendEmail = false } this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } var req request.AddFactorEdbSeriesReq if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil { br.Msg = "参数解析异常" br.ErrMsg = fmt.Sprintf("参数解析异常, Err: %v", e) return } req.SeriesName = strings.TrimSpace(req.SeriesName) if req.SeriesName == "" { br.Msg = "请输入指标系列名称" return } if len(req.EdbInfoIds) <= 0 { br.Msg = "请选择因子指标系列" return } if len(req.EdbInfoIds) > 100 { br.Msg = "添加指标总数量不得超过100" return } calculateLen := len(req.Calculates) if calculateLen > 5 { br.Msg = "计算公式不可超过5个" return } var calculatesJson string if calculateLen > 0 { b, e := json.Marshal(req.Calculates) if e != nil { br.Msg = "计算方式格式有误" br.ErrMsg = "解析计算方式参数失败, Err: " + e.Error() return } calculatesJson = string(b) for _, v := range req.Calculates { switch v.Source { case utils.EdbBaseCalculateNszydpjjs, utils.EdbBaseCalculateHbz, utils.EdbBaseCalculateHcz, utils.EdbBaseCalculateCjjx: if v.Formula == nil { br.Msg = "请输入N值" return } formula, ok := v.Formula.(string) if !ok { br.Msg = "N值格式有误" return } formulaInt, _ := strconv.Atoi(formula) if formulaInt <= 0 { br.Msg = "N值不可小于0, 重新输入" return } case utils.EdbBaseCalculateExponentialSmoothing: if v.Formula == nil { br.Msg = "请填写alpha值" return } formula, ok := v.Formula.(string) if !ok { br.Msg = "alpha值格式有误" return } alpha, _ := strconv.ParseFloat(formula, 64) if alpha <= 0 || alpha >= 1 { br.Msg = "alpha值应在0-1之间, 请重新输入" return } } } } edbArr, e := data_manage.GetEdbInfoByIdList(req.EdbInfoIds) if e != nil { br.Msg = "操作失败" br.ErrMsg = "获取指标列表失败, Err: " + e.Error() return } if len(edbArr) == 0 { br.Msg = "因子指标系列有误" br.ErrMsg = "因子指标系列长度为0" return } seriesItem := new(data_manage.FactorEdbSeries) seriesItem.SeriesName = req.SeriesName seriesItem.EdbInfoType = req.EdbInfoType seriesItem.CreateTime = time.Now().Local() seriesItem.ModifyTime = time.Now().Local() if calculateLen > 0 { seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculating seriesItem.CalculateStep = calculatesJson } mappings := make([]*data_manage.FactorEdbSeriesMapping, 0) for _, v := range edbArr { mappings = append(mappings, &data_manage.FactorEdbSeriesMapping{ EdbInfoId: v.EdbInfoId, EdbCode: v.EdbCode, CreateTime: time.Now().Local(), ModifyTime: time.Now().Local(), }) } seriesId, e := seriesItem.CreateSeriesAndMapping(seriesItem, mappings) if e != nil { br.Msg = "操作失败" br.ErrMsg = "新增因子指标系列失败, Err: " + e.Error() return } var calculateResp data_manage.FactorEdbSeriesStepCalculateResp if calculateLen > 0 { calculateResp, e = data.FactorEdbStepCalculate(seriesId, edbArr, req.Calculates, this.Lang, false) if e != nil { br.Msg = "操作失败" br.ErrMsg = "计算因子指标失败, Err: " + e.Error() return } cols := []string{seriesItem.Cols().CalculateState, seriesItem.Cols().ModifyTime} seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculated seriesItem.ModifyTime = time.Now().Local() if e = seriesItem.Update(cols); e != nil { br.Msg = "操作失败" br.ErrMsg = "更新因子指标系列计算状态失败, Err: " + e.Error() return } } else { for _, v := range edbArr { calculateResp.Success = append(calculateResp.Success, data_manage.FactorEdbSeriesStepCalculateResult{ EdbInfoId: v.EdbInfoId, EdbCode: v.EdbCode, Msg: "保存成功", }) } } calculateResp.SeriesId = seriesId br.Data = calculateResp br.Ret = 200 br.Success = true br.Msg = "操作成功" br.IsAddLog = true } // @router /factor_edb_series/edit [post] func (this *FactorEdbSeriesController) Edit() { br := new(models.BaseResponse).Init() defer func() { if br.ErrMsg == "" { br.IsSendEmail = false } this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } var req request.EditFactorEdbSeriesReq if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil { br.Msg = "参数解析异常" br.ErrMsg = fmt.Sprintf("参数解析异常, Err: %v", e) return } if req.SeriesId <= 0 { br.Msg = "参数有误" br.ErrMsg = fmt.Sprintf("参数有误, SeriesId: %d", req.SeriesId) return } req.SeriesName = strings.TrimSpace(req.SeriesName) if req.SeriesName == "" { br.Msg = "请输入指标系列名称" return } if len(req.EdbInfoIds) <= 0 { br.Msg = "请选择因子指标系列" return } if len(req.EdbInfoIds) > 100 { br.Msg = "添加指标总数量不得超过100" return } calculateLen := len(req.Calculates) if calculateLen > 5 { br.Msg = "计算公式不可超过5个" return } var calculatesJson string if calculateLen > 0 { b, e := json.Marshal(req.Calculates) if e != nil { br.Msg = "计算方式格式有误" br.ErrMsg = "解析计算方式参数失败, Err: " + e.Error() return } calculatesJson = string(b) for _, v := range req.Calculates { switch v.Source { case utils.EdbBaseCalculateNszydpjjs, utils.EdbBaseCalculateHbz, utils.EdbBaseCalculateHcz, utils.EdbBaseCalculateCjjx: if v.Formula == nil { br.Msg = "请输入N值" return } formula, ok := v.Formula.(string) if !ok { br.Msg = "N值格式有误" return } formulaInt, _ := strconv.Atoi(formula) if formulaInt <= 0 { br.Msg = "N值不可小于0, 重新输入" return } case utils.EdbBaseCalculateExponentialSmoothing: if v.Formula == nil { br.Msg = "请填写alpha值" return } formula, ok := v.Formula.(string) if !ok { br.Msg = "alpha值格式有误" return } alpha, _ := strconv.ParseFloat(formula, 64) if alpha <= 0 || alpha >= 1 { br.Msg = "alpha值应在0-1之间, 请重新输入" return } } } } seriesOb := new(data_manage.FactorEdbSeries) seriesItem, e := seriesOb.GetItemById(req.SeriesId) if e != nil { if utils.IsErrNoRow(e) { br.Msg = "该因子指标系列不存在" return } br.Msg = "获取失败" br.ErrMsg = "获取因子指标系列失败, Err: " + e.Error() return } originCalculateState := seriesItem.CalculateState edbArr, e := data_manage.GetEdbInfoByIdList(req.EdbInfoIds) if e != nil { br.Msg = "操作失败" br.ErrMsg = "获取指标列表失败, Err: " + e.Error() return } if len(edbArr) == 0 { br.Msg = "因子指标系列有误" br.ErrMsg = "因子指标系列长度为0" return } var calculateResp data_manage.FactorEdbSeriesStepCalculateResp calculateResp.SeriesId = seriesItem.FactorEdbSeriesId seriesItem.SeriesName = req.SeriesName seriesItem.EdbInfoType = req.EdbInfoType seriesItem.ModifyTime = time.Now().Local() updateCols := []string{seriesOb.Cols().SeriesName, seriesOb.Cols().EdbInfoType, seriesOb.Cols().ModifyTime} if !req.Recalculate { if e = seriesItem.Update(updateCols); e != nil { br.Msg = "操作成功" br.ErrMsg = "更新因子指标系列信息失败, Err: " + e.Error() return } for _, v := range edbArr { calculateResp.Success = append(calculateResp.Success, data_manage.FactorEdbSeriesStepCalculateResult{ EdbInfoId: v.EdbInfoId, EdbCode: v.EdbCode, Msg: "保存成功", }) } br.Data = calculateResp br.Ret = 200 br.Success = true br.Msg = "操作成功" return } seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculateNone if calculateLen > 0 { seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculating seriesItem.CalculateStep = calculatesJson updateCols = append(updateCols, seriesOb.Cols().CalculateState, seriesOb.Cols().CalculateStep) } mappings := make([]*data_manage.FactorEdbSeriesMapping, 0) for _, v := range edbArr { mappings = append(mappings, &data_manage.FactorEdbSeriesMapping{ EdbInfoId: v.EdbInfoId, EdbCode: v.EdbCode, CreateTime: time.Now().Local(), ModifyTime: time.Now().Local(), }) } if e = seriesItem.EditSeriesAndMapping(seriesItem, mappings, updateCols); e != nil { br.Msg = "操作失败" br.ErrMsg = "编辑因子指标系列失败, Err: " + e.Error() return } calculateResp, e = data.FactorEdbStepCalculate(seriesItem.FactorEdbSeriesId, edbArr, req.Calculates, this.Lang, req.Recalculate) if e != nil { br.Msg = "操作失败" br.ErrMsg = "计算因子指标失败, Err: " + e.Error() return } if seriesItem.CalculateState == data_manage.FactorEdbSeriesCalculating { seriesItem.CalculateState = data_manage.FactorEdbSeriesCalculated } if originCalculateState != seriesItem.CalculateState { cols := []string{seriesItem.Cols().CalculateState, seriesItem.Cols().ModifyTime} seriesItem.ModifyTime = time.Now().Local() if e = seriesItem.Update(cols); e != nil { br.Msg = "操作失败" br.ErrMsg = "更新因子指标系列计算状态失败, Err: " + e.Error() return } } br.Data = calculateResp br.Ret = 200 br.Success = true br.Msg = "操作成功" br.IsAddLog = true } // @router /factor_edb_series/detail [get] func (this *FactorEdbSeriesController) Detail() { br := new(models.BaseResponse).Init() defer func() { if br.ErrMsg == "" { br.IsSendEmail = false } this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } seriesId, _ := this.GetInt("SeriesId", 0) if seriesId <= 0 { br.Msg = "参数有误" br.ErrMsg = fmt.Sprintf("参数有误, SeriesId: %d", seriesId) return } seriesOb := new(data_manage.FactorEdbSeries) series, e := seriesOb.GetItemById(seriesId) if e != nil { if utils.IsErrNoRow(e) { br.Msg = "该因子指标系列不存在" return } br.Msg = "获取失败" br.ErrMsg = "获取因子指标系列失败, Err: " + e.Error() return } mappingOb := new(data_manage.FactorEdbSeriesMapping) cond := fmt.Sprintf(" AND %s = ?", mappingOb.Cols().FactorEdbSeriesId) pars := make([]interface{}, 0) pars = append(pars, seriesId) mappings, e := mappingOb.GetItemsByCondition(cond, pars, []string{}, fmt.Sprintf("%s ASC", mappingOb.Cols().CreateTime)) if e != nil { br.Msg = "获取失败" br.ErrMsg = "获取因子指标系列关联失败, Err: " + e.Error() return } resp := new(data_manage.FactorEdbSeriesDetail) resp.FactorEdbSeriesItem = series.Format2Item() for _, m := range mappings { resp.EdbMappings = append(resp.EdbMappings, m.Format2Item()) } br.Data = resp br.Ret = 200 br.Success = true br.Msg = "获取成功" } // @router /factor_edb_series/correlation/matrix [post] func (this *FactorEdbSeriesController) CorrelationMatrix() { br := new(models.BaseResponse).Init() defer func() { if br.ErrMsg == "" { br.IsSendEmail = false } this.Data["json"] = br this.ServeJSON() }() sysUser := this.SysUser if sysUser == nil { br.Msg = "请登录" br.ErrMsg = "请登录,SysUser Is Empty" br.Ret = 408 return } var req request.FactorEdbSeriesCorrelationMatrixReq if e := json.Unmarshal(this.Ctx.Input.RequestBody, &req); e != nil { br.Msg = "参数解析异常" br.ErrMsg = fmt.Sprintf("参数解析异常, Err: %v", e) return } if req.BaseEdbInfoId <= 0 { br.Msg = "请选择标的指标" return } if len(req.SeriesIds) == 0 { br.Msg = "请选择因子指标系列" return } if req.Correlation.LeadValue <= 0 { br.Msg = "分析周期不允许设置为负数或0" return } if req.Correlation.LeadUnit == "" { br.Msg = "请选择分析周期频度" return } leadUnitDays, ok := utils.FrequencyDaysMap[req.Correlation.LeadUnit] if !ok { br.Msg = "错误的分析周期频度" br.ErrMsg = fmt.Sprintf("分析周期频度有误: %s", req.Correlation.LeadUnit) return } if req.Correlation.CalculateUnit == "" { br.Msg = "请选择计算窗口频度" return } calculateUnitDays, ok := utils.FrequencyDaysMap[req.Correlation.CalculateUnit] if !ok { br.Msg = "错误的计算窗口频度" br.ErrMsg = fmt.Sprintf("计算窗口频度有误: %s", req.Correlation.CalculateUnit) return } leadDays := 2 * req.Correlation.LeadValue * leadUnitDays calculateDays := req.Correlation.CalculateValue * calculateUnitDays if calculateDays < leadDays { br.Msg = "计算窗口必须≥2*分析周期" return } var calculatePars data_manage.CalculateCorrelationMatrixPars calculatePars.BaseEdbInfoId = req.BaseEdbInfoId calculatePars.SeriesIds = req.SeriesIds calculatePars.Correlation = req.Correlation resp, _, e := correlationServ.CalculateCorrelationMatrix(calculatePars) if e != nil { br.Msg = "计算失败" br.ErrMsg = fmt.Sprintf("计算相关性矩阵失败, %v", e) return } br.Data = resp br.Ret = 200 br.Success = true br.Msg = "获取成功" }