warehouse.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. package trade_analysis
  2. import (
  3. "encoding/json"
  4. "eta/eta_api/models/data_manage"
  5. "eta/eta_api/models/data_manage/chart_theme"
  6. tradeAnalysisModel "eta/eta_api/models/data_manage/trade_analysis"
  7. "eta/eta_api/services/data"
  8. "eta/eta_api/utils"
  9. "fmt"
  10. "strconv"
  11. "strings"
  12. "time"
  13. )
  14. // CheckWarehouseChartExtraConfig 校验持仓分析图表参数
  15. func CheckWarehouseChartExtraConfig(extraConfig tradeAnalysisModel.WarehouseExtraConfig) (pass bool, tips string) {
  16. if extraConfig.Exchange == "" {
  17. tips = "请选择交易所"
  18. return
  19. }
  20. if extraConfig.ClassifyName == "" {
  21. tips = "请选择品种"
  22. return
  23. }
  24. if len(extraConfig.Contracts) == 0 {
  25. tips = "请选择合约"
  26. return
  27. }
  28. if len(extraConfig.Companies) == 0 {
  29. tips = "请选择期货公司"
  30. return
  31. }
  32. if len(extraConfig.Companies) > 5 {
  33. tips = "最多可选5个期货公司"
  34. return
  35. }
  36. if extraConfig.PredictRatio < 0 || extraConfig.PredictRatio > 1 {
  37. tips = "请输入正确的估计参数"
  38. return
  39. }
  40. pass = true
  41. return
  42. }
  43. func GetWarehouseChartResp(chartView *data_manage.ChartInfoView, companyTradeData []*tradeAnalysisModel.ContractCompanyTradeData, multiEdb []*tradeAnalysisModel.WarehouseEdbSaveItem, extraConfig tradeAnalysisModel.WarehouseExtraConfig, chartConfig tradeAnalysisModel.WarehouseChartPars) (chartResp *data_manage.ChartInfoDetailResp, err error) {
  44. edbMappings, defaultChartName, e := FormatCompanyTradeData2EdbMappings(companyTradeData, chartConfig.WarehouseChartType, chartConfig.DateType, chartConfig.DateTypeNum, chartConfig.StartDate, chartConfig.EndDate, chartConfig.ChartEdbInfoList)
  45. if e != nil {
  46. err = fmt.Errorf("多单数据转为指标失败, %v", e)
  47. return
  48. }
  49. // chartView为空表示为预览图, 有则表示为详情图
  50. var chartThemeId int
  51. chartType := utils.CHART_TYPE_CURVE // 曲线图
  52. if chartView == nil {
  53. // 图表样式/主题
  54. chartThemeType, e := chart_theme.GetChartThemeTypeByChartTypeAndSource(chartType, utils.CHART_SOURCE_DEFAULT)
  55. if e != nil {
  56. err = fmt.Errorf("获取图表类型失败, %v", e)
  57. return
  58. }
  59. chartThemeId = chartThemeType.DefaultChartThemeId
  60. chartView = new(data_manage.ChartInfoView)
  61. chartView.ChartType = chartType
  62. chartView.Source = utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS
  63. chartView.ChartName = defaultChartName
  64. chartView.ChartNameEn = defaultChartName
  65. } else {
  66. chartThemeId = chartView.ChartThemeId
  67. }
  68. chartView.DateType = chartConfig.DateType
  69. chartView.DateTypeNum = chartConfig.DateTypeNum
  70. chartView.StartDate = chartConfig.StartDate
  71. chartView.EndDate = chartConfig.EndDate
  72. chartTheme, e := data.GetChartThemeConfig(chartThemeId, utils.CHART_SOURCE_DEFAULT, chartType)
  73. if e != nil {
  74. err = fmt.Errorf("获取图表主题失败, %v", e)
  75. return
  76. }
  77. chartView.ChartThemeId = chartTheme.ChartThemeId
  78. chartView.ChartThemeStyle = chartTheme.Config
  79. chartResp = new(data_manage.ChartInfoDetailResp)
  80. chartResp.ChartInfo = chartView
  81. chartResp.EdbInfoList = edbMappings
  82. dataResp := tradeAnalysisModel.WarehouseChartDataResp{WarehouseExtraConfig: extraConfig, MultiEdbMappings: multiEdb}
  83. dataResp.WarehouseChartType = chartConfig.WarehouseChartType
  84. chartResp.DataResp = dataResp
  85. return
  86. }
  87. // AddWarehouseChart 添加持仓分析图表
  88. func AddWarehouseChart(req data_manage.AddChartInfoReq, extraConfig tradeAnalysisModel.WarehouseExtraConfig, adminId int, adminRealName string) (chartInfo *data_manage.ChartInfo, err error) {
  89. // 图表信息
  90. chartInfo = new(data_manage.ChartInfo)
  91. chartInfo.ChartName = req.ChartName
  92. chartInfo.ChartNameEn = req.ChartName
  93. chartInfo.ChartClassifyId = req.ChartClassifyId
  94. chartInfo.SysUserId = adminId
  95. chartInfo.SysUserRealName = adminRealName
  96. chartInfo.CreateTime = time.Now()
  97. chartInfo.ModifyTime = time.Now()
  98. chartInfo.IsSetName = 0
  99. timestamp := strconv.FormatInt(time.Now().UnixNano(), 10)
  100. chartInfo.UniqueCode = utils.MD5(utils.CHART_PREFIX + "_" + timestamp)
  101. chartInfo.ChartType = utils.CHART_TYPE_CURVE
  102. chartInfo.Calendar = "公历"
  103. chartInfo.DateType = req.DateType
  104. chartInfo.StartDate = req.StartDate
  105. chartInfo.EndDate = req.EndDate
  106. chartInfo.SeasonStartDate = req.StartDate
  107. chartInfo.SeasonEndDate = req.EndDate
  108. chartInfo.LeftMin = req.LeftMin
  109. chartInfo.LeftMax = req.LeftMax
  110. chartInfo.RightMin = req.RightMin
  111. chartInfo.RightMax = req.RightMax
  112. chartInfo.Right2Min = req.Right2Min
  113. chartInfo.Right2Max = req.Right2Max
  114. chartInfo.Source = utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS
  115. chartInfo.ChartThemeId = req.ChartThemeId
  116. chartInfo.SourcesFrom = req.SourcesFrom
  117. chartInfo.Instructions = req.Instructions
  118. chartInfo.MarkersLines = req.MarkersLines
  119. chartInfo.MarkersAreas = req.MarkersAreas
  120. chartInfo.ExtraConfig = req.ExtraConfig
  121. chartInfo.DateTypeNum = req.DateTypeNum
  122. chartInfo.MinMaxSave = req.MinMaxSave
  123. // 图例信息-由于持仓分析图表无指标, 图例信息就不存在chart_edb_mapping里了, 而是chart_series
  124. seriesList := make([]*data_manage.ChartSeries, 0)
  125. for _, v := range req.ChartEdbInfoList {
  126. t := new(data_manage.ChartSeries)
  127. t.SeriesName = v.EdbAliasName
  128. t.SeriesNameEn = v.EdbAliasName
  129. t.IsAxis = v.IsAxis
  130. t.UniqueFlag = v.UniqueFlag
  131. t.CreateTime = time.Now().Local()
  132. t.ModifyTime = time.Now().Local()
  133. seriesList = append(seriesList, t)
  134. }
  135. // 图表关联多图配置
  136. multiChartMapping := new(data_manage.MultipleGraphConfigChartMapping)
  137. if extraConfig.MultipleGraphConfigId > 0 {
  138. multiChartMapping.MultipleGraphConfigId = extraConfig.MultipleGraphConfigId
  139. multiChartMapping.Source = utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS
  140. multiChartMapping.CreateTime = time.Now().Local()
  141. multiChartMapping.ModifyTime = time.Now().Local()
  142. }
  143. // 新增
  144. if e := tradeAnalysisModel.CreateWarehouseChart(chartInfo, seriesList, multiChartMapping); e != nil {
  145. err = fmt.Errorf("新增图表失败, %v", e)
  146. return
  147. }
  148. // 添加es数据
  149. go data.EsAddOrEditChartInfo(chartInfo.ChartInfoId)
  150. return
  151. }
  152. // EditWarehouseChart 编辑持仓分析图表
  153. func EditWarehouseChart(req data_manage.EditChartInfoReq) (chartItem *data_manage.ChartInfo, err error) {
  154. // 更新图表
  155. e := data_manage.EditChartInfoAndMapping(&req, "", "公历", req.DateType, 0, ``, make([]*data_manage.ChartSaveItem, 0), "")
  156. if e != nil {
  157. err = fmt.Errorf("更新图表失败, %v", e)
  158. return
  159. }
  160. chartItem, e = data_manage.GetChartInfoById(req.ChartInfoId)
  161. if e != nil {
  162. err = fmt.Errorf("获取更新后的图表失败, %v", e)
  163. return
  164. }
  165. // 替换原图例
  166. if e = data_manage.DeleteChartSeriesAndEdbMapping(req.ChartInfoId); e != nil {
  167. err = fmt.Errorf("删除原图例失败, %v", e)
  168. return
  169. }
  170. seriesList := make([]*data_manage.ChartSeries, 0)
  171. for _, v := range req.ChartEdbInfoList {
  172. t := new(data_manage.ChartSeries)
  173. t.SeriesName = v.EdbAliasName
  174. t.SeriesNameEn = v.EdbAliasName
  175. t.ChartInfoId = chartItem.ChartInfoId
  176. t.IsAxis = v.IsAxis
  177. t.UniqueFlag = v.UniqueFlag
  178. t.CreateTime = time.Now().Local()
  179. t.ModifyTime = time.Now().Local()
  180. seriesList = append(seriesList, t)
  181. }
  182. if len(seriesList) > 0 {
  183. seriesOb := new(data_manage.ChartSeries)
  184. if e = seriesOb.CreateMulti(seriesList); e != nil {
  185. err = fmt.Errorf("新增图例失败, %v", e)
  186. return
  187. }
  188. }
  189. // 更新ES
  190. go func() {
  191. data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
  192. data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
  193. }()
  194. return
  195. }
  196. // CopyWarehouseChart 复制持仓分析图表
  197. func CopyWarehouseChart(classifyId int, chartName string, originChart *data_manage.ChartInfo, adminId int, adminRealName string) (chartInfo *data_manage.ChartInfo, err error) {
  198. var extraConfig tradeAnalysisModel.WarehouseExtraConfig
  199. if e := json.Unmarshal([]byte(originChart.ExtraConfig), &extraConfig); e != nil {
  200. err = fmt.Errorf("图表配置有误, %v", e)
  201. return
  202. }
  203. // 新增配置并绑定图表
  204. multiConfigCopy := &data_manage.MultipleGraphConfig{
  205. SysUserId: adminId,
  206. SysUserRealName: adminRealName,
  207. ModifyTime: time.Now(),
  208. CreateTime: time.Now(),
  209. }
  210. if e := data_manage.AddMultipleGraphConfig(multiConfigCopy); e != nil {
  211. err = fmt.Errorf("新增持仓分析多图配置失败, %v", e)
  212. return
  213. }
  214. extraConfig.MultipleGraphConfigId = multiConfigCopy.MultipleGraphConfigId
  215. configByte, e := json.Marshal(extraConfig)
  216. if e != nil {
  217. err = fmt.Errorf("图表配置格式化失败, %v", e)
  218. return
  219. }
  220. // 新增图表
  221. chartInfo = &data_manage.ChartInfo{
  222. ChartName: chartName,
  223. ChartClassifyId: classifyId,
  224. SysUserId: adminId,
  225. SysUserRealName: adminRealName,
  226. UniqueCode: utils.MD5(utils.CHART_PREFIX + "_" + strconv.FormatInt(time.Now().UnixNano(), 10)),
  227. CreateTime: time.Now(),
  228. ModifyTime: time.Now(),
  229. DateType: originChart.DateType,
  230. StartDate: originChart.StartDate,
  231. EndDate: originChart.EndDate,
  232. IsSetName: originChart.IsSetName,
  233. EdbInfoIds: originChart.EdbInfoIds,
  234. ChartType: originChart.ChartType,
  235. Calendar: originChart.Calendar,
  236. SeasonStartDate: originChart.SeasonStartDate,
  237. SeasonEndDate: originChart.SeasonEndDate,
  238. ChartImage: originChart.ChartImage,
  239. BarConfig: originChart.BarConfig,
  240. LeftMin: originChart.LeftMin,
  241. LeftMax: originChart.LeftMax,
  242. RightMin: originChart.RightMin,
  243. RightMax: originChart.RightMax,
  244. Right2Min: originChart.Right2Min,
  245. Right2Max: originChart.Right2Max,
  246. Disabled: originChart.Disabled,
  247. Source: originChart.Source,
  248. ExtraConfig: string(configByte),
  249. SeasonExtraConfig: originChart.SeasonExtraConfig,
  250. StartYear: originChart.StartYear,
  251. Unit: originChart.Unit,
  252. UnitEn: originChart.UnitEn,
  253. ChartThemeId: originChart.ChartThemeId,
  254. SourcesFrom: originChart.SourcesFrom,
  255. Instructions: originChart.Instructions,
  256. MarkersLines: originChart.MarkersLines,
  257. MarkersAreas: originChart.MarkersAreas,
  258. DateTypeNum: originChart.DateTypeNum,
  259. }
  260. // 图例信息
  261. seriesList, e := data_manage.GetChartSeriesByChartInfoId(originChart.ChartInfoId)
  262. if e != nil {
  263. err = fmt.Errorf("获取图例信息失败, %v", e)
  264. return
  265. }
  266. seriesCopy := make([]*data_manage.ChartSeries, 0)
  267. for _, v := range seriesList {
  268. t := new(data_manage.ChartSeries)
  269. t.SeriesName = v.SeriesName
  270. t.SeriesNameEn = v.SeriesNameEn
  271. t.IsAxis = v.IsAxis
  272. t.UniqueFlag = v.UniqueFlag
  273. t.CreateTime = time.Now().Local()
  274. t.ModifyTime = time.Now().Local()
  275. seriesCopy = append(seriesCopy, t)
  276. }
  277. // 新增图表-多图配置关联
  278. configChartMapping := &data_manage.MultipleGraphConfigChartMapping{
  279. MultipleGraphConfigId: multiConfigCopy.MultipleGraphConfigId,
  280. Source: utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS,
  281. ModifyTime: time.Now().Local(),
  282. CreateTime: time.Now().Local(),
  283. }
  284. // 新增
  285. if e = tradeAnalysisModel.CreateWarehouseChart(chartInfo, seriesCopy, configChartMapping); e != nil {
  286. err = fmt.Errorf("新增图表失败, %v", e)
  287. return
  288. }
  289. // 新增ES
  290. go data.EsAddOrEditChartInfo(chartInfo.ChartInfoId)
  291. return
  292. }
  293. // CheckEdbSave 校验指标新增
  294. func CheckEdbSave(extraConfig tradeAnalysisModel.WarehouseExtraConfig, multiEdbList []*data_manage.MultipleGraphConfigEdbMapping, IsSaveAs bool) (newEdbList []*tradeAnalysisModel.WarehouseEdbSaveItem, removeEdbIds []int, err error) {
  295. // 另存为或无关联指标时, 返回应当新增的全部指标列表
  296. newEdbList = make([]*tradeAnalysisModel.WarehouseEdbSaveItem, 0)
  297. suffixNames := tradeAnalysisModel.WarehouseTypeSuffixNames
  298. prefix := strings.Join(extraConfig.Contracts, "")
  299. if len(multiEdbList) == 0 || IsSaveAs {
  300. for _, v := range extraConfig.Companies {
  301. edb := new(tradeAnalysisModel.WarehouseEdbSaveItem)
  302. edb.EdbName = fmt.Sprintf("%s%s%s", prefix, v, suffixNames[extraConfig.WarehouseChartType])
  303. edb.Unit = tradeAnalysisModel.WarehouseDefaultUnit
  304. edb.Frequency = tradeAnalysisModel.WarehouseDefaultFrequency
  305. edb.UniqueFlag = v
  306. //conf := extraConfig
  307. //conf.Companies = []string{v}
  308. //b, e := json.Marshal(conf)
  309. //if e != nil {
  310. // err = fmt.Errorf("指标配置JSON格式化异常, %v", e)
  311. // return
  312. //}
  313. //edb.ExtraConfig = string(b)
  314. newEdbList = append(newEdbList, edb)
  315. }
  316. return
  317. }
  318. // 已有关联指标
  319. var edbIds []int
  320. for _, v := range multiEdbList {
  321. edbIds = append(edbIds, v.EdbInfoId)
  322. }
  323. if len(edbIds) == 0 {
  324. err = fmt.Errorf("关联指标IDs异常")
  325. return
  326. }
  327. warehouseType := extraConfig.WarehouseChartType
  328. // 获取已关联的指标信息
  329. edbList, e := data_manage.GetEdbInfoByIdList(edbIds)
  330. if e != nil {
  331. err = fmt.Errorf("获取指标信息失败, %v", e)
  332. return
  333. }
  334. // 只需要匹配期货公司即可, 合约数不匹配那么是不需要新增指标的
  335. existsMap := make(map[string]int) // [期货公司]:[指标ID]
  336. for _, v := range edbList {
  337. // 解析计算公式中的配置信息, 计算公式为空、解析失败的为异常需要移除绑定关系
  338. if v.CalculateFormula == "" {
  339. removeEdbIds = append(removeEdbIds, v.EdbInfoId)
  340. continue
  341. }
  342. var conf tradeAnalysisModel.WarehouseExtraConfig
  343. if e = json.Unmarshal([]byte(v.CalculateFormula), &conf); e != nil {
  344. utils.FileLog.Info("持仓分析图表-解析指标计算公式失败, EdbInfoId: %d, Conf: %s", v.EdbInfoId, v.CalculateFormula)
  345. removeEdbIds = append(removeEdbIds, v.EdbInfoId)
  346. continue
  347. }
  348. if len(conf.Companies) != 1 {
  349. utils.FileLog.Info("持仓分析图表-指标计算公式异常, EdbInfoId: %d, Conf: %s", v.EdbInfoId, v.CalculateFormula)
  350. removeEdbIds = append(removeEdbIds, v.EdbInfoId)
  351. continue
  352. }
  353. // 方向与配置中的方向不一致, 那么忽略
  354. if conf.WarehouseChartType != warehouseType {
  355. continue
  356. }
  357. existsMap[conf.Companies[0]] = v.EdbInfoId
  358. }
  359. // 配置中的, 不在已绑定中的需要新增
  360. confMap := make(map[string]bool) // [期货公司]:True
  361. for _, v := range extraConfig.Companies {
  362. confMap[v] = true
  363. if _, ok := existsMap[v]; !ok {
  364. // 需要新增的指标
  365. edb := new(tradeAnalysisModel.WarehouseEdbSaveItem)
  366. edb.EdbName = fmt.Sprintf("%s%s%s", prefix, v, suffixNames[extraConfig.WarehouseChartType])
  367. edb.Unit = tradeAnalysisModel.WarehouseDefaultUnit
  368. edb.Frequency = tradeAnalysisModel.WarehouseDefaultFrequency
  369. edb.UniqueFlag = v
  370. //conf := extraConfig
  371. //conf.Companies = []string{v}
  372. //b, e := json.Marshal(conf)
  373. //if e != nil {
  374. // err = fmt.Errorf("指标配置JSON格式化异常, %v", e)
  375. // return
  376. //}
  377. //edb.ExtraConfig = string(b)
  378. newEdbList = append(newEdbList, edb)
  379. continue
  380. }
  381. }
  382. // 已绑定的, 不在配置中的需要移除绑定
  383. for k, v := range existsMap {
  384. if _, ok := existsMap[k]; !ok {
  385. removeEdbIds = append(removeEdbIds, v)
  386. continue
  387. }
  388. }
  389. return
  390. }