package logic import ( "strconv" "strings" "time" "big-qmt/go-client/config" "big-qmt/go-client/libs" "big-qmt/go-client/sdk" ) func openSignal(client *sdk.Client, ticks map[string]sdk.Tick, openSignals []*libs.SignalItem) { for _, item := range openSignals { // 验证信号配置的时间区间 if !CheckTimezone(item.SignalKey) { continue } // 是否有锁 if OrderBook.IsLock("BUY", item.Code) { continue } // 验证价格 price := ticks[item.Code].LastPrice if price <= 0 { continue } // 防止接飞刀 if !OpenWatch.Triggered("开仓", item.Code, price) { continue } // 计算开仓数量 volume := libs.CalcBuyVolume(price, config.Account.BuyValue) if volume <= 0 { continue } // 开仓 orderID := NewOrderID("base") if !OrderBook.Place(client, sdk.OpBuy, item.Code, volume, orderID) { continue } // 保存状态 QuantState.Set(&StateItem{Code: item.Code, BaseOrderId: orderID, BaseQty: volume, BaseCost: price, BaseStatus: StatusIng}) if err := QuantState.Save(); err != nil { logf("ERROR", "%v", err) } logf("INFO", "[ZT][开仓] %s 买入 %d 股", item.Code, volume) } } // 当前时间区间验证 *代表全时间段,9:30-10:30,13:30-14:30 代表2个时间段 func CheckTimezone(sk string) bool { timezone := strings.TrimSpace(config.Global.Signals[sk].Timezone) if timezone == "*" { return true } parse := func(value string) (int, bool) { parts := strings.Split(strings.TrimSpace(value), ":") if len(parts) != 2 { return 0, false } hour, errHour := strconv.Atoi(parts[0]) minute, errMinute := strconv.Atoi(parts[1]) if errHour != nil || errMinute != nil || hour < 0 || hour > 23 || minute < 0 || minute > 59 { return 0, false } return hour*60 + minute, true } current := time.Now() now := current.Hour()*60 + current.Minute() for _, section := range strings.Split(timezone, ",") { bounds := strings.Split(strings.TrimSpace(section), "-") if len(bounds) != 2 { continue } start, startOK := parse(bounds[0]) end, endOK := parse(bounds[1]) if !startOK || !endOK { continue } if (start <= end && now >= start && now <= end) || (start > end && (now >= start || now <= end)) { return true } } return false }