dev 3
This commit is contained in:
@@ -3,17 +3,23 @@ package logic
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"big-qmt/go-client/config"
|
||||
"big-qmt/go-client/libs"
|
||||
"big-qmt/go-client/sdk"
|
||||
)
|
||||
|
||||
func Overview(cfg Config, assets *sdk.Assets, positions []sdk.Position) {
|
||||
func logf(level, format string, args ...any) {
|
||||
log.Printf("[%s] %s", level, fmt.Sprintf(format, args...))
|
||||
}
|
||||
|
||||
func Overview(assets *sdk.Assets, positions []sdk.Position) {
|
||||
fmt.Println("\n" + strings.Repeat("=", 80))
|
||||
fmt.Printf("【时间】%s\n", time.Now().Format("2006-01-02 15:04:05"))
|
||||
fmt.Printf("【配置】account_id: %s host_key: %s open_money: %.0f\n", cfg.AccountID, cfg.HostKey, cfg.OpenMoney)
|
||||
fmt.Printf("【配置】account_id: %s host_key: %s buy_value: %.0f\n", config.Account.AccountID, config.Account.HostKey, config.Account.BuyValue)
|
||||
if assets != nil {
|
||||
fmt.Printf("【资金】总资产:%.2f元,可用资金:%.2f元\n", assets.Total, assets.Available)
|
||||
} else {
|
||||
@@ -25,18 +31,20 @@ func Overview(cfg Config, assets *sdk.Assets, positions []sdk.Position) {
|
||||
if p.Volume <= 0 {
|
||||
continue
|
||||
}
|
||||
code := normalizeCode(p.StockCode, "")
|
||||
code := p.StockCode
|
||||
fmt.Printf("【持仓】%s %s 持仓=%d 可用=%d 冻结=%d 在途=%d 昨仓=%d 成本=%.3f 现价=%.3f 市值=%.2f 浮盈=%.2f 盈亏比例=%.2f%%\n",
|
||||
code, p.StockName, p.Volume, p.CanUseVolume, p.FrozenVolume, p.OnRoadVolume, p.YesterdayVolume,
|
||||
p.OpenPrice, p.LastPrice, p.MarketValue, p.FloatProfit, p.ProfitRate*100)
|
||||
}
|
||||
}
|
||||
|
||||
func RunOnce(ctx context.Context, client *sdk.Client, books *OrderBook, cfg Config) {
|
||||
if !tradingTime(time.Now()) {
|
||||
func RunOnce(ctx context.Context, client *sdk.Client, books *OrderBook, signals *libs.SignalResult) {
|
||||
if !libs.TradingTime(time.Now()) {
|
||||
return
|
||||
}
|
||||
roundCtx, cancel := context.WithTimeout(ctx, cfg.HTTPTimeout*4)
|
||||
// 每轮先消费 QMT 回写,终态订单会立即释放本地委托锁。
|
||||
books.readReceipts()
|
||||
roundCtx, cancel := context.WithTimeout(ctx, config.HttpTimeOut*4)
|
||||
defer cancel()
|
||||
|
||||
assets, err := client.Assets(roundCtx)
|
||||
@@ -50,24 +58,19 @@ func RunOnce(ctx context.Context, client *sdk.Client, books *OrderBook, cfg Conf
|
||||
return
|
||||
}
|
||||
|
||||
signals := fetchSignal(cfg, "dcm_signal")
|
||||
seen := map[string]struct{}{}
|
||||
stockList := make([]string, 0, len(signals)+len(positions))
|
||||
stockList := make([]string, 0, len(signals.Data)+len(positions))
|
||||
addCode := func(code string) {
|
||||
n := normalizeCode(code, "")
|
||||
if n == "" {
|
||||
n = strings.ToUpper(strings.TrimSpace(code))
|
||||
}
|
||||
if n == "" {
|
||||
if code == "" {
|
||||
return
|
||||
}
|
||||
if _, ok := seen[n]; ok {
|
||||
if _, ok := seen[code]; ok {
|
||||
return
|
||||
}
|
||||
seen[n] = struct{}{}
|
||||
stockList = append(stockList, n)
|
||||
seen[code] = struct{}{}
|
||||
stockList = append(stockList, code)
|
||||
}
|
||||
for code := range signals {
|
||||
for code := range signals.Data {
|
||||
addCode(code)
|
||||
}
|
||||
for _, p := range positions {
|
||||
@@ -82,46 +85,40 @@ func RunOnce(ctx context.Context, client *sdk.Client, books *OrderBook, cfg Conf
|
||||
return
|
||||
}
|
||||
for code, tick := range raw {
|
||||
ticks[normalizeCode(code, "")] = tick
|
||||
ticks[code] = tick
|
||||
}
|
||||
}
|
||||
runRound(roundCtx, client, books, cfg, assets, ticks, positions, signals)
|
||||
runRound(roundCtx, client, books, assets, ticks, positions, signals.Data)
|
||||
}
|
||||
|
||||
func runRound(ctx context.Context, client *sdk.Client, books *OrderBook, cfg Config, assets *sdk.Assets, ticks map[string]sdk.Tick, positions []sdk.Position, signals map[string]map[string]any) {
|
||||
books.cancelExpired(ctx, client, cfg)
|
||||
func runRound(ctx context.Context, client *sdk.Client, books *OrderBook, assets *sdk.Assets, ticks map[string]sdk.Tick, positions []sdk.Position, signals map[string]libs.SignalItem) {
|
||||
if !books.cancelExpired(ctx, client) {
|
||||
logf("ERROR", "[ZT] 委托查询失败,本轮跳过")
|
||||
return
|
||||
}
|
||||
buys, sells, ok := books.activeSets(ctx, client)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
hold := positionCodes(positions)
|
||||
openSignals := map[string]map[string]any{}
|
||||
openSignals := map[string]libs.SignalItem{}
|
||||
for code, signal := range signals {
|
||||
norm := normalizeCode(code, "")
|
||||
if norm == "" {
|
||||
norm = code
|
||||
}
|
||||
if _, held := hold[norm]; held {
|
||||
if _, held := hold[code]; held {
|
||||
continue
|
||||
}
|
||||
openSignals[norm] = signal
|
||||
openSignals[code] = signal
|
||||
}
|
||||
for code := range buys {
|
||||
delete(openSignals, code)
|
||||
}
|
||||
marketOK := libs.AllowOpen()
|
||||
buyBudget := 0.0
|
||||
if assets != nil {
|
||||
buyBudget = assets.Available - assets.Total*config.Account.MinCashRatio
|
||||
}
|
||||
if len(openSignals) > 0 {
|
||||
if books.refresh(ctx, client, cfg) {
|
||||
buys, _, ok := books.activeSets(ctx, client, cfg)
|
||||
if ok {
|
||||
filtered := map[string]map[string]any{}
|
||||
for code, signal := range openSignals {
|
||||
if _, buying := buys[code]; buying {
|
||||
continue
|
||||
}
|
||||
filtered[code] = signal
|
||||
}
|
||||
openSignals = filtered
|
||||
}
|
||||
}
|
||||
openSignal(ctx, client, books, ticks, openSignals, marketOK, &buyBudget)
|
||||
}
|
||||
marketOK := libs.AllowOpen(cfg.APIHost, cfg.HTTPTimeout)
|
||||
if len(openSignals) > 0 {
|
||||
openSignal(ctx, client, books, cfg, assets, ticks, openSignals, marketOK)
|
||||
}
|
||||
managePositions(ctx, client, books, cfg, ticks, positions, marketOK)
|
||||
managePositions(ctx, client, books, ticks, positions, buys, sells, marketOK, &buyBudget)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user