gitee.com/quant1x/engine@v1.8.4/tracker/tracker_sector.go (about)

     1  package tracker
     2  
     3  import (
     4  	"fmt"
     5  	"gitee.com/quant1x/engine/factors"
     6  	"gitee.com/quant1x/engine/market"
     7  	"gitee.com/quant1x/engine/models"
     8  	"gitee.com/quant1x/exchange"
     9  	"gitee.com/quant1x/gotdx/securities"
    10  	"gitee.com/quant1x/gox/api"
    11  	"gitee.com/quant1x/gox/progressbar"
    12  	"gitee.com/quant1x/gox/tags"
    13  	"gitee.com/quant1x/num"
    14  	"gitee.com/quant1x/pkg/tablewriter"
    15  	"os"
    16  	"slices"
    17  	"sort"
    18  )
    19  
    20  // ScanSectorForTick 扫描板块
    21  func ScanSectorForTick(barIndex *int) []string {
    22  	// 不分板块类型, 所有的板块放在一起排序
    23  	allBlocks := scanBlockByTypeForTick(barIndex, securities.BK_GAINIAN)
    24  	// 扫描板块内个股排名
    25  	blockCount := len(allBlocks)
    26  	fmt.Println()
    27  	bar := progressbar.NewBar(*barIndex, "执行[板块个股涨幅扫描]", blockCount)
    28  	for i := 0; i < blockCount; i++ {
    29  		bar.Add(1)
    30  		block := &allBlocks[i]
    31  		topCode := SecurityUnknown
    32  		topName := SecurityUnknown
    33  		topRate := 0.00
    34  		stockCodes := block.StockCodes
    35  		var stockSnapshots []factors.QuoteSnapshot
    36  		for _, s := range stockCodes {
    37  			stockCode := s
    38  			securityCode := exchange.CorrectSecurityCode(stockCode)
    39  			tmpBlocks, _ := __stock2Block[securityCode]
    40  			if len(tmpBlocks) == 0 {
    41  				tmpBlocks = make([]SectorInfo, 0)
    42  			}
    43  			tmpBlocks = append(tmpBlocks, *block)
    44  			__stock2Block[securityCode] = tmpBlocks
    45  			snapshot := models.GetStrategySnapshot(securityCode)
    46  			if snapshot == nil {
    47  				continue
    48  			}
    49  			stockSnapshots = append(stockSnapshots, *snapshot)
    50  		}
    51  		if len(stockSnapshots) == 0 {
    52  			continue
    53  		}
    54  
    55  		sort.Slice(stockSnapshots, func(i, j int) bool {
    56  			a := stockSnapshots[i]
    57  			b := stockSnapshots[j]
    58  			return StockSort(a, b)
    59  		})
    60  
    61  		var stockList []string
    62  		//stockTopNInSector := rules.RuleParameters.StockTopNInSector
    63  		stockCountOfSector := len(stockSnapshots)
    64  		for j := 0; j < stockCountOfSector; /* && j < stockTopNInSector*/ j++ {
    65  			si := stockSnapshots[j]
    66  			stockCode := si.SecurityCode
    67  			if market.IsNeedIgnore(stockCode) {
    68  				continue
    69  			}
    70  			stockList = append(stockList, stockCode)
    71  		}
    72  		__block2Top[block.Code] = stockList
    73  		stockTopList := slices.Clone(stockSnapshots)
    74  		sort.Slice(stockTopList, func(i, j int) bool {
    75  			a := stockTopList[i]
    76  			b := stockTopList[j]
    77  			return a.ChangeRate > b.ChangeRate
    78  		})
    79  		topStock := stockTopList[0]
    80  		topCode = topStock.SecurityCode
    81  		f10 := factors.GetL5F10(topCode)
    82  		if f10 != nil {
    83  			topName = f10.SecurityName
    84  		}
    85  		topRate = num.NetChangeRate(topStock.LastClose, topStock.Price)
    86  		total := 0
    87  		limits := 0
    88  		ling := 0
    89  		up := 0
    90  		down := 0
    91  		for j := 0; j < len(stockSnapshots); j++ {
    92  			gp := stockSnapshots[j]
    93  			total += 1
    94  			zfLimit := exchange.MarketLimit(gp.SecurityCode)
    95  			lastClose := num.Decimal(gp.LastClose)
    96  			zhangting := num.Decimal(lastClose * float64(1.000+zfLimit))
    97  			price := num.Decimal(gp.Price)
    98  			if price >= zhangting {
    99  				limits += 1
   100  			}
   101  			if price > lastClose {
   102  				up++
   103  			} else if price < lastClose {
   104  				down++
   105  			} else {
   106  				ling += 1
   107  			}
   108  			gp.TopNo = j
   109  			_, ok := __stock2Rank[gp.SecurityCode]
   110  			if !ok {
   111  				__stock2Rank[gp.SecurityCode] = gp
   112  			}
   113  		}
   114  		for j, v := range allBlocks {
   115  			if v.Code == block.Code {
   116  				//allBlocks[j].Name = name
   117  				allBlocks[j].TopCode = topCode
   118  				allBlocks[j].TopName = topName
   119  				allBlocks[j].TopRate = topRate
   120  				//allBlocks[j].TopNo = j
   121  				allBlocks[j].Count = total
   122  				allBlocks[j].LimitUpNum = limits
   123  				allBlocks[j].UpCount = up
   124  				allBlocks[j].NoChangeNum = ling
   125  				allBlocks[j].DownCount = down
   126  				__mapBlockData[v.Code] = allBlocks[j]
   127  			}
   128  		}
   129  	}
   130  
   131  	// 输出 板块排行表格
   132  	lastBlocks := api.Filter(allBlocks, tickSectorFilter)
   133  	bn := len(lastBlocks)
   134  	//if bn >= rules.RuleParameters.SectorsTopN {
   135  	//	bn = rules.RuleParameters.SectorsTopN
   136  	//}
   137  	topBlocks := lastBlocks[:bn]
   138  	blkTable := tablewriter.NewWriter(os.Stdout)
   139  	blkHeaders := tags.GetHeadersByTags(SectorInfo{})
   140  	blkTable.SetHeader(blkHeaders)
   141  	var blkValues [][]string
   142  	var targets []string
   143  	for _, block := range topBlocks {
   144  		values := tags.GetValuesByTags(block)
   145  		blkValues = append(blkValues, values)
   146  		// 是否从前排板块中检索个股
   147  		//if rules.RuleParameters.SectorsFilter {
   148  		targets = append(targets, block.StockCodes...)
   149  		//}
   150  	}
   151  	blkTable.AppendBulk(blkValues)
   152  	fmt.Println()
   153  	blkTable.Render()
   154  	targets = api.Unique(targets)
   155  	return targets
   156  }