This commit is contained in:
2026-08-25 22:35:44 +08:00
parent ec58641d09
commit f14423418a
23 changed files with 738 additions and 680 deletions

View File

@@ -9,42 +9,74 @@ import (
"time"
"big-qmt/go-client/apps/zt/logic"
"big-qmt/go-client/config"
"big-qmt/go-client/libs"
"big-qmt/go-client/sdk"
"github.com/robfig/cron/v3"
)
func main() {
log.SetFlags(log.LstdFlags | log.Lmicroseconds)
cfg := logic.LoadConfig()
client := sdk.New(cfg.QMTBaseURL, cfg.QMTToken, cfg.HTTPTimeout).SetAccountType(cfg.AccountType)
books := logic.NewOrderBook()
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer stop()
startup := context.Background()
assets, err := client.Assets(startup)
// 第一步:只从 YAML 文件加载系统配置和本机账户配置。
err := config.Load("etc")
if err != nil {
log.Printf("[ERROR] 启动获取资产失败: %v", err)
log.Fatalf("[ERROR] 加载配置失败: %v", err)
}
positions, err := client.Positions(startup)
if err != nil {
log.Printf("[ERROR] 启动获取持仓失败: %v", err)
positions = []sdk.Position{}
}
logic.Overview(cfg, assets, positions)
log.Printf("[INFO] [ZT] host_key=%s interval=%s signal=%s/a/dcm_signal", cfg.HostKey, cfg.LoopInterval, cfg.APIHost)
log.Printf("[INFO] [ZT] Init Success, waiting trading session")
client := sdk.New(config.Global.QMTBaseURL, config.Global.QMTToken, config.HttpTimeOut)
ticker := time.NewTicker(cfg.LoopInterval)
defer ticker.Stop()
logic.RunOnce(ctx, client, books, cfg)
// 第二步QMT 未就绪时持续重试,退出信号仍可立即终止等待。
assets, positions, ok := waitForQMT(ctx, client)
if !ok {
return
}
// 第三步:连接成功后接管首次持仓并打印账户概览。
logic.BootstrapState(positions)
logic.Overview(assets, positions)
signals, err := libs.FetchSignal(libs.Dcm_Signal, config.Account.HostKey)
if err != nil {
log.Printf("[ERROR] [ZT] 获取开仓信号失败: %v", err)
signals = &libs.SignalResult{Data: map[string]libs.SignalItem{}}
}
log.Printf("[INFO] [ZT] 已加载 %d 个开仓信号", len(signals.Data))
// 第四步:工作日每 30 秒触发,交易时段由 RunOnce 统一判断。
books := logic.NewOrderBook()
scheduler := cron.New(
cron.WithSeconds(),
cron.WithChain(cron.SkipIfStillRunning(cron.DefaultLogger)),
)
if _, err := scheduler.AddFunc("0,30 * 9-15 * * 1-5", func() {
logic.RunOnce(ctx, client, books, signals)
}); err != nil {
log.Fatalf("[ERROR] 创建计划任务失败: %v", err)
}
scheduler.Start()
log.Printf("[INFO] [ZT] 计划任务已启动")
<-ctx.Done()
<-scheduler.Stop().Done()
log.Printf("[INFO] [ZT] 停止")
}
func waitForQMT(ctx context.Context, client *sdk.Client) (*sdk.Assets, []sdk.Position, bool) {
for {
attempt, cancel := context.WithTimeout(ctx, config.HttpTimeOut)
assets, assetsErr := client.Assets(attempt)
positions, positionsErr := client.Positions(attempt)
cancel()
if assetsErr == nil && positionsErr == nil {
log.Printf("[INFO] [ZT] QMT连接成功: %s", config.Global.QMTBaseURL)
return assets, positions, true
}
log.Printf("[WARNING] [ZT] QMT未就绪5秒后重试: assets=%v positions=%v", assetsErr, positionsErr)
select {
case <-ctx.Done():
log.Printf("[INFO] [ZT] 停止")
return
case <-ticker.C:
logic.RunOnce(ctx, client, books, cfg)
return nil, nil, false
case <-time.After(5 * time.Second):
}
}
}