Skip to content

Commit 4c253c7

Browse files
committed
Performance: Ticks#Goto will only load if the requested time is not currently loaded
Performance: Ticks#Goto will seek to the requested time based on current cursor. In a use case where ticks is used to only load until a bar is filled will benefit from this algorithm greatly. The new algorithm will go to previous tick once, and finish. If compared to previous algorithm where it will always seek from beginning to the requested time.
1 parent db7e59d commit 4c253c7

File tree

1 file changed

+79
-26
lines changed

1 file changed

+79
-26
lines changed

api/tickdata/ticks/ticks.go

Lines changed: 79 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -71,28 +71,24 @@ func (t *Ticks) Goto(to time.Time) (isSuccess bool, err error) {
7171

7272
to = to.In(time.UTC) // Done to ease debugging
7373
t.isCompleted = false
74-
for currTime := to; currTime.Before(t.end); currTime = currTime.Add(time.Hour) {
75-
bi := bi5.New(currTime, t.symbol, t.downloadFolderPath)
76-
77-
// Download might return errors when there's no tick data during weekend or holiday
78-
if bi.Download() == nil {
79-
t.ticks, err = bi.Ticks()
80-
if err != nil {
81-
t.complete()
82-
return
83-
} else if len(t.ticks) != 0 {
84-
t.ticksDayHour = currTime
85-
t.ticksIdx = t.searchTickIdx()
86-
t.currTick = nil
87-
88-
isSuccess, err = t.Next()
89-
currTick := t.currTick
90-
for isSuccess && (to.After(currTick.UTC()) || to.Equal(currTick.UTC())) {
91-
isSuccess, err = t.Next()
92-
currTick = t.Current()
74+
for currTime := t.timeToHour(to); currTime.Before(t.end); currTime = currTime.Add(time.Hour) {
75+
if t.ticksDayHour.Equal(currTime) {
76+
return t.resetTicksPointer(to)
77+
} else {
78+
bi := bi5.New(currTime, t.symbol, t.downloadFolderPath)
79+
80+
// Download might return errors when there's no tick data during weekend or holiday
81+
if bi.Download() == nil {
82+
t.ticks, err = bi.Ticks()
83+
if err != nil {
84+
t.complete()
85+
return
86+
} else if len(t.ticks) != 0 {
87+
t.ticksIdx = 0
88+
t.ticksDayHour = currTime
89+
t.seek(to)
90+
return true, nil
9391
}
94-
95-
return
9692
}
9793
}
9894
}
@@ -119,16 +115,73 @@ func (t Ticks) nextDownloadHour() time.Time {
119115
return time.Date(next.Year(), next.Month(), next.Day(), next.Hour(), 0, 0, 0, time.UTC)
120116
}
121117

122-
func (t Ticks) searchTickIdx() (idx int) {
118+
func (t *Ticks) seek(target time.Time) {
123119
count := len(t.ticks)
124-
for idx = 0; idx < count; idx++ {
125-
tick := t.ticks[idx]
126-
if !tick.UTC().Before(t.start) {
120+
i := t.ticksIdx
121+
for ; i < count; i++ {
122+
tickTime := t.ticks[i].UTC()
123+
if tickTime.After(target) {
127124
break
128125
}
129126
}
130127

131-
return idx - 1
128+
if i > 0 {
129+
i--
130+
}
131+
t.ticksIdx = i
132+
t.currTick = t.ticks[i]
133+
}
134+
135+
func (t Ticks) resetTicksPointer(to time.Time) (bool, error) {
136+
if t.currTick == nil { // If beginning of hour
137+
return t.Next()
138+
}
139+
140+
currTickTime := t.currTick.UTC()
141+
if currTickTime.Before(to) {
142+
t.seek(to)
143+
return true, nil
144+
}
145+
146+
// CurrentTick before target is handled above,
147+
// We only need to search backward
148+
prevTick := t.prevTick()
149+
for {
150+
if currTickTime.Equal(to) {
151+
return true, nil
152+
} else {
153+
if prevTick != nil {
154+
prevTrickTime := prevTick.UTC()
155+
if prevTrickTime.Before(to) {
156+
return true, nil
157+
} else {
158+
// Prev is Equal or before, either way, we need to go left
159+
t.ticksIdx--
160+
t.currTick = prevTick
161+
162+
if prevTrickTime.Equal(to) {
163+
// If it's Equal, we're done
164+
return true, nil
165+
}
166+
}
167+
} else {
168+
t.ticksIdx = 0
169+
t.currTick = t.ticks[0]
170+
return true, nil
171+
}
172+
}
173+
}
174+
}
175+
176+
func (t Ticks) prevTick() *tickdata.TickData {
177+
if t.ticksIdx == 0 {
178+
return nil
179+
}
180+
return t.ticks[t.ticksIdx-1]
181+
}
182+
183+
func (t Ticks) timeToHour(tt time.Time) time.Time {
184+
return time.Date(tt.Year(), tt.Month(), tt.Day(), tt.Hour(), 0, 0, 0, tt.Location()).UTC()
132185
}
133186

134187
var isLogSetup = false

0 commit comments

Comments
 (0)