all: replace all Index(i) callers

This commit is contained in:
c9s 2023-06-01 07:46:50 +08:00
parent 5515f588e3
commit c9c13b2013
No known key found for this signature in database
GPG Key ID: 7385E7E464CB0A54
32 changed files with 142 additions and 269 deletions

View File

@ -40,19 +40,11 @@ func (inc *AD) Update(high, low, cloze, volume float64) {
} }
func (inc *AD) Last(i int) float64 { func (inc *AD) Last(i int) float64 {
length := len(inc.Values) return inc.Values.Last(i)
if length == 0 || length-i-1 < 0 {
return 0
}
return inc.Values[length-i-1]
} }
func (inc *AD) Index(i int) float64 { func (inc *AD) Index(i int) float64 {
length := len(inc.Values) return inc.Last(i)
if length == 0 || length-i-1 < 0 {
return 0
}
return inc.Values[length-i-1]
} }
func (inc *AD) Length() int { func (inc *AD) Length() int {

View File

@ -66,17 +66,11 @@ func (inc *ALMA) Update(value float64) {
} }
func (inc *ALMA) Last(i int) float64 { func (inc *ALMA) Last(i int) float64 {
if i >= len(inc.Values) { return inc.Values.Last(i)
return 0
}
return inc.Values[len(inc.Values)-i-1]
} }
func (inc *ALMA) Index(i int) float64 { func (inc *ALMA) Index(i int) float64 {
if i >= len(inc.Values) { return inc.Last(i)
return 0
}
return inc.Values[len(inc.Values)-i-1]
} }
func (inc *ALMA) Length() int { func (inc *ALMA) Length() int {

View File

@ -89,10 +89,7 @@ func (inc *ATR) Last(i int) float64 {
} }
func (inc *ATR) Index(i int) float64 { func (inc *ATR) Index(i int) float64 {
if inc.RMA == nil { return inc.Last(i)
return 0
}
return inc.RMA.Index(i)
} }
func (inc *ATR) Length() int { func (inc *ATR) Length() int {

View File

@ -81,10 +81,7 @@ func (inc *ATRP) Last(i int) float64 {
} }
func (inc *ATRP) Index(i int) float64 { func (inc *ATRP) Index(i int) float64 {
if inc.RMA == nil { return inc.Last(i)
return 0
}
return inc.RMA.Index(i)
} }
func (inc *ATRP) Length() int { func (inc *ATRP) Length() int {

View File

@ -48,13 +48,6 @@ func (inc *EMV) Update(high, low, vol float64) {
inc.Values.Update(result) inc.Values.Update(result)
} }
func (inc *EMV) Index(i int) float64 {
if inc.Values == nil {
return 0
}
return inc.Values.Index(i)
}
func (inc *EMV) Last(i int) float64 { func (inc *EMV) Last(i int) float64 {
if inc.Values == nil { if inc.Values == nil {
return 0 return 0
@ -63,6 +56,10 @@ func (inc *EMV) Last(i int) float64 {
return inc.Values.Last(i) return inc.Values.Last(i)
} }
func (inc *EMV) Index(i int) float64 {
return inc.Last(i)
}
func (inc *EMV) Length() int { func (inc *EMV) Length() int {
if inc.Values == nil { if inc.Values == nil {
return 0 return 0

View File

@ -55,10 +55,6 @@ func (inc *EWMA) Update(value float64) {
} }
func (inc *EWMA) Last(i int) float64 { func (inc *EWMA) Last(i int) float64 {
if len(inc.Values) == 0 {
return 0
}
return inc.Values.Last(i) return inc.Values.Last(i)
} }

View File

@ -45,24 +45,18 @@ func (inc *GHFilter) update(value, uncertainty float64) {
inc.lastMeasurement = value inc.lastMeasurement = value
} }
func (inc *GHFilter) Index(i int) float64 {
return inc.Last(i)
}
func (inc *GHFilter) Length() int { func (inc *GHFilter) Length() int {
if inc.Values == nil {
return 0
}
return inc.Values.Length() return inc.Values.Length()
} }
func (inc *GHFilter) Last(i int) float64 { func (inc *GHFilter) Last(i int) float64 {
if inc.Values == nil {
return 0.0
}
return inc.Values.Last(i) return inc.Values.Last(i)
} }
func (inc *GHFilter) Index(i int) float64 {
return inc.Last(i)
}
// interfaces implementation check // interfaces implementation check
var _ Simple = &GHFilter{} var _ Simple = &GHFilter{}
var _ types.SeriesExtend = &GHFilter{} var _ types.SeriesExtend = &GHFilter{}

View File

@ -44,14 +44,11 @@ func (inc *HULL) Last(i int) float64 {
if inc.result == nil { if inc.result == nil {
return 0 return 0
} }
return inc.result.Index(i) return inc.result.Last(i)
} }
func (inc *HULL) Index(i int) float64 { func (inc *HULL) Index(i int) float64 {
if inc.result == nil { return inc.Last(i)
return 0
}
return inc.result.Index(i)
} }
func (inc *HULL) Length() int { func (inc *HULL) Length() int {

View File

@ -24,12 +24,8 @@ func (inc *PivotHigh) Length() int {
return inc.Values.Length() return inc.Values.Length()
} }
func (inc *PivotHigh) Last(int) float64 { func (inc *PivotHigh) Last(i int) float64 {
if len(inc.Values) == 0 { return inc.Values.Last(i)
return 0.0
}
return inc.Values.Last(0)
} }
func (inc *PivotHigh) Update(value float64) { func (inc *PivotHigh) Update(value float64) {

View File

@ -24,12 +24,8 @@ func (inc *PivotLow) Length() int {
return inc.Values.Length() return inc.Values.Length()
} }
func (inc *PivotLow) Last(int) float64 { func (inc *PivotLow) Last(i int) float64 {
if len(inc.Values) == 0 { return inc.Values.Last(i)
return 0.0
}
return inc.Values.Last(0)
} }
func (inc *PivotLow) Update(value float64) { func (inc *PivotLow) Update(value float64) {

View File

@ -34,11 +34,8 @@ type PSAR struct {
UpdateCallbacks []func(value float64) UpdateCallbacks []func(value float64)
} }
func (inc *PSAR) Last(int) float64 { func (inc *PSAR) Last(i int) float64 {
if len(inc.Values) == 0 { return inc.Values.Last(i)
return 0
}
return inc.Values.Last(0)
} }
func (inc *PSAR) Length() int { func (inc *PSAR) Length() int {

View File

@ -24,8 +24,8 @@ func (s *DriftMA) Update(value, weight float64) {
s.ma2.Update(s.drift.Last(0)) s.ma2.Update(s.drift.Last(0))
} }
func (s *DriftMA) Last(int) float64 { func (s *DriftMA) Last(i int) float64 {
return s.ma2.Last(0) return s.ma2.Last(i)
} }
func (s *DriftMA) Index(i int) float64 { func (s *DriftMA) Index(i int) float64 {

View File

@ -8,11 +8,11 @@ type ElliottWave struct {
} }
func (s *ElliottWave) Index(i int) float64 { func (s *ElliottWave) Index(i int) float64 {
return s.maQuick.Index(i)/s.maSlow.Index(i) - 1.0 return s.Last(i)
} }
func (s *ElliottWave) Last(int) float64 { func (s *ElliottWave) Last(i int) float64 {
return s.maQuick.Last(0)/s.maSlow.Last(0) - 1.0 return s.maQuick.Index(i)/s.maSlow.Index(i) - 1.0
} }
func (s *ElliottWave) Length() int { func (s *ElliottWave) Length() int {

View File

@ -180,11 +180,11 @@ type VWEMA struct {
V types.UpdatableSeries V types.UpdatableSeries
} }
func (inc *VWEMA) Last(int) float64 { func (inc *VWEMA) Index(i int) float64 {
return inc.PV.Last(0) / inc.V.Last(0) return inc.Last(i)
} }
func (inc *VWEMA) Index(i int) float64 { func (inc *VWEMA) Last(i int) float64 {
if i >= inc.PV.Length() { if i >= inc.PV.Length() {
return 0 return 0
} }

View File

@ -31,23 +31,14 @@ type MOM struct {
} }
func (inc *MOM) Index(i int) float64 { func (inc *MOM) Index(i int) float64 {
if inc.Values == nil { return inc.Last(i)
return 0 }
}
func (inc *MOM) Last(i int) float64 {
return inc.Values.Last(i) return inc.Values.Last(i)
} }
func (inc *MOM) Last(int) float64 {
if inc.Values.Length() == 0 {
return 0
}
return inc.Values.Last(0)
}
func (inc *MOM) Length() int { func (inc *MOM) Length() int {
if inc.Values == nil {
return 0
}
return inc.Values.Length() return inc.Values.Length()
} }

View File

@ -19,8 +19,8 @@ type PMR struct {
types.IntervalWindow types.IntervalWindow
types.SeriesBase types.SeriesBase
Values floats.Slice Values floats.Slice
SMA *indicator.SMA SMA *indicator.SMA
EndTime time.Time EndTime time.Time
updateCallbacks []func(value float64) updateCallbacks []func(value float64)
@ -40,20 +40,12 @@ func (inc *PMR) Update(price float64) {
} }
} }
func (inc *PMR) Last(int) float64 { func (inc *PMR) Last(i int) float64 {
if len(inc.Values) == 0 { return inc.Values.Last(i)
return 0
}
return inc.Values[len(inc.Values)-1]
} }
func (inc *PMR) Index(i int) float64 { func (inc *PMR) Index(i int) float64 {
if i >= len(inc.Values) { return inc.Last(i)
return 0
}
return inc.Values[len(inc.Values)-1-i]
} }
func (inc *PMR) Length() int { func (inc *PMR) Length() int {

View File

@ -23,8 +23,8 @@ type PVD struct {
types.IntervalWindow types.IntervalWindow
types.SeriesBase types.SeriesBase
Values floats.Slice Values floats.Slice
Prices *types.Queue Prices *types.Queue
Volumes *types.Queue Volumes *types.Queue
EndTime time.Time EndTime time.Time
@ -47,20 +47,12 @@ func (inc *PVD) Update(price float64, volume float64) {
} }
} }
func (inc *PVD) Last(int) float64 { func (inc *PVD) Last(i int) float64 {
if len(inc.Values) == 0 { return inc.Values.Last(i)
return 0
}
return inc.Values[len(inc.Values)-1]
} }
func (inc *PVD) Index(i int) float64 { func (inc *PVD) Index(i int) float64 {
if i >= len(inc.Values) { return inc.Last(i)
return 0
}
return inc.Values[len(inc.Values)-1-i]
} }
func (inc *PVD) Length() int { func (inc *PVD) Length() int {

View File

@ -35,20 +35,12 @@ func (inc *RR) Update(price float64) {
} }
func (inc *RR) Last(int) float64 { func (inc *RR) Last(i int) float64 {
if len(inc.Values) == 0 { return inc.Values.Last(i)
return 0
}
return inc.Values[len(inc.Values)-1]
} }
func (inc *RR) Index(i int) float64 { func (inc *RR) Index(i int) float64 {
if i >= len(inc.Values) { return inc.Last(i)
return 0
}
return inc.Values[len(inc.Values)-1-i]
} }
func (inc *RR) Length() int { func (inc *RR) Length() int {
@ -101,7 +93,7 @@ func (inc *RR) LoadK(allKLines []types.KLine) {
inc.EmitUpdate(inc.Last(0)) inc.EmitUpdate(inc.Last(0))
} }
//func calculateReturn(klines []types.KLine, window int, val KLineValueMapper) (float64, error) { // func calculateReturn(klines []types.KLine, window int, val KLineValueMapper) (float64, error) {
// length := len(klines) // length := len(klines)
// if length == 0 || length < window { // if length == 0 || length < window {
// return 0.0, fmt.Errorf("insufficient elements for calculating VOL with window = %d", window) // return 0.0, fmt.Errorf("insufficient elements for calculating VOL with window = %d", window)
@ -110,4 +102,4 @@ func (inc *RR) LoadK(allKLines []types.KLine) {
// rate := val(klines[length-1])/val(klines[length-2]) - 1 // rate := val(klines[length-1])/val(klines[length-2]) - 1
// //
// return rate, nil // return rate, nil
//} // }

View File

@ -30,23 +30,14 @@ type VMOM struct {
} }
func (inc *VMOM) Index(i int) float64 { func (inc *VMOM) Index(i int) float64 {
if inc.Values == nil { return inc.Last(i)
return 0 }
}
func (inc *VMOM) Last(i int) float64 {
return inc.Values.Last(i) return inc.Values.Last(i)
} }
func (inc *VMOM) Last(int) float64 {
if inc.Values.Length() == 0 {
return 0
}
return inc.Values.Last(0)
}
func (inc *VMOM) Length() int { func (inc *VMOM) Length() int {
if inc.Values == nil {
return 0
}
return inc.Values.Length() return inc.Values.Length()
} }

View File

@ -51,20 +51,12 @@ func (inc *SHARK) Update(high, low, price float64) {
} }
func (inc *SHARK) Last(int) float64 { func (inc *SHARK) Last(i int) float64 {
if len(inc.Values) == 0 { return inc.Values.Last(i)
return 0
}
return inc.Values[len(inc.Values)-1]
} }
func (inc *SHARK) Index(i int) float64 { func (inc *SHARK) Index(i int) float64 {
if i >= len(inc.Values) { return inc.Last(i)
return 0
}
return inc.Values[len(inc.Values)-1-i]
} }
func (inc *SHARK) Length() int { func (inc *SHARK) Length() int {
@ -107,7 +99,7 @@ func (inc SHARK) SharkLong(highs, lows floats.Slice, p float64, lookback int) fl
if lows.Index(b-1) > lows.Index(b) && lows.Index(b) < lows.Index(b+1) { if lows.Index(b-1) > lows.Index(b) && lows.Index(b) < lows.Index(b+1) {
B := lows.Index(b) B := lows.Index(b)
if hB > B && B > lB { if hB > B && B > lB {
//log.Infof("got point B:%f", B) // log.Infof("got point B:%f", B)
AB := math.Abs(A - B) AB := math.Abs(A - B)
hC := B + 1.618*AB hC := B + 1.618*AB
lC := B + 1.13*AB lC := B + 1.13*AB
@ -115,24 +107,24 @@ func (inc SHARK) SharkLong(highs, lows floats.Slice, p float64, lookback int) fl
if highs.Index(c-1) < highs.Index(c) && highs.Index(c) > highs.Index(c+1) { if highs.Index(c-1) < highs.Index(c) && highs.Index(c) > highs.Index(c+1) {
C := highs.Index(c) C := highs.Index(c)
if hC > C && C > lC { if hC > C && C > lC {
//log.Infof("got point C:%f", C) // log.Infof("got point C:%f", C)
XC := math.Abs(X - C) XC := math.Abs(X - C)
hD := C - 0.886*XC hD := C - 0.886*XC
lD := C - 1.13*XC lD := C - 1.13*XC
//for d := 1; d < c; d++ { // for d := 1; d < c; d++ {
//if lows.Index(d-1) > lows.Index(d) && lows.Index(d) < lows.Index(d+1) { // if lows.Index(d-1) > lows.Index(d) && lows.Index(d) < lows.Index(d+1) {
D := p //lows.Index(d) D := p // lows.Index(d)
if hD > D && D > lD { if hD > D && D > lD {
BC := math.Abs(B - C) BC := math.Abs(B - C)
hD2 := C - 1.618*BC hD2 := C - 1.618*BC
lD2 := C - 2.24*BC lD2 := C - 2.24*BC
if hD2 > D && D > lD2 { if hD2 > D && D > lD2 {
//log.Infof("got point D:%f", D) // log.Infof("got point D:%f", D)
score++ score++
} }
} }
//} // }
//} // }
} }
} }
} }
@ -161,7 +153,7 @@ func (inc SHARK) SharkShort(highs, lows floats.Slice, p float64, lookback int) f
if highs.Index(b-1) > highs.Index(b) && highs.Index(b) < highs.Index(b+1) { if highs.Index(b-1) > highs.Index(b) && highs.Index(b) < highs.Index(b+1) {
B := highs.Index(b) B := highs.Index(b)
if hB > B && B > lB { if hB > B && B > lB {
//log.Infof("got point B:%f", B) // log.Infof("got point B:%f", B)
AB := math.Abs(A - B) AB := math.Abs(A - B)
lC := B - 1.618*AB lC := B - 1.618*AB
hC := B - 1.13*AB hC := B - 1.13*AB
@ -169,24 +161,24 @@ func (inc SHARK) SharkShort(highs, lows floats.Slice, p float64, lookback int) f
if lows.Index(c-1) < lows.Index(c) && lows.Index(c) > lows.Index(c+1) { if lows.Index(c-1) < lows.Index(c) && lows.Index(c) > lows.Index(c+1) {
C := lows.Index(c) C := lows.Index(c)
if hC > C && C > lC { if hC > C && C > lC {
//log.Infof("got point C:%f", C) // log.Infof("got point C:%f", C)
XC := math.Abs(X - C) XC := math.Abs(X - C)
lD := C + 0.886*XC lD := C + 0.886*XC
hD := C + 1.13*XC hD := C + 1.13*XC
//for d := 1; d < c; d++ { // for d := 1; d < c; d++ {
//if lows.Index(d-1) > lows.Index(d) && lows.Index(d) < lows.Index(d+1) { // if lows.Index(d-1) > lows.Index(d) && lows.Index(d) < lows.Index(d+1) {
D := p //lows.Index(d) D := p // lows.Index(d)
if hD > D && D > lD { if hD > D && D > lD {
BC := math.Abs(B - C) BC := math.Abs(B - C)
lD2 := C + 1.618*BC lD2 := C + 1.618*BC
hD2 := C + 2.24*BC hD2 := C + 2.24*BC
if hD2 > D && D > lD2 { if hD2 > D && D > lD2 {
//log.Infof("got point D:%f", D) // log.Infof("got point D:%f", D)
score++ score++
} }
} }
//} // }
//} // }
} }
} }
} }

View File

@ -53,20 +53,12 @@ func (inc *NRR) Update(openPrice, closePrice float64) {
inc.ReturnValues.Push(irr) inc.ReturnValues.Push(irr)
} }
func (inc *NRR) Last(int) float64 { func (inc *NRR) Last(i int) float64 {
if len(inc.Values) == 0 { return inc.Values.Last(i)
return 0
}
return inc.Values[len(inc.Values)-1]
} }
func (inc *NRR) Index(i int) float64 { func (inc *NRR) Index(i int) float64 {
if i >= len(inc.Values) { return inc.Last(i)
return 0
}
return inc.Values[len(inc.Values)-1-i]
} }
func (inc *NRR) Length() int { func (inc *NRR) Length() int {

View File

@ -19,20 +19,13 @@ type LinReg struct {
} }
// Last slope of linear regression baseline // Last slope of linear regression baseline
func (lr *LinReg) Last(int) float64 { func (lr *LinReg) Last(i int) float64 {
if lr.Values.Length() == 0 { return lr.Values.Last(i)
return 0.0
}
return lr.Values.Last(0)
} }
// Index returns the slope of specified index // Index returns the slope of specified index
func (lr *LinReg) Index(i int) float64 { func (lr *LinReg) Index(i int) float64 {
if i >= lr.Values.Length() { return lr.Last(i)
return 0.0
}
return lr.Values.Index(i)
} }
// Length of the slope values // Length of the slope values

View File

@ -12,7 +12,7 @@ func (f *FilterResult) Last(j int) float64 {
return 0 return 0
} }
if len(f.c) > j { if len(f.c) > j {
return f.a.Index(f.c[j]) return f.a.Last(f.c[j])
} }
l := f.a.Length() l := f.a.Length()
k := len(f.c) k := len(f.c)
@ -21,7 +21,7 @@ func (f *FilterResult) Last(j int) float64 {
i = f.c[k-1] + 1 i = f.c[k-1] + 1
} }
for ; i < l; i++ { for ; i < l; i++ {
tmp := f.a.Index(i) tmp := f.a.Last(i)
if f.b(i, tmp) { if f.b(i, tmp) {
f.c = append(f.c, i) f.c = append(f.c, i)
if j == k { if j == k {

View File

@ -26,7 +26,7 @@ func (a *AbsResult) Last(i int) float64 {
} }
func (a *AbsResult) Index(i int) float64 { func (a *AbsResult) Index(i int) float64 {
return math.Abs(a.a.Index(i)) return a.Last(i)
} }
func (a *AbsResult) Length() int { func (a *AbsResult) Length() int {
@ -49,7 +49,7 @@ func LinearRegression(a Series, lookback int) (alpha float64, beta float64) {
var weights []float64 var weights []float64
for i := 0; i < lookback; i++ { for i := 0; i < lookback; i++ {
x[i] = float64(i) x[i] = float64(i)
y[i] = a.Index(i) y[i] = a.Last(i)
} }
alpha, beta = stat.LinearRegression(x, y, weights, false) alpha, beta = stat.LinearRegression(x, y, weights, false)
return return
@ -83,8 +83,8 @@ func NextCross(a Series, b Series, lookback int) (int, float64, bool) {
var weights []float64 var weights []float64
for i := 0; i < lookback; i++ { for i := 0; i < lookback; i++ {
x[i] = float64(i) x[i] = float64(i)
y1[i] = a.Index(i) y1[i] = a.Last(i)
y2[i] = b.Index(i) y2[i] = b.Last(i)
} }
alpha1, beta1 := stat.LinearRegression(x, y1, weights, false) alpha1, beta1 := stat.LinearRegression(x, y1, weights, false)
alpha2, beta2 := stat.LinearRegression(x, y2, weights, false) alpha2, beta2 := stat.LinearRegression(x, y2, weights, false)
@ -113,9 +113,9 @@ func (c *CrossResult) Last() bool {
return false return false
} }
if c.isOver { if c.isOver {
return c.a.Last(0)-c.b.Last(0) > 0 && c.a.Index(1)-c.b.Index(1) < 0 return c.a.Last(0)-c.b.Last(0) > 0 && c.a.Last(1)-c.b.Last(1) < 0
} else { } else {
return c.a.Last(0)-c.b.Last(0) < 0 && c.a.Index(1)-c.b.Index(1) > 0 return c.a.Last(0)-c.b.Last(0) < 0 && c.a.Last(1)-c.b.Last(1) > 0
} }
} }
@ -124,9 +124,9 @@ func (c *CrossResult) Index(i int) bool {
return false return false
} }
if c.isOver { if c.isOver {
return c.a.Index(i)-c.b.Index(i) > 0 && c.a.Index(i+1)-c.b.Index(i+1) < 0 return c.a.Last(i)-c.b.Last(i) > 0 && c.a.Last(i+1)-c.b.Last(i+1) < 0
} else { } else {
return c.a.Index(i)-c.b.Index(i) < 0 && c.a.Index(i+1)-c.b.Index(i+1) > 0 return c.a.Last(i)-c.b.Last(i) < 0 && c.a.Last(i+1)-c.b.Last(i+1) > 0
} }
} }
@ -161,7 +161,7 @@ func Highest(a Series, lookback int) float64 {
} }
highest := a.Last(0) highest := a.Last(0)
for i := 1; i < lookback; i++ { for i := 1; i < lookback; i++ {
current := a.Index(i) current := a.Last(i)
if highest < current { if highest < current {
highest = current highest = current
} }
@ -175,7 +175,7 @@ func Lowest(a Series, lookback int) float64 {
} }
lowest := a.Last(0) lowest := a.Last(0)
for i := 1; i < lookback; i++ { for i := 1; i < lookback; i++ {
current := a.Index(i) current := a.Last(i)
if lowest > current { if lowest > current {
lowest = current lowest = current
} }
@ -247,7 +247,7 @@ func Sub(a interface{}, b interface{}) SeriesExtend {
} }
func (a *MinusSeriesResult) Last(i int) float64 { func (a *MinusSeriesResult) Last(i int) float64 {
return a.a.Index(i) - a.b.Index(i) return a.a.Last(i) - a.b.Last(i)
} }
func (a *MinusSeriesResult) Index(i int) float64 { func (a *MinusSeriesResult) Index(i int) float64 {
@ -303,7 +303,7 @@ type DivSeriesResult struct {
} }
func (a *DivSeriesResult) Last(i int) float64 { func (a *DivSeriesResult) Last(i int) float64 {
return a.a.Index(i) / a.b.Index(i) return a.a.Last(i) / a.b.Last(i)
} }
func (a *DivSeriesResult) Index(i int) float64 { func (a *DivSeriesResult) Index(i int) float64 {
@ -334,7 +334,7 @@ type MulSeriesResult struct {
} }
func (a *MulSeriesResult) Last(i int) float64 { func (a *MulSeriesResult) Last(i int) float64 {
return a.a.Index(i) * a.b.Index(i) return a.a.Last(i) * a.b.Last(i)
} }
func (a *MulSeriesResult) Index(i int) float64 { func (a *MulSeriesResult) Index(i int) float64 {
@ -427,19 +427,19 @@ func Dot(a interface{}, b interface{}, limit ...int) float64 {
} else if isaf && !isbf { } else if isaf && !isbf {
sum := 0. sum := 0.
for i := 0; i < l; i++ { for i := 0; i < l; i++ {
sum += aaf * bbs.Index(i) sum += aaf * bbs.Last(i)
} }
return sum return sum
} else if !isaf && isbf { } else if !isaf && isbf {
sum := 0. sum := 0.
for i := 0; i < l; i++ { for i := 0; i < l; i++ {
sum += aas.Index(i) * bbf sum += aas.Last(i) * bbf
} }
return sum return sum
} else { } else {
sum := 0. sum := 0.
for i := 0; i < l; i++ { for i := 0; i < l; i++ {
sum += aas.Index(i) * bbs.Index(i) sum += aas.Last(i) * bbs.Index(i)
} }
return sum return sum
} }
@ -458,7 +458,7 @@ func Array(a Series, limit ...int) (result []float64) {
} }
result = make([]float64, l) result = make([]float64, l)
for i := 0; i < l; i++ { for i := 0; i < l; i++ {
result[i] = a.Index(i) result[i] = a.Last(i)
} }
return return
} }
@ -475,7 +475,7 @@ func Reverse(a Series, limit ...int) (result floats.Slice) {
} }
result = make([]float64, l) result = make([]float64, l)
for i := 0; i < l; i++ { for i := 0; i < l; i++ {
result[l-i-1] = a.Index(i) result[l-i-1] = a.Last(i)
} }
return return
} }
@ -489,7 +489,7 @@ func (c *ChangeResult) Last(i int) float64 {
if i+c.offset >= c.a.Length() { if i+c.offset >= c.a.Length() {
return 0 return 0
} }
return c.a.Index(i) - c.a.Index(i+c.offset) return c.a.Last(i) - c.a.Last(i+c.offset)
} }
func (c *ChangeResult) Index(i int) float64 { func (c *ChangeResult) Index(i int) float64 {
@ -524,7 +524,7 @@ func (c *PercentageChangeResult) Last(i int) float64 {
if i+c.offset >= c.a.Length() { if i+c.offset >= c.a.Length() {
return 0 return 0
} }
return c.a.Index(i)/c.a.Index(i+c.offset) - 1 return c.a.Last(i)/c.a.Last(i+c.offset) - 1
} }
func (c *PercentageChangeResult) Index(i int) float64 { func (c *PercentageChangeResult) Index(i int) float64 {
@ -565,7 +565,7 @@ func Stdev(a Series, params ...int) float64 {
avg := Mean(a, length) avg := Mean(a, length)
s := .0 s := .0
for i := 0; i < length; i++ { for i := 0; i < length; i++ {
diff := a.Index(i) - avg diff := a.Last(i) - avg
s += diff * diff s += diff * diff
} }
if length-ddof == 0 { if length-ddof == 0 {
@ -588,7 +588,7 @@ func Kendall(a, b Series, length int) float64 {
concordant, discordant := 0, 0 concordant, discordant := 0, 0
for i := 0; i < length; i++ { for i := 0; i < length; i++ {
for j := i + 1; j < length; j++ { for j := i + 1; j < length; j++ {
value := (aRanks.Index(i) - aRanks.Index(j)) * (bRanks.Index(i) - bRanks.Index(j)) value := (aRanks.Last(i) - aRanks.Last(j)) * (bRanks.Last(i) - bRanks.Last(j))
if value > 0 { if value > 0 {
concordant++ concordant++
} else { } else {
@ -606,10 +606,10 @@ func Rank(a Series, length int) SeriesExtend {
rank := make([]float64, length) rank := make([]float64, length)
mapper := make([]float64, length+1) mapper := make([]float64, length+1)
for i := length - 1; i >= 0; i-- { for i := length - 1; i >= 0; i-- {
ii := a.Index(i) ii := a.Last(i)
counter := 0. counter := 0.
for j := 0; j < length; j++ { for j := 0; j < length; j++ {
if a.Index(j) <= ii { if a.Last(j) <= ii {
counter += 1. counter += 1.
} }
} }
@ -633,8 +633,8 @@ func Pearson(a, b Series, length int) float64 {
x := make([]float64, length) x := make([]float64, length)
y := make([]float64, length) y := make([]float64, length)
for i := 0; i < length; i++ { for i := 0; i < length; i++ {
x[i] = a.Index(i) x[i] = a.Last(i)
y[i] = b.Index(i) y[i] = b.Last(i)
} }
return stat.Correlation(x, y, nil) return stat.Correlation(x, y, nil)
} }
@ -690,7 +690,7 @@ func Covariance(a Series, b Series, length int) float64 {
meanb := Mean(b, length) meanb := Mean(b, length)
sum := 0.0 sum := 0.0
for i := 0; i < length; i++ { for i := 0; i < length; i++ {
sum += (a.Index(i) - meana) * (b.Index(i) - meanb) sum += (a.Last(i) - meana) * (b.Last(i) - meanb)
} }
sum /= float64(length) sum /= float64(length)
return sum return sum
@ -711,7 +711,7 @@ func Skew(a Series, length int) float64 {
sum2 := 0.0 sum2 := 0.0
sum3 := 0.0 sum3 := 0.0
for i := 0; i < length; i++ { for i := 0; i < length; i++ {
diff := a.Index(i) - mean diff := a.Last(i) - mean
sum2 += diff * diff sum2 += diff * diff
sum3 += diff * diff * diff sum3 += diff * diff * diff
} }
@ -735,7 +735,7 @@ func (inc *ShiftResult) Last(i int) float64 {
return 0 return 0
} }
return inc.a.Index(inc.offset + i) return inc.a.Last(inc.offset + i)
} }
func (inc *ShiftResult) Index(i int) float64 { func (inc *ShiftResult) Index(i int) float64 {
@ -811,11 +811,11 @@ func Softmax(a Series, window int) SeriesExtend {
s := 0.0 s := 0.0
max := Highest(a, window) max := Highest(a, window)
for i := 0; i < window; i++ { for i := 0; i < window; i++ {
s += math.Exp(a.Index(i) - max) s += math.Exp(a.Last(i) - max)
} }
out := NewQueue(window) out := NewQueue(window)
for i := window - 1; i >= 0; i-- { for i := window - 1; i >= 0; i-- {
out.Update(math.Exp(a.Index(i)-max) / s) out.Update(math.Exp(a.Last(i)-max) / s)
} }
return out return out
} }
@ -825,7 +825,7 @@ func Softmax(a Series, window int) SeriesExtend {
// - sum(v * ln(v)) // - sum(v * ln(v))
func Entropy(a Series, window int) (e float64) { func Entropy(a Series, window int) (e float64) {
for i := 0; i < window; i++ { for i := 0; i < window; i++ {
v := a.Index(i) v := a.Last(i)
if v != 0 { if v != 0 {
e -= v * math.Log(v) e -= v * math.Log(v)
} }
@ -836,9 +836,9 @@ func Entropy(a Series, window int) (e float64) {
// CrossEntropy computes the cross-entropy between the two distributions // CrossEntropy computes the cross-entropy between the two distributions
func CrossEntropy(a, b Series, window int) (e float64) { func CrossEntropy(a, b Series, window int) (e float64) {
for i := 0; i < window; i++ { for i := 0; i < window; i++ {
v := a.Index(i) v := a.Last(i)
if v != 0 { if v != 0 {
e -= v * math.Log(b.Index(i)) e -= v * math.Log(b.Last(i))
} }
} }
return e return e
@ -893,7 +893,7 @@ func LogisticRegression(x []Series, y Series, lookback, iterations int, learning
xx := make([][]float64, lookback) xx := make([][]float64, lookback)
for i := 0; i < lookback; i++ { for i := 0; i < lookback; i++ {
for j := 0; j < features; j++ { for j := 0; j < features; j++ {
xx[i] = append(xx[i], x[j].Index(lookback-i-1)) xx[i] = append(xx[i], x[j].Last(lookback-i-1))
} }
} }
yy := Reverse(y, lookback) yy := Reverse(y, lookback)
@ -1002,7 +1002,7 @@ func (canvas *Canvas) Plot(tag string, a Series, endTime Time, length int, inter
if a.Length() == 0 { if a.Length() == 0 {
return return
} }
oldest := a.Index(a.Length() - 1) oldest := a.Last(a.Length() - 1)
interval := canvas.Interval interval := canvas.Interval
if len(intervals) > 0 { if len(intervals) > 0 {
interval = intervals[0] interval = intervals[0]
@ -1026,7 +1026,7 @@ func (canvas *Canvas) PlotRaw(tag string, a Series, length int) {
if a.Length() == 0 { if a.Length() == 0 {
return return
} }
oldest := a.Index(a.Length() - 1) oldest := a.Last(a.Length() - 1)
canvas.Series = append(canvas.Series, chart.ContinuousSeries{ canvas.Series = append(canvas.Series, chart.ContinuousSeries{
Name: tag, Name: tag,
XValues: x, XValues: x,

View File

@ -24,7 +24,7 @@ func TestQueue(t *testing.T) {
func TestFloat(t *testing.T) { func TestFloat(t *testing.T) {
var a Series = Sub(3., 2.) var a Series = Sub(3., 2.)
assert.Equal(t, a.Last(0), 1.) assert.Equal(t, a.Last(0), 1.)
assert.Equal(t, a.Index(100), 1.) assert.Equal(t, a.Last(100), 1.)
} }
func TestNextCross(t *testing.T) { func TestNextCross(t *testing.T) {
@ -67,8 +67,8 @@ func TestCorr(t *testing.T) {
corr := Correlation(&a, &b, 4, Pearson) corr := Correlation(&a, &b, 4, Pearson)
assert.InDelta(t, corr, -0.8510644, 0.001) assert.InDelta(t, corr, -0.8510644, 0.001)
out := Rank(&a, 4) out := Rank(&a, 4)
assert.Equal(t, out.Index(0), 2.5) assert.Equal(t, out.Last(0), 2.5)
assert.Equal(t, out.Index(1), 4.0) assert.Equal(t, out.Last(1), 4.0)
corr = Correlation(&a, &b, 4, Spearman) corr = Correlation(&a, &b, 4, Spearman)
assert.InDelta(t, corr, -0.94868, 0.001) assert.InDelta(t, corr, -0.94868, 0.001)
} }
@ -119,7 +119,7 @@ func TestSoftmax(t *testing.T) {
out := Softmax(&a, a.Length()) out := Softmax(&a, a.Length())
r := floats.Slice{0.8360188027814407, 0.11314284146556013, 0.05083835575299916} r := floats.Slice{0.8360188027814407, 0.11314284146556013, 0.05083835575299916}
for i := 0; i < out.Length(); i++ { for i := 0; i < out.Length(); i++ {
assert.InDelta(t, r.Index(i), out.Index(i), 0.001) assert.InDelta(t, r.Last(i), out.Last(i), 0.001)
} }
} }
@ -128,7 +128,7 @@ func TestSigmoid(t *testing.T) {
out := Sigmoid(&a) out := Sigmoid(&a)
r := floats.Slice{0.9525741268224334, 0.7310585786300049, 0.8909031788043871} r := floats.Slice{0.9525741268224334, 0.7310585786300049, 0.8909031788043871}
for i := 0; i < out.Length(); i++ { for i := 0; i < out.Length(); i++ {
assert.InDelta(t, r.Index(i), out.Index(i), 0.001, "i=%d", i) assert.InDelta(t, r.Last(i), out.Last(i), 0.001, "i=%d", i)
} }
} }
@ -143,7 +143,6 @@ func TestAdd(t *testing.T) {
var b NumberSeries = 2.0 var b NumberSeries = 2.0
out := Add(&a, &b) out := Add(&a, &b)
assert.Equal(t, out.Last(0), 5.0) assert.Equal(t, out.Last(0), 5.0)
assert.Equal(t, out.Index(0), 5.0)
assert.Equal(t, out.Length(), math.MaxInt32) assert.Equal(t, out.Length(), math.MaxInt32)
} }
@ -153,7 +152,7 @@ func TestDiv(t *testing.T) {
out := Div(&a, &b) out := Div(&a, &b)
assert.Equal(t, 1.0, out.Last(0)) assert.Equal(t, 1.0, out.Last(0))
assert.Equal(t, 3, out.Length()) assert.Equal(t, 3, out.Length())
assert.Equal(t, 0.5, out.Index(1)) assert.Equal(t, 0.5, out.Last(1))
} }
func TestMul(t *testing.T) { func TestMul(t *testing.T) {
@ -162,7 +161,7 @@ func TestMul(t *testing.T) {
out := Mul(&a, &b) out := Mul(&a, &b)
assert.Equal(t, out.Last(0), 4.0) assert.Equal(t, out.Last(0), 4.0)
assert.Equal(t, out.Length(), 3) assert.Equal(t, out.Length(), 3)
assert.Equal(t, out.Index(1), 2.0) assert.Equal(t, out.Last(1), 2.0)
} }
func TestArray(t *testing.T) { func TestArray(t *testing.T) {

View File

@ -597,26 +597,11 @@ type KLineSeries struct {
kv KValueType kv KValueType
} }
func (k *KLineSeries) Last(int) float64 { func (k *KLineSeries) Index(i int) float64 {
length := len(*k.lines) return k.Last(i)
switch k.kv {
case kOpUnknown:
panic("kline series operator unknown")
case kOpenValue:
return (*k.lines)[length-1].GetOpen().Float64()
case kCloseValue:
return (*k.lines)[length-1].GetClose().Float64()
case kLowValue:
return (*k.lines)[length-1].GetLow().Float64()
case kHighValue:
return (*k.lines)[length-1].GetHigh().Float64()
case kVolumeValue:
return (*k.lines)[length-1].Volume.Float64()
}
return 0
} }
func (k *KLineSeries) Index(i int) float64 { func (k *KLineSeries) Last(i int) float64 {
length := len(*k.lines) length := len(*k.lines)
if length == 0 || length-i-1 < 0 { if length == 0 || length-i-1 < 0 {
return 0 return 0

View File

@ -17,7 +17,7 @@ func Omega(returns Series, returnThresholds ...float64) float64 {
win := 0.0 win := 0.0
loss := 0.0 loss := 0.0
for i := 0; i < length; i++ { for i := 0; i < length; i++ {
out := threshold - returns.Index(i) out := threshold - returns.Last(i)
if out > 0 { if out > 0 {
win += out win += out
} else { } else {

View File

@ -2,6 +2,7 @@ package types
import ( import (
"fmt" "fmt"
"gonum.org/v1/gonum/mat" "gonum.org/v1/gonum/mat"
) )
@ -21,7 +22,7 @@ func (pca *PCA) Fit(x []SeriesExtend, lookback int) error {
for i, xx := range x { for i, xx := range x {
mean := xx.Mean(lookback) mean := xx.Mean(lookback)
for j := 0; j < lookback; j++ { for j := 0; j < lookback; j++ {
vec[i+j*i] = xx.Index(j) - mean vec[i+j*i] = xx.Last(j) - mean
} }
} }
pca.svd = &mat.SVD{} pca.svd = &mat.SVD{}
@ -40,7 +41,7 @@ func (pca *PCA) Transform(x []SeriesExtend, lookback int, features int) (result
vec := make([]float64, lookback*len(x)) vec := make([]float64, lookback*len(x))
for i, xx := range x { for i, xx := range x {
for j := 0; j < lookback; j++ { for j := 0; j < lookback; j++ {
vec[i+j*i] = xx.Index(j) vec[i+j*i] = xx.Last(j)
} }
} }
newX := mat.NewDense(lookback, len(x), vec) newX := mat.NewDense(lookback, len(x), vec)

View File

@ -21,6 +21,7 @@ func (inc *Queue) Last(i int) float64 {
if i < 0 || len(inc.arr)-i-1 < 0 { if i < 0 || len(inc.arr)-i-1 < 0 {
return 0 return 0
} }
return inc.arr[len(inc.arr)-1-i] return inc.arr[len(inc.arr)-1-i]
} }

View File

@ -103,7 +103,7 @@ func Sum(a Series, limit ...int) (sum float64) {
l = limit[0] l = limit[0]
} }
for i := 0; i < l; i++ { for i := 0; i < l; i++ {
sum += a.Index(i) sum += a.Last(i)
} }
return sum return sum
} }

View File

@ -12,19 +12,16 @@ type SeriesBase struct {
} }
func (s *SeriesBase) Index(i int) float64 { func (s *SeriesBase) Index(i int) float64 {
return s.Last(i)
}
func (s *SeriesBase) Last(i int) float64 {
if s.Series == nil { if s.Series == nil {
return 0 return 0
} }
return s.Series.Last(i) return s.Series.Last(i)
} }
func (s *SeriesBase) Last(int) float64 {
if s.Series == nil {
return 0
}
return s.Series.Last(0)
}
func (s *SeriesBase) Length() int { func (s *SeriesBase) Length() int {
if s.Series == nil { if s.Series == nil {
return 0 return 0

View File

@ -6,9 +6,11 @@ import (
// Sortino: Calcluates the sotino ratio of access returns // Sortino: Calcluates the sotino ratio of access returns
// //
// ROI_excess E[ROI] - ROI_risk_free // ROI_excess E[ROI] - ROI_risk_free
//
// sortino = ---------- = ----------------------- // sortino = ---------- = -----------------------
// risk sqrt(E[ROI_drawdown^2]) //
// risk sqrt(E[ROI_drawdown^2])
// //
// @param returns (Series): Series of profit/loss percentage every specific interval // @param returns (Series): Series of profit/loss percentage every specific interval
// @param riskFreeReturns (float): risk-free return rate of year // @param riskFreeReturns (float): risk-free return rate of year
@ -29,7 +31,7 @@ func Sortino(returns Series, riskFreeReturns float64, periods int, annualize boo
} }
var sum = 0. var sum = 0.
for i := 0; i < num; i++ { for i := 0; i < num; i++ {
exRet := returns.Index(i) - avgRiskFreeReturns exRet := returns.Last(i) - avgRiskFreeReturns
if exRet < 0 { if exRet < 0 {
sum += exRet * exRet sum += exRet * exRet
} }