11点涨停逻辑变更为10点
This commit is contained in:
@@ -2,6 +2,7 @@ package service
|
||||
|
||||
import (
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"level_go/internal/model"
|
||||
@@ -193,7 +194,7 @@ func buildLimitBreakNextPerformanceStock(row limitBreakNextPerformanceRow) model
|
||||
if row.FirstTime != nil {
|
||||
item.FirstTime = formatLimitTime(*row.FirstTime)
|
||||
}
|
||||
item.BreakTimeBefore1100 = isLimitBreakTimeBeforeEleven(item.FirstTime)
|
||||
item.BreakTimeBefore1100 = isLimitBreakTimeBeforeTen(item.FirstTime)
|
||||
if row.TPreClose != nil && *row.TPreClose > 0 {
|
||||
// T 日开盘涨幅以 T 日前收为基准,低于 101% 用于筛选低开/小幅高开炸板。
|
||||
item.TOpenPctChg = pctChangePtr(row.TOpen, *row.TPreClose)
|
||||
@@ -251,12 +252,38 @@ func formatLimitTime(value string) string {
|
||||
return timeText[0:2] + ":" + timeText[2:4] + ":" + timeText[4:6]
|
||||
}
|
||||
|
||||
// isLimitBreakTimeBeforeEleven 判断炸板时间是否早于 11:00。
|
||||
// isLimitBreakTimeBeforeTen 判断炸板时间是否早于 10:00。
|
||||
//
|
||||
// 空时间在当前业务中视为满足条件,保持历史接口行为。
|
||||
func isLimitBreakTimeBeforeEleven(limitTime string) bool {
|
||||
func isLimitBreakTimeBeforeTen(limitTime string) bool {
|
||||
if strings.TrimSpace(limitTime) == "" {
|
||||
return true
|
||||
}
|
||||
return isBeforeEleven(&limitTime)
|
||||
|
||||
timeText := formatLimitTime(limitTime)
|
||||
parts := strings.Split(timeText, ":")
|
||||
if len(parts) < 2 || len(parts) > 3 {
|
||||
return false
|
||||
}
|
||||
|
||||
hour, err := strconv.Atoi(parts[0])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
minute, err := strconv.Atoi(parts[1])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
second := 0
|
||||
if len(parts) == 3 {
|
||||
second, err = strconv.Atoi(parts[2])
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
}
|
||||
if hour < 0 || hour > 23 || minute < 0 || minute > 59 || second < 0 || second > 59 {
|
||||
return false
|
||||
}
|
||||
|
||||
return hour < 10
|
||||
}
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
package service
|
||||
|
||||
import "testing"
|
||||
|
||||
// TestBuildLimitBreakNextPerformanceStockIntradayProfitableUsesTHigh 验证 T+1 盘中可盈利口径。
|
||||
//
|
||||
// 业务要求用 T+1 最高价覆盖 T 日最高价来判断是否可解套,而不是只和 T 日收盘价比较。
|
||||
func TestBuildLimitBreakNextPerformanceStockIntradayProfitableUsesTHigh(t *testing.T) {
|
||||
tClose := 9.50
|
||||
tHigh := 10.00
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
nextHigh *float64
|
||||
want *bool
|
||||
}{
|
||||
{
|
||||
name: "next high below T high cannot cover T high buy loss",
|
||||
nextHigh: float64Ptr(9.99),
|
||||
want: boolPtr(false),
|
||||
},
|
||||
{
|
||||
name: "next high equal T high covers T high buy loss",
|
||||
nextHigh: float64Ptr(10.00),
|
||||
want: boolPtr(true),
|
||||
},
|
||||
{
|
||||
name: "missing next high returns nil",
|
||||
nextHigh: nil,
|
||||
want: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
item := buildLimitBreakNextPerformanceStock(limitBreakNextPerformanceRow{
|
||||
TClose: &tClose,
|
||||
THigh: &tHigh,
|
||||
NextHigh: tt.nextHigh,
|
||||
})
|
||||
|
||||
if tt.want == nil {
|
||||
if item.NextIntradayProfitable != nil {
|
||||
t.Fatalf("NextIntradayProfitable = %v, want nil", *item.NextIntradayProfitable)
|
||||
}
|
||||
return
|
||||
}
|
||||
if item.NextIntradayProfitable == nil {
|
||||
t.Fatalf("NextIntradayProfitable = nil, want %v", *tt.want)
|
||||
}
|
||||
if *item.NextIntradayProfitable != *tt.want {
|
||||
t.Fatalf("NextIntradayProfitable = %v, want %v", *item.NextIntradayProfitable, *tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// float64Ptr 是测试用指针辅助函数。
|
||||
func float64Ptr(value float64) *float64 {
|
||||
return &value
|
||||
}
|
||||
|
||||
// boolPtr 是测试用指针辅助函数。
|
||||
func boolPtr(value bool) *bool {
|
||||
return &value
|
||||
}
|
||||
@@ -167,9 +167,9 @@ candidate AS (
|
||||
LEFT JOIN limit_list_d ppl
|
||||
ON ppl.ts_code = pl.ts_code AND ppl.trade_date = c.previous_two_trade_date AND ppl.` + "`limit`" + ` = 'U'
|
||||
INNER JOIN stock_daily d
|
||||
ON d.ts_code = pl.ts_code AND d.trade_date = c.trade_date
|
||||
ON d.ts_code = pl.ts_code COLLATE utf8mb4_0900_ai_ci AND d.trade_date = c.trade_date
|
||||
LEFT JOIN stock_daily nd
|
||||
ON nd.ts_code = pl.ts_code AND nd.trade_date = c.next_trade_date
|
||||
ON nd.ts_code = pl.ts_code COLLATE utf8mb4_0900_ai_ci AND nd.trade_date = c.next_trade_date
|
||||
LEFT JOIN stock_basic sb
|
||||
ON sb.ts_code = pl.ts_code COLLATE utf8mb4_unicode_ci
|
||||
WHERE c.trade_date BETWEEN ? AND ?
|
||||
|
||||
Reference in New Issue
Block a user