118 lines
3.0 KiB
Go
118 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"os"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
|
|
"big-qmt/go-client/sdk"
|
|
)
|
|
|
|
var (
|
|
BaseURL = "http://127.0.0.1:10086"
|
|
Token = "QMTbyYanweidong"
|
|
AccountType = "stock"
|
|
PassCodes = []string{}
|
|
Timeout = 15 * time.Second
|
|
)
|
|
|
|
func main() {
|
|
client := sdk.New(BaseURL, Token, AccountType, Timeout)
|
|
ctx, cancel := context.WithTimeout(context.Background(), Timeout)
|
|
defer cancel()
|
|
|
|
assets, err := client.Assets(ctx, AccountType)
|
|
if err != nil {
|
|
fatal("获取资产失败: %v", err)
|
|
}
|
|
positions, err := client.Positions(ctx, AccountType)
|
|
if err != nil {
|
|
fatal("获取持仓失败: %v", err)
|
|
}
|
|
|
|
fmt.Println(strings.Repeat("=", 80))
|
|
fmt.Printf("【时间】%s\n", time.Now().Format("2006-01-02 15:04:05"))
|
|
fmt.Printf("【服务】%s accountType=%s\n", BaseURL, AccountType)
|
|
fmt.Printf("【资金】总资产:%.2f元,可用资金:%.2f元\n", assets.Total, assets.Available)
|
|
fmt.Printf("【持仓】%d只\n", len(positions))
|
|
fmt.Println(strings.Repeat("=", 80))
|
|
|
|
sort.Slice(positions, func(i, j int) bool {
|
|
return positions[i].StockCode < positions[j].StockCode
|
|
})
|
|
for _, p := range positions {
|
|
if p.Volume <= 0 {
|
|
continue
|
|
}
|
|
fmt.Printf(
|
|
"【持仓】%s %s 持仓=%d 可用=%d 冻结=%d 在途=%d 昨仓=%d 成本=%.3f 现价=%.3f 市值=%.2f 浮盈=%.2f 盈亏比例=%.2f%%\n",
|
|
p.StockCode, p.StockName, p.Volume, p.CanUseVolume, p.FrozenVolume, p.OnRoadVolume, p.YesterdayVolume,
|
|
p.OpenPrice, p.LastPrice, p.MarketValue, p.FloatProfit, p.ProfitRate*100,
|
|
)
|
|
}
|
|
|
|
printTicks(client, Timeout, PassCodes)
|
|
}
|
|
|
|
func printTicks(client *sdk.Client, timeout time.Duration, codes []string) {
|
|
fmt.Println(strings.Repeat("-", 80))
|
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
|
defer cancel()
|
|
ticks, err := client.FullTick(ctx, codes)
|
|
if err != nil {
|
|
fatal("获取行情失败: %v", err)
|
|
}
|
|
fmt.Printf("【行情】请求 %d 只,返回 %d 只\n", len(codes), len(ticks))
|
|
keys := make([]string, 0, len(ticks))
|
|
for code := range ticks {
|
|
keys = append(keys, code)
|
|
}
|
|
sort.Strings(keys)
|
|
for _, code := range keys {
|
|
t := ticks[code]
|
|
fmt.Printf("【Tick】%s last=%.3f close=%.3f open=%s high=%s low=%s volume=%s\n",
|
|
code, t.LastPrice, t.LastClose,
|
|
rawStr(t.Raw, "open", "lastOpen", "Open"),
|
|
rawStr(t.Raw, "high", "High"),
|
|
rawStr(t.Raw, "low", "Low"),
|
|
rawStr(t.Raw, "volume", "Volume"),
|
|
)
|
|
}
|
|
}
|
|
|
|
func splitCSV(s string) []string {
|
|
parts := strings.Split(s, ",")
|
|
out := make([]string, 0, len(parts))
|
|
for _, p := range parts {
|
|
p = strings.TrimSpace(p)
|
|
if p != "" {
|
|
out = append(out, p)
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
func rawStr(m map[string]any, names ...string) string {
|
|
for _, name := range names {
|
|
if v, ok := m[name]; ok && v != nil {
|
|
return fmt.Sprint(v)
|
|
}
|
|
}
|
|
return "-"
|
|
}
|
|
|
|
func envOr(key, fallback string) string {
|
|
if v := strings.TrimSpace(os.Getenv(key)); v != "" {
|
|
return v
|
|
}
|
|
return fallback
|
|
}
|
|
|
|
func fatal(format string, args ...any) {
|
|
fmt.Fprintf(os.Stderr, format+"\n", args...)
|
|
os.Exit(1)
|
|
}
|