@@ -15,7 +15,6 @@ import (
1515 slog "log"
1616 "os"
1717 "path/filepath"
18- "sort"
1918 "time"
2019)
2120
@@ -58,8 +57,9 @@ type PlotData struct {
5857}
5958
6059type DataState struct {
61- Time int64 // ns
62- Index int // datas 中的索引
60+ PrevTime int64 // ns
61+ Time int64 // ns
62+ Index int // datas 中的索引
6363}
6464
6565type Backtest struct {
@@ -72,7 +72,7 @@ type Backtest struct {
7272 start time.Time // 开始时间
7373 end time.Time // 结束时间
7474 currentTimeNS int64 // ns
75- sortedDatas []* DataState
75+ timeNsDatas []int64
7676
7777 startedAt time.Time // 运行开始时间
7878 endedAt time.Time // 运行结束时间
@@ -179,18 +179,11 @@ func (b *Backtest) Run() {
179179 data .Reset (b .start , b .end )
180180 }
181181
182- // 初始化数据
183- b .sortedDatas = make ([]* DataState , 0 , len (b .datas ))
184- for i := 0 ; i < len (b .datas ); i ++ {
185- b .sortedDatas = append (b .sortedDatas , & DataState {
186- Time : 0 ,
187- Index : i ,
188- })
182+ if ! b .next () {
183+ log .Error ("error" )
184+ return
189185 }
190186
191- // 设置数据缓存
192- b .setDataCache ()
193-
194187 // 初始净值
195188 strategyTester .addInitItemStats ()
196189 strategyTester .OnInit ()
@@ -215,60 +208,163 @@ func (b *Backtest) Run() {
215208 b .endedAt = time .Now ()
216209}
217210
211+ // 新的 next 方法
218212func (b * Backtest ) next () bool {
219- if b . currentTimeNS == 0 {
220- return b .nextInternal ()
213+ if len ( b . datas ) == 1 {
214+ return b .nextOne ()
221215 }
222216
223- for _ , data := range b .sortedDatas {
224- if b .currentTimeNS < data .Time {
225- b .currentTimeNS = data .Time
226- return true
217+ if b .currentTimeNS == 0 {
218+ for _ , data := range b .datas {
219+ if ! data .Next () {
220+ return false
221+ }
222+ }
223+
224+ b .resetSortedDatas ()
225+
226+ // 取时间最大项
227+ b .currentTimeNS = b .timeNsDatas [len (b .timeNsDatas )- 1 ]
228+ n := len (b .datas )
229+ for i := 0 ; i < n ; i ++ {
230+ data := b .datas [i ]
231+ for {
232+ if data .GetOrderBook ().Time .UnixNano () >= b .currentTimeNS {
233+ break
234+ }
235+ if ! data .Next () {
236+ return false
237+ }
238+ }
227239 }
240+ return true
228241 }
229242
230- return b .nextInternal ()
231- }
243+ for {
244+ for _ , timeNs := range b .timeNsDatas {
245+ if b .currentTimeNS < timeNs {
246+ b .currentTimeNS = timeNs
247+ if ! b .ensureMoveNext (b .currentTimeNS ) {
248+ return false
249+ }
250+ return true
251+ }
252+ }
232253
233- func (b * Backtest ) nextInternal () bool {
234- if len (b .datas ) == 1 {
235- ret := b .datas [0 ].Next ()
236- if ret {
237- b .currentTimeNS = b .datas [0 ].GetOrderBook ().Time .UnixNano ()
254+ for _ , data := range b .datas {
255+ if ! data .Next () {
256+ return false
257+ }
238258 }
239- return ret
259+
260+ b .resetSortedDatas ()
240261 }
262+ }
241263
242- for _ , data := range b .datas {
243- if ! data .Next () {
244- return false
264+ func (b * Backtest ) ensureMoveNext (ns int64 ) bool {
265+ n := len (b .datas )
266+ count := 0
267+ for i := 0 ; i < n ; i ++ {
268+ data := b .datas [i ]
269+ for {
270+ if data .GetOrderBook ().Time .UnixNano () >= ns {
271+ break
272+ }
273+ if ! data .Next () {
274+ return false
275+ }
276+ count ++
245277 }
246278 }
247-
248- b .setDataCache ()
249-
279+ if count > 0 {
280+ // 重新排序
281+ b .resetSortedDatas ()
282+ }
250283 return true
251284}
252285
253- func (b * Backtest ) setDataCache () {
254- // 数据对齐,提前排序
255- n := len (b .datas )
256- if n == 0 {
257- return
286+ func (b * Backtest ) resetSortedDatas () {
287+ nDatas := len (b .datas )
288+ if len (b .timeNsDatas ) != nDatas * 2 {
289+ b .timeNsDatas = make ([]int64 , nDatas * 2 )
258290 }
259291
260- for i := 0 ; i < n ; i ++ {
261- b .sortedDatas [i ].Time = b .datas [i ].GetOrderBook ().Time .UnixNano ()
262- b .sortedDatas [i ].Index = i
292+ for i := 0 ; i < nDatas ; i ++ {
293+ index := i * 2
294+ b .timeNsDatas [index ] = b .datas [i ].GetOrderBookRaw (1 ).Time .UnixNano ()
295+ b .timeNsDatas [index + 1 ] = b .datas [i ].GetOrderBook ().Time .UnixNano ()
263296 }
264297
265- sort .Slice (b .sortedDatas , func (i , j int ) bool {
266- return b .sortedDatas [i ].Time < b .sortedDatas [j ].Time
267- })
298+ utils .SortInt64 (b .timeNsDatas )
299+ }
268300
269- b .currentTimeNS = b .sortedDatas [0 ].Time
301+ func (b * Backtest ) nextOne () bool {
302+ ret := b .datas [0 ].Next ()
303+ if ret {
304+ b .currentTimeNS = b .datas [0 ].GetOrderBook ().Time .UnixNano ()
305+ }
306+ return ret
270307}
271308
309+ //func (b *Backtest) next() bool {
310+ // if b.currentTimeNS == 0 {
311+ // return b.nextInternal()
312+ // }
313+ //
314+ // for _, data := range b.sortedDatas {
315+ // if b.currentTimeNS < data.Time {
316+ // b.currentTimeNS = data.Time
317+ // return true
318+ // }
319+ // }
320+ //
321+ // return b.nextInternal()
322+ //}
323+
324+ //func (b *Backtest) nextInternal() bool {
325+ // if len(b.datas) == 1 {
326+ // ret := b.datas[0].Next()
327+ // if ret {
328+ // b.currentTimeNS = b.datas[0].GetOrderBook().Time.UnixNano()
329+ // }
330+ // return ret
331+ // }
332+ //
333+ // for _, data := range b.datas {
334+ // if !data.Next() {
335+ // return false
336+ // }
337+ // }
338+ //
339+ // b.setDataCache()
340+ //
341+ // return true
342+ //}
343+
344+ //func (b *Backtest) setDataCache() {
345+ // // 数据对齐,提前排序
346+ // n := len(b.datas)
347+ // if n == 0 {
348+ // return
349+ // }
350+ //
351+ // for i := 0; i < n; i++ {
352+ // b.sortedDatas[i].Time = b.datas[i].GetOrderBook().Time.UnixNano()
353+ // b.sortedDatas[i].Index = i
354+ // }
355+ //
356+ // sort.Slice(b.sortedDatas, func(i, j int) bool {
357+ // return b.sortedDatas[i].Time < b.sortedDatas[j].Time
358+ // })
359+ //
360+ // if b.currentTimeNS == 0 {
361+ // // 第一次按右对齐
362+ // b.currentTimeNS = b.sortedDatas[len(b.sortedDatas)-1].Time
363+ // } else {
364+ // b.currentTimeNS = b.sortedDatas[0].Time
365+ // }
366+ //}
367+
272368func (b * Backtest ) GetPrices () (result []float64 ) {
273369 n := len (b .datas )
274370 result = make ([]float64 , n )
0 commit comments