deving
This commit is contained in:
@@ -19,13 +19,44 @@ func main() {
|
|||||||
impl.NewImpl()
|
impl.NewImpl()
|
||||||
|
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
run()
|
ClosedTable()
|
||||||
|
UnclosedTable()
|
||||||
fmt.Println("")
|
fmt.Println("")
|
||||||
}
|
}
|
||||||
|
|
||||||
func run() {
|
func ClosedTable() {
|
||||||
tw := table.NewWriter()
|
tw := table.NewWriter()
|
||||||
tw.SetStyle(table.StyleLight)
|
tw.SetStyle(table.StyleLight)
|
||||||
|
tw.SetTitle("已清仓列表")
|
||||||
|
tw.AppendHeader(table.Row{"ID", "Code", "Name", "OpenDate", "OpenPrice", "CloseDate", "ClosePrice", "PNL/Per", "PNLRate(%)"})
|
||||||
|
var data []models.MockPosition
|
||||||
|
impl.DBService.Where("status=?", 1).Find(&data)
|
||||||
|
var tPNL, tPNLR, cost, sell float64
|
||||||
|
for _, item := range data {
|
||||||
|
var stock models.StockBasic
|
||||||
|
impl.DBService.Where("ts_code=?", item.Code).First(&stock)
|
||||||
|
|
||||||
|
pnl := utils.FloatRound(item.ClosePrice-item.OpenPrice, 2)
|
||||||
|
pnlRate := utils.FloatRound(pnl/item.OpenPrice*100, 2)
|
||||||
|
|
||||||
|
tPNL = tPNL + pnl
|
||||||
|
cost = cost + item.OpenPrice
|
||||||
|
sell = sell + item.ClosePrice
|
||||||
|
|
||||||
|
tw.AppendRow(table.Row{item.ID, item.Code, stock.Name, item.CreatedAt.Format("2006-01-02"), item.OpenPrice, item.UpdatedAt.Format("2006-01-02"), item.ClosePrice, pnl, pnlRate})
|
||||||
|
}
|
||||||
|
|
||||||
|
tPNLR = utils.FloatRound(((sell-cost)/cost)*100, 2)
|
||||||
|
|
||||||
|
tw.AppendFooter(table.Row{"", "", "", "TOTAL", utils.FloatRound(cost, 2), utils.FloatRound(sell, 2), utils.FloatRound(tPNL, 2), tPNLR})
|
||||||
|
|
||||||
|
fmt.Println(tw.Render())
|
||||||
|
}
|
||||||
|
|
||||||
|
func UnclosedTable() {
|
||||||
|
tw := table.NewWriter()
|
||||||
|
tw.SetStyle(table.StyleLight)
|
||||||
|
tw.SetTitle("未平仓列表")
|
||||||
tw.AppendHeader(table.Row{"ID", "Code", "Name", "OpenDate", "OpenPrice", "TodayPrice", "PNL/Per", "PNLRate(%)"})
|
tw.AppendHeader(table.Row{"ID", "Code", "Name", "OpenDate", "OpenPrice", "TodayPrice", "PNL/Per", "PNLRate(%)"})
|
||||||
var data []models.MockPosition
|
var data []models.MockPosition
|
||||||
impl.DBService.Where("status=?", 0).Find(&data)
|
impl.DBService.Where("status=?", 0).Find(&data)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
func Run(key string, ymd int) {
|
func Run(key string, ymd int) {
|
||||||
log.Println("Run Mock Order.")
|
log.Println("Run Mock Order.")
|
||||||
var stocks []*models.StratModel
|
var stocks []*models.StratModel
|
||||||
impl.DBService.Where("strat_key=? and ymd=? and ai_score>=?", key, ymd, 5).Find(&stocks)
|
impl.DBService.Where("strat_key=? and ymd=? and rsi_score>0 and macd_score>0 ai_score>=?", key, ymd, 5).Find(&stocks)
|
||||||
if len(stocks) == 0 {
|
if len(stocks) == 0 {
|
||||||
log.Println("No data to process.")
|
log.Println("No data to process.")
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -45,13 +45,11 @@ func Starter(ctx *gin.Context) {
|
|||||||
|
|
||||||
// 满足以上规则在让Deepseek分析
|
// 满足以上规则在让Deepseek分析
|
||||||
if model.UpDateDay > 360 && model.StScore > 0 && model.IndustryScore > 1 && model.GtPrice > 0 && model.GtAmount > 0 && model.RoeScore > 0 {
|
if model.UpDateDay > 360 && model.StScore > 0 && model.IndustryScore > 1 && model.GtPrice > 0 && model.GtAmount > 0 && model.RoeScore > 0 {
|
||||||
model.AiScore = 0 // 待分析
|
model.Status = 1 // 待Indicator分析
|
||||||
model.Status = 1
|
|
||||||
model.TotalScore = float64(model.IndustryScore + model.StScore + model.GtPrice + model.GtAmount + model.RoeScore)
|
model.TotalScore = float64(model.IndustryScore + model.StScore + model.GtPrice + model.GtAmount + model.RoeScore)
|
||||||
model.RecommendDesc = "Rule规则"
|
model.AddDesc("Rule规则满足,加入标的")
|
||||||
} else {
|
} else {
|
||||||
model.Status = -1
|
model.Status = -1
|
||||||
model.AiScore = -2
|
|
||||||
model.AddDesc("Rule规则不满足,不加入标的")
|
model.AddDesc("Rule规则不满足,不加入标的")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,16 +62,12 @@ func Starter(ctx *gin.Context) {
|
|||||||
impl.DBService.Model(&models.StratModel{}).Where("status=1 and ymd=?", ymd).Find(&allowStocks)
|
impl.DBService.Model(&models.StratModel{}).Where("status=1 and ymd=?", ymd).Find(&allowStocks)
|
||||||
for _, m := range allowStocks {
|
for _, m := range allowStocks {
|
||||||
// CTA:RSI指标贴近下轨并成上涨趋势
|
// CTA:RSI指标贴近下轨并成上涨趋势
|
||||||
indicator.New(m).RunRsi()
|
rsiResult := indicator.RunRsi(m.Code)
|
||||||
|
impl.DBService.Model(m).Where("id=?", m.ID).Updates(map[string]any{"rsi_score": rsiResult.Score, "rsi_val_oversold": rsiResult.Oversold, "rsi_val_prve": rsiResult.Prve, "rsi_val_last": rsiResult.Last, "recommend_desc": m.RecommendDesc + "||Rsi:" + rsiResult.Desc})
|
||||||
// 满足以上规则在让Deepseek分析
|
|
||||||
if m.ScoreRsi < 0 {
|
|
||||||
impl.DBService.Model(m).Where("id=?", m.ID).Updates(map[string]any{"ai_score": -2, "recommend_desc": m.RecommendDesc + "||" + "无需AI分析,RsiScore:" + utils.Int2String(m.ScoreRsi)})
|
|
||||||
}
|
|
||||||
|
|
||||||
// CTA:MACD指标红绿柱及价量关系
|
// CTA:MACD指标红绿柱及价量关系
|
||||||
score, desc := indicator.New(m).RunMacd()
|
macdResult := indicator.RunMacd(m.Code)
|
||||||
impl.DBService.Model(m).Where("id=?", m.ID).Updates(map[string]any{"macd_score": score, "recommend_desc": m.RecommendDesc + "||" + desc})
|
impl.DBService.Model(m).Where("id=?", m.ID).Updates(map[string]any{"macd_score": macdResult.Score, "macd_val": macdResult.Val, "recommend_desc": m.RecommendDesc + "||Macd:" + macdResult.Desc})
|
||||||
}
|
}
|
||||||
|
|
||||||
// 加入资金流向特大的标的
|
// 加入资金流向特大的标的
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ func Boot() {
|
|||||||
// 启动 AI 分析任务
|
// 启动 AI 分析任务
|
||||||
func BootAiStart(key string, ymd int) error {
|
func BootAiStart(key string, ymd int) error {
|
||||||
var datas []models.StratModel
|
var datas []models.StratModel
|
||||||
err := impl.DBService.Where("strat_key=? and ymd=? and ai_score=0", key, ymd).Find(&datas).Error
|
err := impl.DBService.Where("strat_key=? and ymd=? and (rsi_score>0 or macd_score>0)", key, ymd).Find(&datas).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Failed to query data: %v", err)
|
log.Printf("Failed to query data: %v", err)
|
||||||
return fmt.Errorf("query failed: %w", err)
|
return fmt.Errorf("query failed: %w", err)
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ MACD在0轴下方金叉后,股价小幅调整导致快慢线黏合,但并未
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"git.apinb.com/bsm-sdk/core/utils"
|
"git.apinb.com/bsm-sdk/core/utils"
|
||||||
"git.apinb.com/quant/gostock/internal/impl"
|
"git.apinb.com/quant/gostock/internal/impl"
|
||||||
@@ -57,11 +58,21 @@ const (
|
|||||||
defaultMacdSignal = 9
|
defaultMacdSignal = 9
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
desc []string
|
||||||
|
)
|
||||||
|
|
||||||
|
type MacdResult struct {
|
||||||
|
Score int
|
||||||
|
Val float64
|
||||||
|
Desc string
|
||||||
|
}
|
||||||
|
|
||||||
// RunMacd 根据MACD红绿柱及价量关系,对当前标的进行打分与描述
|
// RunMacd 根据MACD红绿柱及价量关系,对当前标的进行打分与描述
|
||||||
func (r *IndicatorFactory) RunMacd() (int, string) {
|
func RunMacd(code string) *MacdResult {
|
||||||
args, _, err := GetArgConfig(r.Model.Code)
|
args, _, err := GetArgConfig(code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return -1, "MACD参数错误!"
|
return &MacdResult{Score: -1, Desc: "MACD参数错误!"}
|
||||||
}
|
}
|
||||||
|
|
||||||
fast := args.EmaFast
|
fast := args.EmaFast
|
||||||
@@ -85,19 +96,19 @@ func (r *IndicatorFactory) RunMacd() (int, string) {
|
|||||||
var vols []float64
|
var vols []float64
|
||||||
|
|
||||||
impl.DBService.Model(models.StockDaily{}).
|
impl.DBService.Model(models.StockDaily{}).
|
||||||
Where("ts_code = ?", r.Model.Code).
|
Where("ts_code = ?", code).
|
||||||
Order("trade_date desc").
|
Order("trade_date desc").
|
||||||
Limit(limit).
|
Limit(limit).
|
||||||
Pluck("close", &closes)
|
Pluck("close", &closes)
|
||||||
|
|
||||||
impl.DBService.Model(models.StockDaily{}).
|
impl.DBService.Model(models.StockDaily{}).
|
||||||
Where("ts_code = ?", r.Model.Code).
|
Where("ts_code = ?", code).
|
||||||
Order("trade_date desc").
|
Order("trade_date desc").
|
||||||
Limit(limit).
|
Limit(limit).
|
||||||
Pluck("vol", &vols)
|
Pluck("vol", &vols)
|
||||||
|
|
||||||
if len(closes) < slow+signal+5 {
|
if len(closes) < slow+signal+5 {
|
||||||
return -1, "MACD 数据不足"
|
return &MacdResult{Score: -1, Desc: "MACD 数据不足"}
|
||||||
}
|
}
|
||||||
|
|
||||||
closes = ReverseSlice(closes)
|
closes = ReverseSlice(closes)
|
||||||
@@ -112,7 +123,7 @@ func (r *IndicatorFactory) RunMacd() (int, string) {
|
|||||||
macdLine, signalLine, hist := talib.Macd(closes, fast, slow, signal)
|
macdLine, signalLine, hist := talib.Macd(closes, fast, slow, signal)
|
||||||
n := len(hist)
|
n := len(hist)
|
||||||
if n < 5 {
|
if n < 5 {
|
||||||
return -1, "MACD 计算结果不足"
|
return &MacdResult{Score: -1, Desc: "MACD 计算结果不足"}
|
||||||
}
|
}
|
||||||
|
|
||||||
lastIdx := n - 1
|
lastIdx := n - 1
|
||||||
@@ -123,33 +134,33 @@ func (r *IndicatorFactory) RunMacd() (int, string) {
|
|||||||
lastMacd := macdLine[lastIdx]
|
lastMacd := macdLine[lastIdx]
|
||||||
lastSignal := signalLine[lastIdx]
|
lastSignal := signalLine[lastIdx]
|
||||||
|
|
||||||
r.Model.MacdVal = utils.FloatRound(lastHist, 4)
|
macdVal := utils.FloatRound(lastHist, 4)
|
||||||
|
|
||||||
score := -1
|
score := -1
|
||||||
|
|
||||||
// 3.1 基础买入信号:绿柱转红柱,零轴下方或附近
|
// 3.1 基础买入信号:绿柱转红柱,零轴下方或附近
|
||||||
if prevHist < 0 && lastHist > 0 && lastMacd <= 0 {
|
if prevHist < 0 && lastHist > 0 && lastMacd <= 0 {
|
||||||
score = maxInt(score, 1)
|
score = maxInt(score, 1)
|
||||||
return score, fmt.Sprintf("MACD红绿柱反转:由绿转红,零轴下方/附近,hist=%.4f", lastHist)
|
desc = append(desc, "MACD红绿柱反转:由绿转红,零轴下方/附近")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3.2 趋势跟随买入:红柱连续伸长,DIF/DEA在零轴上方
|
// 3.2 趋势跟随买入:红柱连续伸长,DIF/DEA在零轴上方
|
||||||
if lastMacd > 0 && lastSignal > 0 && isGrowingPositive(hist, 3) {
|
if lastMacd > 0 && lastSignal > 0 && isGrowingPositive(hist, 3) {
|
||||||
score = maxInt(score, 2)
|
score = maxInt(score, 2)
|
||||||
return score, "MACD红柱连续伸长,DIF/DEA零轴上方,趋势跟随买入信号"
|
desc = append(desc, "MACD红柱连续伸长,DIF/DEA零轴上方,趋势跟随买入信号")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3.4 底背离买入:价格新低但绿柱底部抬高,随后红柱确认
|
// 3.4 底背离买入:价格新低但绿柱底部抬高,随后红柱确认
|
||||||
if lastHist > 0 && hasBottomDivergence(closes, hist) {
|
if lastHist > 0 && hasBottomDivergence(closes, hist) {
|
||||||
score = maxInt(score, 2)
|
score = maxInt(score, 2)
|
||||||
return score, "MACD底背离:价格创新低但绿柱底部抬高,红柱确认"
|
desc = append(desc, "MACD价格新低但绿柱底部抬高,后续红柱确认")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 5.1 零轴下金叉后的拒绝死叉:金叉发生在零轴下方,之后未形成有效死叉,红柱再次放大
|
// 5.1 零轴下金叉后的拒绝死叉:金叉发生在零轴下方,之后未形成有效死叉,红柱再次放大
|
||||||
if lastHist > 0 && isGrowingPositive(hist, 2) && hasGoldenCrossRejection(macdLine, signalLine, hist) {
|
if lastHist > 0 && isGrowingPositive(hist, 2) && hasGoldenCrossRejection(macdLine, signalLine, hist) {
|
||||||
score = maxInt(score, 3)
|
score = maxInt(score, 3)
|
||||||
return score, "MACD零轴下金叉后拒绝死叉,红柱再次放大,疑似洗盘结束主升浪启动"
|
desc = append(desc, "MACD零轴下金叉后拒绝死叉,红柱再次放大")
|
||||||
}
|
}
|
||||||
|
|
||||||
// 成交量验证:红柱放大但缩量,降低一次评分
|
// 成交量验证:红柱放大但缩量,降低一次评分
|
||||||
@@ -159,17 +170,21 @@ func (r *IndicatorFactory) RunMacd() (int, string) {
|
|||||||
if score <= 0 {
|
if score <= 0 {
|
||||||
score = -1
|
score = -1
|
||||||
}
|
}
|
||||||
return score, "MACD红柱放大但成交量未同步放大,信号可靠性降低"
|
return &MacdResult{Score: score, Val: macdVal, Desc: "MACD红柱放大但成交量未同步放大,信号可靠性降低"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if score == -1 {
|
if score == -1 {
|
||||||
if lastHist <= 0 {
|
if lastHist <= 0 {
|
||||||
return -1, fmt.Sprintf("MACD未出现明确多头信号,hist=%.4f", lastHist)
|
return &MacdResult{Score: -1, Val: macdVal, Desc: fmt.Sprintf("MACD未出现明确多头信号,hist=%.4f", lastHist)}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return score, "无信号"
|
if score > 0 {
|
||||||
|
return &MacdResult{Score: score, Val: macdVal, Desc: strings.Join(desc, "||")}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &MacdResult{Score: -1, Val: macdVal, Desc: "无信号"}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 最近k根红柱是否连续伸长(严格递增且均为正)
|
// 最近k根红柱是否连续伸长(严格递增且均为正)
|
||||||
@@ -329,4 +344,3 @@ func maxInt(a, b int) int {
|
|||||||
}
|
}
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
package indicator
|
|
||||||
|
|
||||||
import "git.apinb.com/quant/gostock/internal/models"
|
|
||||||
|
|
||||||
type IndicatorFactory struct {
|
|
||||||
Model *models.StratModel
|
|
||||||
}
|
|
||||||
|
|
||||||
func New(m *models.StratModel) *IndicatorFactory {
|
|
||||||
return &IndicatorFactory{
|
|
||||||
Model: m,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -22,6 +22,14 @@ type StockArgConf struct {
|
|||||||
BestByWinRate string `json:"best_by_win_rate"`
|
BestByWinRate string `json:"best_by_win_rate"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RsiResult struct {
|
||||||
|
Score int
|
||||||
|
Oversold int
|
||||||
|
Prve float64
|
||||||
|
Last float64
|
||||||
|
Desc string
|
||||||
|
}
|
||||||
|
|
||||||
func GetArgConfig(code string) (*models.StockArgs, *StockArgConf, error) {
|
func GetArgConfig(code string) (*models.StockArgs, *StockArgConf, error) {
|
||||||
var args models.StockArgs
|
var args models.StockArgs
|
||||||
err := impl.DBService.Where("ts_code = ?", code).First(&args).Error
|
err := impl.DBService.Where("ts_code = ?", code).First(&args).Error
|
||||||
@@ -38,32 +46,24 @@ func GetArgConfig(code string) (*models.StockArgs, *StockArgConf, error) {
|
|||||||
return &args, &conf, nil
|
return &args, &conf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *IndicatorFactory) RunRsi() {
|
func RunRsi(code string) *RsiResult {
|
||||||
args, conf, err := GetArgConfig(r.Model.Code)
|
args, conf, err := GetArgConfig(code)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Model.ScoreRsi = -1
|
return &RsiResult{Score: -1, Desc: "RSI参数错误!"}
|
||||||
r.Model.AddDesc("RSI参数错误!")
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if args.RsiOversold == 0 {
|
if args.RsiOversold == 0 {
|
||||||
r.Model.ScoreRsi = -1
|
return &RsiResult{Score: -1, Desc: "RSI Oversold=0,参数错误!"}
|
||||||
r.Model.AddDesc("RSI RsiOversold=0,参数错误!")
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if conf.BestByProfit != "rsi" {
|
if conf.BestByProfit != "rsi" {
|
||||||
r.Model.ScoreRsi = -1
|
return &RsiResult{Score: -1, Desc: "BestByProfit不是RSI"}
|
||||||
r.Model.AddDesc("BestByProfit不是RSI")
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var close []float64
|
var close []float64
|
||||||
impl.DBService.Model(models.StockDaily{}).Where("ts_code = ?", r.Model.Code).Order("trade_date desc").Limit(args.RsiPeriod*4).Pluck("close", &close)
|
impl.DBService.Model(models.StockDaily{}).Where("ts_code = ?", code).Order("trade_date desc").Limit(args.RsiPeriod*4).Pluck("close", &close)
|
||||||
if len(close) < args.RsiPeriod {
|
if len(close) < args.RsiPeriod {
|
||||||
r.Model.ScoreRsi = -1
|
return &RsiResult{Score: -1, Desc: "数据不足"}
|
||||||
r.Model.AddDesc("数据不足")
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
newCloses := ReverseSlice(close)
|
newCloses := ReverseSlice(close)
|
||||||
@@ -72,46 +72,46 @@ func (r *IndicatorFactory) RunRsi() {
|
|||||||
rsiResult := talib.Rsi(newCloses, args.RsiPeriod)
|
rsiResult := talib.Rsi(newCloses, args.RsiPeriod)
|
||||||
prveRsi := utils.FloatRound(rsiResult[len(rsiResult)-2], 2)
|
prveRsi := utils.FloatRound(rsiResult[len(rsiResult)-2], 2)
|
||||||
lastRsi := utils.FloatRound(rsiResult[len(rsiResult)-1], 2)
|
lastRsi := utils.FloatRound(rsiResult[len(rsiResult)-1], 2)
|
||||||
r.Model.ValRsiLast = lastRsi
|
|
||||||
r.Model.ValRsiPrve = prveRsi
|
r := &RsiResult{Oversold: args.RsiOversold, Prve: prveRsi, Last: lastRsi}
|
||||||
r.Model.ValRsiOversold = args.RsiOversold
|
|
||||||
prveRsiInt := int(prveRsi)
|
prveRsiInt := int(prveRsi)
|
||||||
lastRsiInt := int(lastRsi)
|
lastRsiInt := int(lastRsi)
|
||||||
|
|
||||||
if lastRsiInt == 0 {
|
if lastRsiInt == 0 {
|
||||||
r.Model.ScoreRsi = -1
|
r.Score = -1
|
||||||
r.Model.AddDesc("RSI lastRsiInt=0,计算错误!")
|
r.Desc = "RSI lastRsiInt=0,计算错误!"
|
||||||
return
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
// 跌破RSI下轨
|
// 跌破RSI下轨
|
||||||
if lastRsiInt > args.RsiOversold {
|
if lastRsiInt > args.RsiOversold {
|
||||||
if CheckLowest(close, lastRsiInt, 14) {
|
if CheckLowest(close, lastRsiInt, 14) {
|
||||||
r.Model.ScoreRsi = 1
|
r.Score = 1
|
||||||
r.Model.AddDesc(fmt.Sprintf("RSI=%d 跌破下轨,14日最低", lastRsiInt))
|
r.Desc = fmt.Sprintf("RSI=%d 跌破下轨,14日最低", lastRsiInt)
|
||||||
return
|
return r
|
||||||
}
|
}
|
||||||
if CheckLowest(close, lastRsiInt, 20) {
|
if CheckLowest(close, lastRsiInt, 20) {
|
||||||
r.Model.ScoreRsi = 1
|
r.Score = 1
|
||||||
r.Model.AddDesc(fmt.Sprintf("RSI=%d 跌破下轨,20日最低", lastRsiInt))
|
r.Desc = fmt.Sprintf("RSI=%d 跌破下轨,20日最低", lastRsiInt)
|
||||||
return
|
return r
|
||||||
}
|
}
|
||||||
r.Model.ScoreRsi = -1
|
r.Score = -1
|
||||||
r.Model.AddDesc(fmt.Sprintf("RSI=%d 高于Oversold%d", lastRsiInt, args.RsiOversold))
|
r.Desc = fmt.Sprintf("RSI=%d 高于Oversold%d", lastRsiInt, args.RsiOversold)
|
||||||
return
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
// RSI跌破下轨后呈上涨趋势
|
// RSI跌破下轨后呈上涨趋势
|
||||||
if lastRsiInt < prveRsiInt {
|
if lastRsiInt < prveRsiInt {
|
||||||
r.Model.ScoreRsi = -1
|
r.Score = -1
|
||||||
r.Model.AddDesc(fmt.Sprintf("Rsi=%d prveRsi=%d,突破下轨,持续下跌", lastRsiInt, prveRsiInt))
|
r.Desc = fmt.Sprintf("Rsi=%d prveRsi=%d,突破下轨,持续下跌", lastRsiInt, prveRsiInt)
|
||||||
return
|
return r
|
||||||
} else if lastRsiInt == prveRsiInt {
|
} else if lastRsiInt == prveRsiInt {
|
||||||
r.Model.ScoreRsi = 1
|
r.Score = 1
|
||||||
r.Model.AddDesc(fmt.Sprintf("Rsi=%d prveRsi=%d,突破下轨,与前一交易日无太大波动", lastRsiInt, prveRsiInt))
|
r.Desc = fmt.Sprintf("Rsi=%d prveRsi=%d,突破下轨,与前一交易日无太大波动", lastRsiInt, prveRsiInt)
|
||||||
return
|
return r
|
||||||
}
|
}
|
||||||
r.Model.ScoreRsi = 2
|
r.Score = 1
|
||||||
r.Model.AddDesc(fmt.Sprintf("Rsi=%d prveRsi=%d,突破下轨后呈上涨趋势", lastRsiInt, prveRsiInt))
|
r.Desc = fmt.Sprintf("Rsi=%d prveRsi=%d,突破下轨后呈上涨趋势", lastRsiInt, prveRsiInt)
|
||||||
return
|
return r
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,18 +23,18 @@ type StratModel struct {
|
|||||||
GtPrice int // 最近20日交易日价格大于设定值
|
GtPrice int // 最近20日交易日价格大于设定值
|
||||||
RoeScore int // ROE 是否大于设定值
|
RoeScore int // ROE 是否大于设定值
|
||||||
ValRoe float64 // ROE 值
|
ValRoe float64 // ROE 值
|
||||||
ScoreRsi int
|
RecommendDesc string // 推荐描述
|
||||||
RecommendDesc string // 推荐描述
|
Status int // 状态 -1:不推荐,0:正常 1:推荐
|
||||||
Status int // 状态 -1:不推荐,0:正常 1:推荐
|
|
||||||
|
|
||||||
// macd
|
// macd
|
||||||
MacdScore int
|
MacdScore int `gorm:"default:0"`
|
||||||
MacdVal float64
|
MacdVal float64
|
||||||
|
|
||||||
// 值
|
// Rsi值
|
||||||
ValRsiOversold int
|
RsiScore int `gorm:"default:0"`
|
||||||
ValRsiPrve float64
|
RsiValOversold int
|
||||||
ValRsiLast float64
|
RsiValPrve float64
|
||||||
|
RsiValLast float64
|
||||||
|
|
||||||
//AI
|
//AI
|
||||||
AiSummary string
|
AiSummary string
|
||||||
|
|||||||
Reference in New Issue
Block a user