66 lines
1.2 KiB
Go
66 lines
1.2 KiB
Go
package com
|
||
|
||
import (
|
||
"math"
|
||
"slices"
|
||
)
|
||
|
||
type Slop struct {
|
||
lastCalc int
|
||
sampleNum int
|
||
Dirt int // 大周期斜率方向:1向上,0不明确,-1向下
|
||
rate float64 // 斜率阈值,推荐0.25
|
||
Data []float64
|
||
Top float64
|
||
Btm float64
|
||
}
|
||
|
||
func NewSlop(sampleNum int, rate float64) *Slop {
|
||
return &Slop{
|
||
Dirt: 0,
|
||
sampleNum: sampleNum,
|
||
rate: rate,
|
||
Top: math.NaN(),
|
||
Btm: math.NaN(),
|
||
}
|
||
}
|
||
|
||
func (s *Slop) Update(barNum int, slop float64) {
|
||
s.Data = append(s.Data, math.Abs(slop))
|
||
if len(s.Data) < s.sampleNum {
|
||
return
|
||
}
|
||
if !math.IsNaN(s.Top) {
|
||
s.Dirt = 0
|
||
if slop >= s.Top {
|
||
s.Dirt = 1
|
||
} else if slop <= s.Btm {
|
||
s.Dirt = -1
|
||
}
|
||
}
|
||
if barNum-s.lastCalc < s.sampleNum/2 {
|
||
return
|
||
}
|
||
if len(s.Data) > s.sampleNum {
|
||
s.Data = s.Data[len(s.Data)-s.sampleNum:]
|
||
}
|
||
thres := CutScore(s.Data, s.rate)
|
||
s.Top = thres
|
||
s.Btm = -thres
|
||
s.lastCalc = barNum
|
||
s.Dirt = 0
|
||
if slop >= s.Top {
|
||
s.Dirt = 1
|
||
} else if slop <= s.Btm {
|
||
s.Dirt = -1
|
||
}
|
||
}
|
||
|
||
func CutScore(vals []float64, rate float64) float64 {
|
||
arr := make([]float64, len(vals))
|
||
copy(arr, vals)
|
||
slices.Sort(arr)
|
||
idx := int(float64(len(vals)) * rate)
|
||
return arr[idx]
|
||
}
|