trade_position_analysis_classify.go 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. package data
  2. import (
  3. "eta/eta_task/models/data_manage"
  4. "eta/eta_task/services/alarm_msg"
  5. "eta/eta_task/utils"
  6. "fmt"
  7. "sort"
  8. "strconv"
  9. "time"
  10. )
  11. // FixPositionTask 补全缺失的合约, 注意和原先的定时任务区分开来
  12. func FixPositionTask() (err error) {
  13. exchanges := []string{"zhengzhou", "dalian", "shanghai", "cffex", "ine", "guangzhou"} //郑商所,大商所,上期所,中金所,上期能源
  14. //exchanges := []string{"guangzhou"} //郑商所,大商所,上期所,中金所,上期能源
  15. for i := 194; i > 1; i-- {
  16. // 定时任务避开昨日和今日的数据,以免和原先的定时任务InitPositionTask冲突
  17. startDate := time.Now().AddDate(0, 0, -i).Format(utils.FormatDate)
  18. //startDate := "2024-01-08"
  19. endDate := startDate
  20. for _, v := range exchanges {
  21. exchange := v
  22. err = nil
  23. fmt.Println("FixPositionTask: 启动:" + exchange)
  24. utils.FileLog.Info("FixPositionTask: 启动:" + exchange)
  25. fmt.Println("开始" + startDate + "结束" + endDate)
  26. utils.FileLog.Info(fmt.Sprintf("FixPositionTask:开始:%s; 结束:%s", startDate, endDate))
  27. var tradePosition TradePositionInterface
  28. if exchange == "guangzhou" {
  29. tradePosition = &GuangzhouTradePosition{}
  30. } else {
  31. tradePosition = &BaseTradePosition{}
  32. }
  33. tErr, errMsg := InitTradePositionClassify(exchange, startDate, endDate, tradePosition)
  34. if tErr != nil {
  35. err = tErr
  36. fmt.Println("FixPositionTask: 操作失败:" + errMsg + tErr.Error())
  37. utils.FileLog.Info(fmt.Sprintf("InitTradePosition: 操作失败:%s:%s", errMsg, tErr.Error()))
  38. continue
  39. }
  40. fmt.Println("FixPositionTask:" + exchange + "已完成")
  41. utils.FileLog.Info("FixPositionTask:" + exchange + "已完成")
  42. }
  43. }
  44. return
  45. }
  46. // InitTradePositionClassify 持仓分析补全缺失的合约
  47. func InitTradePositionClassify(exchange, startDate, endDate string, tradePosition TradePositionInterface) (err error, errMsg string) {
  48. defer func() {
  49. if err != nil {
  50. tips := fmt.Sprintf("持仓分析-补全缺失的品种数据 操作失败, Exchange: %s, Err: %s, Msg: %s", exchange, err.Error(), errMsg)
  51. utils.FileLog.Info(tips)
  52. alarm_msg.SendAlarmMsg(tips, 3)
  53. }
  54. }()
  55. //判断合约数与数据源是否一致
  56. originClassifyList, tmpErr := tradePosition.GetTradePositionOriginClassifyByExchangeDataTime(exchange, startDate, endDate)
  57. if tmpErr != nil {
  58. err = tmpErr
  59. errMsg = "查询原始数据分类个数失败,GetTradePositionOriginClassifyCountByExchangeDataTime() Err: "
  60. return
  61. }
  62. topClassifyList, tmpErr := data_manage.GetTradePositionTopClassifyByExchangeDataTime(exchange, startDate, endDate)
  63. if tmpErr != nil {
  64. err = tmpErr
  65. errMsg = "查询榜单数据分类个数失败,GetTradePositionTopClassifyCountByExchangeDataTime() Err: "
  66. return
  67. }
  68. if len(originClassifyList) == len(topClassifyList) {
  69. //合约数目一致,无需补全
  70. return
  71. }
  72. if len(originClassifyList) == 0 {
  73. return
  74. }
  75. topClassifyMap := make(map[string][]data_manage.TradePositionClassifyInfo)
  76. for _, v := range topClassifyList {
  77. str := fmt.Sprintf("%s_%s", v.ClassifyName, v.ClassifyType)
  78. topClassifyMap[str] = append(topClassifyMap[str], v)
  79. }
  80. classifyMap := make(map[string]struct{})
  81. classifyNames := make([]string, 0)
  82. classifyTypes := make([]string, 0)
  83. for _, v := range originClassifyList {
  84. str := fmt.Sprintf("%s_%s", v.ClassifyName, v.ClassifyType)
  85. if _, ok := topClassifyMap[str]; !ok {
  86. classifyTypes = append(classifyTypes, v.ClassifyType)
  87. if _, ok1 := classifyMap[v.ClassifyName]; !ok1 {
  88. classifyNames = append(classifyNames, v.ClassifyName)
  89. classifyMap[v.ClassifyName] = struct{}{}
  90. }
  91. }
  92. }
  93. if len(classifyTypes) == 0 {
  94. return
  95. }
  96. //批量导入缺失的合约
  97. err = tradePosition.MultiInsertTradeBaseDataToTopByClassify(exchange, startDate, endDate, classifyNames, classifyTypes)
  98. if err != nil {
  99. errMsg = "新增原始数据失败,MultiInsertTradeBaseDataToTop() Err: "
  100. return
  101. }
  102. originList, err := data_manage.GetTradePositionTopByExchangeDataTimeByClassify(exchange, startDate, endDate, classifyNames, classifyTypes)
  103. if err != nil {
  104. errMsg = "查询原始数据失败, GetTradePositionTopByExchangeDataTime() Err: "
  105. return
  106. }
  107. if len(originList) <= 0 {
  108. // 忽略周末
  109. w := time.Now().Weekday().String()
  110. if w == "Saturday" || w == "Sunday" {
  111. return
  112. }
  113. // 每天最后一个小时执行依旧无数据时, 才进行邮件提示
  114. if time.Now().Hour() != 23 {
  115. return
  116. }
  117. err = fmt.Errorf("原始数据没有值")
  118. return
  119. }
  120. // 原始数据日期
  121. dates, e := tradePosition.GetTradePositionTopOriginDataTimes(exchange)
  122. if e != nil {
  123. err = fmt.Errorf("GetTradePositionTopOriginDataTimes err: %s", e.Error())
  124. return
  125. }
  126. now := time.Now()
  127. dataTimeMap := make(map[string]*data_manage.TradePositionTop)
  128. onlyEmptyMap := make(map[string]bool)
  129. onlyEmptyNameMap := make(map[string]*data_manage.TradePositionTop)
  130. topLastMap := make(map[string]int)
  131. topLastRankMap := make(map[string]int)
  132. list := make([]*data_manage.TradePositionTop, 0)
  133. for _, v := range originList {
  134. tmp0, tmpErr := dealTradeOriginData(dataTimeMap, onlyEmptyMap, onlyEmptyNameMap, v, topLastMap, topLastRankMap, startDate, now, dates)
  135. if tmpErr != nil {
  136. err = tmpErr
  137. errMsg = "处理原始数据失败 dealTradeOriginData() Err: "
  138. return
  139. }
  140. if tmp0 != nil {
  141. list = append(list, tmp0)
  142. }
  143. if len(list) >= 1000 {
  144. err = data_manage.InsertMultiTradePositionTop(exchange, list)
  145. if err != nil {
  146. errMsg = "批量新增昨日数据失败,InsertMultiTradePositionTop() Err: "
  147. return
  148. }
  149. list = make([]*data_manage.TradePositionTop, 0)
  150. }
  151. }
  152. if len(list) > 0 {
  153. err = data_manage.InsertMultiTradePositionTop(exchange, list)
  154. if err != nil {
  155. errMsg = "批量新增昨日数据失败,InsertMultiTradePositionTop() Err: "
  156. return
  157. }
  158. list = make([]*data_manage.TradePositionTop, 0)
  159. }
  160. // 处理某个期货公司只有买单没有卖单,或者只有卖单没有买单的情况
  161. for k, v := range onlyEmptyNameMap {
  162. _, ok1 := onlyEmptyMap[k+"_1"]
  163. _, ok2 := onlyEmptyMap[k+"_2"]
  164. var dealType int
  165. if ok1 && !ok2 {
  166. dealType = 2 //只有买单没有卖单
  167. } else if !ok1 && ok2 {
  168. dealType = 1 //只有卖单没有买单的情况
  169. } else {
  170. continue
  171. }
  172. if dealType > 0 {
  173. str := v.ClassifyName + "_" + v.ClassifyType + "_" + v.DataTime + "_" + strconv.Itoa(dealType)
  174. dealValue := 0
  175. if lastVal, ok := topLastMap[str]; ok {
  176. dealValue = int(float64(lastVal)*0.7 + 0.5)
  177. }
  178. tmp := &data_manage.TradePositionTop{
  179. ClassifyName: v.ClassifyName,
  180. ClassifyType: v.ClassifyType,
  181. DealShortName: v.DealShortName,
  182. DataTime: v.DataTime,
  183. DealValue: dealValue,
  184. CreateTime: now,
  185. ModifyTime: now,
  186. DealType: dealType,
  187. SourceType: 2,
  188. }
  189. list = append(list, tmp)
  190. if len(list) >= 1000 {
  191. err = data_manage.InsertMultiTradePositionTop(exchange, list)
  192. if err != nil {
  193. errMsg = "批量新增前日数据失败,InsertMultiTradePositionTop() Err: "
  194. return
  195. }
  196. list = make([]*data_manage.TradePositionTop, 0)
  197. }
  198. }
  199. }
  200. if len(list) > 0 {
  201. err = data_manage.InsertMultiTradePositionTop(exchange, list)
  202. if err != nil {
  203. errMsg = "批量新增前日数据失败,InsertMultiTradePositionTop() Err: "
  204. return
  205. }
  206. }
  207. //生成净多单,净空单榜单
  208. err = createAnalysisCleanTopClassify(exchange, startDate, endDate, classifyNames, classifyTypes, tradePosition)
  209. if err != nil {
  210. errMsg = "创建净多单,净空单数据失败,createAnalysisCleanTop() Err: "
  211. return
  212. }
  213. err = DealYesterdayDataClassify(exchange, startDate, classifyNames, classifyTypes, tradePosition)
  214. if err != nil {
  215. errMsg = "处理昨日数据失败,DealYesterdayData() Err: "
  216. return
  217. }
  218. return
  219. }
  220. // DealYesterdayDataClassify 更新部分合约的昨日数据
  221. func DealYesterdayDataClassify(exchange, startDate string, classifyNames, classifyTypes []string, tradePosition TradePositionInterface) (err error) {
  222. // 查询最早的日期
  223. firstItem, err := tradePosition.GetFirstBaseFromTradeIndexByDate(exchange)
  224. if err != nil {
  225. return
  226. }
  227. if startDate == firstItem.DataTime { //如果当前是起始日,则无需统计修改前一天的数据
  228. return
  229. }
  230. // 前一个交易日, 前两个交易日
  231. dates, e := tradePosition.GetTradePositionTopOriginDataTimes(exchange)
  232. if e != nil {
  233. err = fmt.Errorf("GetTradePositionTopOriginDataTimes err: %s", e.Error())
  234. return
  235. }
  236. yesterdayStr := getPrevTradeDataDate(startDate, dates)
  237. beforeYesterdayStr := getPrevTradeDataDate(yesterdayStr, dates)
  238. // 先查出T日最原始的数据
  239. originList, err := data_manage.GetTradePositionTopByExchangeDataTimeByClassify(exchange, startDate, startDate, classifyNames, classifyTypes)
  240. if err != nil {
  241. return
  242. }
  243. originBuyMap := make(map[string]*data_manage.TradePositionTop)
  244. originSoldMap := make(map[string]*data_manage.TradePositionTop)
  245. for _, v := range originList {
  246. if v.SourceType != 0 {
  247. continue
  248. }
  249. str := v.ClassifyName + "_" + v.ClassifyType + "_" + v.DealShortName
  250. if v.DealType == 1 {
  251. originBuyMap[str] = v
  252. } else if v.DealType == 2 {
  253. originSoldMap[str] = v
  254. }
  255. }
  256. // 然后查询T-1中数据来源类型是2的数据
  257. changeList, err := data_manage.GetTradePositionTopByExchangeSourceTypeClassify(exchange, yesterdayStr, 2, classifyNames, classifyTypes)
  258. if err != nil {
  259. return
  260. }
  261. if len(changeList) <= 0 {
  262. //err = fmt.Errorf("前天的数据无需修改")
  263. return
  264. }
  265. // 查询出前日的成交量
  266. beforeYesterdayList, err := data_manage.GetTradePositionTopByExchangeDataTimeByClassify(exchange, beforeYesterdayStr, beforeYesterdayStr, classifyNames, classifyTypes)
  267. if err != nil {
  268. return
  269. }
  270. beforeYesterdayMap1 := make(map[string]int)
  271. beforeYesterdayMap2 := make(map[string]int)
  272. if len(beforeYesterdayList) > 0 {
  273. for _, v := range beforeYesterdayList {
  274. if v.SourceType == 2 {
  275. continue
  276. }
  277. str := v.ClassifyName + "_" + v.ClassifyType + "_" + v.DealShortName
  278. if v.DealType == 1 {
  279. beforeYesterdayMap1[str] = v.DealValue
  280. } else if v.DealType == 2 {
  281. beforeYesterdayMap2[str] = v.DealValue
  282. }
  283. }
  284. }
  285. // 根据原始数据中的值推算出最新的值
  286. now := time.Now()
  287. // 批量更新到分析表中,
  288. var updateAnalysisData []data_manage.UpdateDealValueChange
  289. for _, v := range changeList {
  290. str := v.ClassifyName + "_" + v.ClassifyType + "_" + v.DealShortName
  291. dealValue := 0
  292. dealChange := 0
  293. if v.DealType == 1 {
  294. if n, ok := originBuyMap[str]; ok {
  295. dealValue = n.DealValue - n.DealChange
  296. if beforeVal, ok1 := beforeYesterdayMap1[str]; ok1 {
  297. dealChange = dealValue - beforeVal
  298. }
  299. tmp := data_manage.UpdateDealValueChange{
  300. Id: v.Id,
  301. DealValue: dealValue,
  302. DealChange: dealChange,
  303. SourceType: 1,
  304. ModifyTime: now,
  305. }
  306. updateAnalysisData = append(updateAnalysisData, tmp)
  307. }
  308. } else if v.DealType == 2 {
  309. if n, ok := originSoldMap[str]; ok {
  310. dealValue = n.DealValue - n.DealChange
  311. if beforeVal, ok1 := beforeYesterdayMap2[str]; ok1 {
  312. dealChange = dealValue - beforeVal
  313. }
  314. tmp := data_manage.UpdateDealValueChange{
  315. Id: v.Id,
  316. DealValue: dealValue,
  317. DealChange: dealChange,
  318. SourceType: 1,
  319. ModifyTime: now,
  320. }
  321. updateAnalysisData = append(updateAnalysisData, tmp)
  322. }
  323. }
  324. }
  325. if len(updateAnalysisData) > 0 {
  326. err = data_manage.MultiUpdatePositionTop(exchange, updateAnalysisData)
  327. if err != nil {
  328. return
  329. }
  330. //删除T-1日净多单和净空单的榜单
  331. err = data_manage.DeletePositionTopByDataTimeClassify(exchange, yesterdayStr, 3, classifyNames, classifyTypes)
  332. if err != nil {
  333. return
  334. }
  335. err = data_manage.DeletePositionTopByDataTimeClassify(exchange, yesterdayStr, 4, classifyNames, classifyTypes)
  336. if err != nil {
  337. return
  338. }
  339. //重新生成净多单和净空单的榜单
  340. err = createAnalysisCleanTopClassify(exchange, yesterdayStr, yesterdayStr, classifyNames, classifyTypes, tradePosition)
  341. if err != nil {
  342. return
  343. }
  344. //T-1日重新生成净多单和净空单的榜单后,需要更新T日净多单和净空单榜单里的变化量
  345. err = updateAnalysisCleanTopChangeValClassify(exchange, startDate, yesterdayStr, classifyNames, classifyTypes)
  346. if err != nil {
  347. return
  348. }
  349. }
  350. return
  351. }
  352. // createAnalysisCleanTopClassify 生成部分合约的净多单,净空单榜单
  353. func createAnalysisCleanTopClassify(exchange, startDate, endDate string, classifyNames, classifyTypes []string, tradePosition TradePositionInterface) (err error) {
  354. defer func() {
  355. if err != nil {
  356. fmt.Println("createAnalysisCleanTop err: " + err.Error())
  357. }
  358. }()
  359. topList := make([]*data_manage.TradePositionTop, 0)
  360. now := time.Now()
  361. var subDataList data_manage.TradePositionSubList
  362. subChangeMap1 := make(map[string]int) //净多单map
  363. subChangeMap2 := make(map[string]int) //净空单map
  364. // 2023-05-10 此处取前一个交易日, 不一定是昨日
  365. dates, e := tradePosition.GetTradePositionTopOriginDataTimes(exchange)
  366. if e != nil {
  367. err = fmt.Errorf("GetTradePositionTopOriginDataTimes err: %s", e.Error())
  368. return
  369. }
  370. yesterday := getPrevTradeDataDate(startDate, dates)
  371. // 上一个交易日的净多单
  372. yesterdayTopList1, tErr := data_manage.GetTradePositionTopByExchangeDataTimeTypeClassify(exchange, yesterday, 3, classifyNames, classifyTypes)
  373. if tErr != nil {
  374. err = tErr
  375. return
  376. }
  377. if len(yesterdayTopList1) > 0 {
  378. for _, v := range yesterdayTopList1 {
  379. nameStr := v.ClassifyName + "_" + v.ClassifyType + "_" + v.DataTime + "_" + v.DealShortName
  380. subChangeMap1[nameStr] = v.DealValue
  381. }
  382. }
  383. // 上一个交易日的净空单
  384. yesterdayTopList2, tErr := data_manage.GetTradePositionTopByExchangeDataTimeTypeClassify(exchange, yesterday, 4, classifyNames, classifyTypes)
  385. if tErr != nil {
  386. err = tErr
  387. return
  388. }
  389. if len(yesterdayTopList2) > 0 {
  390. for _, v := range yesterdayTopList2 {
  391. nameStr := v.ClassifyName + "_" + v.ClassifyType + "_" + v.DataTime + "_" + v.DealShortName
  392. subChangeMap2[nameStr] = v.DealValue
  393. }
  394. }
  395. // 根据当日多单/空单数据, 生成净多单/净空单数据
  396. originDataList, err := data_manage.GetTradePositionTopByExchangeDataTimeByClassify(exchange, startDate, endDate, classifyNames, classifyTypes)
  397. if err != nil {
  398. return
  399. }
  400. buyDataMap := make(map[string]int)
  401. for _, v := range originDataList {
  402. str := v.ClassifyName + "_" + v.ClassifyType + "_" + v.DataTime + "_" + v.DealShortName
  403. if v.DealType == 1 {
  404. buyDataMap[str] = v.DealValue
  405. } else if v.DealType == 2 {
  406. subValue := 0
  407. dealType := 0
  408. if buy, ok := buyDataMap[str]; ok {
  409. subValue = buy - v.DealValue
  410. if subValue >= 0 {
  411. dealType = 3
  412. } else {
  413. subValue = -subValue
  414. dealType = 4
  415. }
  416. }
  417. tmp := &data_manage.TradePositionSub{
  418. ClassifyName: v.ClassifyName,
  419. ClassifyType: v.ClassifyType,
  420. DataTime: v.DataTime,
  421. DealShortName: v.DealShortName,
  422. SubValue: subValue,
  423. DealType: dealType,
  424. }
  425. subDataList = append(subDataList, tmp)
  426. }
  427. }
  428. if len(subDataList) > 0 {
  429. sort.Sort(subDataList)
  430. }
  431. // 根据净多单/净空单数据, 比对上一个交易日的日期计算成交变化量, 并写入
  432. var dealType int
  433. rankMap := make(map[string]int)
  434. for _, v := range subDataList {
  435. subValue := v.SubValue
  436. nameStr := v.ClassifyName + "_" + v.ClassifyType + "_" + v.DataTime + "_" + v.DealShortName
  437. if v.DealType == 3 {
  438. subChangeMap1[nameStr] = subValue
  439. dealType = 3
  440. if _, ok := rankMap[v.ClassifyName+"_"+v.ClassifyType+"_"+v.DataTime+"_3"]; !ok {
  441. rankMap[v.ClassifyName+"_"+v.ClassifyType+"_"+v.DataTime+"_3"] = 1
  442. } else {
  443. rankMap[v.ClassifyName+"_"+v.ClassifyType+"_"+v.DataTime+"_3"]++
  444. }
  445. } else if v.DealType == 4 {
  446. subChangeMap2[nameStr] = subValue
  447. dealType = 4
  448. if _, ok := rankMap[v.ClassifyName+"_"+v.ClassifyType+"_"+v.DataTime+"_4"]; !ok {
  449. rankMap[v.ClassifyName+"_"+v.ClassifyType+"_"+v.DataTime+"_4"] = 1
  450. } else {
  451. rankMap[v.ClassifyName+"_"+v.ClassifyType+"_"+v.DataTime+"_4"]++
  452. }
  453. }
  454. // 2023-05-10 目前看该方法的引用startDate和endDate其实是同一天, 所以前一个交易日直接用上面的yesterday
  455. tmpTimeStr := yesterday
  456. //和T-1日比较差值
  457. //var tmpTimeStr string
  458. //tmpTimeStr, err = getYesterdayDate(v.DataTime)
  459. //if err != nil {
  460. // return
  461. //}
  462. yesterdayStr := v.ClassifyName + "_" + v.ClassifyType + "_" + tmpTimeStr + "_" + v.DealShortName
  463. dealChange := 0
  464. if dealType == 3 {
  465. if c, ok := subChangeMap1[yesterdayStr]; ok {
  466. dealChange = subValue - c
  467. }
  468. } else if dealType == 4 {
  469. if c, ok := subChangeMap2[yesterdayStr]; ok {
  470. dealChange = subValue - c
  471. }
  472. }
  473. tmp := &data_manage.TradePositionTop{
  474. ClassifyName: v.ClassifyName,
  475. ClassifyType: v.ClassifyType,
  476. DataTime: v.DataTime,
  477. CreateTime: now,
  478. ModifyTime: now,
  479. DealShortName: v.DealShortName,
  480. DealValue: subValue,
  481. DealChange: dealChange,
  482. DealType: dealType,
  483. Rank: rankMap[v.ClassifyName+"_"+v.ClassifyType+"_"+v.DataTime+"_"+strconv.Itoa(dealType)],
  484. }
  485. topList = append(topList, tmp)
  486. if len(topList) >= 1000 {
  487. err = data_manage.InsertMultiTradePositionTop(exchange, topList)
  488. if err != nil {
  489. return
  490. }
  491. topList = make([]*data_manage.TradePositionTop, 0)
  492. }
  493. }
  494. if len(topList) >= 0 {
  495. err = data_manage.InsertMultiTradePositionTop(exchange, topList)
  496. if err != nil {
  497. return
  498. }
  499. }
  500. return
  501. }
  502. // updateAnalysisCleanTopChangeValClassify T-1日重新生成净多单和净空单的榜单后,需要更新T日净多单和净空单榜单里的变化量
  503. func updateAnalysisCleanTopChangeValClassify(exchange, startDate, yesterday string, classifyNames, classifyTypes []string) (err error) {
  504. defer func() {
  505. if err != nil {
  506. fmt.Println("updateAnalysisCleanTopChangeVal err: " + err.Error())
  507. }
  508. }()
  509. //查询T日的净多单和净空单榜单列表
  510. //查询T-1日的净多单和净空单列表
  511. //组装数据,计算T日与T-1日的变更值
  512. //更新变更值
  513. topList := make([]*data_manage.TradePositionTop, 0) //T日和T+1日列表
  514. todayTopList := make([]*data_manage.TradePositionTop, 0) //T日列表
  515. yesterdayTopListMap := make(map[string]int) //净多单净空单持仓量map
  516. // 查询T日和T-1日的净多单和净空单列表
  517. topList, err = data_manage.GetTradePositionTopCleanByExchangeDataTimeClassify(exchange, yesterday, startDate, classifyNames, classifyTypes)
  518. if err != nil {
  519. return
  520. }
  521. if len(topList) == 0 {
  522. return
  523. }
  524. for _, v := range topList {
  525. if v.DataTime == startDate {
  526. todayTopList = append(todayTopList, v)
  527. } else if v.DataTime == yesterday {
  528. nameStr := v.ClassifyName + "_" + v.ClassifyType + "_" + v.DataTime + "_" + v.DealShortName + "_" + strconv.Itoa(v.DealType)
  529. yesterdayTopListMap[nameStr] = v.DealValue
  530. }
  531. }
  532. if len(todayTopList) == 0 {
  533. return
  534. }
  535. // 根据净多单/净空单数据, 比对上一个交易日的日期计算成交变化量, 并写入
  536. now := time.Now()
  537. updateList := make([]data_manage.UpdateChangeVal, 0)
  538. for _, v := range todayTopList {
  539. //T日值-T-1日值
  540. yesterdayStr := v.ClassifyName + "_" + v.ClassifyType + "_" + yesterday + "_" + v.DealShortName + "_" + strconv.Itoa(v.DealType)
  541. dealChange := 0
  542. if c, ok := yesterdayTopListMap[yesterdayStr]; ok {
  543. dealChange = v.DealValue - c
  544. }
  545. if dealChange != v.DealChange {
  546. tmp := data_manage.UpdateChangeVal{
  547. Id: v.Id,
  548. ModifyTime: now,
  549. DealChange: dealChange,
  550. }
  551. updateList = append(updateList, tmp)
  552. }
  553. }
  554. if len(updateList) > 0 {
  555. err = data_manage.MultiUpdatePositionTopChangeVal(exchange, updateList)
  556. if err != nil {
  557. return
  558. }
  559. }
  560. return
  561. }