新增注释
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user