新增注释

This commit is contained in:
2026-05-09 17:50:40 +08:00
parent d5c053e59d
commit 8504838ccb
19 changed files with 404 additions and 217 deletions
+16 -8
View File
@@ -8,10 +8,12 @@ import (
"level_go/internal/model"
)
// StockService 提供股票行情查询和区间表现分析能力。
type StockService struct {
DB *gorm.DB
DB *gorm.DB // 数据库连接。
}
// GetHistoryKline 查询指定股票自固定起点以来的日 K 线。
func (s *StockService) GetHistoryKline(code string) ([]model.StockDaily, error) {
var dailies []model.StockDaily
startDate := "2020-01-02"
@@ -24,10 +26,14 @@ func (s *StockService) GetHistoryKline(code string) ([]model.StockDaily, error)
return dailies, err
}
// roundTo2 把浮点数四舍五入到两位小数。
func roundTo2(val float64) float64 {
return math.Round(val*100) / 100
}
// AnalyzePerformance 分析某个涨停日之后到结束日期之间的下跌和反弹表现。
//
// startDate 既是涨停筛选日期,也是行情区间起点;endDate 是行情区间终点。
func (s *StockService) AnalyzePerformance(startDate, endDate string) ([]model.AnalysisResponse, error) {
var results []model.AnalysisResponse
var limits []struct {
@@ -37,7 +43,7 @@ func (s *StockService) AnalyzePerformance(startDate, endDate string) ([]model.An
High float64
}
// 查询涨停股
// 查询 startDate 当日涨停股,并优先使用涨停合并表中的计算最高价。
query := `SELECT l.ts_code, l.name, d.open, COALESCE(l.calc_high, d.high, 0) AS high FROM stock_limit_combined_data l
LEFT JOIN stock_daily d ON l.ts_code = d.ts_code AND l.trade_date = d.trade_date
WHERE l.trade_date = ? AND l.final_status = 1`
@@ -75,7 +81,7 @@ func (s *StockService) AnalyzePerformance(startDate, endDate string) ([]model.An
continue
}
// A. 计算区间绝对最高价
// A. 计算区间绝对最高价,用于前端展示真实区间高点。
overallMax := dailies[0].High
overallMaxDate := dailies[0].TradeDate.Format("2006-01-02")
for _, d := range dailies {
@@ -85,11 +91,11 @@ func (s *StockService) AnalyzePerformance(startDate, endDate string) ([]model.An
}
}
// B. 逻辑计算
// B. 逻辑计算以涨停日最高价为分界,区分“未跌破涨停高点”和“跌破后反弹”两类形态。
limitHigh := stock.High
postDailies := dailies[1:]
// 找出涨停后的全局最低
// 找出涨停后的全局最低,用来判断是否跌破涨停日最高价。
minLowAfterLimit := postDailies[0].Low
for _, d := range postDailies {
if d.Low < minLowAfterLimit {
@@ -102,7 +108,7 @@ func (s *StockService) AnalyzePerformance(startDate, endDate string) ([]model.An
var logicMaxDate string
if minLowAfterLimit >= limitHigh {
// 形态 1:强势。计算涨幅
// 形态 1:强势,后续最低价仍高于涨停日最高价,因此只统计向上空间。
currMax := limitHigh
maxIdx := -1
for i, d := range postDailies {
@@ -120,7 +126,7 @@ func (s *StockService) AnalyzePerformance(startDate, endDate string) ([]model.An
}
dropPct = nil
} else {
// 形态 2:破位。计算降幅和反弹
// 形态 2:破位,先找到破位最低点,再计算从此前最高点到最低点的降幅。
absMinLow := postDailies[0].Low
minIdx := 0
for i, d := range postDailies {
@@ -129,7 +135,7 @@ func (s *StockService) AnalyzePerformance(startDate, endDate string) ([]model.An
minIdx = i
}
}
// 找到涨停到该最低点之间的最高
// 找到涨停日到最低点之间的最高价,作为本次回撤的逻辑高点。
rangeDailies := dailies[:minIdx+2]
rangeMax := dailies[0].High
maxD := startDate
@@ -150,6 +156,7 @@ func (s *StockService) AnalyzePerformance(startDate, endDate string) ([]model.An
reboundPct = &rVal
}
// 收盘价序列给前端画趋势图使用。
var closePrices []float64
for _, d := range dailies {
closePrices = append(closePrices, d.Close)
@@ -171,6 +178,7 @@ func (s *StockService) AnalyzePerformance(startDate, endDate string) ([]model.An
})
}
// 优先展示跌幅更大的破位股票;强势股票由于 DropPct 为 nil 排在后面。
sort.Slice(results, func(i, j int) bool {
if results[i].DropPct == nil && results[j].DropPct != nil {
return false