warehouse.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  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.Source = utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS
  113. chartInfo.ChartThemeId = req.ChartThemeId
  114. chartInfo.SourcesFrom = req.SourcesFrom
  115. chartInfo.Instructions = req.Instructions
  116. chartInfo.MarkersLines = req.MarkersLines
  117. chartInfo.MarkersAreas = req.MarkersAreas
  118. chartInfo.ExtraConfig = req.ExtraConfig
  119. chartInfo.DateTypeNum = req.DateTypeNum
  120. chartInfo.MinMaxSave = req.MinMaxSave
  121. //_, e := data_manage.AddChartInfo(chartInfo)
  122. //if e != nil {
  123. // err = fmt.Errorf("新增持仓分析图表失败, %v", e)
  124. // return
  125. //}
  126. // 图例信息-由于持仓分析图表无指标, 图例信息就不存在chart_edb_mapping里了, 而是chart_series
  127. seriesList := make([]*data_manage.ChartSeries, 0)
  128. for _, v := range req.ChartEdbInfoList {
  129. t := new(data_manage.ChartSeries)
  130. t.SeriesName = v.EdbAliasName
  131. t.SeriesNameEn = v.EdbAliasName
  132. t.ChartInfoId = chartInfo.ChartInfoId
  133. t.IsAxis = v.IsAxis
  134. t.UniqueFlag = v.UniqueFlag
  135. t.CreateTime = time.Now().Local()
  136. t.ModifyTime = time.Now().Local()
  137. seriesList = append(seriesList, t)
  138. }
  139. // 图表关联多图配置
  140. multiChartMapping := new(data_manage.MultipleGraphConfigChartMapping)
  141. if extraConfig.MultipleGraphConfigId > 0 {
  142. multiChartMapping.MultipleGraphConfigId = extraConfig.MultipleGraphConfigId
  143. multiChartMapping.ChartInfoId = chartInfo.ChartInfoId
  144. multiChartMapping.Source = utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS
  145. multiChartMapping.CreateTime = time.Now().Local()
  146. multiChartMapping.ModifyTime = time.Now().Local()
  147. //multipleGraphConfigChartMapping := &data_manage.MultipleGraphConfigChartMapping{
  148. // MultipleGraphConfigId: extraConfig.MultipleGraphConfigId,
  149. // ChartInfoId: chartInfo.ChartInfoId,
  150. // Source: utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS,
  151. // ModifyTime: time.Now(),
  152. // CreateTime: time.Now(),
  153. //}
  154. //if err = data_manage.AddMultipleGraphConfigChartMapping(multipleGraphConfigChartMapping); err != nil {
  155. // err = fmt.Errorf("持仓分析图表关联多图配置失败, %v", e)
  156. // return
  157. //}
  158. }
  159. // 新增
  160. if e := tradeAnalysisModel.CreateWarehouseChart(chartInfo, seriesList, multiChartMapping); e != nil {
  161. err = fmt.Errorf("新增图表失败, %v", e)
  162. return
  163. }
  164. // 添加es数据
  165. go data.EsAddOrEditChartInfo(chartInfo.ChartInfoId)
  166. return
  167. }
  168. // EditWarehouseChart 编辑持仓分析图表
  169. func EditWarehouseChart(req data_manage.EditChartInfoReq) (chartItem *data_manage.ChartInfo, err error) {
  170. // 更新图表
  171. e := data_manage.EditChartInfoAndMapping(&req, "", "公历", req.DateType, 0, ``, make([]*data_manage.ChartSaveItem, 0), "")
  172. if e != nil {
  173. err = fmt.Errorf("更新图表失败, %v", e)
  174. return
  175. }
  176. chartItem, e = data_manage.GetChartInfoById(req.ChartInfoId)
  177. if e != nil {
  178. err = fmt.Errorf("获取更新后的图表失败, %v", e)
  179. return
  180. }
  181. // 替换原图例
  182. if e = data_manage.DeleteChartSeriesAndEdbMapping(req.ChartInfoId); e != nil {
  183. err = fmt.Errorf("删除原图例失败, %v", e)
  184. return
  185. }
  186. seriesList := make([]*data_manage.ChartSeries, 0)
  187. for _, v := range req.ChartEdbInfoList {
  188. t := new(data_manage.ChartSeries)
  189. t.SeriesName = v.EdbAliasName
  190. t.SeriesNameEn = v.EdbAliasName
  191. t.ChartInfoId = chartItem.ChartInfoId
  192. t.IsAxis = v.IsAxis
  193. t.UniqueFlag = v.UniqueFlag
  194. t.CreateTime = time.Now().Local()
  195. t.ModifyTime = time.Now().Local()
  196. seriesList = append(seriesList, t)
  197. }
  198. if len(seriesList) > 0 {
  199. seriesOb := new(data_manage.ChartSeries)
  200. if e = seriesOb.CreateMulti(seriesList); e != nil {
  201. err = fmt.Errorf("新增图例失败, %v", e)
  202. return
  203. }
  204. }
  205. // 更新ES
  206. go func() {
  207. data.EsAddOrEditChartInfo(chartItem.ChartInfoId)
  208. data.EsAddOrEditMyChartInfoByChartInfoId(chartItem.ChartInfoId)
  209. }()
  210. return
  211. }
  212. // CopyWarehouseChart 复制持仓分析图表
  213. func CopyWarehouseChart(classifyId int, chartName string, originChart *data_manage.ChartInfo, adminId int, adminRealName string) (chartInfo *data_manage.ChartInfo, err error) {
  214. var extraConfig tradeAnalysisModel.WarehouseExtraConfig
  215. if e := json.Unmarshal([]byte(originChart.ExtraConfig), &extraConfig); e != nil {
  216. err = fmt.Errorf("图表配置有误, %v", e)
  217. return
  218. }
  219. // 新增配置并绑定图表
  220. multipleGraphConfig := &data_manage.MultipleGraphConfig{
  221. SysUserId: adminId,
  222. SysUserRealName: adminRealName,
  223. ModifyTime: time.Now(),
  224. CreateTime: time.Now(),
  225. }
  226. if e := data_manage.AddMultipleGraphConfig(multipleGraphConfig); e != nil {
  227. err = fmt.Errorf("新增持仓分析多图配置失败, %v", e)
  228. return
  229. }
  230. extraConfig.MultipleGraphConfigId = multipleGraphConfig.MultipleGraphConfigId
  231. configByte, e := json.Marshal(extraConfig)
  232. if e != nil {
  233. err = fmt.Errorf("图表配置格式化失败, %v", e)
  234. return
  235. }
  236. // 新增图表
  237. chartInfo = &data_manage.ChartInfo{
  238. ChartName: chartName,
  239. ChartClassifyId: classifyId,
  240. SysUserId: adminId,
  241. SysUserRealName: adminRealName,
  242. UniqueCode: utils.MD5(utils.CHART_PREFIX + "_" + strconv.FormatInt(time.Now().UnixNano(), 10)),
  243. CreateTime: time.Now(),
  244. ModifyTime: time.Now(),
  245. DateType: originChart.DateType,
  246. StartDate: originChart.StartDate,
  247. EndDate: originChart.EndDate,
  248. IsSetName: originChart.IsSetName,
  249. EdbInfoIds: originChart.EdbInfoIds,
  250. ChartType: originChart.ChartType,
  251. Calendar: originChart.Calendar,
  252. SeasonStartDate: originChart.SeasonStartDate,
  253. SeasonEndDate: originChart.SeasonEndDate,
  254. ChartImage: originChart.ChartImage,
  255. BarConfig: originChart.BarConfig,
  256. LeftMin: originChart.LeftMin,
  257. LeftMax: originChart.LeftMax,
  258. RightMin: originChart.RightMin,
  259. RightMax: originChart.RightMax,
  260. Right2Min: originChart.Right2Min,
  261. Right2Max: originChart.Right2Max,
  262. Disabled: originChart.Disabled,
  263. Source: originChart.Source,
  264. ExtraConfig: string(configByte),
  265. SeasonExtraConfig: originChart.SeasonExtraConfig,
  266. StartYear: originChart.StartYear,
  267. Unit: originChart.Unit,
  268. UnitEn: originChart.UnitEn,
  269. ChartThemeId: originChart.ChartThemeId,
  270. SourcesFrom: originChart.SourcesFrom,
  271. Instructions: originChart.Instructions,
  272. MarkersLines: originChart.MarkersLines,
  273. MarkersAreas: originChart.MarkersAreas,
  274. }
  275. _, e = data_manage.AddChartInfo(chartInfo)
  276. if e != nil {
  277. err = fmt.Errorf("新增持仓分析图失败, %v", e)
  278. return
  279. }
  280. // 新增图表-多图配置关联
  281. configChartMapping := &data_manage.MultipleGraphConfigChartMapping{
  282. MultipleGraphConfigId: extraConfig.MultipleGraphConfigId,
  283. ChartInfoId: chartInfo.ChartInfoId,
  284. Source: utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS,
  285. ModifyTime: time.Now(),
  286. CreateTime: time.Now(),
  287. }
  288. if e = data_manage.AddMultipleGraphConfigChartMapping(configChartMapping); e != nil {
  289. err = fmt.Errorf("持仓分析图表关联多图配置失败, %v", e)
  290. return
  291. }
  292. // 新增ES
  293. go data.EsAddOrEditChartInfo(chartInfo.ChartInfoId)
  294. return
  295. }
  296. // CheckEdbSave 校验指标新增
  297. func CheckEdbSave(extraConfig tradeAnalysisModel.WarehouseExtraConfig, multiEdbList []*data_manage.MultipleGraphConfigEdbMapping, IsSaveAs bool) (newEdbList []*tradeAnalysisModel.WarehouseEdbSaveItem, removeEdbIds []int, err error) {
  298. // 另存为或无关联指标时, 返回应当新增的全部指标列表
  299. newEdbList = make([]*tradeAnalysisModel.WarehouseEdbSaveItem, 0)
  300. suffixNames := tradeAnalysisModel.WarehouseTypeSuffixNames
  301. prefix := strings.Join(extraConfig.Contracts, "")
  302. if len(multiEdbList) == 0 || IsSaveAs {
  303. for _, v := range extraConfig.Companies {
  304. edb := new(tradeAnalysisModel.WarehouseEdbSaveItem)
  305. edb.EdbName = fmt.Sprintf("%s%s%s", prefix, v, suffixNames[extraConfig.WarehouseChartType])
  306. edb.Unit = tradeAnalysisModel.WarehouseDefaultUnit
  307. edb.Frequency = tradeAnalysisModel.WarehouseDefaultFrequency
  308. edb.UniqueFlag = v
  309. //conf := extraConfig
  310. //conf.Companies = []string{v}
  311. //b, e := json.Marshal(conf)
  312. //if e != nil {
  313. // err = fmt.Errorf("指标配置JSON格式化异常, %v", e)
  314. // return
  315. //}
  316. //edb.ExtraConfig = string(b)
  317. newEdbList = append(newEdbList, edb)
  318. }
  319. return
  320. }
  321. // 已有关联指标
  322. var edbIds []int
  323. for _, v := range multiEdbList {
  324. edbIds = append(edbIds, v.EdbInfoId)
  325. }
  326. if len(edbIds) == 0 {
  327. err = fmt.Errorf("关联指标IDs异常")
  328. return
  329. }
  330. warehouseType := extraConfig.WarehouseChartType
  331. // 获取已关联的指标信息
  332. edbList, e := data_manage.GetEdbInfoByIdList(edbIds)
  333. if e != nil {
  334. err = fmt.Errorf("获取指标信息失败, %v", e)
  335. return
  336. }
  337. // 只需要匹配期货公司即可, 合约数不匹配那么是不需要新增指标的
  338. existsMap := make(map[string]int) // [期货公司]:[指标ID]
  339. for _, v := range edbList {
  340. // 解析计算公式中的配置信息, 计算公式为空、解析失败的为异常需要移除绑定关系
  341. if v.CalculateFormula == "" {
  342. removeEdbIds = append(removeEdbIds, v.EdbInfoId)
  343. continue
  344. }
  345. var conf tradeAnalysisModel.WarehouseExtraConfig
  346. if e = json.Unmarshal([]byte(v.CalculateFormula), &conf); e != nil {
  347. utils.FileLog.Info("持仓分析图表-解析指标计算公式失败, EdbInfoId: %d, Conf: %s", v.EdbInfoId, v.CalculateFormula)
  348. removeEdbIds = append(removeEdbIds, v.EdbInfoId)
  349. continue
  350. }
  351. if len(conf.Companies) != 1 {
  352. utils.FileLog.Info("持仓分析图表-指标计算公式异常, EdbInfoId: %d, Conf: %s", v.EdbInfoId, v.CalculateFormula)
  353. removeEdbIds = append(removeEdbIds, v.EdbInfoId)
  354. continue
  355. }
  356. // 方向与配置中的方向不一致, 那么忽略
  357. if conf.WarehouseChartType != warehouseType {
  358. continue
  359. }
  360. existsMap[conf.Companies[0]] = v.EdbInfoId
  361. }
  362. // 配置中的, 不在已绑定中的需要新增
  363. confMap := make(map[string]bool) // [期货公司]:True
  364. for _, v := range extraConfig.Companies {
  365. confMap[v] = true
  366. if _, ok := existsMap[v]; !ok {
  367. // 需要新增的指标
  368. edb := new(tradeAnalysisModel.WarehouseEdbSaveItem)
  369. edb.EdbName = fmt.Sprintf("%s%s%s", prefix, v, suffixNames[extraConfig.WarehouseChartType])
  370. edb.Unit = tradeAnalysisModel.WarehouseDefaultUnit
  371. edb.Frequency = tradeAnalysisModel.WarehouseDefaultFrequency
  372. edb.UniqueFlag = v
  373. //conf := extraConfig
  374. //conf.Companies = []string{v}
  375. //b, e := json.Marshal(conf)
  376. //if e != nil {
  377. // err = fmt.Errorf("指标配置JSON格式化异常, %v", e)
  378. // return
  379. //}
  380. //edb.ExtraConfig = string(b)
  381. newEdbList = append(newEdbList, edb)
  382. continue
  383. }
  384. }
  385. // 已绑定的, 不在配置中的需要移除绑定
  386. for k, v := range existsMap {
  387. if _, ok := existsMap[k]; !ok {
  388. removeEdbIds = append(removeEdbIds, v)
  389. continue
  390. }
  391. }
  392. return
  393. }