trade_analysis_data.go 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019
  1. package trade_analysis
  2. import (
  3. "eta/eta_api/models/data_manage"
  4. tradeAnalysisModel "eta/eta_api/models/data_manage/trade_analysis"
  5. "eta/eta_api/services/data"
  6. "eta/eta_api/utils"
  7. "fmt"
  8. "sort"
  9. "strings"
  10. "time"
  11. )
  12. // FormatCompanyTradeData2EdbMappings [公司-合约加总]转为指标数据
  13. func FormatCompanyTradeData2EdbMappings(companyTradeData []*tradeAnalysisModel.ContractCompanyTradeData, tradeType, dateType, dateTypeNum int, startDate, endDate string, chartEdbList []*data_manage.ChartSaveItem) (edbMappings []*data_manage.ChartEdbInfoMapping, chartName string, err error) {
  14. edbMappings = make([]*data_manage.ChartEdbInfoMapping, 0)
  15. if dateType <= 0 {
  16. dateType = utils.DateTypeOneMonth
  17. }
  18. // 期货公司名称作为标识进行匹配
  19. edbMap := make(map[string]*data_manage.ChartSaveItem)
  20. if len(chartEdbList) > 0 {
  21. for _, v := range chartEdbList {
  22. edbMap[v.UniqueFlag] = v
  23. }
  24. }
  25. for k, v := range companyTradeData {
  26. mapping := new(data_manage.ChartEdbInfoMapping)
  27. mapping.EdbName = v.CompanyName
  28. mapping.EdbNameEn = v.CompanyName
  29. mapping.EdbAliasName = v.CompanyName
  30. mapping.EdbAliasNameEn = v.CompanyName
  31. mapping.Frequency = "日度"
  32. mapping.FrequencyEn = data.GetFrequencyEn(mapping.Frequency)
  33. mapping.SourceName = utils.SourceNameTradeAnalysis
  34. mapping.Source = utils.CHART_SOURCE_TRADE_ANALYSIS_PROCESS
  35. mapping.IsAxis = 1
  36. mapping.EdbInfoType = 1
  37. mapping.StartDate = v.StartDate.Format(utils.FormatDate)
  38. mapping.EndDate = v.EndDate.Format(utils.FormatDate)
  39. mapping.ConvertUnit = tradeAnalysisModel.WarehouseDefaultUnit // 固定单位
  40. mapping.UniqueFlag = v.CompanyName // 期货公司名称作为每条曲线的唯一标识
  41. // 有配置那么取配置中的图例名称和左右轴
  42. edbConf := edbMap[mapping.UniqueFlag]
  43. if edbConf != nil {
  44. mapping.EdbName = edbConf.EdbAliasName
  45. mapping.EdbNameEn = edbConf.EdbAliasName
  46. mapping.EdbAliasName = edbConf.EdbAliasName
  47. mapping.EdbAliasNameEn = edbConf.EdbAliasName
  48. mapping.IsAxis = edbConf.IsAxis
  49. }
  50. // 根据参数取日期范围
  51. var startTime, endTime time.Time
  52. if dateType > 0 {
  53. st, ed := utils.GetDateByDateTypeV2(dateType, startDate, endDate, dateTypeNum, time.Time{})
  54. if st != "" {
  55. startTime, _ = time.ParseInLocation(utils.FormatDate, st, time.Local)
  56. }
  57. if startTime.IsZero() {
  58. startTime = v.StartDate
  59. }
  60. if ed != "" {
  61. endTime, _ = time.ParseInLocation(utils.FormatDate, ed, time.Local)
  62. }
  63. if endTime.IsZero() {
  64. endTime = time.Now()
  65. }
  66. }
  67. // 指标数据和最值
  68. edbData := make([]*data_manage.EdbDataList, 0)
  69. var minData, maxData float64
  70. var setMinMax bool
  71. for _, dv := range v.DataList {
  72. if dv.Date.Before(startTime) || dv.Date.After(endTime) {
  73. continue
  74. }
  75. // 交易方向
  76. var (
  77. val float64
  78. hasVal bool
  79. )
  80. if tradeType == tradeAnalysisModel.WarehouseBuyChartType {
  81. if dv.BuyValType == tradeAnalysisModel.TradeDataTypeNull {
  82. continue
  83. }
  84. hasVal = true
  85. val = float64(dv.BuyVal)
  86. }
  87. if tradeType == tradeAnalysisModel.WarehouseSoldChartType {
  88. if dv.SoldValType == tradeAnalysisModel.TradeDataTypeNull {
  89. continue
  90. }
  91. hasVal = true
  92. val = float64(dv.SoldVal)
  93. }
  94. if tradeType == tradeAnalysisModel.WarehousePureBuyChartType {
  95. if dv.PureBuyValType == tradeAnalysisModel.TradeDataTypeNull {
  96. continue
  97. }
  98. hasVal = true
  99. val = float64(dv.PureBuyVal)
  100. }
  101. if !hasVal {
  102. continue
  103. }
  104. if !setMinMax {
  105. minData = val
  106. maxData = val
  107. setMinMax = true
  108. }
  109. if val < minData {
  110. minData = val
  111. }
  112. if val > maxData {
  113. maxData = val
  114. }
  115. edbData = append(edbData, &data_manage.EdbDataList{
  116. DataTime: dv.Date.Format(utils.FormatDate),
  117. DataTimestamp: dv.Date.UnixNano() / 1e6,
  118. Value: val,
  119. })
  120. }
  121. mapping.MinData = minData
  122. mapping.MaxData = maxData
  123. mapping.DataList = edbData
  124. edbMappings = append(edbMappings, mapping)
  125. // 图表默认名称
  126. if k == 0 {
  127. chartName += strings.ReplaceAll(v.ClassifyType, ",", "")
  128. }
  129. chartName += v.CompanyName
  130. }
  131. // 图表名称后缀
  132. chartName += tradeAnalysisModel.WarehouseTypeSuffixNames[tradeType]
  133. return
  134. }
  135. func GetWarehouseTradeData(exchange, classifyName string, contracts, companies []string, predictRatio float64) (companyTradeData []*tradeAnalysisModel.ContractCompanyTradeData, err error) {
  136. // 获取合约持仓数据
  137. contractTradeData, lastBuyVal, lastSoldVal, e := GetContractCompanyTradeData(exchange, []string{classifyName}, contracts, companies, time.Time{}, time.Time{})
  138. if e != nil {
  139. err = fmt.Errorf("获取合约-持仓数据失败, %v", e)
  140. return
  141. }
  142. // 填充[合约-公司]预估数据, 并根据[公司-多合约]分组, [公司]算作一个指标, 指标值为[多个合约]的计算加总
  143. companyContracts := make(map[string][]*tradeAnalysisModel.ContractCompanyTradeData)
  144. for _, v := range contractTradeData {
  145. td, fd, ed, e := PredictingTradeData(v.DataList, lastBuyVal[v.ClassifyType], lastSoldVal[v.ClassifyType], predictRatio)
  146. if e != nil {
  147. err = fmt.Errorf("数据补全失败, %v", e)
  148. return
  149. }
  150. v.DataList = td
  151. v.StartDate = fd
  152. v.EndDate = ed
  153. if companyContracts[v.CompanyName] == nil {
  154. companyContracts[v.CompanyName] = make([]*tradeAnalysisModel.ContractCompanyTradeData, 0)
  155. }
  156. companyContracts[v.CompanyName] = append(companyContracts[v.CompanyName], v)
  157. }
  158. // 以[公司]为组, 计算合约加总
  159. mussyTradeData := make(map[string]*tradeAnalysisModel.ContractCompanyTradeData)
  160. for k, v := range companyContracts {
  161. companyData := new(tradeAnalysisModel.ContractCompanyTradeData)
  162. companyData.CompanyName = k
  163. companyData.DataList = make([]*tradeAnalysisModel.ContractCompanyTradeDataList, 0)
  164. contractArr := make([]string, 0)
  165. // 合约加总
  166. sumDateData := make(map[time.Time]*tradeAnalysisModel.ContractCompanyTradeDataList)
  167. for _, vv := range v {
  168. contractArr = append(contractArr, vv.ClassifyType)
  169. for _, dv := range vv.DataList {
  170. if sumDateData[dv.Date] == nil {
  171. sumDateData[dv.Date] = new(tradeAnalysisModel.ContractCompanyTradeDataList)
  172. sumDateData[dv.Date].Date = dv.Date
  173. }
  174. // 数据类型以第一个非零值为准, 只处理多空和净多, 变化就不管了
  175. if sumDateData[dv.Date].BuyValType == tradeAnalysisModel.TradeDataTypeNull && dv.BuyValType > tradeAnalysisModel.TradeDataTypeNull {
  176. sumDateData[dv.Date].BuyValType = dv.BuyValType
  177. }
  178. if sumDateData[dv.Date].BuyValType == tradeAnalysisModel.TradeDataTypeOrigin && dv.BuyValType == tradeAnalysisModel.TradeDataTypeCalculate {
  179. sumDateData[dv.Date].BuyValType = dv.BuyValType
  180. }
  181. if dv.BuyValType > tradeAnalysisModel.TradeDataTypeNull {
  182. sumDateData[dv.Date].BuyVal += dv.BuyVal
  183. }
  184. // 空单
  185. if sumDateData[dv.Date].SoldValType == tradeAnalysisModel.TradeDataTypeNull && dv.SoldValType > tradeAnalysisModel.TradeDataTypeNull {
  186. sumDateData[dv.Date].SoldValType = dv.SoldValType
  187. }
  188. if sumDateData[dv.Date].SoldValType == tradeAnalysisModel.TradeDataTypeOrigin && dv.SoldValType == tradeAnalysisModel.TradeDataTypeCalculate {
  189. sumDateData[dv.Date].SoldValType = dv.SoldValType
  190. }
  191. if dv.SoldValType > tradeAnalysisModel.TradeDataTypeNull {
  192. sumDateData[dv.Date].SoldVal += dv.SoldVal
  193. }
  194. // 净多单
  195. if sumDateData[dv.Date].PureBuyValType == tradeAnalysisModel.TradeDataTypeNull && dv.PureBuyValType > tradeAnalysisModel.TradeDataTypeNull {
  196. sumDateData[dv.Date].PureBuyValType = dv.PureBuyValType
  197. }
  198. if sumDateData[dv.Date].PureBuyValType == tradeAnalysisModel.TradeDataTypeOrigin && dv.PureBuyValType == tradeAnalysisModel.TradeDataTypeCalculate {
  199. sumDateData[dv.Date].PureBuyValType = dv.PureBuyValType
  200. }
  201. if dv.PureBuyValType > tradeAnalysisModel.TradeDataTypeNull {
  202. sumDateData[dv.Date].PureBuyVal += dv.PureBuyVal
  203. }
  204. }
  205. // 多个合约比对开始结束时间
  206. if companyData.StartDate.IsZero() {
  207. companyData.StartDate = vv.StartDate
  208. }
  209. if vv.StartDate.Before(companyData.StartDate) {
  210. companyData.StartDate = vv.StartDate
  211. }
  212. if companyData.EndDate.IsZero() {
  213. companyData.EndDate = vv.EndDate
  214. }
  215. if vv.EndDate.Before(companyData.EndDate) {
  216. companyData.EndDate = vv.EndDate
  217. }
  218. }
  219. for _, sv := range sumDateData {
  220. companyData.DataList = append(companyData.DataList, sv)
  221. }
  222. sort.Slice(companyData.DataList, func(i, j int) bool {
  223. return companyData.DataList[i].Date.Before(companyData.DataList[j].Date)
  224. })
  225. companyData.ClassifyType = strings.Join(contractArr, ",")
  226. mussyTradeData[k] = companyData
  227. }
  228. // 数据根据公司排序, 不然会随机乱
  229. companyTradeData = make([]*tradeAnalysisModel.ContractCompanyTradeData, 0)
  230. for _, v := range companies {
  231. // 没数据也需要加进去, 不然edbList会少
  232. if mussyTradeData[v] == nil {
  233. companyData := new(tradeAnalysisModel.ContractCompanyTradeData)
  234. companyData.CompanyName = v
  235. companyData.DataList = make([]*tradeAnalysisModel.ContractCompanyTradeDataList, 0)
  236. companyTradeData = append(companyTradeData, companyData)
  237. continue
  238. }
  239. companyTradeData = append(companyTradeData, mussyTradeData[v])
  240. }
  241. return
  242. }
  243. // PredictingTradeData 根据数据库中的多空数据填充预估数据
  244. func PredictingTradeData(originData []*tradeAnalysisModel.ContractCompanyTradeDataList, lastBuyDateVal, lastSoldDateVal map[time.Time]int, predictRatio float64) (newData []*tradeAnalysisModel.ContractCompanyTradeDataList, firstDate, endDate time.Time, err error) {
  245. // 测试用的验证数据
  246. //lastBuyDateVal, lastSoldDateVal = make(map[time.Time]int), make(map[time.Time]int)
  247. //lastBuyDateVal[time.Date(2024, 7, 16, 0, 0, 0, 0, time.Local)] = 4602
  248. //lastBuyDateVal[time.Date(2024, 7, 17, 0, 0, 0, 0, time.Local)] = 5116
  249. //lastBuyDateVal[time.Date(2024, 7, 18, 0, 0, 0, 0, time.Local)] = 5130
  250. //lastBuyDateVal[time.Date(2024, 7, 19, 0, 0, 0, 0, time.Local)] = 5354
  251. //lastBuyDateVal[time.Date(2024, 7, 22, 0, 0, 0, 0, time.Local)] = 5916
  252. //lastBuyDateVal[time.Date(2024, 7, 23, 0, 0, 0, 0, time.Local)] = 6524
  253. //lastBuyDateVal[time.Date(2024, 7, 26, 0, 0, 0, 0, time.Local)] = 6575
  254. //lastBuyDateVal[time.Date(2024, 7, 29, 0, 0, 0, 0, time.Local)] = 7461
  255. //lastBuyDateVal[time.Date(2024, 7, 30, 0, 0, 0, 0, time.Local)] = 8488
  256. //
  257. //lastSoldDateVal[time.Date(2024, 7, 11, 0, 0, 0, 0, time.Local)] = 5467
  258. //lastSoldDateVal[time.Date(2024, 7, 12, 0, 0, 0, 0, time.Local)] = 5248
  259. //lastSoldDateVal[time.Date(2024, 7, 15, 0, 0, 0, 0, time.Local)] = 5102
  260. //lastSoldDateVal[time.Date(2024, 7, 16, 0, 0, 0, 0, time.Local)] = 4771
  261. //lastSoldDateVal[time.Date(2024, 7, 23, 0, 0, 0, 0, time.Local)] = 5989
  262. //lastSoldDateVal[time.Date(2024, 7, 26, 0, 0, 0, 0, time.Local)] = 6745
  263. //lastSoldDateVal[time.Date(2024, 7, 30, 0, 0, 0, 0, time.Local)] = 7272
  264. //
  265. //originData = make([]*tradeAnalysisModel.ContractCompanyTradeDataList, 0)
  266. //originData = append(originData, &tradeAnalysisModel.ContractCompanyTradeDataList{
  267. // Date: time.Date(2024, 7, 10, 0, 0, 0, 0, time.Local),
  268. // BuyVal: 14324,
  269. // BuyValType: tradeAnalysisModel.TradeDataTypeOrigin,
  270. // BuyChange: -1107,
  271. // BuyChangeType: tradeAnalysisModel.TradeDataTypeOrigin,
  272. // SoldVal: 0,
  273. // SoldValType: tradeAnalysisModel.TradeDataTypeNull,
  274. // SoldChange: 0,
  275. // SoldChangeType: tradeAnalysisModel.TradeDataTypeNull,
  276. //}, &tradeAnalysisModel.ContractCompanyTradeDataList{
  277. // Date: time.Date(2024, 7, 11, 0, 0, 0, 0, time.Local),
  278. // BuyVal: 14280,
  279. // BuyValType: tradeAnalysisModel.TradeDataTypeOrigin,
  280. // BuyChange: -44,
  281. // BuyChangeType: tradeAnalysisModel.TradeDataTypeOrigin,
  282. //}, &tradeAnalysisModel.ContractCompanyTradeDataList{
  283. // Date: time.Date(2024, 7, 12, 0, 0, 0, 0, time.Local),
  284. // BuyVal: 14214,
  285. // BuyValType: tradeAnalysisModel.TradeDataTypeOrigin,
  286. // BuyChange: -66,
  287. // BuyChangeType: tradeAnalysisModel.TradeDataTypeOrigin,
  288. //}, &tradeAnalysisModel.ContractCompanyTradeDataList{
  289. // Date: time.Date(2024, 7, 15, 0, 0, 0, 0, time.Local),
  290. // BuyVal: 14269,
  291. // BuyValType: tradeAnalysisModel.TradeDataTypeOrigin,
  292. // BuyChange: 55,
  293. // BuyChangeType: tradeAnalysisModel.TradeDataTypeOrigin,
  294. //}, &tradeAnalysisModel.ContractCompanyTradeDataList{
  295. // Date: time.Date(2024, 7, 17, 0, 0, 0, 0, time.Local),
  296. // SoldVal: 5254,
  297. // SoldValType: tradeAnalysisModel.TradeDataTypeOrigin,
  298. // SoldChange: 708,
  299. // SoldChangeType: tradeAnalysisModel.TradeDataTypeOrigin,
  300. //}, &tradeAnalysisModel.ContractCompanyTradeDataList{
  301. // Date: time.Date(2024, 7, 18, 0, 0, 0, 0, time.Local),
  302. // SoldVal: 6595,
  303. // SoldValType: tradeAnalysisModel.TradeDataTypeOrigin,
  304. // SoldChange: 1341,
  305. // SoldChangeType: tradeAnalysisModel.TradeDataTypeOrigin,
  306. //}, &tradeAnalysisModel.ContractCompanyTradeDataList{
  307. // Date: time.Date(2024, 7, 19, 0, 0, 0, 0, time.Local),
  308. // SoldVal: 5938,
  309. // SoldValType: tradeAnalysisModel.TradeDataTypeOrigin,
  310. // SoldChange: -657,
  311. // SoldChangeType: tradeAnalysisModel.TradeDataTypeOrigin,
  312. //}, &tradeAnalysisModel.ContractCompanyTradeDataList{
  313. // Date: time.Date(2024, 7, 22, 0, 0, 0, 0, time.Local),
  314. // SoldVal: 6131,
  315. // SoldValType: tradeAnalysisModel.TradeDataTypeOrigin,
  316. // SoldChange: 193,
  317. // SoldChangeType: tradeAnalysisModel.TradeDataTypeOrigin,
  318. //}, &tradeAnalysisModel.ContractCompanyTradeDataList{
  319. // Date: time.Date(2024, 7, 29, 0, 0, 0, 0, time.Local),
  320. // SoldVal: 6679,
  321. // SoldValType: tradeAnalysisModel.TradeDataTypeOrigin,
  322. // SoldChange: 312,
  323. // SoldChangeType: tradeAnalysisModel.TradeDataTypeOrigin,
  324. //})
  325. if len(originData) == 0 {
  326. return
  327. }
  328. if predictRatio < 0 || predictRatio > 1 {
  329. err = fmt.Errorf("估计参数不在0-1之间")
  330. return
  331. }
  332. sort.Slice(originData, func(i, j int) bool {
  333. return originData[i].Date.Before(originData[j].Date)
  334. })
  335. dateVal := make(map[time.Time]*tradeAnalysisModel.ContractCompanyTradeDataList)
  336. for _, v := range originData {
  337. dateVal[v.Date] = v
  338. }
  339. // 生成开始日期-1d(可能会往前面推算一天)至结束日期间的交易日, 以交易日为时间序列遍历
  340. tradeDays := utils.GetTradingDays(originData[0].Date.AddDate(0, 0, -1), originData[len(originData)-1].Date)
  341. for k, v := range tradeDays {
  342. // T日多空均无的情况
  343. //bothLast := false
  344. if dateVal[v] == nil {
  345. // T-1和T+1[原始数据]均无值, 那么T日无数据
  346. hasPrev, hasNext := false, false
  347. if k-1 >= 0 {
  348. hasPrev = true
  349. }
  350. if k+1 <= len(tradeDays)-1 {
  351. hasNext = true
  352. }
  353. if !hasPrev && !hasNext {
  354. continue
  355. }
  356. // T+1有值, 优先从T+1推, 然后继续走下面计算净多单的逻辑
  357. if hasNext {
  358. nextDay := tradeDays[k+1]
  359. if dateVal[nextDay] != nil {
  360. // T+1有多/空及多空变化, 且是原始数据, 那么推出数据并在map中新加一日数据
  361. if dateVal[nextDay].BuyValType == tradeAnalysisModel.TradeDataTypeOrigin && dateVal[nextDay].BuyChangeType == tradeAnalysisModel.TradeDataTypeOrigin {
  362. if _, ok := dateVal[v]; !ok {
  363. dateVal[v] = new(tradeAnalysisModel.ContractCompanyTradeDataList)
  364. dateVal[v].Date = v
  365. }
  366. dateVal[v].BuyVal = dateVal[nextDay].BuyVal - dateVal[nextDay].BuyChange
  367. dateVal[v].BuyValType = tradeAnalysisModel.TradeDataTypeOrigin
  368. }
  369. if dateVal[nextDay].SoldValType == tradeAnalysisModel.TradeDataTypeOrigin && dateVal[nextDay].SoldChangeType == tradeAnalysisModel.TradeDataTypeOrigin {
  370. if _, ok := dateVal[v]; !ok {
  371. dateVal[v] = new(tradeAnalysisModel.ContractCompanyTradeDataList)
  372. dateVal[v].Date = v
  373. }
  374. dateVal[v].SoldVal = dateVal[nextDay].SoldVal - dateVal[nextDay].SoldChange
  375. dateVal[v].SoldValType = tradeAnalysisModel.TradeDataTypeOrigin
  376. }
  377. }
  378. }
  379. // T+1没推出来而T-1有值, 那么T多空均取末位, 计算净多单
  380. _, has := dateVal[v]
  381. if hasPrev && !has {
  382. sv, sok := lastSoldDateVal[v]
  383. bv, bok := lastBuyDateVal[v]
  384. if !sok && !bok {
  385. continue
  386. }
  387. dateVal[v] = new(tradeAnalysisModel.ContractCompanyTradeDataList)
  388. dateVal[v].Date = v
  389. if sok {
  390. dateVal[v].SoldVal = int(predictRatio*float64(sv) + 0.5)
  391. dateVal[v].SoldValType = tradeAnalysisModel.TradeDataTypeCalculate
  392. }
  393. if bok {
  394. dateVal[v].BuyVal = int(predictRatio*float64(bv) + 0.5)
  395. dateVal[v].BuyValType = tradeAnalysisModel.TradeDataTypeCalculate
  396. }
  397. if dateVal[v].BuyValType > tradeAnalysisModel.TradeDataTypeNull && dateVal[v].SoldValType > tradeAnalysisModel.TradeDataTypeNull {
  398. dateVal[v].PureBuyVal = dateVal[v].BuyVal - dateVal[v].SoldVal
  399. dateVal[v].PureBuyValType = tradeAnalysisModel.TradeDataTypeCalculate
  400. }
  401. continue
  402. }
  403. }
  404. // 多空均有的情况下计算净多单
  405. if dateVal[v].BuyValType == tradeAnalysisModel.TradeDataTypeOrigin && dateVal[v].SoldValType == tradeAnalysisModel.TradeDataTypeOrigin {
  406. dateVal[v].PureBuyVal = dateVal[v].BuyVal - dateVal[v].SoldVal
  407. dateVal[v].PureBuyValType = tradeAnalysisModel.TradeDataTypeOrigin // 原始值算出来的也作原始值
  408. }
  409. // 仅有多单, 空单取末位, 计算净多单
  410. if dateVal[v].BuyValType == tradeAnalysisModel.TradeDataTypeOrigin && dateVal[v].SoldValType == tradeAnalysisModel.TradeDataTypeNull {
  411. if sv, ok := lastSoldDateVal[v]; ok {
  412. dateVal[v].SoldVal = int(predictRatio*float64(sv) + 0.5) // 估计参数*末位值, 向上取整
  413. dateVal[v].SoldValType = tradeAnalysisModel.TradeDataTypeCalculate
  414. dateVal[v].PureBuyVal = dateVal[v].BuyVal - dateVal[v].SoldVal
  415. dateVal[v].PureBuyValType = tradeAnalysisModel.TradeDataTypeCalculate
  416. }
  417. }
  418. // 仅有空单, 多单取末位, 计算净多单
  419. if dateVal[v].SoldValType == tradeAnalysisModel.TradeDataTypeOrigin && dateVal[v].BuyValType == tradeAnalysisModel.TradeDataTypeNull {
  420. if sv, ok := lastBuyDateVal[v]; ok {
  421. dateVal[v].BuyVal = int(predictRatio*float64(sv) + 0.5)
  422. dateVal[v].BuyValType = tradeAnalysisModel.TradeDataTypeCalculate
  423. dateVal[v].PureBuyVal = dateVal[v].BuyVal - dateVal[v].SoldVal
  424. dateVal[v].PureBuyValType = tradeAnalysisModel.TradeDataTypeCalculate
  425. }
  426. }
  427. }
  428. // 二次遍历, 计算与T-1的变化值
  429. for k, v := range tradeDays {
  430. // 无T/T-1数据, 忽略
  431. if dateVal[v] == nil {
  432. continue
  433. }
  434. if k-1 < 0 {
  435. continue
  436. }
  437. beforeDay := tradeDays[k-1]
  438. if dateVal[beforeDay] == nil {
  439. continue
  440. }
  441. // 多单变化
  442. if dateVal[v].BuyChangeType == tradeAnalysisModel.TradeDataTypeNull {
  443. if dateVal[v].BuyValType > tradeAnalysisModel.TradeDataTypeNull && dateVal[beforeDay].BuyValType > tradeAnalysisModel.TradeDataTypeNull {
  444. dateVal[v].BuyChange = dateVal[v].BuyVal - dateVal[beforeDay].BuyVal
  445. // 如果当日多单或者前日多单是估计值, 那么多单变化也为估计值
  446. if dateVal[v].BuyValType == tradeAnalysisModel.TradeDataTypeCalculate || dateVal[beforeDay].BuyValType == tradeAnalysisModel.TradeDataTypeCalculate {
  447. dateVal[v].BuyChangeType = tradeAnalysisModel.TradeDataTypeCalculate
  448. }
  449. }
  450. }
  451. // 空单变化
  452. if dateVal[v].SoldChangeType == tradeAnalysisModel.TradeDataTypeNull {
  453. if dateVal[v].SoldValType > tradeAnalysisModel.TradeDataTypeNull && dateVal[beforeDay].SoldValType > tradeAnalysisModel.TradeDataTypeNull {
  454. dateVal[v].SoldChange = dateVal[v].SoldVal - dateVal[beforeDay].SoldVal
  455. // 如果当日空单或者前日空单是估计值, 那么空单变化也为估计值
  456. if dateVal[v].SoldValType == tradeAnalysisModel.TradeDataTypeCalculate || dateVal[beforeDay].SoldValType == tradeAnalysisModel.TradeDataTypeCalculate {
  457. dateVal[v].SoldChangeType = tradeAnalysisModel.TradeDataTypeCalculate
  458. }
  459. }
  460. }
  461. // 净多变化
  462. if dateVal[v].PureBuyChangeType == tradeAnalysisModel.TradeDataTypeNull {
  463. if dateVal[v].PureBuyValType > tradeAnalysisModel.TradeDataTypeNull && dateVal[beforeDay].PureBuyValType > tradeAnalysisModel.TradeDataTypeNull {
  464. dateVal[v].PureBuyChange = dateVal[v].PureBuyVal - dateVal[beforeDay].PureBuyVal
  465. dateVal[v].PureBuyChangeType = tradeAnalysisModel.TradeDataTypeOrigin
  466. // 如果当日净多单或者前日净多单是估计值, 那么净多单变化也为估计值
  467. if dateVal[v].PureBuyValType == tradeAnalysisModel.TradeDataTypeCalculate || dateVal[beforeDay].PureBuyValType == tradeAnalysisModel.TradeDataTypeCalculate {
  468. dateVal[v].PureBuyChangeType = tradeAnalysisModel.TradeDataTypeCalculate
  469. }
  470. }
  471. }
  472. }
  473. // 重新遍历map, 生成数据序列并排序
  474. newData = make([]*tradeAnalysisModel.ContractCompanyTradeDataList, 0)
  475. for _, v := range dateVal {
  476. if v.BuyValType == tradeAnalysisModel.TradeDataTypeNull && v.SoldValType == tradeAnalysisModel.TradeDataTypeNull {
  477. continue
  478. }
  479. newData = append(newData, v)
  480. }
  481. sort.Slice(newData, func(i, j int) bool {
  482. return newData[i].Date.Before(newData[j].Date)
  483. })
  484. if len(newData) > 0 {
  485. firstDate = newData[0].Date
  486. endDate = newData[len(newData)-1].Date
  487. }
  488. return
  489. }
  490. // GetTopContractRank 获取TOP20根据成交量的合约排名
  491. func GetTopContractRank(exchange string, classifyNames []string, dataDate time.Time) (items []*tradeAnalysisModel.ContractTopRankData, err error) {
  492. // 郑商所/广期所查询方式不一样
  493. var tradeAnalysis TradeAnalysisInterface
  494. switch exchange {
  495. case tradeAnalysisModel.TradeExchangeZhengzhou:
  496. tradeAnalysis = &ZhengzhouTradeAnalysis{}
  497. case tradeAnalysisModel.TradeExchangeGuangzhou:
  498. tradeAnalysis = &GuangzhouTradeAnalysis{}
  499. default:
  500. tradeAnalysis = &BaseTradeAnalysis{}
  501. }
  502. // 郑商所-需要把所选品种转为实际合约进行后续的查询
  503. if exchange == tradeAnalysisModel.TradeExchangeZhengzhou {
  504. classifies, e := GetZhengzhouContractsByClassifyNames(classifyNames)
  505. if e != nil {
  506. err = fmt.Errorf("获取郑商所实际合约失败, %v", e)
  507. return
  508. }
  509. classifyNames = classifies
  510. }
  511. // 获取多单/空单原始数据
  512. rankData, e := tradeAnalysis.GetContractTopRankData(exchange, classifyNames, dataDate)
  513. if e != nil {
  514. err = fmt.Errorf("获取多空单原始数据失败, %v", e)
  515. return
  516. }
  517. items = make([]*tradeAnalysisModel.ContractTopRankData, 0)
  518. for _, v := range rankData {
  519. v.Exchange = exchange
  520. // 郑商所-这里注意把查出来的品种和合约赋值,不然后续是乱的
  521. if v.Exchange == tradeAnalysisModel.TradeExchangeZhengzhou {
  522. v.ClassifyType = v.ClassifyName
  523. v.ClassifyName = GetZhengzhouClassifyName(v.ClassifyName)
  524. }
  525. items = append(items, v)
  526. }
  527. return
  528. }
  529. // GetTableTradeData 获取多空分析表格持仓数据
  530. func GetTableTradeData(exchange string, classifyName string, contracts []string, companyName string, predictRatio float64, startDate, endDate time.Time, contractType int) (companyTradeData []*tradeAnalysisModel.ContractCompanyTradeData, err error) {
  531. companyTradeData = make([]*tradeAnalysisModel.ContractCompanyTradeData, 0)
  532. // 获取合约持仓数据
  533. contractTradeData, lastBuyVal, lastSoldVal, e := GetContractCompanyTradeData(exchange, []string{classifyName}, contracts, []string{companyName}, startDate, endDate)
  534. if e != nil {
  535. err = fmt.Errorf("获取合约-持仓数据失败, %v", e)
  536. return
  537. }
  538. // 填充[合约-公司]预估数据, 并根据[公司-多合约]分组, [公司]算作一个指标, 指标值为[多个合约]的计算加总
  539. companyContracts := make(map[string][]*tradeAnalysisModel.ContractCompanyTradeData)
  540. for _, v := range contractTradeData {
  541. td, fd, ed, e := PredictingTradeData(v.DataList, lastBuyVal[v.ClassifyType], lastSoldVal[v.ClassifyType], predictRatio)
  542. if e != nil {
  543. err = fmt.Errorf("数据补全失败, %v", e)
  544. return
  545. }
  546. v.DataList = td
  547. v.StartDate = fd
  548. v.EndDate = ed
  549. // 合约类型参数不为合约加总时, 每个合约算一行数据
  550. if contractType != tradeAnalysisModel.ContractQueryTypeTotal {
  551. companyTradeData = append(companyTradeData, v)
  552. continue
  553. }
  554. // 往下计算合约加总
  555. if companyContracts[v.CompanyName] == nil {
  556. companyContracts[v.CompanyName] = make([]*tradeAnalysisModel.ContractCompanyTradeData, 0)
  557. }
  558. companyContracts[v.CompanyName] = append(companyContracts[v.CompanyName], v)
  559. }
  560. // 类型为合约加总才往下合并
  561. if contractType != tradeAnalysisModel.ContractQueryTypeTotal {
  562. return
  563. }
  564. // 以[公司]为组, 计算合约加总
  565. for k, v := range companyContracts {
  566. companyData := new(tradeAnalysisModel.ContractCompanyTradeData)
  567. companyData.CompanyName = k
  568. companyData.DataList = make([]*tradeAnalysisModel.ContractCompanyTradeDataList, 0)
  569. contractArr := make([]string, 0)
  570. // 合约加总
  571. sumDateData := make(map[time.Time]*tradeAnalysisModel.ContractCompanyTradeDataList)
  572. for _, vv := range v {
  573. contractArr = append(contractArr, vv.ClassifyType)
  574. for _, dv := range vv.DataList {
  575. if sumDateData[dv.Date] == nil {
  576. sumDateData[dv.Date] = new(tradeAnalysisModel.ContractCompanyTradeDataList)
  577. sumDateData[dv.Date].Date = dv.Date
  578. }
  579. // 数据类型以第一个非零值为准, 只处理多空和净多, 变化就不管了
  580. if sumDateData[dv.Date].BuyValType == tradeAnalysisModel.TradeDataTypeNull && dv.BuyValType > tradeAnalysisModel.TradeDataTypeNull {
  581. sumDateData[dv.Date].BuyValType = dv.BuyValType
  582. }
  583. if sumDateData[dv.Date].BuyValType == tradeAnalysisModel.TradeDataTypeOrigin && dv.BuyValType == tradeAnalysisModel.TradeDataTypeCalculate {
  584. sumDateData[dv.Date].BuyValType = dv.BuyValType
  585. }
  586. if dv.BuyValType > tradeAnalysisModel.TradeDataTypeNull {
  587. sumDateData[dv.Date].BuyVal += dv.BuyVal
  588. }
  589. // 空单
  590. if sumDateData[dv.Date].SoldValType == tradeAnalysisModel.TradeDataTypeNull && dv.SoldValType > tradeAnalysisModel.TradeDataTypeNull {
  591. sumDateData[dv.Date].SoldValType = dv.SoldValType
  592. }
  593. if sumDateData[dv.Date].SoldValType == tradeAnalysisModel.TradeDataTypeOrigin && dv.SoldValType == tradeAnalysisModel.TradeDataTypeCalculate {
  594. sumDateData[dv.Date].SoldValType = dv.SoldValType
  595. }
  596. if dv.SoldValType > tradeAnalysisModel.TradeDataTypeNull {
  597. sumDateData[dv.Date].SoldVal += dv.SoldVal
  598. }
  599. // 净多单
  600. if sumDateData[dv.Date].PureBuyValType == tradeAnalysisModel.TradeDataTypeNull && dv.PureBuyValType > tradeAnalysisModel.TradeDataTypeNull {
  601. sumDateData[dv.Date].PureBuyValType = dv.PureBuyValType
  602. }
  603. if sumDateData[dv.Date].PureBuyValType == tradeAnalysisModel.TradeDataTypeOrigin && dv.PureBuyValType == tradeAnalysisModel.TradeDataTypeCalculate {
  604. sumDateData[dv.Date].PureBuyValType = dv.PureBuyValType
  605. }
  606. if dv.PureBuyValType > tradeAnalysisModel.TradeDataTypeNull {
  607. sumDateData[dv.Date].PureBuyVal += dv.PureBuyVal
  608. }
  609. }
  610. // 多个合约比对开始结束时间
  611. if companyData.StartDate.IsZero() {
  612. companyData.StartDate = vv.StartDate
  613. }
  614. if vv.StartDate.Before(companyData.StartDate) {
  615. companyData.StartDate = vv.StartDate
  616. }
  617. if companyData.EndDate.IsZero() {
  618. companyData.EndDate = vv.EndDate
  619. }
  620. if vv.EndDate.Before(companyData.EndDate) {
  621. companyData.EndDate = vv.EndDate
  622. }
  623. }
  624. for _, sv := range sumDateData {
  625. companyData.DataList = append(companyData.DataList, sv)
  626. }
  627. sort.Slice(companyData.DataList, func(i, j int) bool {
  628. return companyData.DataList[i].Date.Before(companyData.DataList[j].Date)
  629. })
  630. //companyData.ClassifyType = strings.Join(contractArr, ",")
  631. companyData.Exchange = exchange
  632. companyData.CompanyName = k
  633. companyData.ClassifyType = classifyName
  634. companyTradeData = append(companyTradeData, companyData)
  635. }
  636. return
  637. }
  638. // GetCorrelationTableTradeData 获取相关性表格持仓数据
  639. func GetCorrelationTableTradeData(exchange string, classifyName string, contracts, companies []string, predictRatio float64, contractType int) (companyTradeData []*tradeAnalysisModel.ContractCompanyTradeData, err error) {
  640. companyTradeData = make([]*tradeAnalysisModel.ContractCompanyTradeData, 0)
  641. // 获取合约持仓数据
  642. contractTradeData, lastBuyVal, lastSoldVal, e := GetContractCompanyTradeData(exchange, []string{classifyName}, contracts, companies, time.Time{}, time.Time{})
  643. if e != nil {
  644. err = fmt.Errorf("获取合约-持仓数据失败, %v", e)
  645. return
  646. }
  647. // 填充[合约-公司]预估数据, 并根据[公司-多合约]分组, [公司]算作一个指标, 指标值为[多个合约]的计算加总
  648. companyContracts := make(map[string][]*tradeAnalysisModel.ContractCompanyTradeData)
  649. for _, v := range contractTradeData {
  650. td, fd, ed, e := PredictingTradeData(v.DataList, lastBuyVal[v.ClassifyType], lastSoldVal[v.ClassifyType], predictRatio)
  651. if e != nil {
  652. err = fmt.Errorf("数据补全失败, %v", e)
  653. return
  654. }
  655. v.DataList = td
  656. v.StartDate = fd
  657. v.EndDate = ed
  658. // 合约类型参数不为合约加总时, 每个合约算一行数据
  659. if contractType != tradeAnalysisModel.ContractQueryTypeTotal {
  660. companyTradeData = append(companyTradeData, v)
  661. continue
  662. }
  663. // 往下计算合约加总
  664. if companyContracts[v.CompanyName] == nil {
  665. companyContracts[v.CompanyName] = make([]*tradeAnalysisModel.ContractCompanyTradeData, 0)
  666. }
  667. companyContracts[v.CompanyName] = append(companyContracts[v.CompanyName], v)
  668. }
  669. // 类型为合约加总才往下合并
  670. if contractType != tradeAnalysisModel.ContractQueryTypeTotal {
  671. return
  672. }
  673. // 以[公司]为组, 计算合约加总
  674. for k, v := range companyContracts {
  675. companyData := new(tradeAnalysisModel.ContractCompanyTradeData)
  676. companyData.CompanyName = k
  677. companyData.DataList = make([]*tradeAnalysisModel.ContractCompanyTradeDataList, 0)
  678. contractArr := make([]string, 0)
  679. // 合约加总
  680. sumDateData := make(map[time.Time]*tradeAnalysisModel.ContractCompanyTradeDataList)
  681. for _, vv := range v {
  682. contractArr = append(contractArr, vv.ClassifyType)
  683. for _, dv := range vv.DataList {
  684. if sumDateData[dv.Date] == nil {
  685. sumDateData[dv.Date] = new(tradeAnalysisModel.ContractCompanyTradeDataList)
  686. sumDateData[dv.Date].Date = dv.Date
  687. }
  688. // 数据类型以第一个非零值为准, 只处理多空和净多, 变化就不管了
  689. if sumDateData[dv.Date].BuyValType == tradeAnalysisModel.TradeDataTypeNull && dv.BuyValType > tradeAnalysisModel.TradeDataTypeNull {
  690. sumDateData[dv.Date].BuyValType = dv.BuyValType
  691. }
  692. if sumDateData[dv.Date].BuyValType == tradeAnalysisModel.TradeDataTypeOrigin && dv.BuyValType == tradeAnalysisModel.TradeDataTypeCalculate {
  693. sumDateData[dv.Date].BuyValType = dv.BuyValType
  694. }
  695. if dv.BuyValType > tradeAnalysisModel.TradeDataTypeNull {
  696. sumDateData[dv.Date].BuyVal += dv.BuyVal
  697. }
  698. // 空单
  699. if sumDateData[dv.Date].SoldValType == tradeAnalysisModel.TradeDataTypeNull && dv.SoldValType > tradeAnalysisModel.TradeDataTypeNull {
  700. sumDateData[dv.Date].SoldValType = dv.SoldValType
  701. }
  702. if sumDateData[dv.Date].SoldValType == tradeAnalysisModel.TradeDataTypeOrigin && dv.SoldValType == tradeAnalysisModel.TradeDataTypeCalculate {
  703. sumDateData[dv.Date].SoldValType = dv.SoldValType
  704. }
  705. if dv.SoldValType > tradeAnalysisModel.TradeDataTypeNull {
  706. sumDateData[dv.Date].SoldVal += dv.SoldVal
  707. }
  708. // 净多单
  709. if sumDateData[dv.Date].PureBuyValType == tradeAnalysisModel.TradeDataTypeNull && dv.PureBuyValType > tradeAnalysisModel.TradeDataTypeNull {
  710. sumDateData[dv.Date].PureBuyValType = dv.PureBuyValType
  711. }
  712. if sumDateData[dv.Date].PureBuyValType == tradeAnalysisModel.TradeDataTypeOrigin && dv.PureBuyValType == tradeAnalysisModel.TradeDataTypeCalculate {
  713. sumDateData[dv.Date].PureBuyValType = dv.PureBuyValType
  714. }
  715. if dv.PureBuyValType > tradeAnalysisModel.TradeDataTypeNull {
  716. sumDateData[dv.Date].PureBuyVal += dv.PureBuyVal
  717. }
  718. }
  719. // 多个合约比对开始结束时间
  720. if companyData.StartDate.IsZero() {
  721. companyData.StartDate = vv.StartDate
  722. }
  723. if vv.StartDate.Before(companyData.StartDate) {
  724. companyData.StartDate = vv.StartDate
  725. }
  726. if companyData.EndDate.IsZero() {
  727. companyData.EndDate = vv.EndDate
  728. }
  729. if vv.EndDate.Before(companyData.EndDate) {
  730. companyData.EndDate = vv.EndDate
  731. }
  732. }
  733. for _, sv := range sumDateData {
  734. companyData.DataList = append(companyData.DataList, sv)
  735. }
  736. sort.Slice(companyData.DataList, func(i, j int) bool {
  737. return companyData.DataList[i].Date.Before(companyData.DataList[j].Date)
  738. })
  739. //companyData.ClassifyType = strings.Join(contractArr, ",")
  740. companyData.IsTotal = true
  741. companyData.Exchange = exchange
  742. companyData.CompanyName = k
  743. companyData.ClassifyName = classifyName
  744. companyData.ClassifyType = classifyName
  745. companyTradeData = append(companyTradeData, companyData)
  746. }
  747. return
  748. }
  749. // TransTradeData2EdbData 持仓数据转为指标数据
  750. func TransTradeData2EdbData(tradeData []*tradeAnalysisModel.ContractCompanyTradeData, contractPosition int) (edbData []*tradeAnalysisModel.ContractCompanyTradeEdb, edbDataMap []map[time.Time]int, err error) {
  751. if len(tradeData) == 0 {
  752. return
  753. }
  754. edbData = make([]*tradeAnalysisModel.ContractCompanyTradeEdb, 0)
  755. edbDataMap = make([]map[time.Time]int, 0)
  756. for _, v := range tradeData {
  757. newEdb := new(tradeAnalysisModel.ContractCompanyTradeEdb)
  758. newEdb.Exchange = v.Exchange
  759. newEdb.ClassifyName = v.ClassifyName
  760. newEdb.ClassifyType = v.ClassifyType
  761. newEdb.CompanyName = v.CompanyName
  762. newEdb.IsTotal = v.IsTotal
  763. newEdb.ContractPosition = contractPosition
  764. newEdb.StartDate = v.StartDate
  765. newEdb.EndDate = v.EndDate
  766. newEdb.DataList = make([]*tradeAnalysisModel.ContractCompanyTradeEdbData, 0)
  767. dataMap := make(map[time.Time]int)
  768. for _, d := range v.DataList {
  769. var vd int
  770. switch contractPosition {
  771. case tradeAnalysisModel.ContractPositionBuy:
  772. if d.BuyValType == tradeAnalysisModel.TradeDataTypeNull {
  773. continue
  774. }
  775. vd = d.BuyVal
  776. case tradeAnalysisModel.ContractPositionSold:
  777. if d.SoldValType == tradeAnalysisModel.TradeDataTypeNull {
  778. continue
  779. }
  780. vd = d.SoldVal
  781. case tradeAnalysisModel.ContractPositionPureBuy:
  782. if d.PureBuyValType == tradeAnalysisModel.TradeDataTypeNull {
  783. continue
  784. }
  785. vd = d.PureBuyVal
  786. default:
  787. continue
  788. }
  789. newEdb.DataList = append(newEdb.DataList, &tradeAnalysisModel.ContractCompanyTradeEdbData{
  790. DataTime: d.Date,
  791. Val: vd,
  792. })
  793. dataMap[d.Date] = vd
  794. }
  795. edbData = append(edbData, newEdb)
  796. edbDataMap = append(edbDataMap, dataMap)
  797. }
  798. return
  799. }
  800. // GetContractCompanyTradeData 获取合约持仓数据
  801. func GetContractCompanyTradeData(exchange string, classifyNames, contracts, companies []string, startDate, endDate time.Time) (contractTradeData map[string]*tradeAnalysisModel.ContractCompanyTradeData, lastBuyVal, lastSoldVal map[string]map[time.Time]int, err error) {
  802. // 各原始数据表期货公司名称不一致
  803. companyMap := make(map[string]string)
  804. {
  805. ob := new(tradeAnalysisModel.TradeFuturesCompany)
  806. list, e := ob.GetItemsByCondition(``, make([]interface{}, 0), []string{}, "")
  807. if e != nil {
  808. err = fmt.Errorf("获取期货公司名称失败: %v", e)
  809. return
  810. }
  811. switch exchange {
  812. case "zhengzhou":
  813. for _, v := range list {
  814. companyMap[v.CompanyName] = v.ZhengzhouName
  815. }
  816. case "dalian":
  817. for _, v := range list {
  818. companyMap[v.CompanyName] = v.DalianName
  819. }
  820. case "shanghai":
  821. for _, v := range list {
  822. companyMap[v.CompanyName] = v.ShanghaiName
  823. }
  824. case "cffex":
  825. for _, v := range list {
  826. companyMap[v.CompanyName] = v.CffexName
  827. }
  828. case "ine":
  829. for _, v := range list {
  830. companyMap[v.CompanyName] = v.IneName
  831. }
  832. case "guangzhou":
  833. for _, v := range list {
  834. companyMap[v.CompanyName] = v.GuangzhouName
  835. }
  836. }
  837. }
  838. var queryCompanies []string
  839. for _, v := range companies {
  840. if v == tradeAnalysisModel.TradeFuturesCompanyTop20 {
  841. queryCompanies = append(queryCompanies, tradeAnalysisModel.TradeFuturesCompanyTop20)
  842. continue
  843. }
  844. companyName, ok := companyMap[v]
  845. if !ok {
  846. utils.FileLog.Info(fmt.Sprintf("交易所%s公司名称映射不存在: %s", exchange, v))
  847. continue
  848. }
  849. queryCompanies = append(queryCompanies, companyName)
  850. }
  851. // 郑商所/广期所查询方式不一样
  852. var tradeAnalysis TradeAnalysisInterface
  853. switch exchange {
  854. case tradeAnalysisModel.TradeExchangeZhengzhou:
  855. tradeAnalysis = &ZhengzhouTradeAnalysis{}
  856. case tradeAnalysisModel.TradeExchangeGuangzhou:
  857. tradeAnalysis = &GuangzhouTradeAnalysis{}
  858. default:
  859. tradeAnalysis = &BaseTradeAnalysis{}
  860. }
  861. // 获取多单/空单原始数据
  862. originList, _, lastOriginList, e := tradeAnalysis.GetTradeDataByContracts(exchange, classifyNames, contracts, queryCompanies, startDate, endDate)
  863. if e != nil {
  864. err = fmt.Errorf("获取多空单原始数据失败, %v", e)
  865. return
  866. }
  867. // [合约-期货公司]数据分组
  868. contractTradeData = make(map[string]*tradeAnalysisModel.ContractCompanyTradeData)
  869. {
  870. keyDateData := make(map[string]*tradeAnalysisModel.ContractCompanyTradeDataList)
  871. keyDateDataExist := make(map[string]bool)
  872. for _, v := range originList {
  873. companyName := v.CompanyName
  874. k := fmt.Sprintf("%s-%s", v.ClassifyType, companyName)
  875. if contractTradeData[k] == nil {
  876. contractTradeData[k] = new(tradeAnalysisModel.ContractCompanyTradeData)
  877. contractTradeData[k].Exchange = exchange
  878. contractTradeData[k].CompanyName = companyName
  879. contractTradeData[k].ClassifyName = v.ClassifyName
  880. contractTradeData[k].ClassifyType = v.ClassifyType
  881. contractTradeData[k].DataList = make([]*tradeAnalysisModel.ContractCompanyTradeDataList, 0)
  882. }
  883. kd := fmt.Sprintf("%s-%s", k, v.DataTime.Format(utils.FormatDate))
  884. if keyDateData[kd] == nil {
  885. keyDateData[kd] = new(tradeAnalysisModel.ContractCompanyTradeDataList)
  886. keyDateData[kd].Date = v.DataTime
  887. }
  888. if v.ValType == 1 {
  889. keyDateData[kd].BuyVal = v.Val
  890. keyDateData[kd].BuyValType = tradeAnalysisModel.TradeDataTypeOrigin
  891. keyDateData[kd].BuyChange = v.ValChange
  892. keyDateData[kd].BuyChangeType = tradeAnalysisModel.TradeDataTypeOrigin
  893. }
  894. if v.ValType == 2 {
  895. keyDateData[kd].SoldVal = v.Val
  896. keyDateData[kd].SoldValType = tradeAnalysisModel.TradeDataTypeOrigin
  897. keyDateData[kd].SoldChange = v.ValChange
  898. keyDateData[kd].SoldChangeType = tradeAnalysisModel.TradeDataTypeOrigin
  899. }
  900. if !keyDateDataExist[kd] {
  901. contractTradeData[k].DataList = append(contractTradeData[k].DataList, keyDateData[kd])
  902. keyDateDataExist[kd] = true
  903. }
  904. }
  905. }
  906. // 合约的[日期-末位值]
  907. lastBuyVal = make(map[string]map[time.Time]int)
  908. lastSoldVal = make(map[string]map[time.Time]int)
  909. {
  910. for _, v := range lastOriginList {
  911. if v.ValType == 1 {
  912. if lastBuyVal[v.ClassifyType] == nil {
  913. lastBuyVal[v.ClassifyType] = make(map[time.Time]int)
  914. }
  915. lastBuyVal[v.ClassifyType][v.DataTime] = v.Val
  916. continue
  917. }
  918. if lastSoldVal[v.ClassifyType] == nil {
  919. lastSoldVal[v.ClassifyType] = make(map[time.Time]int)
  920. }
  921. lastSoldVal[v.ClassifyType][v.DataTime] = v.Val
  922. }
  923. }
  924. return
  925. }
  926. // GetTradeClassifyNewestDataTime 获取数据最新日期
  927. func GetTradeClassifyNewestDataTime(exchange string, classifyNames []string) (dataTime time.Time, err error) {
  928. var tradeAnalysis TradeAnalysisInterface
  929. switch exchange {
  930. case tradeAnalysisModel.TradeExchangeZhengzhou:
  931. tradeAnalysis = &ZhengzhouTradeAnalysis{}
  932. case tradeAnalysisModel.TradeExchangeGuangzhou:
  933. tradeAnalysis = &GuangzhouTradeAnalysis{}
  934. default:
  935. tradeAnalysis = &BaseTradeAnalysis{}
  936. }
  937. if exchange == tradeAnalysisModel.TradeExchangeZhengzhou {
  938. classifies, e := GetZhengzhouContractsByClassifyNames(classifyNames)
  939. if e != nil {
  940. err = fmt.Errorf("获取郑商所实际合约失败, %v", e)
  941. return
  942. }
  943. classifyNames = classifies
  944. }
  945. d, e := tradeAnalysis.GetClassifyNewestDataTime(exchange, classifyNames)
  946. if e != nil && e.Error() != utils.ErrNoRow() {
  947. err = fmt.Errorf("获取品种最新数据日期失败, %v", e)
  948. return
  949. }
  950. if !d.IsZero() {
  951. dataTime = d
  952. } else {
  953. dataTime = time.Now().Local()
  954. }
  955. return
  956. }