106 lines
2.4 KiB
Go
106 lines
2.4 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"log"
|
|
"os"
|
|
"os/signal"
|
|
"strings"
|
|
"syscall"
|
|
"time"
|
|
|
|
"big-qmt/go-client/sdk"
|
|
)
|
|
|
|
func main() {
|
|
log.SetFlags(log.LstdFlags | log.Lmicroseconds)
|
|
cfg := loadConfig()
|
|
client := sdk.New(cfg.QMTBaseURL, cfg.QMTToken, cfg.AccountType, cfg.HTTPTimeout)
|
|
books := newOrderBook()
|
|
|
|
ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
|
|
defer stop()
|
|
|
|
startup := context.Background()
|
|
assets, err := client.Assets(startup, cfg.AccountType)
|
|
if err != nil {
|
|
logf("ERROR", "启动获取资产失败: %v", err)
|
|
}
|
|
positions, err := client.Positions(startup, cfg.AccountType)
|
|
if err != nil {
|
|
logf("ERROR", "启动获取持仓失败: %v", err)
|
|
positions = []sdk.Position{}
|
|
}
|
|
overview(cfg, assets, positions)
|
|
logf("INFO", "[ZT] host_key=%s interval=%s", cfg.HostKey, cfg.LoopInterval)
|
|
logf("INFO", "[ZT] Init Success, waiting trading session")
|
|
|
|
ticker := time.NewTicker(cfg.LoopInterval)
|
|
defer ticker.Stop()
|
|
runOnce(ctx, client, books, cfg)
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
logf("INFO", "[ZT] 停止")
|
|
return
|
|
case <-ticker.C:
|
|
runOnce(ctx, client, books, cfg)
|
|
}
|
|
}
|
|
}
|
|
|
|
func runOnce(ctx context.Context, client *sdk.Client, books *orderBook, cfg Config) {
|
|
if !tradingTime(time.Now()) {
|
|
return
|
|
}
|
|
roundCtx, cancel := context.WithTimeout(ctx, cfg.HTTPTimeout*4)
|
|
defer cancel()
|
|
|
|
assets, err := client.Assets(roundCtx, cfg.AccountType)
|
|
if err != nil {
|
|
logf("ERROR", "获取资产失败: %v", err)
|
|
return
|
|
}
|
|
positions, err := client.Positions(roundCtx, cfg.AccountType)
|
|
if err != nil {
|
|
logf("ERROR", "获取持仓失败: %v", err)
|
|
return
|
|
}
|
|
codes := passCodes(cfg)
|
|
seen := map[string]struct{}{}
|
|
stockList := make([]string, 0, len(codes)+len(positions))
|
|
addCode := func(code string) {
|
|
n := normalizeCode(code, "")
|
|
if n == "" {
|
|
n = strings.ToUpper(strings.TrimSpace(code))
|
|
}
|
|
if n == "" {
|
|
return
|
|
}
|
|
if _, ok := seen[n]; ok {
|
|
return
|
|
}
|
|
seen[n] = struct{}{}
|
|
stockList = append(stockList, n)
|
|
}
|
|
for _, code := range codes {
|
|
addCode(code)
|
|
}
|
|
for _, p := range positions {
|
|
addCode(p.StockCode)
|
|
}
|
|
ticks := map[string]sdk.Tick{}
|
|
if len(stockList) > 0 {
|
|
raw, err := client.FullTick(roundCtx, stockList)
|
|
if err != nil {
|
|
logf("ERROR", "获取行情失败: %v", err)
|
|
return
|
|
}
|
|
for code, tick := range raw {
|
|
ticks[normalizeCode(code, "")] = tick
|
|
ticks[code] = tick
|
|
}
|
|
}
|
|
runRound(roundCtx, client, books, cfg, assets, ticks, positions)
|
|
}
|