package data_manage import ( "encoding/json" "eta/eta_api/utils" "fmt" "github.com/beego/beego/v2/client/orm" "strings" "time" ) const ( FactorEdbSeriesCalculateNone = 0 FactorEdbSeriesCalculating = 1 FactorEdbSeriesCalculated = 2 ) // FactorEdbSeries 因子指标系列表 type FactorEdbSeries struct { FactorEdbSeriesId int `orm:"column(factor_edb_series_id);pk"` SeriesName string `description:"系列名称"` EdbInfoType int `description:"关联指标类型:0-普通指标;1-预测指标"` CalculateStep string `description:"计算步骤-JSON"` CalculateState int `description:"计算状态: 0-无计算; 1-计算中; 2-计算完成"` CreateTime time.Time `description:"创建时间"` ModifyTime time.Time `description:"修改时间"` } func (m *FactorEdbSeries) TableName() string { return "factor_edb_series" } type FactorEdbSeriesCols struct { PrimaryId string SeriesName string EdbInfoType string CalculateStep string CalculateState string CreateTime string ModifyTime string } func (m *FactorEdbSeries) Cols() FactorEdbSeriesCols { return FactorEdbSeriesCols{ PrimaryId: "factor_edb_series_id", SeriesName: "series_name", EdbInfoType: "edb_info_type", CalculateStep: "calculate_step", CalculateState: "calculate_state", CreateTime: "create_time", ModifyTime: "modify_time", } } func (m *FactorEdbSeries) Create() (err error) { o := orm.NewOrmUsingDB("data") id, err := o.Insert(m) if err != nil { return } m.FactorEdbSeriesId = int(id) return } func (m *FactorEdbSeries) CreateMulti(items []*FactorEdbSeries) (err error) { if len(items) == 0 { return } o := orm.NewOrmUsingDB("data") _, err = o.InsertMulti(len(items), items) return } func (m *FactorEdbSeries) Update(cols []string) (err error) { o := orm.NewOrmUsingDB("data") _, err = o.Update(m, cols...) return } func (m *FactorEdbSeries) Remove() (err error) { o := orm.NewOrmUsingDB("data") sql := fmt.Sprintf(`DELETE FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.Cols().PrimaryId) _, err = o.Raw(sql, m.FactorEdbSeriesId).Exec() return } func (m *FactorEdbSeries) MultiRemove(ids []int) (err error) { if len(ids) == 0 { return } o := orm.NewOrmUsingDB("data") sql := fmt.Sprintf(`DELETE FROM %s WHERE %s IN (%s)`, m.TableName(), m.Cols().PrimaryId, utils.GetOrmInReplace(len(ids))) _, err = o.Raw(sql, ids).Exec() return } func (m *FactorEdbSeries) RemoveByCondition(condition string, pars []interface{}) (err error) { if condition == "" { return } o := orm.NewOrmUsingDB("data") sql := fmt.Sprintf(`DELETE FROM %s WHERE %s`, m.TableName(), condition) _, err = o.Raw(sql, pars).Exec() return } func (m *FactorEdbSeries) GetItemById(id int) (item *FactorEdbSeries, err error) { o := orm.NewOrmUsingDB("data") sql := fmt.Sprintf(`SELECT * FROM %s WHERE %s = ? LIMIT 1`, m.TableName(), m.Cols().PrimaryId) err = o.Raw(sql, id).QueryRow(&item) return } func (m *FactorEdbSeries) GetItemByCondition(condition string, pars []interface{}, orderRule string) (item *FactorEdbSeries, err error) { o := orm.NewOrmUsingDB("data") order := `` if orderRule != "" { order = ` ORDER BY ` + orderRule } sql := fmt.Sprintf(`SELECT * FROM %s WHERE 1=1 %s %s LIMIT 1`, m.TableName(), condition, order) err = o.Raw(sql, pars).QueryRow(&item) return } func (m *FactorEdbSeries) GetCountByCondition(condition string, pars []interface{}) (count int, err error) { o := orm.NewOrmUsingDB("data") sql := fmt.Sprintf(`SELECT COUNT(1) FROM %s WHERE 1=1 %s`, m.TableName(), condition) err = o.Raw(sql, pars).QueryRow(&count) return } func (m *FactorEdbSeries) GetItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string) (items []*FactorEdbSeries, err error) { o := orm.NewOrmUsingDB("data") fields := strings.Join(fieldArr, ",") if len(fieldArr) == 0 { fields = `*` } order := fmt.Sprintf(`ORDER BY %s DESC`, m.Cols().CreateTime) if orderRule != "" { order = ` ORDER BY ` + orderRule } sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s`, fields, m.TableName(), condition, order) _, err = o.Raw(sql, pars).QueryRows(&items) return } func (m *FactorEdbSeries) GetPageItemsByCondition(condition string, pars []interface{}, fieldArr []string, orderRule string, startSize, pageSize int) (items []*FactorEdbSeries, err error) { o := orm.NewOrmUsingDB("data") fields := strings.Join(fieldArr, ",") if len(fieldArr) == 0 { fields = `*` } order := fmt.Sprintf(`ORDER BY %s DESC`, m.Cols().CreateTime) if orderRule != "" { order = ` ORDER BY ` + orderRule } sql := fmt.Sprintf(`SELECT %s FROM %s WHERE 1=1 %s %s LIMIT ?,?`, fields, m.TableName(), condition, order) _, err = o.Raw(sql, pars, startSize, pageSize).QueryRows(&items) return } // FactorEdbSeriesItem 多因子系列信息 type FactorEdbSeriesItem struct { SeriesId int `description:"多因子系列ID"` SeriesName string `description:"系列名称"` EdbInfoType int `description:"关联指标类型:0-普通指标;1-预测指标"` CalculateStep []FactorEdbSeriesCalculatePars `description:"计算步骤-JSON"` CreateTime string `description:"创建时间"` ModifyTime string `description:"修改时间"` } func (m *FactorEdbSeries) Format2Item() (item *FactorEdbSeriesItem) { item = new(FactorEdbSeriesItem) item.SeriesId = m.FactorEdbSeriesId item.SeriesName = m.SeriesName item.EdbInfoType = m.EdbInfoType if m.CalculateStep != "" { _ = json.Unmarshal([]byte(m.CalculateStep), &item.CalculateStep) } item.CreateTime = utils.TimeTransferString(utils.FormatDateTime, m.CreateTime) item.ModifyTime = utils.TimeTransferString(utils.FormatDateTime, m.ModifyTime) return } // FactorEdbSeriesCalculatePars 计算参数 type FactorEdbSeriesCalculatePars struct { Formula interface{} `description:"N值/移动天数/指数修匀alpha值/计算公式等"` Calendar string `description:"公历/农历"` Frequency string `description:"需要转换的频度"` MoveType int `description:"移动方式: 1-领先(默认); 2-滞后"` MoveFrequency string `description:"移动频度"` FromFrequency string `description:"来源的频度"` Source int `description:"计算方式来源(不是指标来源)"` Sort int `description:"计算顺序"` } // CreateSeriesAndMapping 新增系列和指标关联 func (m *FactorEdbSeries) CreateSeriesAndMapping(item *FactorEdbSeries, mappings []*FactorEdbSeriesMapping) (seriesId int, err error) { if item == nil { err = fmt.Errorf("series is nil") return } o := orm.NewOrmUsingDB("data") tx, e := o.Begin() if e != nil { err = fmt.Errorf("orm begin err: %v", e) return } defer func() { if err != nil { _ = tx.Rollback() return } _ = tx.Commit() }() id, e := tx.Insert(item) if e != nil { err = fmt.Errorf("insert series err: %v", e) return } seriesId = int(id) item.FactorEdbSeriesId = seriesId if len(mappings) > 0 { for _, v := range mappings { v.FactorEdbSeriesId = seriesId } _, e = tx.InsertMulti(200, mappings) if e != nil { err = fmt.Errorf("insert multi mapping err: %v", e) return } } return } // EditSeriesAndMapping 编辑系列和指标关联 func (m *FactorEdbSeries) EditSeriesAndMapping(item *FactorEdbSeries, mappings []*FactorEdbSeriesMapping, updateCols []string) (err error) { if item == nil { err = fmt.Errorf("series is nil") return } o := orm.NewOrmUsingDB("data") tx, e := o.Begin() if e != nil { err = fmt.Errorf("orm begin err: %v", e) return } defer func() { if err != nil { _ = tx.Rollback() return } _ = tx.Commit() }() _, e = tx.Update(item, updateCols...) if e != nil { err = fmt.Errorf("update series err: %v", e) return } // 清除原指标关联 mappingOb := new(FactorEdbSeriesMapping) cond := fmt.Sprintf("%s = ?", mappingOb.Cols().FactorEdbSeriesId) pars := make([]interface{}, 0) pars = append(pars, item.FactorEdbSeriesId) sql := fmt.Sprintf(`DELETE FROM %s WHERE %s`, mappingOb.TableName(), cond) _, e = tx.Raw(sql, pars).Exec() if e != nil { err = fmt.Errorf("remove mapping err: %v", e) return } if len(mappings) > 0 { for _, v := range mappings { v.FactorEdbSeriesId = item.FactorEdbSeriesId } _, e = tx.InsertMulti(200, mappings) if e != nil { err = fmt.Errorf("insert multi mapping err: %v", e) return } } return } // FactorEdbSeriesStepCalculateResp 批量计算响应 type FactorEdbSeriesStepCalculateResp struct { SeriesId int `description:"多因子指标系列ID"` Fail []FactorEdbSeriesStepCalculateResult `description:"计算失败的指标"` Success []FactorEdbSeriesStepCalculateResult `description:"计算成功的指标"` } // FactorEdbSeriesStepCalculateResult 批量计算结果 type FactorEdbSeriesStepCalculateResult struct { EdbInfoId int `description:"指标ID"` EdbCode string `description:"指标编码"` Msg string `description:"提示信息"` ErrMsg string `description:"错误信息"` } // FactorEdbSeriesDetail 因子指标系列-详情 type FactorEdbSeriesDetail struct { *FactorEdbSeriesItem EdbMappings []*FactorEdbSeriesMappingItem } // FactorEdbSeriesCorrelationMatrixResp 因子指标系列-相关性矩阵响应 type FactorEdbSeriesCorrelationMatrixResp struct { Fail []FactorEdbSeriesCorrelationMatrixItem `description:"计算失败的指标"` Success []FactorEdbSeriesCorrelationMatrixItem `description:"计算成功的指标"` } // FactorEdbSeriesCorrelationMatrixItem 因子指标系列-相关性矩阵信息 type FactorEdbSeriesCorrelationMatrixItem struct { SeriesId int `description:"因子指标系列ID"` EdbInfoId int `description:"指标ID"` EdbCode string `description:"指标编码"` EdbName string `description:"指标名称"` Values []FactorEdbSeriesCorrelationMatrixValues `description:"X轴和Y轴数据"` Msg string `description:"提示信息"` ErrMsg string `description:"错误信息"` Used bool `description:"是否选中"` SourceName string `description:"指标来源名称"` SourceNameEn string `description:"英文指标来源名称"` } // FactorEdbSeriesCorrelationMatrixValues 因子指标系列-相关性矩阵XY值 type FactorEdbSeriesCorrelationMatrixValues struct { XData int `description:"X轴数据"` YData float64 `description:"Y轴数据"` } // FactorEdbSeriesCorrelationMatrixOrder 排序规则[0 1 2 3 -1 -2 -3] type FactorEdbSeriesCorrelationMatrixOrder []FactorEdbSeriesCorrelationMatrixValues func (a FactorEdbSeriesCorrelationMatrixOrder) Len() int { return len(a) } func (a FactorEdbSeriesCorrelationMatrixOrder) Swap(i, j int) { a[i], a[j] = a[j], a[i] } func (a FactorEdbSeriesCorrelationMatrixOrder) Less(i, j int) bool { // 非负数优先 if a[i].XData >= 0 && a[j].XData < 0 { return true } if a[i].XData < 0 && a[j].XData >= 0 { return false } // 非负数升序排序 if a[i].XData >= 0 { return a[i].XData < a[j].XData } // 负数按绝对值的降序排序(即数值的升序) return a[i].XData > a[j].XData } // CalculateCorrelationMatrixPars 计算相关性矩阵参数 type CalculateCorrelationMatrixPars struct { BaseEdbInfoId int `description:"标的指标ID"` SeriesIds []int `description:"系列IDs"` Correlation CorrelationConfig `description:"相关性配置"` }