123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447 |
- package trade_analysis
- import (
- tradeAnalysisModel "eta/eta_api/models/data_manage/trade_analysis"
- "eta/eta_api/utils"
- "fmt"
- "sort"
- "strings"
- "time"
- )
- // TradeAnalysisInterface 持仓分析查询接口
- type TradeAnalysisInterface interface {
- GetTradeDataByContracts(exchange string, classifyNames, contracts, queryCompanies []string, startDate, endDate time.Time) (items []*tradeAnalysisModel.OriginTradeData, topItems, lastItems []*tradeAnalysisModel.OriginTradeData, err error)
- GetContractTopRankData(exchange string, classifyNames []string, dataDate time.Time) (items []*tradeAnalysisModel.ContractTopRankData, err error)
- GetClassifyNewestDataTime(exchange string, classifyNames []string) (dataTime time.Time, err error)
- }
- // BaseTradeAnalysis 通用交易所
- type BaseTradeAnalysis struct{}
- // GetTradeDataByContracts 根据合约获取公司的持仓数据、TOP20数据以及每日的末位数据
- func (b *BaseTradeAnalysis) GetTradeDataByContracts(exchange string, classifyNames, contracts, queryCompanies []string, startDate, endDate time.Time) (items, topItems, lastItems []*tradeAnalysisModel.OriginTradeData, err error) {
- // 根据合约获取数据
- originData, e := tradeAnalysisModel.GetTradeDataByContracts(exchange, classifyNames, contracts, startDate, endDate)
- if e != nil {
- err = fmt.Errorf("根据合约获取持仓数据失败, %v", e)
- return
- }
- items, topItems, lastItems = formatOriginData2UseData(originData, queryCompanies)
- return
- }
- // formatOriginData2UseData 原始数据转换为持仓数据、TOP20以及末位数据
- func formatOriginData2UseData(originData []*tradeAnalysisModel.BaseFromTradeCommonIndex, queryCompanies []string) (items, topItems, lastItems []*tradeAnalysisModel.OriginTradeData) {
- items, topItems, lastItems = make([]*tradeAnalysisModel.OriginTradeData, 0), make([]*tradeAnalysisModel.OriginTradeData, 0), make([]*tradeAnalysisModel.OriginTradeData, 0)
- buyMaxRank, soldMaxRang := make(map[string]*tradeAnalysisModel.BaseFromTradeCommonIndex), make(map[string]*tradeAnalysisModel.BaseFromTradeCommonIndex)
- for _, v := range originData {
- // TOP20(大商所的Rank存在为0的)
- if v.Rank == 0 || v.Rank == 999 {
- topBuy := &tradeAnalysisModel.OriginTradeData{
- Rank: v.Rank,
- CompanyName: tradeAnalysisModel.TradeFuturesCompanyTop20,
- Val: v.BuyValue,
- ValChange: v.BuyChange,
- ValType: 1,
- DataTime: v.DataTime,
- ClassifyName: v.ClassifyName,
- ClassifyType: v.ClassifyType,
- }
- topSold := &tradeAnalysisModel.OriginTradeData{
- Rank: v.Rank,
- CompanyName: tradeAnalysisModel.TradeFuturesCompanyTop20,
- Val: v.SoldValue,
- ValChange: v.SoldChange,
- ValType: 2,
- DataTime: v.DataTime,
- ClassifyName: v.ClassifyName,
- ClassifyType: v.ClassifyType,
- }
- topItems = append(topItems, topBuy, topSold)
- continue
- }
- // 查询的公司-买单
- contractDateKey := fmt.Sprintf("%s_%s", v.DataTime.Format(utils.FormatDate), v.ClassifyType)
- if utils.InArrayByStr(queryCompanies, v.BuyShortName) {
- items = append(items, &tradeAnalysisModel.OriginTradeData{
- Rank: v.Rank,
- CompanyName: v.BuyShortName,
- Val: v.BuyValue,
- ValChange: v.BuyChange,
- ValType: 1,
- DataTime: v.DataTime,
- ClassifyName: v.ClassifyName,
- ClassifyType: v.ClassifyType,
- })
- // 比对[合约-数据日期]对应的rank,取出末位
- if buyMaxRank[contractDateKey] != nil && v.Rank > buyMaxRank[contractDateKey].Rank {
- buyMaxRank[contractDateKey] = v
- }
- if buyMaxRank[contractDateKey] == nil {
- buyMaxRank[contractDateKey] = v
- }
- }
- // 查询的公司-卖单
- if utils.InArrayByStr(queryCompanies, v.SoldShortName) {
- items = append(items, &tradeAnalysisModel.OriginTradeData{
- Rank: v.Rank,
- CompanyName: v.SoldShortName,
- Val: v.SoldValue,
- ValChange: v.SoldChange,
- ValType: 2,
- DataTime: v.DataTime,
- ClassifyName: v.ClassifyName,
- ClassifyType: v.ClassifyType,
- })
- // 比对数据日期对应的rank,取出末位
- if soldMaxRang[contractDateKey] != nil && v.Rank > soldMaxRang[contractDateKey].Rank {
- soldMaxRang[contractDateKey] = v
- }
- if soldMaxRang[contractDateKey] == nil {
- soldMaxRang[contractDateKey] = v
- }
- }
- }
- // 如果查询的公司中含TOP20,那么追加进items
- var hasTop bool
- if utils.InArrayByStr(queryCompanies, tradeAnalysisModel.TradeFuturesCompanyTop20) {
- hasTop = true
- }
- if hasTop {
- items = append(items, topItems...)
- }
- // 末位数据
- for _, v := range buyMaxRank {
- if v == nil {
- continue
- }
- lastItems = append(lastItems, &tradeAnalysisModel.OriginTradeData{
- Rank: v.Rank,
- CompanyName: v.BuyShortName,
- Val: v.BuyValue,
- ValChange: v.BuyChange,
- ValType: 1,
- DataTime: v.DataTime,
- ClassifyName: v.ClassifyName,
- ClassifyType: v.ClassifyType,
- })
- }
- for _, v := range buyMaxRank {
- if v == nil {
- continue
- }
- lastItems = append(lastItems, &tradeAnalysisModel.OriginTradeData{
- Rank: v.Rank,
- CompanyName: v.SoldShortName,
- Val: v.SoldValue,
- ValChange: v.SoldChange,
- ValType: 2,
- DataTime: v.DataTime,
- ClassifyName: v.ClassifyName,
- ClassifyType: v.ClassifyType,
- })
- }
- return
- }
- func (b *BaseTradeAnalysis) GetContractTopRankData(exchange string, classifyNames []string, dataDate time.Time) (items []*tradeAnalysisModel.ContractTopRankData, err error) {
- return tradeAnalysisModel.GetContractTopRankData(exchange, classifyNames, dataDate)
- }
- func (b *BaseTradeAnalysis) GetClassifyNewestDataTime(exchange string, classifyNames []string) (dataTime time.Time, err error) {
- return tradeAnalysisModel.GetClassifyNewestDataTime(exchange, classifyNames)
- }
- // ZhengzhouTradeAnalysis 郑商所
- type ZhengzhouTradeAnalysis struct{}
- func (z *ZhengzhouTradeAnalysis) GetTradeDataByContracts(exchange string, classifyNames, contracts, queryCompanies []string, startDate, endDate time.Time) (items, topItems, lastItems []*tradeAnalysisModel.OriginTradeData, err error) {
- // 根据品种获取合约
- //classifies, e := GetZhengzhouContractsByClassifyNames(classifyNames)
- //if e != nil {
- // err = fmt.Errorf("获取郑商所实际合约失败, %v", e)
- // return
- //}
- //contracts = classifies
- // 根据合约获取数据
- originData, e := tradeAnalysisModel.GetZhengzhouTradeDataByContracts(contracts, startDate, endDate)
- if e != nil {
- err = fmt.Errorf("根据合约获取持仓数据失败, %v", e)
- return
- }
- items, topItems, lastItems = formatOriginData2UseData(originData, queryCompanies)
- return
- }
- func (z *ZhengzhouTradeAnalysis) GetContractTopRankData(exchange string, classifyNames []string, dataDate time.Time) (items []*tradeAnalysisModel.ContractTopRankData, err error) {
- return tradeAnalysisModel.GetZhengzhouContractTopRankData(classifyNames, dataDate)
- }
- func (z *ZhengzhouTradeAnalysis) GetClassifyNewestDataTime(exchange string, classifyNames []string) (dataTime time.Time, err error) {
- return tradeAnalysisModel.GetClassifyNewestDataTime(exchange, classifyNames)
- }
- // GuangzhouTradeAnalysis 广期所
- type GuangzhouTradeAnalysis struct{}
- func (g *GuangzhouTradeAnalysis) GetTradeDataByContracts(exchange string, classifyNames, contracts, queryCompanies []string, startDate, endDate time.Time) (items, topItems, lastItems []*tradeAnalysisModel.OriginTradeData, err error) {
- items, topItems, lastItems = make([]*tradeAnalysisModel.OriginTradeData, 0), make([]*tradeAnalysisModel.OriginTradeData, 0), make([]*tradeAnalysisModel.OriginTradeData, 0)
- // 取品种ID
- classifyNameId := map[string]int{"si": 7, "lc": 8}
- classifyIdName := map[int]string{7: "si", 8: "lc"}
- var classifyIds []int
- for _, v := range classifyNames {
- if classifyNameId[v] > 0 {
- classifyIds = append(classifyIds, classifyNameId[v])
- }
- }
- // 查询指标
- indexes, e := tradeAnalysisModel.GetBaseFromTradeGuangzhouIndex(classifyIds, contracts, "")
- if e != nil {
- err = fmt.Errorf("获取广期所指标失败, %v", e)
- return
- }
- var indexIds []int
- // 过滤掉成交量,只取买单卖单
- seatNameArr := []string{tradeAnalysisModel.GuangZhouSeatNameBuy, tradeAnalysisModel.GuangZhouSeatNameSold, tradeAnalysisModel.GuangZhouTopSeatNameBuy, tradeAnalysisModel.GuangZhouTopSeatNameSold}
- indexInfo := make(map[int]*tradeAnalysisModel.OriginTradeData)
- // 查询公司中是否含TOP20
- var hasTop bool
- if utils.InArrayByStr(queryCompanies, tradeAnalysisModel.TradeFuturesCompanyTop20) {
- hasTop = true
- }
- isTopIndex := make(map[int]bool)
- for _, v := range indexes {
- // eg.永安期货_si2401_持买单量
- nameArr := strings.Split(v.IndexName, "_")
- if len(nameArr) != 3 {
- continue
- }
- companyName := nameArr[0]
- var isTop bool
- if nameArr[0] == tradeAnalysisModel.GuangZhouTopCompanyAliasName {
- isTop = true
- isTopIndex[v.BaseFromTradeGuangzhouIndexId] = true
- companyName = tradeAnalysisModel.TradeFuturesCompanyTop20
- }
- if !utils.InArrayByStr(seatNameArr, nameArr[2]) {
- continue
- }
- // 过滤掉非TOP20以及非查询公司
- if !isTop && !utils.InArrayByStr(queryCompanies, companyName) {
- continue
- }
- indexIds = append(indexIds, v.BaseFromTradeGuangzhouIndexId)
- // 指标信息
- if indexInfo[v.BaseFromTradeGuangzhouIndexId] == nil {
- contractType := tradeAnalysisModel.GuangzhouSeatNameValType[nameArr[2]]
- if contractType == 0 {
- continue
- }
- indexInfo[v.BaseFromTradeGuangzhouIndexId] = new(tradeAnalysisModel.OriginTradeData)
- indexInfo[v.BaseFromTradeGuangzhouIndexId].CompanyName = companyName
- indexInfo[v.BaseFromTradeGuangzhouIndexId].ClassifyName = classifyIdName[v.BaseFromTradeGuangzhouClassifyId]
- indexInfo[v.BaseFromTradeGuangzhouIndexId].ClassifyType = nameArr[1]
- indexInfo[v.BaseFromTradeGuangzhouIndexId].ValType = contractType
- }
- }
- if len(indexIds) == 0 {
- return
- }
- // 查询指标数据
- indexesData, e := tradeAnalysisModel.GetBaseFromTradeGuangzhouDataByIndexIds(indexIds, startDate, endDate)
- if e != nil {
- err = fmt.Errorf("获取广期所指标数据失败, %v", e)
- return
- }
- // 取出持仓数据、TOP20,比对末位数据
- contractMinData := make(map[string]*tradeAnalysisModel.OriginTradeData) // 合约末位
- for _, v := range indexesData {
- info, ok := indexInfo[v.BaseFromTradeGuangzhouIndexId]
- if !ok {
- continue
- }
- t := &tradeAnalysisModel.OriginTradeData{
- CompanyName: info.CompanyName,
- Val: int(v.Value),
- ValChange: int(v.QtySub),
- DataTime: v.DataTime,
- ClassifyName: info.ClassifyName,
- ClassifyType: info.ClassifyType,
- ValType: info.ValType,
- }
- // 如果是TOP20的指标,查询公司中含有TOP20那么追加进items,否则仅追加进topItems, 且TOP20不参与末位数据的比对
- if isTopIndex[v.BaseFromTradeGuangzhouIndexId] {
- if hasTop {
- items = append(items, t)
- }
- topItems = append(topItems, t)
- continue
- }
- items = append(items, t)
- // 比对末位数据
- k := fmt.Sprintf("%s-%d", info.ClassifyType, info.ValType)
- if contractMinData[k] == nil {
- contractMinData[k] = t
- continue
- }
- if t.Val < contractMinData[k].Val {
- contractMinData[k] = t
- }
- }
- // 末位数据
- for _, v := range contractMinData {
- lastItems = append(lastItems, v)
- }
- return
- }
- func (g *GuangzhouTradeAnalysis) GetContractTopRankData(exchange string, classifyNames []string, dataTime time.Time) (items []*tradeAnalysisModel.ContractTopRankData, err error) {
- items = make([]*tradeAnalysisModel.ContractTopRankData, 0)
- // 取品种ID
- classifyNameId := map[string]int{"si": 7, "lc": 8}
- classifyIdName := map[int]string{7: "si", 8: "lc"}
- var classifyIds []int
- for _, v := range classifyNames {
- if classifyNameId[v] > 0 {
- classifyIds = append(classifyIds, classifyNameId[v])
- }
- }
- // 查询TOP20指标
- indexKeyword := fmt.Sprint("%", tradeAnalysisModel.GuangZhouTopCompanyAliasName, "%")
- indexes, e := tradeAnalysisModel.GetBaseFromTradeGuangzhouIndex(classifyIds, []string{}, indexKeyword)
- if e != nil {
- err = fmt.Errorf("获取广期所指标失败, %v", e)
- return
- }
- var indexIds []int
- indexIdContract := make(map[int]string) // [指标ID-合约_方向]
- contractRankData := make(map[string]*tradeAnalysisModel.ContractTopRankData) // [合约-合约TOP数据]
- for _, v := range indexes {
- // eg.永安期货_si2401_持买单量
- nameArr := strings.Split(v.IndexName, "_")
- if len(nameArr) != 3 {
- continue
- }
- contractCode := nameArr[1]
- indexIds = append(indexIds, v.BaseFromTradeGuangzhouIndexId)
- // 指标对应的[合约+方向]
- k := fmt.Sprintf("%s_%d", contractCode, tradeAnalysisModel.GuangzhouSeatNameValType[nameArr[2]])
- indexIdContract[v.BaseFromTradeGuangzhouIndexId] = k
- // 合约对应的数据
- if contractRankData[contractCode] == nil {
- contractRankData[contractCode] = new(tradeAnalysisModel.ContractTopRankData)
- contractRankData[contractCode].Exchange = exchange
- contractRankData[contractCode].ClassifyName = classifyIdName[v.BaseFromTradeGuangzhouClassifyId]
- contractRankData[contractCode].ClassifyType = contractCode
- contractRankData[contractCode].DataTime = dataTime
- }
- }
- if len(indexIds) == 0 {
- return
- }
- // 查询指标数据
- indexesData, e := tradeAnalysisModel.GetBaseFromTradeGuangzhouDataByIndexIds(indexIds, dataTime, dataTime)
- if e != nil {
- err = fmt.Errorf("获取广期所指标数据失败, %v", e)
- return
- }
- for _, v := range indexesData {
- k := indexIdContract[v.BaseFromTradeGuangzhouIndexId]
- if k == "" {
- continue
- }
- nameArr := strings.Split(k, "_")
- if len(nameArr) != 2 {
- continue
- }
- contractCode := nameArr[0]
- if contractRankData[contractCode] == nil {
- continue
- }
- // 根据方向赋值:1-多单;2-空单;3-成交量
- switch nameArr[1] {
- case "1":
- contractRankData[contractCode].BuyValue = int(v.Value)
- case "2":
- contractRankData[contractCode].SoldValue = int(v.Value)
- case "3":
- contractRankData[contractCode].DealValue = int(v.Value)
- default:
- continue
- }
- }
- // 根据成交量排序并返回排名数据
- for _, v := range contractRankData {
- items = append(items, v)
- }
- sort.Slice(items, func(i, j int) bool {
- return items[i].DealValue > items[j].DealValue
- })
- return
- }
- func (g *GuangzhouTradeAnalysis) GetClassifyNewestDataTime(exchange string, classifyNames []string) (dataTime time.Time, err error) {
- // 取品种ID
- classifyNameId := map[string]int{"si": 7, "lc": 8}
- var classifyIds []int
- for _, v := range classifyNames {
- if classifyNameId[v] > 0 {
- classifyIds = append(classifyIds, classifyNameId[v])
- }
- }
- // 查询TOP20的最新日期
- indexKeyword := fmt.Sprint("%", tradeAnalysisModel.GuangZhouTopCompanyAliasName, "%")
- indexes, e := tradeAnalysisModel.GetBaseFromTradeGuangzhouIndex(classifyIds, []string{}, indexKeyword)
- if e != nil {
- err = fmt.Errorf("获取广期所指标失败, %v", e)
- return
- }
- var indexIds []int
- for _, v := range indexes {
- // eg.永安期货_si2401_持买单量
- nameArr := strings.Split(v.IndexName, "_")
- if len(nameArr) != 3 {
- continue
- }
- indexIds = append(indexIds, v.BaseFromTradeGuangzhouIndexId)
- }
- if len(indexIds) == 0 {
- return
- }
- d, e := tradeAnalysisModel.GetGuangzhouClassifyNewestDataTime(indexIds)
- if e != nil {
- err = fmt.Errorf("获取广期品种最新数据失败, %v", e)
- return
- }
- dataTime = d
- return
- }
|