-
Notifications
You must be signed in to change notification settings - Fork 1
/
candle.go
137 lines (118 loc) · 2.53 KB
/
candle.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package stockutil
import (
"errors"
"time"
)
type Tick struct {
Time time.Time
Value float64
}
type Candle struct {
Open float64
High float64
Low float64
Close float64
Time time.Time
Duration time.Duration
}
type FlatCandle struct {
Open []float64
High []float64
Low []float64
Close []float64
Time []time.Time
Duration time.Duration
}
func (c *FlatCandle) Get(i int) (Candle, error) {
if len(c.Open) <= i {
return Candle{}, errors.New("Out of bounds")
}
return Candle{
Open: c.Open[i],
High: c.High[i],
Low: c.Low[i],
Close: c.Close[i],
Time: c.Time[i],
Duration: c.Duration,
}, nil
}
func TicksToFlatCandle(ticks []Tick, duration time.Duration) *FlatCandle {
r := new(FlatCandle)
r.Duration = duration
var curOpen float64
var curHigh float64
var curLow float64
var curClose float64
var curTime time.Time
var newShift time.Time
for i, _ := range ticks {
var wasZero bool = false
if newShift.IsZero() {
newShift = ticks[i].Time
wasZero = true
}
// New Candle range began
if !newShift.After(ticks[i].Time) {
if !wasZero {
// Add old candle to FlatCandle
r.Open = append(r.Open, curOpen)
r.High = append(r.High, curHigh)
r.Low = append(r.Low, curLow)
r.Close = append(r.Close, curClose)
r.Time = append(r.Time, curTime)
}
// Initialize new candle
newShift = ticks[i].Time.Add(duration)
curTime = ticks[i].Time
curOpen = ticks[i].Value
curHigh = ticks[i].Value
curLow = ticks[i].Value
}
if curHigh < ticks[i].Value {
curHigh = ticks[i].Value
}
if curLow > ticks[i].Value {
curLow = ticks[i].Value
}
curClose = ticks[i].Value
}
return r
}
/*
Is this realy needed?
- Problem 1: Appending
// Returns Open, High, Low, Close as slices from an candle slice
func FlattenCandle(c []Candle) *FlatCandle {
r := &FlatCandle{}
r.Open = make([]float64, len(c))
r.High = make([]float64, len(c))
r.Low = make([]float64, len(c))
r.Close = make([]float64, len(c))
r.Time = make([]time.Time, len(c))
if len(c) > 0 {
r.Duration = c[0].Duration
}
for i, _ := range c {
r.Open[i] = c[i].Open
r.Low[i] = c[i].Low
r.High[i] = c[i].High
r.Close[i] = c[i].Close
r.Time[i] = c[i].Time
}
return r
}
func UnflatCandle(c *FlatCandle) []Candle {
r := make([]Candle, len(c.Open))
for i, _ := range c.Open {
r[i] = Candle{
Open: c.Open[i],
High: c.High[i],
Low: c.Low[i],
Close: c.Close[i],
Time: c.Time[i],
Duration: c.Duration,
}
}
return r
}
*/