|
@@ -0,0 +1,350 @@
|
|
|
+package data_manage
|
|
|
+
|
|
|
+import (
|
|
|
+ "encoding/json"
|
|
|
+ "eta/eta_chart_lib/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) 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:"指标来源名称"`
|
|
|
+}
|
|
|
+
|
|
|
+// 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
|
|
|
+}
|