package trade_analysis import ( "encoding/json" "eta/eta_api/models/data_manage" "eta/eta_api/models/data_manage/chart_theme" tradeAnalysisModel "eta/eta_api/models/data_manage/trade_analysis" "eta/eta_api/services/data" "eta/eta_api/utils" "fmt" "strconv" "strings" "time" ) // CheckWarehouseChartExtraConfig 校验持仓分析图表参数 func CheckWarehouseChartExtraConfig(extraConfig tradeAnalysisModel.WarehouseExtraConfig) (pass bool, tips string) { if extraConfig.Exchange == "" { tips = "请选择交易所" return } if extraConfig.ClassifyName == "" { tips = "请选择品种" return } if len(extraConfig.Contracts) == 0 { tips = "请选择合约" return } if len(extraConfig.Companies) == 0 { tips = "请选择期货公司" return } if len(extraConfig.Companies) > 5 { tips = "最多可选5个期货公司" return } if extraConfig.PredictRatio < 0 || extraConfig.PredictRatio > 1 { tips = "请输入正确的估计参数" return } pass = true return } func GetWarehouseChartResp(chartView *data_manage.ChartInfoView, companyTradeData []*tradeAnalysisModel.ContractCompanyTradeData, multiEdb []*tradeAnalysisModel.WarehouseEdbSaveItem, extraConfig tradeAnalysisModel.WarehouseExtraConfig, chartConfig tradeAnalysisModel.WarehouseChartPars) (chartResp *data_manage.ChartInfoDetailResp, err error) { edbMappings, defaultChartName, e := FormatCompanyTradeData2EdbMappings(companyTradeData, chartConfig.WarehouseChartType, chartConfig.DateType, chartConfig.DateTypeNum, chartConfig.StartDate, chartConfig.EndDate, chartConfig.ChartEdbInfoList) if e != nil { err = fmt.Errorf("多单数据转为指标失败, %v", e) return } // chartView为空表示为预览图, 有则表示为详情图 var chartThemeId int chartType := utils.CHART_TYPE_CURVE // 曲线图 if chartView == nil { // 图表样式/主题 chartThemeType, e := chart_theme.GetChartThemeTypeByChartTypeAndSource(chartType, utils.CHART_SOURCE_DEFAULT) if e != nil { err = fmt.Errorf("获取图表类型失败, %v", e) return } chartThemeId = chartThemeType.DefaultChartThemeId chartView = new(data_manage.ChartInfoView) chartView.ChartType = chartType chartView.Source = utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS chartView.ChartName = defaultChartName chartView.ChartNameEn = defaultChartName } else { chartThemeId = chartView.ChartThemeId } chartView.DateType = chartConfig.DateType chartView.DateTypeNum = chartConfig.DateTypeNum chartView.StartDate = chartConfig.StartDate chartView.EndDate = chartConfig.EndDate chartTheme, e := data.GetChartThemeConfig(chartThemeId, utils.CHART_SOURCE_DEFAULT, chartType) if e != nil { err = fmt.Errorf("获取图表主题失败, %v", e) return } chartView.ChartThemeId = chartTheme.ChartThemeId chartView.ChartThemeStyle = chartTheme.Config chartResp = new(data_manage.ChartInfoDetailResp) chartResp.ChartInfo = chartView chartResp.EdbInfoList = edbMappings dataResp := tradeAnalysisModel.WarehouseChartDataResp{WarehouseExtraConfig: extraConfig, MultiEdbMappings: multiEdb} dataResp.WarehouseChartType = chartConfig.WarehouseChartType chartResp.DataResp = dataResp return } // AddWarehouseChart 添加持仓分析图表 func AddWarehouseChart(req data_manage.AddChartInfoReq, extraConfig tradeAnalysisModel.WarehouseExtraConfig, adminId int, adminRealName string) (chartInfo *data_manage.ChartInfo, err error) { // 图表信息 chartInfo = new(data_manage.ChartInfo) chartInfo.ChartName = req.ChartName chartInfo.ChartNameEn = req.ChartName chartInfo.ChartClassifyId = req.ChartClassifyId chartInfo.SysUserId = adminId chartInfo.SysUserRealName = adminRealName chartInfo.CreateTime = time.Now() chartInfo.ModifyTime = time.Now() chartInfo.IsSetName = 0 timestamp := strconv.FormatInt(time.Now().UnixNano(), 10) chartInfo.UniqueCode = utils.MD5(utils.CHART_PREFIX + "_" + timestamp) chartInfo.ChartType = utils.CHART_TYPE_CURVE chartInfo.Calendar = "公历" chartInfo.DateType = req.DateType chartInfo.StartDate = req.StartDate chartInfo.EndDate = req.EndDate chartInfo.SeasonStartDate = req.StartDate chartInfo.SeasonEndDate = req.EndDate chartInfo.LeftMin = req.LeftMin chartInfo.LeftMax = req.LeftMax chartInfo.RightMin = req.RightMin chartInfo.RightMax = req.RightMax chartInfo.Right2Min = req.Right2Min chartInfo.Right2Max = req.Right2Max chartInfo.Source = utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS chartInfo.ChartThemeId = req.ChartThemeId chartInfo.SourcesFrom = req.SourcesFrom chartInfo.Instructions = req.Instructions chartInfo.MarkersLines = req.MarkersLines chartInfo.MarkersAreas = req.MarkersAreas chartInfo.ExtraConfig = req.ExtraConfig chartInfo.DateTypeNum = req.DateTypeNum chartInfo.MinMaxSave = req.MinMaxSave // 图例信息-由于持仓分析图表无指标, 图例信息就不存在chart_edb_mapping里了, 而是chart_series seriesList := make([]*data_manage.ChartSeries, 0) for _, v := range req.ChartEdbInfoList { t := new(data_manage.ChartSeries) t.SeriesName = v.EdbAliasName t.SeriesNameEn = v.EdbAliasName t.IsAxis = v.IsAxis t.UniqueFlag = v.UniqueFlag t.CreateTime = time.Now().Local() t.ModifyTime = time.Now().Local() seriesList = append(seriesList, t) } // 图表关联多图配置 multiChartMapping := new(data_manage.MultipleGraphConfigChartMapping) if extraConfig.MultipleGraphConfigId > 0 { multiChartMapping.MultipleGraphConfigId = extraConfig.MultipleGraphConfigId multiChartMapping.Source = utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS multiChartMapping.CreateTime = time.Now().Local() multiChartMapping.ModifyTime = time.Now().Local() } // 新增 if e := tradeAnalysisModel.CreateWarehouseChart(chartInfo, seriesList, multiChartMapping); e != nil { err = fmt.Errorf("新增图表失败, %v", e) return } // 添加es数据 go data.EsAddOrEditChartInfo(chartInfo.ChartInfoId) return } // EditWarehouseChart 编辑持仓分析图表 func EditWarehouseChart(req data_manage.EditChartInfoReq) (chartItem *data_manage.ChartInfo, err error) { // 更新图表 e := data_manage.EditChartInfoAndMapping(&req, "", "公历", req.DateType, 0, ``, make([]*data_manage.ChartSaveItem, 0), "") if e != nil { err = fmt.Errorf("更新图表失败, %v", e) return } chartItem, e = data_manage.GetChartInfoById(req.ChartInfoId) if e != nil { err = fmt.Errorf("获取更新后的图表失败, %v", e) return } // 替换原图例 if e = data_manage.DeleteChartSeriesAndEdbMapping(req.ChartInfoId); e != nil { err = fmt.Errorf("删除原图例失败, %v", e) return } seriesList := make([]*data_manage.ChartSeries, 0) for _, v := range req.ChartEdbInfoList { t := new(data_manage.ChartSeries) t.SeriesName = v.EdbAliasName t.SeriesNameEn = v.EdbAliasName t.ChartInfoId = chartItem.ChartInfoId t.IsAxis = v.IsAxis t.UniqueFlag = v.UniqueFlag t.CreateTime = time.Now().Local() t.ModifyTime = time.Now().Local() seriesList = append(seriesList, t) } if len(seriesList) > 0 { seriesOb := new(data_manage.ChartSeries) if e = seriesOb.CreateMulti(seriesList); e != nil { err = fmt.Errorf("新增图例失败, %v", e) return } } // 更新ES go func() { data.EsAddOrEditChartInfo(chartItem.ChartInfoId) data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId) }() return } // CopyWarehouseChart 复制持仓分析图表 func CopyWarehouseChart(classifyId int, chartName string, originChart *data_manage.ChartInfo, adminId int, adminRealName string) (chartInfo *data_manage.ChartInfo, err error) { var extraConfig tradeAnalysisModel.WarehouseExtraConfig if e := json.Unmarshal([]byte(originChart.ExtraConfig), &extraConfig); e != nil { err = fmt.Errorf("图表配置有误, %v", e) return } // 新增配置并绑定图表 multiConfigCopy := &data_manage.MultipleGraphConfig{ SysUserId: adminId, SysUserRealName: adminRealName, ModifyTime: time.Now(), CreateTime: time.Now(), } if e := data_manage.AddMultipleGraphConfig(multiConfigCopy); e != nil { err = fmt.Errorf("新增持仓分析多图配置失败, %v", e) return } extraConfig.MultipleGraphConfigId = multiConfigCopy.MultipleGraphConfigId configByte, e := json.Marshal(extraConfig) if e != nil { err = fmt.Errorf("图表配置格式化失败, %v", e) return } // 新增图表 chartInfo = &data_manage.ChartInfo{ ChartName: chartName, ChartClassifyId: classifyId, SysUserId: adminId, SysUserRealName: adminRealName, UniqueCode: utils.MD5(utils.CHART_PREFIX + "_" + strconv.FormatInt(time.Now().UnixNano(), 10)), CreateTime: time.Now(), ModifyTime: time.Now(), DateType: originChart.DateType, StartDate: originChart.StartDate, EndDate: originChart.EndDate, IsSetName: originChart.IsSetName, EdbInfoIds: originChart.EdbInfoIds, ChartType: originChart.ChartType, Calendar: originChart.Calendar, SeasonStartDate: originChart.SeasonStartDate, SeasonEndDate: originChart.SeasonEndDate, ChartImage: originChart.ChartImage, BarConfig: originChart.BarConfig, LeftMin: originChart.LeftMin, LeftMax: originChart.LeftMax, RightMin: originChart.RightMin, RightMax: originChart.RightMax, Right2Min: originChart.Right2Min, Right2Max: originChart.Right2Max, Disabled: originChart.Disabled, Source: originChart.Source, ExtraConfig: string(configByte), SeasonExtraConfig: originChart.SeasonExtraConfig, StartYear: originChart.StartYear, Unit: originChart.Unit, UnitEn: originChart.UnitEn, ChartThemeId: originChart.ChartThemeId, SourcesFrom: originChart.SourcesFrom, Instructions: originChart.Instructions, MarkersLines: originChart.MarkersLines, MarkersAreas: originChart.MarkersAreas, DateTypeNum: originChart.DateTypeNum, } // 图例信息 seriesList, e := data_manage.GetChartSeriesByChartInfoId(originChart.ChartInfoId) if e != nil { err = fmt.Errorf("获取图例信息失败, %v", e) return } seriesCopy := make([]*data_manage.ChartSeries, 0) for _, v := range seriesList { t := new(data_manage.ChartSeries) t.SeriesName = v.SeriesName t.SeriesNameEn = v.SeriesNameEn t.IsAxis = v.IsAxis t.UniqueFlag = v.UniqueFlag t.CreateTime = time.Now().Local() t.ModifyTime = time.Now().Local() seriesCopy = append(seriesCopy, t) } // 新增图表-多图配置关联 configChartMapping := &data_manage.MultipleGraphConfigChartMapping{ MultipleGraphConfigId: multiConfigCopy.MultipleGraphConfigId, Source: utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS, ModifyTime: time.Now().Local(), CreateTime: time.Now().Local(), } // 新增 if e = tradeAnalysisModel.CreateWarehouseChart(chartInfo, seriesCopy, configChartMapping); e != nil { err = fmt.Errorf("新增图表失败, %v", e) return } // 新增ES go data.EsAddOrEditChartInfo(chartInfo.ChartInfoId) return } // CheckEdbSave 校验指标新增 func CheckEdbSave(extraConfig tradeAnalysisModel.WarehouseExtraConfig, multiEdbList []*data_manage.MultipleGraphConfigEdbMapping, IsSaveAs bool) (newEdbList []*tradeAnalysisModel.WarehouseEdbSaveItem, removeEdbIds []int, err error) { // 另存为或无关联指标时, 返回应当新增的全部指标列表 newEdbList = make([]*tradeAnalysisModel.WarehouseEdbSaveItem, 0) suffixNames := tradeAnalysisModel.WarehouseTypeSuffixNames prefix := strings.Join(extraConfig.Contracts, "") if len(multiEdbList) == 0 || IsSaveAs { for _, v := range extraConfig.Companies { edb := new(tradeAnalysisModel.WarehouseEdbSaveItem) edb.EdbName = fmt.Sprintf("%s%s%s", prefix, v, suffixNames[extraConfig.WarehouseChartType]) edb.Unit = tradeAnalysisModel.WarehouseDefaultUnit edb.Frequency = tradeAnalysisModel.WarehouseDefaultFrequency edb.UniqueFlag = v //conf := extraConfig //conf.Companies = []string{v} //b, e := json.Marshal(conf) //if e != nil { // err = fmt.Errorf("指标配置JSON格式化异常, %v", e) // return //} //edb.ExtraConfig = string(b) newEdbList = append(newEdbList, edb) } return } // 已有关联指标 var edbIds []int for _, v := range multiEdbList { edbIds = append(edbIds, v.EdbInfoId) } if len(edbIds) == 0 { err = fmt.Errorf("关联指标IDs异常") return } warehouseType := extraConfig.WarehouseChartType // 获取已关联的指标信息 edbList, e := data_manage.GetEdbInfoByIdList(edbIds) if e != nil { err = fmt.Errorf("获取指标信息失败, %v", e) return } // 只需要匹配期货公司即可, 合约数不匹配那么是不需要新增指标的 existsMap := make(map[string]int) // [期货公司]:[指标ID] for _, v := range edbList { // 解析计算公式中的配置信息, 计算公式为空、解析失败的为异常需要移除绑定关系 if v.CalculateFormula == "" { removeEdbIds = append(removeEdbIds, v.EdbInfoId) continue } var conf tradeAnalysisModel.WarehouseExtraConfig if e = json.Unmarshal([]byte(v.CalculateFormula), &conf); e != nil { utils.FileLog.Info("持仓分析图表-解析指标计算公式失败, EdbInfoId: %d, Conf: %s", v.EdbInfoId, v.CalculateFormula) removeEdbIds = append(removeEdbIds, v.EdbInfoId) continue } if len(conf.Companies) != 1 { utils.FileLog.Info("持仓分析图表-指标计算公式异常, EdbInfoId: %d, Conf: %s", v.EdbInfoId, v.CalculateFormula) removeEdbIds = append(removeEdbIds, v.EdbInfoId) continue } // 方向与配置中的方向不一致, 那么忽略 if conf.WarehouseChartType != warehouseType { continue } existsMap[conf.Companies[0]] = v.EdbInfoId } // 配置中的, 不在已绑定中的需要新增 confMap := make(map[string]bool) // [期货公司]:True for _, v := range extraConfig.Companies { confMap[v] = true if _, ok := existsMap[v]; !ok { // 需要新增的指标 edb := new(tradeAnalysisModel.WarehouseEdbSaveItem) edb.EdbName = fmt.Sprintf("%s%s%s", prefix, v, suffixNames[extraConfig.WarehouseChartType]) edb.Unit = tradeAnalysisModel.WarehouseDefaultUnit edb.Frequency = tradeAnalysisModel.WarehouseDefaultFrequency edb.UniqueFlag = v //conf := extraConfig //conf.Companies = []string{v} //b, e := json.Marshal(conf) //if e != nil { // err = fmt.Errorf("指标配置JSON格式化异常, %v", e) // return //} //edb.ExtraConfig = string(b) newEdbList = append(newEdbList, edb) continue } } // 已绑定的, 不在配置中的需要移除绑定 for k, v := range existsMap { if _, ok := existsMap[k]; !ok { removeEdbIds = append(removeEdbIds, v) continue } } return }