gitee.com/quant1x/engine@v1.8.4/services/task_update_misc.go (about)

     1  package services
     2  
     3  import (
     4  	"gitee.com/quant1x/engine/cache"
     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/quotes"
    10  	"gitee.com/quant1x/gox/api"
    11  	"gitee.com/quant1x/gox/coroutine"
    12  	"gitee.com/quant1x/gox/logger"
    13  	"gitee.com/quant1x/gox/progressbar"
    14  	"gitee.com/quant1x/gox/runtime"
    15  	"time"
    16  )
    17  
    18  // 更新快照
    19  func jobUpdateMiscAndSnapshot() {
    20  	now := time.Now()
    21  	updateInRealTime, _ := exchange.CanUpdateInRealtime()
    22  	// 集合竞价时段更新数据
    23  	if updateInRealTime && exchange.CheckCallAuctionTime(now) {
    24  		realtimeUpdateMiscAndSnapshot()
    25  	} else {
    26  		if runtime.Debug() {
    27  			realtimeUpdateMiscAndSnapshot()
    28  		}
    29  	}
    30  }
    31  
    32  var (
    33  	snapshotDate = cache.DefaultCanReadDate()
    34  	mapSnapshot  = map[string][]quotes.Snapshot{}
    35  	onceSnapshot coroutine.RollingOnce
    36  )
    37  
    38  func resetSnapshotCache() {
    39  	date := cache.DefaultCanReadDate()
    40  	if date > snapshotDate {
    41  		clear(mapSnapshot)
    42  		snapshotDate = date
    43  		factors.SwitchDate(snapshotDate)
    44  	}
    45  }
    46  
    47  // realtimeUpdateMiscAndSnapshot 更新快照缓存
    48  func realtimeUpdateMiscAndSnapshot() {
    49  	onceSnapshot.Do(resetSnapshotCache)
    50  	moduleName := "执行[misc]"
    51  	logger.Infof("%s: begin", moduleName)
    52  	allCodes := market.GetCodeList()
    53  	count := len(allCodes)
    54  	currentDate := cache.DefaultCanReadDate()
    55  	bar := progressbar.NewBar(barIndexUpdateExchangeAndSnapshot, moduleName, count)
    56  	for _, securityCode := range allCodes {
    57  		bar.Add(1)
    58  		if api.StartsWith(securityCode, []string{"88"}) {
    59  			securityCode = "sh" + securityCode
    60  		}
    61  		v := models.GetTickFromMemory(securityCode)
    62  		if v == nil || v.Date != currentDate {
    63  			// 如果snapshot缓存无效, 或者日期不是当前日期, 跳过
    64  			continue
    65  		}
    66  		//kind := exchange.AssertCode(securityCode)
    67  		timestamp := time.Now()
    68  		// 1. 修订日期
    69  		v.Date = currentDate
    70  		securityCode := v.SecurityCode
    71  		misc := factors.GetL5Misc(securityCode)
    72  		if misc == nil {
    73  			logger.Errorf("加载misc[%s-%s]失败", currentDate, securityCode)
    74  			misc = &factors.Misc{
    75  				Date: currentDate,
    76  				Code: securityCode,
    77  			}
    78  		} else {
    79  			misc.Date = currentDate
    80  		}
    81  		// 2. 计算开盘和收盘的成交量
    82  		misc.OpenVolume = int64(v.OpenVolume)
    83  		misc.CloseVolume = int64(v.CloseVolume)
    84  		// 计算开盘换手z和收盘换手z
    85  		f10 := factors.GetL5F10(securityCode)
    86  		if f10 != nil {
    87  			misc.OpenTurnZ = f10.TurnZ(misc.OpenVolume)
    88  			misc.CloseTurnZ = f10.TurnZ(misc.CloseVolume)
    89  		}
    90  		// 3. 计算快照扩展数据
    91  		if exchange.CheckCallAuctionOpen(timestamp) {
    92  			// 3.1 早盘情绪有时效性
    93  			// 计算早盘竞价方向
    94  			misc.OpenBiddingDirection, misc.OpenVolumeDirection = v.CheckDirection()
    95  			// 3.2 计算早盘情绪
    96  			misc.OpenSentiment, misc.OpenConsistent = market.SnapshotSentiment(*v)
    97  		} else {
    98  			// 3.3 盘中及盘后的数据的计算都没有问题
    99  			// 计算收盘竞价方向
   100  			misc.CloseBiddingDirection, misc.CloseVolumeDirection = v.CheckDirection()
   101  			// 3.4 计算收盘情绪
   102  			misc.CloseSentiment, misc.CloseConsistent = market.SnapshotSentiment(*v)
   103  		}
   104  		// 4. 竞价上午竞价观察
   105  		if exchange.CheckCallAuctionOpen(timestamp) {
   106  			// 4.1 竞价开盘
   107  			if misc.BidOpen == 0 {
   108  				misc.BidOpen = v.Ask1
   109  			}
   110  			// 4.2 竞价结束
   111  			misc.BidClose = v.Price
   112  			// 4.3 竞价最高
   113  			if misc.BidHigh == 0 || misc.BidHigh < v.Ask1 {
   114  				misc.BidHigh = v.Ask1
   115  			}
   116  			// 4.4 竞价最低
   117  			if misc.BidLow == 0 || misc.BidLow > v.Ask1 {
   118  				misc.BidLow = v.Ask1
   119  			}
   120  			// 4.4 竞价匹配量, 竞价结束前更新
   121  			if v.Active == 0 {
   122  				misc.BidMatched = float64(v.BidVol1)
   123  				// 4.5 竞价未匹配量
   124  				if v.BidVol2 == 0 {
   125  					misc.BidUnmatched = float64(v.AskVol2)
   126  					misc.BidDirection = -1
   127  				}
   128  				if v.AskVol2 == 0 {
   129  					misc.BidUnmatched = float64(v.BidVol2)
   130  					misc.BidDirection = 1
   131  				}
   132  			}
   133  		}
   134  		// 5. 缓存数据
   135  		//cacheSnapshots = append(cacheSnapshots, *exchange)
   136  
   137  		// 6. 更新内存中的数据
   138  		factors.UpdateL5Misc(misc)
   139  		// 7. 刷新缓存
   140  		cacheList, ok := mapSnapshot[securityCode]
   141  		if !ok {
   142  			cacheList = []quotes.Snapshot{}
   143  		}
   144  		if len(cacheList) > 0 {
   145  			lastDay := cacheList[len(cacheList)-1].Date
   146  			lastServerTime := cacheList[len(cacheList)-1].ServerTime
   147  			if currentDate == lastDay && v.ServerTime <= lastServerTime {
   148  				// 时间戳在缓存之前, 忽略
   149  				continue
   150  			}
   151  		}
   152  		cacheList = append(cacheList, *v)
   153  		if len(cacheList) > 0 {
   154  			mapSnapshot[securityCode] = cacheList
   155  		}
   156  	}
   157  	bar.Wait()
   158  	// 刷新Misc快照本地cache
   159  	factors.RefreshL5Misc()
   160  	timestamp := time.Now()
   161  	if exchange.CheckCallAuctionOpenFinished(timestamp) || exchange.CheckCallAuctionCloseFinished(timestamp) {
   162  		// 早盘和尾盘集合竞价结束后刷新缓存文件
   163  		for _, listSnapshot := range mapSnapshot {
   164  			if len(listSnapshot) == 0 {
   165  				continue
   166  			}
   167  			// 获取第一条记录
   168  			first := listSnapshot[0]
   169  			securityCode := first.SecurityCode
   170  			filename := cache.SnapshotFilename(securityCode)
   171  			cacheList := []quotes.Snapshot{}
   172  			err := api.CsvToSlices(filename, &cacheList)
   173  			if err == nil && len(cacheList) > 0 {
   174  				// 缓存中最后一条记录
   175  				rows := len(cacheList)
   176  				last := cacheList[rows-1]
   177  				// 日期
   178  				lastDay := last.Date
   179  				// 时间戳
   180  				lastServerTime := last.ServerTime
   181  				for _, v := range listSnapshot {
   182  					if currentDate == lastDay && v.ServerTime <= lastServerTime {
   183  						// 时间戳在缓存之前, 忽略
   184  						continue
   185  					}
   186  					cacheList = append(cacheList, v)
   187  				}
   188  			} else {
   189  				// 如果缓存文件不存在, 用缓存数据
   190  				cacheList = listSnapshot
   191  			}
   192  			if len(cacheList) > 0 {
   193  				_ = api.SlicesToCsv(filename, cacheList)
   194  			}
   195  		}
   196  	}
   197  	logger.Infof("%s: end", moduleName)
   198  }