128 lines
3.2 KiB
Go
128 lines
3.2 KiB
Go
package index
|
|
|
|
import (
|
|
"log"
|
|
|
|
"git.apinb.com/quant/strategy/internal/core/trade"
|
|
"github.com/markcheno/go-talib"
|
|
)
|
|
|
|
// LineRegSlope 根据线性回归斜率分析最新4条K线是否存在反转情况
|
|
// 改进版本:修复了逻辑错误,增加了边界检查,优化了性能
|
|
func LineRegSlope(a *Args) (action string) {
|
|
// 边界检查:确保有足够的数据
|
|
if len(a.InReal) < a.Period {
|
|
if a.Debug {
|
|
log.Println("LineRegSlope: 数据不足,需要至少", a.Period, "条数据")
|
|
}
|
|
return
|
|
}
|
|
|
|
result := talib.LinearRegSlope(a.InReal, a.Period)
|
|
|
|
// 边界检查:确保结果数组有足够的数据
|
|
if len(result) < 4 {
|
|
if a.Debug {
|
|
log.Println("LineRegSlope: 线性回归结果不足4条")
|
|
}
|
|
return
|
|
}
|
|
|
|
// 获取最新4条K线的斜率值
|
|
origin := result[len(result)-4:]
|
|
|
|
// 处理斜率值,保留所有值(移除过于严格的过滤)
|
|
var k4 []float64
|
|
for _, val := range origin {
|
|
if val >= 0.001 || val <= -0.001 {
|
|
roundedVal := trade.FloatRound(val, 6)
|
|
k4 = append(k4, roundedVal)
|
|
}
|
|
}
|
|
|
|
if a.Debug {
|
|
log.Println("Origin", result)
|
|
log.Println("Kline4", k4)
|
|
}
|
|
|
|
// 检查是否有足够的数据
|
|
if len(k4) < 4 {
|
|
return
|
|
}
|
|
|
|
// 判断反转信号
|
|
// 下降反转:从正斜率转为负斜率,且斜率递减
|
|
if k4[0] > 0 && k4[3] < 0 {
|
|
// 检查斜率是否呈现递减趋势(从正到负的平滑过渡)
|
|
if isDecreasingTrend(k4) {
|
|
action = "DOWN"
|
|
}
|
|
}
|
|
|
|
// 上升反转:从负斜率转为正斜率,且斜率递增
|
|
if k4[0] < 0 && k4[3] > 0 {
|
|
// 检查斜率是否呈现递增趋势(从负到正的平滑过渡)
|
|
if isIncreasingTrend(k4) {
|
|
action = "UP"
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// isDecreasingTrend 检查斜率是否呈现递减趋势
|
|
func isDecreasingTrend(slopes []float64) bool {
|
|
// 简化的递减判断:确保整体趋势是递减的
|
|
// 允许中间有小的波动,但整体方向是向下的
|
|
for i := 1; i < len(slopes); i++ {
|
|
if slopes[i] > slopes[i-1] {
|
|
// 如果发现上升,检查是否只是小幅波动
|
|
if slopes[i]-slopes[i-1] > 0.01 { // 允许小幅波动
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// isIncreasingTrend 检查斜率是否呈现递增趋势
|
|
func isIncreasingTrend(slopes []float64) bool {
|
|
// 简化的递增判断:确保整体趋势是递增的
|
|
// 允许中间有小的波动,但整体方向是向上的
|
|
for i := 1; i < len(slopes); i++ {
|
|
if slopes[i] < slopes[i-1] {
|
|
// 如果发现下降,检查是否只是小幅波动
|
|
if slopes[i-1]-slopes[i] > 0.01 { // 允许小幅波动
|
|
return false
|
|
}
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
// CurrentSlopeDirection 基于最新线性回归斜率给出当前方向(非反转)
|
|
// 返回:"UP" / "DOWN" / ""(无明显方向)
|
|
func CurrentSlopeDirection(a *Args) string {
|
|
if len(a.InReal) < a.Period {
|
|
if a.Debug {
|
|
log.Println("CurrentSlopeDirection: 数据不足,需要至少", a.Period, "条数据")
|
|
}
|
|
return ""
|
|
}
|
|
|
|
s := talib.LinearRegSlope(a.InReal, a.Period)
|
|
if len(s) == 0 {
|
|
return ""
|
|
}
|
|
|
|
latest := s[len(s)-1]
|
|
// 轻微阈值,避免噪声抖动;可按回测调整
|
|
const threshold = 0.0002
|
|
if latest > threshold {
|
|
return "UP"
|
|
}
|
|
if latest < -threshold {
|
|
return "DOWN"
|
|
}
|
|
return ""
|
|
} |