74 lines
1.9 KiB
Go
74 lines
1.9 KiB
Go
package rule
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"git.apinb.com/quant/gostock/internal/impl"
|
|
"git.apinb.com/quant/gostock/internal/logic/types"
|
|
"git.apinb.com/quant/gostock/internal/models"
|
|
talib "github.com/markcheno/go-talib"
|
|
)
|
|
|
|
type Rsi struct {
|
|
Key string
|
|
Name string
|
|
Conf *StockArgConf
|
|
Args *models.StockArgs
|
|
}
|
|
|
|
type StockArgConf struct {
|
|
BestByDrawdown string `json:"best_by_drawdown"`
|
|
BestByProfit string `json:"best_by_profit"`
|
|
BestByReturn string `json:"best_by_return"`
|
|
BestBySharpe string `json:"best_by_sharpe"`
|
|
BestByWinRate string `json:"best_by_win_rate"`
|
|
}
|
|
|
|
func NewRsi(args *models.StockArgs) *Rsi {
|
|
rsi := &Rsi{
|
|
Key: "Rsi",
|
|
Name: "RSI指标",
|
|
Conf: nil,
|
|
Args: nil,
|
|
}
|
|
|
|
if args == nil {
|
|
return rsi
|
|
}
|
|
|
|
var conf StockArgConf
|
|
err := json.Unmarshal([]byte(args.Config), &conf)
|
|
if err != nil {
|
|
return rsi
|
|
}
|
|
|
|
rsi.Conf = &conf
|
|
rsi.Args = args
|
|
return rsi
|
|
}
|
|
|
|
func (r *Rsi) Run(code string) *types.RuleResult {
|
|
if r.Conf == nil {
|
|
return &types.RuleResult{Key: r.Key, Name: r.Name, Score: -1, Desc: "参数错误!"}
|
|
}
|
|
|
|
if r.Conf.BestByProfit != "rsi" {
|
|
return &types.RuleResult{Key: r.Key, Name: r.Name, Score: -1, Desc: "BestByProfit!=RSI,BestByProfit=" + r.Conf.BestByProfit}
|
|
}
|
|
|
|
var close []float64
|
|
impl.DBService.Model(models.StockDaily{}).Where("ts_code = ?", code).Order("trade_date desc").Limit(r.Args.RsiPeriod*4).Pluck("close", &close)
|
|
if len(close) < r.Args.RsiPeriod {
|
|
return &types.RuleResult{Key: r.Key, Name: r.Name, Score: -1, Desc: "数据不足"}
|
|
}
|
|
|
|
rsiResult := talib.Rsi(close, r.Args.RsiPeriod)
|
|
lastRsi := rsiResult[len(rsiResult)-1]
|
|
if lastRsi > float64(r.Args.RsiOversold) {
|
|
return &types.RuleResult{Key: r.Key, Name: r.Name, Score: -1, Desc: fmt.Sprintf("RSI=%.2f 高于%d", lastRsi, r.Args.RsiOversold)}
|
|
}
|
|
|
|
return &types.RuleResult{Key: r.Key, Name: r.Name, Score: 1, Desc: fmt.Sprintf("RSI=%.2f 低于%d", lastRsi, r.Args.RsiOversold)}
|
|
}
|