trade_analysis_data.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480
  1. package trade_analysis
  2. import (
  3. "eta/eta_index_lib/models"
  4. tradeAnalysisModel "eta/eta_index_lib/models/trade_analysis"
  5. "eta/eta_index_lib/utils"
  6. "fmt"
  7. "sort"
  8. "strings"
  9. "time"
  10. )
  11. // FormatCompanyTradeData2EdbData [公司-合约加总]转为指标数据
  12. func FormatCompanyTradeData2EdbData(companyTradeData *tradeAnalysisModel.ContractCompanyTradeData, tradeType int) (edbData []*models.EdbDataList, err error) {
  13. if companyTradeData == nil {
  14. err = fmt.Errorf("持仓数据异常")
  15. return
  16. }
  17. edbData = make([]*models.EdbDataList, 0)
  18. var minData, maxData float64
  19. for dk, dv := range companyTradeData.DataList {
  20. // 交易方向
  21. var val float64
  22. if tradeType == tradeAnalysisModel.WarehouseBuyChartType {
  23. if dv.BuyValType == tradeAnalysisModel.TradeDataTypeNull {
  24. continue
  25. }
  26. val = float64(dv.BuyVal)
  27. }
  28. if tradeType == tradeAnalysisModel.WarehouseSoldChartType {
  29. if dv.SoldValType == tradeAnalysisModel.TradeDataTypeNull {
  30. continue
  31. }
  32. val = float64(dv.SoldVal)
  33. }
  34. if tradeType == tradeAnalysisModel.WarehousePureBuyChartType {
  35. if dv.PureBuyValType == tradeAnalysisModel.TradeDataTypeNull {
  36. continue
  37. }
  38. val = float64(dv.PureBuyVal)
  39. }
  40. if dk == 0 {
  41. minData = val
  42. maxData = val
  43. }
  44. if val < minData {
  45. minData = val
  46. }
  47. if val > maxData {
  48. maxData = val
  49. }
  50. edbData = append(edbData, &models.EdbDataList{
  51. DataTime: dv.Date.Format(utils.FormatDate),
  52. DataTimestamp: dv.Date.UnixNano() / 1e6,
  53. Value: val,
  54. })
  55. }
  56. return
  57. }
  58. func GetOriginTradeData(exchange, classifyName string, contracts, companies []string, predictRatio float64) (companyTradeData []*tradeAnalysisModel.ContractCompanyTradeData, err error) {
  59. // 各原始数据表期货公司名称不一致
  60. companyMap := make(map[string]string)
  61. {
  62. ob := new(tradeAnalysisModel.TradeFuturesCompany)
  63. list, e := ob.GetItemsByCondition(``, make([]interface{}, 0), []string{}, "")
  64. if e != nil {
  65. err = fmt.Errorf("获取期货公司名称失败: %v", e)
  66. return
  67. }
  68. switch exchange {
  69. case "zhengzhou":
  70. for _, v := range list {
  71. companyMap[v.CompanyName] = v.ZhengzhouName
  72. }
  73. case "dalian":
  74. for _, v := range list {
  75. companyMap[v.CompanyName] = v.DalianName
  76. }
  77. case "shanghai":
  78. for _, v := range list {
  79. companyMap[v.CompanyName] = v.ShanghaiName
  80. }
  81. case "cffex":
  82. for _, v := range list {
  83. companyMap[v.CompanyName] = v.CffexName
  84. }
  85. case "ine":
  86. for _, v := range list {
  87. companyMap[v.CompanyName] = v.IneName
  88. }
  89. case "guangzhou":
  90. for _, v := range list {
  91. companyMap[v.CompanyName] = v.GuangzhouName
  92. }
  93. }
  94. }
  95. var queryCompanies []string
  96. for _, v := range companies {
  97. if v == tradeAnalysisModel.TradeFuturesCompanyTop20 {
  98. queryCompanies = append(queryCompanies, tradeAnalysisModel.TradeFuturesCompanyTop20)
  99. continue
  100. }
  101. companyName, ok := companyMap[v]
  102. if !ok {
  103. utils.FileLog.Info(fmt.Sprintf("交易所%s公司名称映射不存在: %s", exchange, v))
  104. continue
  105. }
  106. queryCompanies = append(queryCompanies, companyName)
  107. }
  108. // 郑商所/广期所查询方式不一样
  109. var tradeAnalysis TradeAnalysisInterface
  110. switch exchange {
  111. case tradeAnalysisModel.TradeExchangeZhengzhou:
  112. tradeAnalysis = &ZhengzhouTradeAnalysis{}
  113. case tradeAnalysisModel.TradeExchangeGuangzhou:
  114. tradeAnalysis = &GuangzhouTradeAnalysis{}
  115. default:
  116. tradeAnalysis = &BaseTradeAnalysis{}
  117. }
  118. // 获取多单/空单原始数据
  119. originList, e := tradeAnalysis.GetTradeDataByClassifyAndCompany(exchange, classifyName, contracts, queryCompanies)
  120. if e != nil {
  121. err = fmt.Errorf("获取多空单原始数据失败, %v", e)
  122. return
  123. }
  124. keyItems := make(map[string]*tradeAnalysisModel.ContractCompanyTradeData)
  125. keyDateData := make(map[string]*tradeAnalysisModel.ContractCompanyTradeDataList)
  126. keyDateDataExist := make(map[string]bool)
  127. for _, v := range originList {
  128. // Rank999和0对应的是TOP20
  129. companyName := v.CompanyName
  130. if v.Rank == 999 || v.Rank == 0 {
  131. companyName = tradeAnalysisModel.TradeFuturesCompanyTop20
  132. }
  133. k := fmt.Sprintf("%s-%s", v.ClassifyType, companyName)
  134. if keyItems[k] == nil {
  135. keyItems[k] = new(tradeAnalysisModel.ContractCompanyTradeData)
  136. keyItems[k].CompanyName = companyName
  137. keyItems[k].ClassifyType = v.ClassifyType
  138. keyItems[k].DataList = make([]*tradeAnalysisModel.ContractCompanyTradeDataList, 0)
  139. }
  140. kd := fmt.Sprintf("%s-%s", k, v.DataTime.Format(utils.FormatDate))
  141. if keyDateData[kd] == nil {
  142. keyDateData[kd] = new(tradeAnalysisModel.ContractCompanyTradeDataList)
  143. keyDateData[kd].Date = v.DataTime
  144. }
  145. if v.ValType == 1 {
  146. keyDateData[kd].BuyVal = v.Val
  147. keyDateData[kd].BuyValType = tradeAnalysisModel.TradeDataTypeOrigin
  148. keyDateData[kd].BuyChange = v.ValChange
  149. keyDateData[kd].BuyChangeType = tradeAnalysisModel.TradeDataTypeOrigin
  150. }
  151. if v.ValType == 2 {
  152. keyDateData[kd].SoldVal = v.Val
  153. keyDateData[kd].SoldValType = tradeAnalysisModel.TradeDataTypeOrigin
  154. keyDateData[kd].SoldChange = v.ValChange
  155. keyDateData[kd].SoldChangeType = tradeAnalysisModel.TradeDataTypeOrigin
  156. }
  157. if !keyDateDataExist[kd] {
  158. keyItems[k].DataList = append(keyItems[k].DataList, keyDateData[kd])
  159. keyDateDataExist[kd] = true
  160. }
  161. }
  162. // 获取[合约]每日的末位多空单
  163. contractLastBuyDateVal := make(map[string]map[time.Time]int)
  164. contractLastSoldDateVal := make(map[string]map[time.Time]int)
  165. {
  166. lastOriginList, e := tradeAnalysis.GetLastTradeDataByClassify(exchange, classifyName, contracts)
  167. if e != nil {
  168. err = fmt.Errorf("获取末位多空单原始数据失败, %v", e)
  169. return
  170. }
  171. for _, v := range lastOriginList {
  172. if v.ValType == 1 {
  173. if contractLastBuyDateVal[v.ClassifyType] == nil {
  174. contractLastBuyDateVal[v.ClassifyType] = make(map[time.Time]int)
  175. }
  176. contractLastBuyDateVal[v.ClassifyType][v.DataTime] = v.Val
  177. continue
  178. }
  179. if contractLastSoldDateVal[v.ClassifyType] == nil {
  180. contractLastSoldDateVal[v.ClassifyType] = make(map[time.Time]int)
  181. }
  182. contractLastSoldDateVal[v.ClassifyType][v.DataTime] = v.Val
  183. }
  184. }
  185. // 填充[合约-公司]预估数据, 并根据[公司-多合约]分组, [公司]算作一个指标, 指标值为[多个合约]的计算加总
  186. companyContracts := make(map[string][]*tradeAnalysisModel.ContractCompanyTradeData)
  187. for _, v := range keyItems {
  188. td, fd, ed, e := PredictingTradeData(v.DataList, contractLastBuyDateVal[v.ClassifyType], contractLastSoldDateVal[v.ClassifyType], predictRatio)
  189. if e != nil {
  190. err = fmt.Errorf("数据补全失败, %v", e)
  191. return
  192. }
  193. v.DataList = td
  194. v.StartDate = fd
  195. v.EndDate = ed
  196. if companyContracts[v.CompanyName] == nil {
  197. companyContracts[v.CompanyName] = make([]*tradeAnalysisModel.ContractCompanyTradeData, 0)
  198. }
  199. companyContracts[v.CompanyName] = append(companyContracts[v.CompanyName], v)
  200. }
  201. // 以[公司]为组, 计算合约加总
  202. mussyTradeData := make(map[string]*tradeAnalysisModel.ContractCompanyTradeData)
  203. for k, v := range companyContracts {
  204. companyData := new(tradeAnalysisModel.ContractCompanyTradeData)
  205. companyData.CompanyName = k
  206. companyData.DataList = make([]*tradeAnalysisModel.ContractCompanyTradeDataList, 0)
  207. contractArr := make([]string, 0)
  208. // 合约加总
  209. sumDateData := make(map[time.Time]*tradeAnalysisModel.ContractCompanyTradeDataList)
  210. for _, vv := range v {
  211. contractArr = append(contractArr, vv.ClassifyType)
  212. for _, dv := range vv.DataList {
  213. if sumDateData[dv.Date] == nil {
  214. sumDateData[dv.Date] = new(tradeAnalysisModel.ContractCompanyTradeDataList)
  215. sumDateData[dv.Date].Date = dv.Date
  216. }
  217. // 数据类型以第一个非零值为准, 只处理多空和净多, 变化就不管了
  218. if sumDateData[dv.Date].BuyValType == tradeAnalysisModel.TradeDataTypeNull && dv.BuyValType > tradeAnalysisModel.TradeDataTypeNull {
  219. sumDateData[dv.Date].BuyValType = dv.BuyValType
  220. }
  221. if sumDateData[dv.Date].BuyValType == tradeAnalysisModel.TradeDataTypeOrigin && dv.BuyValType == tradeAnalysisModel.TradeDataTypeCalculate {
  222. sumDateData[dv.Date].BuyValType = dv.BuyValType
  223. }
  224. if dv.BuyValType > tradeAnalysisModel.TradeDataTypeNull {
  225. sumDateData[dv.Date].BuyVal += dv.BuyVal
  226. }
  227. // 空单
  228. if sumDateData[dv.Date].SoldValType == tradeAnalysisModel.TradeDataTypeNull && dv.SoldValType > tradeAnalysisModel.TradeDataTypeNull {
  229. sumDateData[dv.Date].SoldValType = dv.SoldValType
  230. }
  231. if sumDateData[dv.Date].SoldValType == tradeAnalysisModel.TradeDataTypeOrigin && dv.SoldValType == tradeAnalysisModel.TradeDataTypeCalculate {
  232. sumDateData[dv.Date].SoldValType = dv.SoldValType
  233. }
  234. if dv.SoldValType > tradeAnalysisModel.TradeDataTypeNull {
  235. sumDateData[dv.Date].SoldVal += dv.SoldVal
  236. }
  237. // 净多单
  238. if sumDateData[dv.Date].PureBuyValType == tradeAnalysisModel.TradeDataTypeNull && dv.PureBuyValType > tradeAnalysisModel.TradeDataTypeNull {
  239. sumDateData[dv.Date].PureBuyValType = dv.PureBuyValType
  240. }
  241. if sumDateData[dv.Date].PureBuyValType == tradeAnalysisModel.TradeDataTypeOrigin && dv.PureBuyValType == tradeAnalysisModel.TradeDataTypeCalculate {
  242. sumDateData[dv.Date].PureBuyValType = dv.PureBuyValType
  243. }
  244. if dv.PureBuyValType > tradeAnalysisModel.TradeDataTypeNull {
  245. sumDateData[dv.Date].PureBuyVal += dv.PureBuyVal
  246. }
  247. }
  248. // 多个合约比对开始结束时间
  249. if companyData.StartDate.IsZero() {
  250. companyData.StartDate = vv.StartDate
  251. }
  252. if vv.StartDate.Before(companyData.StartDate) {
  253. companyData.StartDate = vv.StartDate
  254. }
  255. if companyData.EndDate.IsZero() {
  256. companyData.EndDate = vv.EndDate
  257. }
  258. if vv.EndDate.Before(companyData.EndDate) {
  259. companyData.EndDate = vv.EndDate
  260. }
  261. }
  262. for _, sv := range sumDateData {
  263. companyData.DataList = append(companyData.DataList, sv)
  264. }
  265. sort.Slice(companyData.DataList, func(i, j int) bool {
  266. return companyData.DataList[i].Date.Before(companyData.DataList[j].Date)
  267. })
  268. companyData.ClassifyType = strings.Join(contractArr, ",")
  269. mussyTradeData[k] = companyData
  270. }
  271. // 数据根据公司排序, 不然会随机乱
  272. companyTradeData = make([]*tradeAnalysisModel.ContractCompanyTradeData, 0)
  273. for _, v := range companies {
  274. // 没数据也需要加进去, 不然edbList会少
  275. if mussyTradeData[v] == nil {
  276. companyData := new(tradeAnalysisModel.ContractCompanyTradeData)
  277. companyData.CompanyName = v
  278. companyData.DataList = make([]*tradeAnalysisModel.ContractCompanyTradeDataList, 0)
  279. companyTradeData = append(companyTradeData, companyData)
  280. continue
  281. }
  282. companyTradeData = append(companyTradeData, mussyTradeData[v])
  283. }
  284. return
  285. }
  286. // PredictingTradeData 根据数据库中的多空数据填充预估数据
  287. func PredictingTradeData(originData []*tradeAnalysisModel.ContractCompanyTradeDataList, lastBuyDateVal, lastSoldDateVal map[time.Time]int, predictRatio float64) (newData []*tradeAnalysisModel.ContractCompanyTradeDataList, firstDate, endDate time.Time, err error) {
  288. if len(originData) == 0 {
  289. return
  290. }
  291. if predictRatio < 0 || predictRatio > 1 {
  292. err = fmt.Errorf("估计参数不在0-1之间")
  293. return
  294. }
  295. sort.Slice(originData, func(i, j int) bool {
  296. return originData[i].Date.Before(originData[j].Date)
  297. })
  298. dateVal := make(map[time.Time]*tradeAnalysisModel.ContractCompanyTradeDataList)
  299. for _, v := range originData {
  300. dateVal[v.Date] = v
  301. }
  302. // 生成开始日期-1d(可能会往前面推算一天)至结束日期间的交易日, 以交易日为时间序列遍历
  303. tradeDays := utils.GetTradingDays(originData[0].Date.AddDate(0, 0, -1), originData[len(originData)-1].Date)
  304. for k, v := range tradeDays {
  305. // T日多空均无的情况
  306. //bothLast := false
  307. if dateVal[v] == nil {
  308. // T-1和T+1[原始数据]均无值, 那么T日无数据
  309. hasPrev, hasNext := false, false
  310. if k-1 >= 0 {
  311. hasPrev = true
  312. }
  313. if k+1 <= len(tradeDays)-1 {
  314. hasNext = true
  315. }
  316. if !hasPrev && !hasNext {
  317. continue
  318. }
  319. // T+1有值, 优先从T+1推, 然后继续走下面计算净多单的逻辑
  320. if hasNext {
  321. nextDay := tradeDays[k+1]
  322. if dateVal[nextDay] != nil {
  323. // T+1有多/空及多空变化, 且是原始数据, 那么推出数据并在map中新加一日数据
  324. if dateVal[nextDay].BuyValType == tradeAnalysisModel.TradeDataTypeOrigin && dateVal[nextDay].BuyChangeType == tradeAnalysisModel.TradeDataTypeOrigin {
  325. if _, ok := dateVal[v]; !ok {
  326. dateVal[v] = new(tradeAnalysisModel.ContractCompanyTradeDataList)
  327. dateVal[v].Date = v
  328. }
  329. dateVal[v].BuyVal = dateVal[nextDay].BuyVal - dateVal[nextDay].BuyChange
  330. dateVal[v].BuyValType = tradeAnalysisModel.TradeDataTypeOrigin
  331. }
  332. if dateVal[nextDay].SoldValType == tradeAnalysisModel.TradeDataTypeOrigin && dateVal[nextDay].SoldChangeType == tradeAnalysisModel.TradeDataTypeOrigin {
  333. if _, ok := dateVal[v]; !ok {
  334. dateVal[v] = new(tradeAnalysisModel.ContractCompanyTradeDataList)
  335. dateVal[v].Date = v
  336. }
  337. dateVal[v].SoldVal = dateVal[nextDay].SoldVal - dateVal[nextDay].SoldChange
  338. dateVal[v].SoldValType = tradeAnalysisModel.TradeDataTypeOrigin
  339. }
  340. }
  341. }
  342. // T+1没推出来而T-1有值, 那么T多空均取末位, 计算净多单
  343. _, has := dateVal[v]
  344. if hasPrev && !has {
  345. sv, sok := lastSoldDateVal[v]
  346. bv, bok := lastBuyDateVal[v]
  347. if !sok && !bok {
  348. continue
  349. }
  350. dateVal[v] = new(tradeAnalysisModel.ContractCompanyTradeDataList)
  351. dateVal[v].Date = v
  352. if sok {
  353. dateVal[v].SoldVal = int(predictRatio*float64(sv) + 0.5)
  354. dateVal[v].SoldValType = tradeAnalysisModel.TradeDataTypeCalculate
  355. }
  356. if bok {
  357. dateVal[v].BuyVal = int(predictRatio*float64(bv) + 0.5)
  358. dateVal[v].BuyValType = tradeAnalysisModel.TradeDataTypeCalculate
  359. }
  360. if dateVal[v].BuyValType > tradeAnalysisModel.TradeDataTypeNull && dateVal[v].SoldValType > tradeAnalysisModel.TradeDataTypeNull {
  361. dateVal[v].PureBuyVal = dateVal[v].BuyVal - dateVal[v].SoldVal
  362. dateVal[v].PureBuyValType = tradeAnalysisModel.TradeDataTypeCalculate
  363. }
  364. continue
  365. }
  366. }
  367. // 多空均有的情况下计算净多单
  368. if dateVal[v].BuyValType == tradeAnalysisModel.TradeDataTypeOrigin && dateVal[v].SoldValType == tradeAnalysisModel.TradeDataTypeOrigin {
  369. dateVal[v].PureBuyVal = dateVal[v].BuyVal - dateVal[v].SoldVal
  370. dateVal[v].PureBuyValType = tradeAnalysisModel.TradeDataTypeOrigin // 原始值算出来的也作原始值
  371. }
  372. // 仅有多单, 空单取末位, 计算净多单
  373. if dateVal[v].BuyValType == tradeAnalysisModel.TradeDataTypeOrigin && dateVal[v].SoldValType == tradeAnalysisModel.TradeDataTypeNull {
  374. if sv, ok := lastSoldDateVal[v]; ok {
  375. dateVal[v].SoldVal = int(predictRatio*float64(sv) + 0.5) // 估计参数*末位值, 向上取整
  376. dateVal[v].SoldValType = tradeAnalysisModel.TradeDataTypeCalculate
  377. dateVal[v].PureBuyVal = dateVal[v].BuyVal - dateVal[v].SoldVal
  378. dateVal[v].PureBuyValType = tradeAnalysisModel.TradeDataTypeCalculate
  379. }
  380. }
  381. // 仅有空单, 多单取末位, 计算净多单
  382. if dateVal[v].SoldValType == tradeAnalysisModel.TradeDataTypeOrigin && dateVal[v].BuyValType == tradeAnalysisModel.TradeDataTypeNull {
  383. if sv, ok := lastBuyDateVal[v]; ok {
  384. dateVal[v].BuyVal = int(predictRatio*float64(sv) + 0.5)
  385. dateVal[v].BuyValType = tradeAnalysisModel.TradeDataTypeCalculate
  386. dateVal[v].PureBuyVal = dateVal[v].BuyVal - dateVal[v].SoldVal
  387. dateVal[v].PureBuyValType = tradeAnalysisModel.TradeDataTypeCalculate
  388. }
  389. }
  390. }
  391. // 二次遍历, 计算与T-1的变化值
  392. for k, v := range tradeDays {
  393. // 无T/T-1数据, 忽略
  394. if dateVal[v] == nil {
  395. continue
  396. }
  397. if k-1 < 0 {
  398. continue
  399. }
  400. beforeDay := tradeDays[k-1]
  401. if dateVal[beforeDay] == nil {
  402. continue
  403. }
  404. // 多单变化
  405. if dateVal[v].BuyChangeType == tradeAnalysisModel.TradeDataTypeNull {
  406. if dateVal[v].BuyValType > tradeAnalysisModel.TradeDataTypeNull && dateVal[beforeDay].BuyValType > tradeAnalysisModel.TradeDataTypeNull {
  407. dateVal[v].BuyChange = dateVal[v].BuyVal - dateVal[beforeDay].BuyVal
  408. // 如果当日多单或者前日多单是估计值, 那么多单变化也为估计值
  409. if dateVal[v].BuyValType == tradeAnalysisModel.TradeDataTypeCalculate || dateVal[beforeDay].BuyValType == tradeAnalysisModel.TradeDataTypeCalculate {
  410. dateVal[v].BuyChangeType = tradeAnalysisModel.TradeDataTypeCalculate
  411. }
  412. }
  413. }
  414. // 空单变化
  415. if dateVal[v].SoldChangeType == tradeAnalysisModel.TradeDataTypeNull {
  416. if dateVal[v].SoldValType > tradeAnalysisModel.TradeDataTypeNull && dateVal[beforeDay].SoldValType > tradeAnalysisModel.TradeDataTypeNull {
  417. dateVal[v].SoldChange = dateVal[v].SoldVal - dateVal[beforeDay].SoldVal
  418. // 如果当日空单或者前日空单是估计值, 那么空单变化也为估计值
  419. if dateVal[v].SoldValType == tradeAnalysisModel.TradeDataTypeCalculate || dateVal[beforeDay].SoldValType == tradeAnalysisModel.TradeDataTypeCalculate {
  420. dateVal[v].SoldChangeType = tradeAnalysisModel.TradeDataTypeCalculate
  421. }
  422. }
  423. }
  424. // 净多变化
  425. if dateVal[v].PureBuyChangeType == tradeAnalysisModel.TradeDataTypeNull {
  426. if dateVal[v].PureBuyValType > tradeAnalysisModel.TradeDataTypeNull && dateVal[beforeDay].PureBuyValType > tradeAnalysisModel.TradeDataTypeNull {
  427. dateVal[v].PureBuyChange = dateVal[v].PureBuyVal - dateVal[beforeDay].PureBuyVal
  428. dateVal[v].PureBuyChangeType = tradeAnalysisModel.TradeDataTypeOrigin
  429. // 如果当日净多单或者前日净多单是估计值, 那么净多单变化也为估计值
  430. if dateVal[v].PureBuyValType == tradeAnalysisModel.TradeDataTypeCalculate || dateVal[beforeDay].PureBuyValType == tradeAnalysisModel.TradeDataTypeCalculate {
  431. dateVal[v].PureBuyChangeType = tradeAnalysisModel.TradeDataTypeCalculate
  432. }
  433. }
  434. }
  435. }
  436. // 重新遍历map, 生成数据序列并排序
  437. newData = make([]*tradeAnalysisModel.ContractCompanyTradeDataList, 0)
  438. for _, v := range dateVal {
  439. if v.BuyValType == tradeAnalysisModel.TradeDataTypeNull && v.SoldValType == tradeAnalysisModel.TradeDataTypeNull {
  440. continue
  441. }
  442. newData = append(newData, v)
  443. }
  444. sort.Slice(newData, func(i, j int) bool {
  445. return newData[i].Date.Before(newData[j].Date)
  446. })
  447. if len(newData) > 0 {
  448. firstDate = newData[0].Date
  449. endDate = newData[len(newData)-1].Date
  450. }
  451. return
  452. }