gitee.com/quant1x/engine@v1.8.4/models/snapshot_tick.go (about) 1 package models 2 3 import ( 4 "gitee.com/quant1x/engine/factors" 5 "gitee.com/quant1x/exchange" 6 "gitee.com/quant1x/gotdx" 7 "gitee.com/quant1x/gotdx/quotes" 8 "gitee.com/quant1x/gotdx/securities" 9 "gitee.com/quant1x/gox/api" 10 "gitee.com/quant1x/gox/logger" 11 "gitee.com/quant1x/gox/progressbar" 12 "gitee.com/quant1x/num" 13 "sync" 14 ) 15 16 var ( 17 __mutexTicks sync.RWMutex 18 __cacheTicks = map[string]quotes.Snapshot{} 19 ) 20 21 // GetTickFromMemory 获取快照缓存 22 func GetTickFromMemory(securityCode string) *quotes.Snapshot { 23 __mutexTicks.RLock() 24 v, found := __cacheTicks[securityCode] 25 __mutexTicks.RUnlock() 26 if found { 27 return &v 28 } 29 return nil 30 } 31 32 // GetStrategySnapshot 从缓存中获取快照 33 func GetStrategySnapshot(securityCode string) *factors.QuoteSnapshot { 34 v := GetTickFromMemory(securityCode) 35 if v == nil || v.State != quotes.TDX_SECURITY_TRADE_STATE_NORMAL { 36 // 非正常交易的记录忽略掉 37 return nil 38 } 39 snapshot := factors.QuoteSnapshot{} 40 _ = api.Copy(&snapshot, &v) 41 snapshot.Name = securities.GetStockName(securityCode) 42 //snapshot.Code = securityCode 43 snapshot.OpeningChangeRate = num.NetChangeRate(snapshot.LastClose, snapshot.Open) 44 snapshot.ChangeRate = num.NetChangeRate(snapshot.LastClose, snapshot.Price) 45 f10 := factors.GetL5F10(securityCode) 46 if f10 != nil { 47 snapshot.Capital = f10.Capital 48 snapshot.FreeCapital = f10.FreeCapital 49 snapshot.OpenTurnZ = f10.TurnZ(snapshot.OpenVolume) 50 } 51 history := factors.GetL5History(securityCode) 52 if history != nil { 53 lastMinuteVolume := history.GetMV5() 54 snapshot.OpenQuantityRatio = float64(snapshot.OpenVolume) / lastMinuteVolume 55 minuteVolume := float64(snapshot.Vol) / float64(exchange.Minutes(snapshot.Date)) 56 snapshot.QuantityRatio = minuteVolume / lastMinuteVolume 57 } 58 snapshot.OpenBiddingDirection, snapshot.OpenVolumeDirection = v.CheckDirection() 59 return &snapshot 60 } 61 62 // SyncAllSnapshots 实时更新快照 63 func SyncAllSnapshots(barIndex *int) { 64 modName := "同步快照数据" 65 allCodes := securities.AllCodeList() 66 count := len(allCodes) 67 var bar *progressbar.Bar = nil 68 if barIndex != nil { 69 bar = progressbar.NewBar(*barIndex, "执行["+modName+"]", count) 70 } 71 currentDate := exchange.GetCurrentlyDay() 72 tdxApi := gotdx.GetTdxApi() 73 parallelCount := tdxApi.NumOfServers() 74 parallelCount /= 2 75 if parallelCount < 2 { 76 parallelCount = 2 77 } 78 var snapshots []quotes.Snapshot 79 var wg sync.WaitGroup 80 var mutex sync.Mutex 81 codeCh := make(chan []string, parallelCount) 82 83 // 启动goroutine来处理快照获取 84 for i := 0; i < parallelCount; i++ { 85 go func() { 86 for subCodes := range codeCh { 87 for i := 0; i < quotes.DefaultRetryTimes; i++ { 88 list, err := tdxApi.GetSnapshot(subCodes) 89 if err != nil { 90 logger.Errorf("ZS: 网络异常: %+v, 重试: %d", err, i+1) 91 continue 92 } 93 mutex.Lock() 94 for _, v := range list { 95 // 修订日期 96 v.Date = currentDate 97 snapshots = append(snapshots, v) 98 } 99 mutex.Unlock() 100 101 break 102 } 103 } 104 wg.Done() 105 }() 106 } 107 108 for start := 0; start < count; start += quotes.TDX_SECURITY_QUOTES_MAX { 109 length := count - start 110 if length >= quotes.TDX_SECURITY_QUOTES_MAX { 111 length = quotes.TDX_SECURITY_QUOTES_MAX 112 } 113 var subCodes []string 114 for i := 0; i < length; i++ { 115 securityCode := allCodes[start+i] 116 subCodes = append(subCodes, securityCode) 117 if barIndex != nil { 118 bar.Add(1) 119 } 120 } 121 if len(subCodes) == 0 { 122 continue 123 } 124 codeCh <- subCodes 125 } 126 // channel 关闭后, 仍然可以读, 一直到读完全部数据 127 close(codeCh) 128 129 wg.Add(parallelCount) 130 wg.Wait() 131 // 如果有进度条 132 if bar != nil { 133 // 等待进度条结束 134 bar.Wait() 135 } 136 137 __mutexTicks.Lock() 138 for _, v := range snapshots { 139 __cacheTicks[v.SecurityCode] = v 140 } 141 __mutexTicks.Unlock() 142 143 if barIndex != nil { 144 *barIndex++ 145 } 146 }