This commit is contained in:
2026-08-25 18:59:18 +08:00
parent fa62436a73
commit ec58641d09
23 changed files with 563 additions and 944 deletions

View File

@@ -26,19 +26,22 @@ type Position struct {
ExpireDate string `json:"ExpireDate"`
}
// Assets 对应 /api/v2/assets。
type Assets struct {
Total float64 `json:"total"`
Available float64 `json:"available"`
}
type accountBody struct {
Account string `json:"account"`
func (c *Client) Positions(ctx context.Context) ([]Position, error) {
return c.decodePositions(ctx, "/api/v2/positions")
}
func (c *Client) Positions(ctx context.Context, account string) ([]Position, error) {
func (c *Client) Holding(ctx context.Context) ([]Position, error) {
return c.decodePositions(ctx, "/api/holding")
}
func (c *Client) decodePositions(ctx context.Context, path string) ([]Position, error) {
raw := map[string]json.RawMessage{}
if err := c.post(ctx, "/api/v2/positions", accountBody{Account: c.Account(account)}, &raw); err != nil {
if err := c.post(ctx, path, map[string]any{"account": c.accountType}, &raw); err != nil {
return nil, err
}
out := make([]Position, 0, len(raw))
@@ -55,48 +58,29 @@ func (c *Client) Positions(ctx context.Context, account string) ([]Position, err
return out, nil
}
func (c *Client) Holding(ctx context.Context, account string) ([]Position, error) {
raw := map[string]json.RawMessage{}
if err := c.post(ctx, "/api/holding", accountBody{Account: c.Account(account)}, &raw); err != nil {
return nil, err
}
out := make([]Position, 0, len(raw))
for code, blob := range raw {
var p Position
if err := json.Unmarshal(blob, &p); err != nil {
return nil, fmt.Errorf("holding %s: %w", code, err)
}
if p.StockCode == "" {
p.StockCode = code
}
out = append(out, p)
}
return out, nil
}
func (c *Client) Assets(ctx context.Context, account string) (*Assets, error) {
func (c *Client) Assets(ctx context.Context) (*Assets, error) {
var out Assets
if err := c.post(ctx, "/api/v2/assets", accountBody{Account: c.Account(account)}, &out); err != nil {
if err := c.post(ctx, "/api/v2/assets", map[string]any{"account": c.accountType}, &out); err != nil {
return nil, err
}
return &out, nil
}
func (c *Client) TotalMoney(ctx context.Context, account string) (float64, error) {
func (c *Client) TotalMoney(ctx context.Context) (float64, error) {
var out struct {
TotalMoney float64 `json:"total_money"`
}
if err := c.post(ctx, "/api/money/total", accountBody{Account: c.Account(account)}, &out); err != nil {
if err := c.post(ctx, "/api/money/total", map[string]any{"account": c.accountType}, &out); err != nil {
return 0, err
}
return out.TotalMoney, nil
}
func (c *Client) AvailableMoney(ctx context.Context, account string) (float64, error) {
func (c *Client) AvailableMoney(ctx context.Context) (float64, error) {
var out struct {
AvailableMoney float64 `json:"available_money"`
}
if err := c.post(ctx, "/api/money/available", accountBody{Account: c.Account(account)}, &out); err != nil {
if err := c.post(ctx, "/api/money/available", map[string]any{"account": c.accountType}, &out); err != nil {
return 0, err
}
return out.AvailableMoney, nil
@@ -141,11 +125,11 @@ type OrderStatus struct {
VolumeTraded int `json:"volume_traded"`
}
func (c *Client) OrderStatusList(ctx context.Context, account string) ([]OrderStatus, error) {
func (c *Client) OrderStatusList(ctx context.Context) ([]OrderStatus, error) {
var out struct {
Orders []OrderStatus `json:"orders"`
}
if err := c.post(ctx, "/api/order/status", accountBody{Account: c.Account(account)}, &out); err != nil {
if err := c.post(ctx, "/api/order/status", map[string]any{"account": c.accountType}, &out); err != nil {
return nil, err
}
return out.Orders, nil
@@ -164,29 +148,29 @@ type CancelAllResult struct {
CanceledSysIDs []string `json:"canceled_sys_ids"`
}
func (c *Client) CancelAll(ctx context.Context, account string) (*CancelAllResult, error) {
func (c *Client) CancelAll(ctx context.Context) (*CancelAllResult, error) {
var out CancelAllResult
if err := c.post(ctx, "/api/order/cancel_all", accountBody{Account: c.Account(account)}, &out); err != nil {
if err := c.post(ctx, "/api/order/cancel_all", map[string]any{"account": c.accountType}, &out); err != nil {
return nil, err
}
return &out, nil
}
// CancelByRule 按「代码.市场 + (剩余+已成)」匹配撤单。HTTP 没有按委托号撤单ZT 用它代替 cancel(orderId)
func (c *Client) CancelByRule(ctx context.Context, stock string, volume int, account string) (*CancelAllResult, error) {
// CancelByRule 按「代码.市场 + (剩余+已成)」匹配撤单。HTTP 没有按委托号撤单。
func (c *Client) CancelByRule(ctx context.Context, stock string, volume int) (*CancelAllResult, error) {
var out CancelAllResult
body := map[string]any{"stock": stock, "volume": volume, "account": c.Account(account)}
body := map[string]any{"stock": stock, "volume": volume, "account": c.accountType}
if err := c.post(ctx, "/api/order/cancel_order", body, &out); err != nil {
return nil, err
}
return &out, nil
}
func (c *Client) Deals(ctx context.Context, account string) ([]map[string]string, error) {
func (c *Client) Deals(ctx context.Context) ([]map[string]string, error) {
var out struct {
Deals []map[string]string `json:"deals"`
}
if err := c.post(ctx, "/api/order/deal", accountBody{Account: c.Account(account)}, &out); err != nil {
if err := c.post(ctx, "/api/order/deal", map[string]any{"account": c.accountType}, &out); err != nil {
return nil, err
}
return out.Deals, nil

View File

@@ -3,65 +3,28 @@ package sdk
import "context"
func (c *Client) IsLastBar(ctx context.Context) (any, error) {
var out struct {
IsLastBar any `json:"is_last_bar"`
}
if err := c.get(ctx, "/api/check/is_last_bar", &out); err != nil {
return nil, err
}
return out.IsLastBar, nil
return c.getField(ctx, "/api/check/is_last_bar", "is_last_bar")
}
func (c *Client) IsNewBar(ctx context.Context) (any, error) {
var out struct {
IsNewBar any `json:"is_new_bar"`
}
if err := c.get(ctx, "/api/check/is_new_bar", &out); err != nil {
return nil, err
}
return out.IsNewBar, nil
return c.getField(ctx, "/api/check/is_new_bar", "is_new_bar")
}
func (c *Client) IsSuspendedStock(ctx context.Context, stockcode string) (any, error) {
var out struct {
Stockcode string `json:"stockcode"`
IsSuspended any `json:"is_suspended"`
}
if err := c.post(ctx, "/api/check/is_suspended_stock", map[string]any{"stockcode": stockcode}, &out); err != nil {
return nil, err
}
return out.IsSuspended, nil
return c.postField(ctx, "/api/check/is_suspended_stock", map[string]any{"stockcode": stockcode}, "is_suspended")
}
func (c *Client) IsSectorStock(ctx context.Context, sectorname, market, stockcode string) (any, error) {
var out struct {
IsInSector any `json:"is_in_sector"`
}
body := map[string]any{"sectorname": sectorname, "market": market, "stockcode": stockcode}
if err := c.post(ctx, "/api/check/is_sector_stock", body, &out); err != nil {
return nil, err
}
return out.IsInSector, nil
return c.postField(ctx, "/api/check/is_sector_stock", body, "is_in_sector")
}
func (c *Client) IsTypedStock(ctx context.Context, stocktypenum int, market, stockcode string) (any, error) {
var out struct {
Result any `json:"result"`
}
body := map[string]any{"stocktypenum": stocktypenum, "market": market, "stockcode": stockcode}
if err := c.post(ctx, "/api/check/is_typed_stock", body, &out); err != nil {
return nil, err
}
return out.Result, nil
return c.postField(ctx, "/api/check/is_typed_stock", body, "result")
}
func (c *Client) IndustryNameOfStock(ctx context.Context, industryType, stockcode string) (any, error) {
var out struct {
IndustryName any `json:"industry_name"`
}
body := map[string]any{"industryType": industryType, "stockcode": stockcode}
if err := c.post(ctx, "/api/check/get_industry_name_of_stock", body, &out); err != nil {
return nil, err
}
return out.IndustryName, nil
return c.postField(ctx, "/api/check/get_industry_name_of_stock", body, "industry_name")
}

View File

@@ -11,25 +11,30 @@ import (
"time"
)
// Client 调用 QMT HTTP API。
type Client struct {
baseURL string
token string
baseURL string
token string
accountType string
http *http.Client
http *http.Client
}
func New(baseURL, token, accountType string, timeout time.Duration) *Client {
base := strings.TrimRight(baseURL, "/")
return &Client{baseURL: base, token: token, accountType: accountType, http: &http.Client{Timeout: timeout}}
}
func (c *Client) Account(override string) string {
if strings.TrimSpace(override) != "" {
return override
func New(baseURL, token string, timeout time.Duration) *Client {
if timeout <= 0 {
timeout = 15 * time.Second
}
return c.accountType
return &Client{
baseURL: strings.TrimRight(baseURL, "/"),
token: token,
accountType: "stock",
http: &http.Client{Timeout: timeout},
}
}
func (c *Client) SetAccountType(accountType string) *Client {
if strings.TrimSpace(accountType) != "" {
c.accountType = accountType
}
return c
}
func (c *Client) get(ctx context.Context, path string, dest any) error {
@@ -92,14 +97,32 @@ func (c *Client) do(ctx context.Context, method, path string, body any, dest any
return nil
}
func truncate(b []byte, n int) string {
if len(b) <= n {
return string(b)
func (c *Client) getField(ctx context.Context, path, key string) (any, error) {
var out map[string]any
if err := c.get(ctx, path, &out); err != nil {
return nil, err
}
return string(b[:n]) + "..."
return out[key], nil
}
func ArrayJoin(items []string) string {
func (c *Client) postField(ctx context.Context, path string, body any, key string) (any, error) {
var out map[string]any
if err := c.post(ctx, path, body, &out); err != nil {
return nil, err
}
if msg, ok := out["error"].(string); ok && msg != "" {
return nil, &BusinessError{Message: msg}
}
if key == "" {
return out, nil
}
if v, ok := out[key]; ok {
return v, nil
}
return out, nil
}
func csvJoin(items []string) string {
parts := make([]string, 0, len(items))
for _, s := range items {
s = strings.TrimSpace(s)
@@ -109,3 +132,10 @@ func ArrayJoin(items []string) string {
}
return strings.Join(parts, ",")
}
func truncate(b []byte, n int) string {
if len(b) <= n {
return string(b)
}
return string(b[:n]) + "..."
}

View File

@@ -15,20 +15,17 @@ func asString(v any) string {
return x
case json.Number:
return x.String()
case []byte:
return string(x)
default:
return strings.TrimSpace(fmtAny(v))
return strings.TrimSpace(fmtSprint(v))
}
}
func fmtAny(v any) string {
func fmtSprint(v any) string {
b, err := json.Marshal(v)
if err != nil {
return ""
}
s := strings.Trim(string(b), `"`)
return s
return strings.Trim(string(b), `"`)
}
func asFloat(v any) float64 {
@@ -56,39 +53,11 @@ func asFloat(v any) float64 {
}
}
func asInt(v any) int {
return int(asFloat(v))
}
func asBool(v any) bool {
switch x := v.(type) {
case bool:
return x
case string:
s := strings.ToLower(strings.TrimSpace(x))
return s == "true" || s == "1" || s == "yes"
default:
return asFloat(v) != 0
}
}
func mapField(m map[string]any, names ...string) any {
for _, name := range names {
if name == "" {
continue
}
if v, ok := m[name]; ok && v != nil {
return v
}
}
return nil
}
func mapFieldS(m map[string]string, names ...string) string {
for _, name := range names {
if v, ok := m[name]; ok && strings.TrimSpace(v) != "" {
return v
}
}
return ""
}

View File

@@ -16,121 +16,63 @@ type ContextInfo struct {
}
func (c *Client) ContextPeriod(ctx context.Context) (any, error) {
var out struct {
Period any `json:"period"`
}
if err := c.get(ctx, "/api/context/period", &out); err != nil {
return nil, err
}
return out.Period, nil
return c.getField(ctx, "/api/context/period", "period")
}
func (c *Client) ContextBarpos(ctx context.Context) (any, error) {
var out struct {
Barpos any `json:"barpos"`
}
if err := c.get(ctx, "/api/context/barpos", &out); err != nil {
return nil, err
}
return out.Barpos, nil
return c.getField(ctx, "/api/context/barpos", "barpos")
}
func (c *Client) ContextTimeTickSize(ctx context.Context) (any, error) {
var out struct {
TimeTickSize any `json:"time_tick_size"`
}
if err := c.get(ctx, "/api/context/time_tick_size", &out); err != nil {
return nil, err
}
return out.TimeTickSize, nil
return c.getField(ctx, "/api/context/time_tick_size", "time_tick_size")
}
func (c *Client) ContextStockcode(ctx context.Context) (any, error) {
var out struct {
Stockcode any `json:"stockcode"`
}
if err := c.get(ctx, "/api/context/stockcode", &out); err != nil {
return nil, err
}
return out.Stockcode, nil
return c.getField(ctx, "/api/context/stockcode", "stockcode")
}
func (c *Client) ContextDividendType(ctx context.Context) (any, error) {
var out struct {
DividendType any `json:"dividend_type"`
}
if err := c.get(ctx, "/api/context/dividend_type", &out); err != nil {
return nil, err
}
return out.DividendType, nil
return c.getField(ctx, "/api/context/dividend_type", "dividend_type")
}
func (c *Client) ContextMarket(ctx context.Context) (any, error) {
var out struct {
Market any `json:"market"`
}
if err := c.get(ctx, "/api/context/market", &out); err != nil {
return nil, err
}
return out.Market, nil
return c.getField(ctx, "/api/context/market", "market")
}
func (c *Client) ContextDoBackTest(ctx context.Context) (any, error) {
var out struct {
DoBackTest any `json:"do_back_test"`
}
if err := c.get(ctx, "/api/context/do_back_test", &out); err != nil {
return nil, err
}
return out.DoBackTest, nil
return c.getField(ctx, "/api/context/do_back_test", "do_back_test")
}
func (c *Client) ContextBenchmark(ctx context.Context) (any, error) {
var out struct {
Benchmark any `json:"benchmark"`
}
if err := c.get(ctx, "/api/context/benchmark", &out); err != nil {
return nil, err
}
return out.Benchmark, nil
return c.getField(ctx, "/api/context/benchmark", "benchmark")
}
func (c *Client) ContextCapital(ctx context.Context) (any, error) {
var out struct {
Capital any `json:"capital"`
}
if err := c.get(ctx, "/api/context/capital", &out); err != nil {
return nil, err
}
return out.Capital, nil
return c.getField(ctx, "/api/context/capital", "capital")
}
func (c *Client) ContextUniverse(ctx context.Context) ([]string, error) {
var out struct {
Universe any `json:"universe"`
}
if err := c.get(ctx, "/api/context/universe", &out); err != nil {
v, err := c.getField(ctx, "/api/context/universe", "universe")
if err != nil {
return nil, err
}
switch v := out.Universe.(type) {
switch u := v.(type) {
case nil:
return nil, nil
case []any:
codes := make([]string, 0, len(v))
for _, item := range v {
s := asString(item)
if s != "" {
codes := make([]string, 0, len(u))
for _, item := range u {
if s := asString(item); s != "" {
codes = append(codes, s)
}
}
return codes, nil
case []string:
return v, nil
return u, nil
default:
s := asString(v)
if s == "" {
return nil, nil
if s := asString(u); s != "" {
return []string{s}, nil
}
return []string{s}, nil
return nil, nil
}
}

View File

@@ -2,7 +2,8 @@ package sdk
import (
"context"
"fmt"
"strconv"
"strings"
)
type Tick struct {
@@ -12,21 +13,21 @@ type Tick struct {
}
type HistoryDataRequest struct {
Len int `json:"len"`
Period string `json:"period,omitempty"`
Field string `json:"field,omitempty"`
DividendType int `json:"dividend_type"`
SkipPaused string `json:"skip_paused,omitempty"`
Len int
Period string
Field string
DividendType int
SkipPaused *bool
}
type MarketDataRequest struct {
Fields string `json:"fields,omitempty"`
StockCode string `json:"stock_code,omitempty"`
StartTime string `json:"start_time,omitempty"`
EndTime string `json:"end_time,omitempty"`
Period string `json:"period,omitempty"`
DividendType string `json:"dividend_type,omitempty"`
Count int `json:"count"`
Fields []string
Stocks []string
StartTime string
EndTime string
Period string
DividendType string
Count int
}
type SubscribeResult struct {
@@ -35,64 +36,30 @@ type SubscribeResult struct {
}
func (c *Client) StockName(ctx context.Context, stockcode string) (any, error) {
var out struct {
Name any `json:"name"`
}
if err := c.post(ctx, "/api/data/stock_name", map[string]any{"stockcode": stockcode}, &out); err != nil {
return nil, err
}
return out.Name, nil
return c.postField(ctx, "/api/data/stock_name", map[string]any{"stockcode": stockcode}, "name")
}
func (c *Client) OpenDate(ctx context.Context, stockcode string) (any, error) {
var out struct {
OpenDate any `json:"open_date"`
}
if err := c.post(ctx, "/api/data/open_date", map[string]any{"stockcode": stockcode}, &out); err != nil {
return nil, err
}
return out.OpenDate, nil
return c.postField(ctx, "/api/data/open_date", map[string]any{"stockcode": stockcode}, "open_date")
}
func (c *Client) LastVolume(ctx context.Context, stockcode string) (any, error) {
var out struct {
LastVolume any `json:"last_volume"`
}
if err := c.post(ctx, "/api/data/last_volume", map[string]any{"stockcode": stockcode}, &out); err != nil {
return nil, err
}
return out.LastVolume, nil
return c.postField(ctx, "/api/data/last_volume", map[string]any{"stockcode": stockcode}, "last_volume")
}
func (c *Client) BarTimetag(ctx context.Context, index int) (any, error) {
var out struct {
Timetag any `json:"timetag"`
}
if err := c.post(ctx, "/api/data/bar_timetag", map[string]any{"index": index}, &out); err != nil {
return nil, err
}
return out.Timetag, nil
return c.postField(ctx, "/api/data/bar_timetag", map[string]any{"index": index}, "timetag")
}
func (c *Client) TickTimetag(ctx context.Context) (any, error) {
var out struct {
Timetag any `json:"timetag"`
}
if err := c.get(ctx, "/api/data/tick_timetag", &out); err != nil {
return nil, err
}
return out.Timetag, nil
return c.getField(ctx, "/api/data/tick_timetag", "timetag")
}
func (c *Client) Sector(ctx context.Context, sector string, realtime string) ([]any, error) {
body := map[string]any{"sector": sector}
if realtime != "" {
body["realtime"] = realtime
}
func (c *Client) Sector(ctx context.Context, sector string, realtime int) ([]any, error) {
var out struct {
Stocks []any `json:"stocks"`
}
if err := c.post(ctx, "/api/data/sector", body, &out); err != nil {
if err := c.post(ctx, "/api/data/sector", map[string]any{"sector": sector, "realtime": realtime}, &out); err != nil {
return nil, err
}
return out.Stocks, nil
@@ -119,99 +86,58 @@ func (c *Client) StockListInSector(ctx context.Context, sectorname string) ([]an
}
func (c *Client) WeightInIndex(ctx context.Context, indexcode, stockcode string) (any, error) {
var out struct {
Weight any `json:"weight"`
}
body := map[string]any{"indexcode": indexcode, "stockcode": stockcode}
if err := c.post(ctx, "/api/data/weight_in_index", body, &out); err != nil {
return nil, err
}
return out.Weight, nil
return c.postField(ctx, "/api/data/weight_in_index", map[string]any{"indexcode": indexcode, "stockcode": stockcode}, "weight")
}
func (c *Client) ContractMultiplier(ctx context.Context, contractcode string) (any, error) {
var out struct {
Multiplier any `json:"multiplier"`
}
if err := c.post(ctx, "/api/data/contract_multiplier", map[string]any{"contractcode": contractcode}, &out); err != nil {
return nil, err
}
return out.Multiplier, nil
return c.postField(ctx, "/api/data/contract_multiplier", map[string]any{"contractcode": contractcode}, "multiplier")
}
func (c *Client) RiskFreeRate(ctx context.Context, index int) (any, error) {
var out struct {
RiskFreeRate any `json:"risk_free_rate"`
}
if err := c.post(ctx, "/api/data/risk_free_rate", map[string]any{"index": index}, &out); err != nil {
return nil, err
}
return out.RiskFreeRate, nil
return c.postField(ctx, "/api/data/risk_free_rate", map[string]any{"index": index}, "risk_free_rate")
}
func (c *Client) DateLocation(ctx context.Context, strdate string) (any, error) {
var out struct {
Location any `json:"location"`
}
if err := c.post(ctx, "/api/data/date_location", map[string]any{"strdate": strdate}, &out); err != nil {
return nil, err
}
return out.Location, nil
return c.postField(ctx, "/api/data/date_location", map[string]any{"strdate": strdate}, "location")
}
func (c *Client) HistoryData(ctx context.Context, req HistoryDataRequest) (any, error) {
if req.Len == 0 {
req.Len = 10
}
if req.SkipPaused == "" {
req.SkipPaused = "true"
skip := "true"
if req.SkipPaused != nil {
skip = strconv.FormatBool(*req.SkipPaused)
}
var out map[string]any
if err := c.post(ctx, "/api/data/history_data", req, &out); err != nil {
return nil, err
return c.postField(ctx, "/api/data/history_data", map[string]any{
"len": req.Len, "period": req.Period, "field": req.Field,
"dividend_type": req.DividendType, "skip_paused": skip,
}, "data")
}
func (c *Client) marketDataBody(req MarketDataRequest) map[string]any {
return map[string]any{
"fields": csvJoin(req.Fields),
"stock_code": csvJoin(req.Stocks),
"start_time": req.StartTime,
"end_time": req.EndTime,
"period": req.Period,
"dividend_type": req.DividendType,
"count": req.Count,
}
if msg, ok := out["error"].(string); ok && msg != "" {
return nil, &BusinessError{Message: msg}
}
return out["data"], nil
}
func (c *Client) MarketData(ctx context.Context, req MarketDataRequest) (any, error) {
var out struct {
Data any `json:"data"`
}
if err := c.post(ctx, "/api/data/market_data", req, &out); err != nil {
return nil, err
}
return out.Data, nil
return c.postField(ctx, "/api/data/market_data", c.marketDataBody(req), "data")
}
func (c *Client) MarketDataEx(ctx context.Context, req MarketDataRequest) (any, error) {
body := map[string]any{
"fields": req.Fields,
"stock_code": req.StockCode,
"period": req.Period,
"start_time": req.StartTime,
"end_time": req.EndTime,
"count": req.Count,
"dividend_type": req.DividendType,
}
var out struct {
Data any `json:"data"`
}
if err := c.post(ctx, "/api/data/market_data_ex", body, &out); err != nil {
return nil, err
}
return out.Data, nil
return c.postField(ctx, "/api/data/market_data_ex", c.marketDataBody(req), "data")
}
func (c *Client) FullTick(ctx context.Context, stocks []string) (map[string]Tick, error) {
joined := ArrayJoin(stocks)
if joined == "" {
return nil, fmt.Errorf("full_tick: stocks empty")
}
raw := map[string]any{}
if err := c.post(ctx, "/api/data/full_tick", map[string]any{"stocks": joined}, &raw); err != nil {
if err := c.post(ctx, "/api/data/full_tick", map[string]any{"stocks": stocks}, &raw); err != nil {
return nil, err
}
out := make(map[string]Tick, len(raw))
@@ -228,23 +154,11 @@ func (c *Client) FullTick(ctx context.Context, stocks []string) (map[string]Tick
}
func (c *Client) DividFactors(ctx context.Context, stockcode string) (any, error) {
var out struct {
Factors any `json:"factors"`
}
if err := c.post(ctx, "/api/data/divid_factors", map[string]any{"stockcode": stockcode}, &out); err != nil {
return nil, err
}
return out.Factors, nil
return c.postField(ctx, "/api/data/divid_factors", map[string]any{"stockcode": stockcode}, "factors")
}
func (c *Client) MainContract(ctx context.Context, codemarket string) (any, error) {
var out struct {
MainContract any `json:"main_contract"`
}
if err := c.post(ctx, "/api/data/main_contract", map[string]any{"codemarket": codemarket}, &out); err != nil {
return nil, err
}
return out.MainContract, nil
return c.postField(ctx, "/api/data/main_contract", map[string]any{"codemarket": codemarket}, "main_contract")
}
func (c *Client) TimetagToDatetime(ctx context.Context, timetag int64, format string) (any, error) {
@@ -252,23 +166,11 @@ func (c *Client) TimetagToDatetime(ctx context.Context, timetag int64, format st
if format != "" {
body["format"] = format
}
var out struct {
Datetime any `json:"datetime"`
}
if err := c.post(ctx, "/api/data/timetag_to_datetime", body, &out); err != nil {
return nil, err
}
return out.Datetime, nil
return c.postField(ctx, "/api/data/timetag_to_datetime", body, "datetime")
}
func (c *Client) TotalShare(ctx context.Context, stockcode string) (any, error) {
var out struct {
TotalShare any `json:"total_share"`
}
if err := c.post(ctx, "/api/data/total_share", map[string]any{"stockcode": stockcode}, &out); err != nil {
return nil, err
}
return out.TotalShare, nil
return c.postField(ctx, "/api/data/total_share", map[string]any{"stockcode": stockcode}, "total_share")
}
func (c *Client) TradingDates(ctx context.Context, stockcode, startDate, endDate, period string, count int) ([]any, error) {
@@ -286,242 +188,145 @@ func (c *Client) TradingDates(ctx context.Context, stockcode, startDate, endDate
}
func (c *Client) Svol(ctx context.Context, stockcode string) (any, error) {
var out struct {
Svol any `json:"svol"`
}
if err := c.post(ctx, "/api/data/svol", map[string]any{"stockcode": stockcode}, &out); err != nil {
return nil, err
}
return out.Svol, nil
return c.postField(ctx, "/api/data/svol", map[string]any{"stockcode": stockcode}, "svol")
}
func (c *Client) Bvol(ctx context.Context, stockcode string) (any, error) {
var out struct {
Bvol any `json:"bvol"`
}
if err := c.post(ctx, "/api/data/bvol", map[string]any{"stockcode": stockcode}, &out); err != nil {
return nil, err
}
return out.Bvol, nil
return c.postField(ctx, "/api/data/bvol", map[string]any{"stockcode": stockcode}, "bvol")
}
func (c *Client) dataPayload(ctx context.Context, path string, body map[string]any) (any, error) {
var out map[string]any
if err := c.post(ctx, path, body, &out); err != nil {
return nil, err
}
if msg, ok := out["error"].(string); ok && msg != "" {
return nil, &BusinessError{Message: msg}
}
if v, ok := out["data"]; ok {
return v, nil
}
return out, nil
func (c *Client) Longhubang(ctx context.Context, stockList []string, startTime, endTime string) (any, error) {
return c.postField(ctx, "/api/data/longhubang", map[string]any{
"stock_list": csvJoin(stockList), "startTime": startTime, "endTime": endTime,
}, "data")
}
func (c *Client) Longhubang(ctx context.Context, stockList, startTime, endTime string) (any, error) {
return c.dataPayload(ctx, "/api/data/longhubang", map[string]any{
"stock_list": stockList, "startTime": startTime, "endTime": endTime,
})
}
func (c *Client) Top10ShareHolder(ctx context.Context, stockList, dataName, startTime, endTime string) (any, error) {
return c.dataPayload(ctx, "/api/data/top10_share_holder", map[string]any{
"stock_list": stockList, "data_name": dataName, "start_time": startTime, "end_time": endTime,
})
func (c *Client) Top10ShareHolder(ctx context.Context, stockList []string, dataName, startTime, endTime string) (any, error) {
return c.postField(ctx, "/api/data/top10_share_holder", map[string]any{
"stock_list": csvJoin(stockList), "data_name": dataName, "start_time": startTime, "end_time": endTime,
}, "data")
}
func (c *Client) OptionDetail(ctx context.Context, optioncode string) (any, error) {
var out struct {
Detail any `json:"detail"`
}
if err := c.post(ctx, "/api/data/option_detail", map[string]any{"optioncode": optioncode}, &out); err != nil {
return nil, err
}
return out.Detail, nil
return c.postField(ctx, "/api/data/option_detail", map[string]any{"optioncode": optioncode}, "detail")
}
func (c *Client) TurnoverRate(ctx context.Context, stockList, startTime, endTime string) (any, error) {
return c.dataPayload(ctx, "/api/data/turnover_rate", map[string]any{
"stock_list": stockList, "startTime": startTime, "endTime": endTime,
})
func (c *Client) TurnoverRate(ctx context.Context, stockList []string, startTime, endTime string) (any, error) {
return c.postField(ctx, "/api/data/turnover_rate", map[string]any{
"stock_list": csvJoin(stockList), "startTime": startTime, "endTime": endTime,
}, "data")
}
func (c *Client) ETFInfo(ctx context.Context, stockcode string) (any, error) {
var out struct {
Info any `json:"info"`
}
if err := c.post(ctx, "/api/data/etf_info", map[string]any{"stockcode": stockcode}, &out); err != nil {
return nil, err
}
return out.Info, nil
return c.postField(ctx, "/api/data/etf_info", map[string]any{"stockcode": stockcode}, "info")
}
func (c *Client) ETFIOPV(ctx context.Context, stockcode string) (any, error) {
var out struct {
IOPV any `json:"iopv"`
}
if err := c.post(ctx, "/api/data/etf_iopv", map[string]any{"stockcode": stockcode}, &out); err != nil {
return nil, err
}
return out.IOPV, nil
return c.postField(ctx, "/api/data/etf_iopv", map[string]any{"stockcode": stockcode}, "iopv")
}
func (c *Client) InstrumentDetail(ctx context.Context, stockcode string) (any, error) {
var out struct {
Detail any `json:"detail"`
}
if err := c.post(ctx, "/api/data/instrumentdetail", map[string]any{"stockcode": stockcode}, &out); err != nil {
return nil, err
}
return out.Detail, nil
return c.postField(ctx, "/api/data/instrumentdetail", map[string]any{"stockcode": stockcode}, "detail")
}
func (c *Client) ContractExpireDate(ctx context.Context, codemarket string) (any, error) {
var out struct {
ExpireDate any `json:"expire_date"`
}
if err := c.post(ctx, "/api/data/contract_expire_date", map[string]any{"codemarket": codemarket}, &out); err != nil {
return nil, err
}
return out.ExpireDate, nil
return c.postField(ctx, "/api/data/contract_expire_date", map[string]any{"codemarket": codemarket}, "expire_date")
}
func (c *Client) OptionUndlData(ctx context.Context, undlCodeRef string) (any, error) {
var out struct {
Data any `json:"data"`
}
if err := c.post(ctx, "/api/data/option_undl_data", map[string]any{"undl_code_ref": undlCodeRef}, &out); err != nil {
return nil, err
}
return out.Data, nil
return c.postField(ctx, "/api/data/option_undl_data", map[string]any{"undl_code_ref": undlCodeRef}, "data")
}
type FinancialDataRequest struct {
Tabname string `json:"tabname,omitempty"`
Colname string `json:"colname,omitempty"`
Market string `json:"market,omitempty"`
Code string `json:"code,omitempty"`
ReportType string `json:"report_type,omitempty"`
Barpos int `json:"barpos"`
FieldList string `json:"fieldList,omitempty"`
StockList string `json:"stockList,omitempty"`
StartDate string `json:"startDate,omitempty"`
EndDate string `json:"endDate,omitempty"`
Tabname string
Colname string
Market string
Code string
ReportType string
Barpos int
FieldList []string
StockList []string
StartDate string
EndDate string
}
func (c *Client) FinancialData(ctx context.Context, req FinancialDataRequest) (any, error) {
var out map[string]any
if err := c.post(ctx, "/api/data/financial_data", req, &out); err != nil {
return nil, err
body := map[string]any{
"tabname": req.Tabname, "colname": req.Colname, "market": req.Market, "code": req.Code,
"report_type": req.ReportType, "barpos": req.Barpos,
"fieldList": csvJoin(req.FieldList), "stockList": csvJoin(req.StockList),
"startDate": req.StartDate, "endDate": req.EndDate,
}
if msg, ok := out["error"].(string); ok && msg != "" {
return nil, &BusinessError{Message: msg}
}
return out["data"], nil
return c.postField(ctx, "/api/data/financial_data", body, "data")
}
type FactorDataRequest struct {
FieldList string `json:"fieldList,omitempty"`
StockList string `json:"stockList,omitempty"`
StockCode string `json:"stockCode,omitempty"`
StartDate string `json:"startDate,omitempty"`
EndDate string `json:"endDate,omitempty"`
FieldList []string
StockList []string
StockCode string
StartDate string
EndDate string
}
func (c *Client) FactorData(ctx context.Context, req FactorDataRequest) (any, error) {
var out map[string]any
if err := c.post(ctx, "/api/data/factor_data", req, &out); err != nil {
return nil, err
body := map[string]any{
"fieldList": csvJoin(req.FieldList), "stockList": csvJoin(req.StockList),
"stockCode": req.StockCode, "startDate": req.StartDate, "endDate": req.EndDate,
}
if msg, ok := out["error"].(string); ok && msg != "" {
return nil, &BusinessError{Message: msg}
}
return out["data"], nil
return c.postField(ctx, "/api/data/factor_data", body, "data")
}
func (c *Client) HisSTData(ctx context.Context, stockCode string) (any, error) {
var out struct {
Data any `json:"data"`
}
if err := c.post(ctx, "/api/data/his_st_data", map[string]any{"stockCode": stockCode}, &out); err != nil {
return nil, err
}
return out.Data, nil
return c.postField(ctx, "/api/data/his_st_data", map[string]any{"stockCode": stockCode}, "data")
}
func (c *Client) HisIndexData(ctx context.Context, index string) (any, error) {
var out struct {
Data any `json:"data"`
}
if err := c.post(ctx, "/api/data/his_index_data", map[string]any{"index": index}, &out); err != nil {
return nil, err
}
return out.Data, nil
return c.postField(ctx, "/api/data/his_index_data", map[string]any{"index": index}, "data")
}
func (c *Client) AllSubscription(ctx context.Context) (any, error) {
var out struct {
Subscriptions any `json:"subscriptions"`
}
if err := c.get(ctx, "/api/data/all_subscription", &out); err != nil {
return nil, err
}
return out.Subscriptions, nil
return c.getField(ctx, "/api/data/all_subscription", "subscriptions")
}
func (c *Client) OptionList(ctx context.Context, undlCode, dedate, opttype, isavailable string) (any, error) {
body := map[string]any{"undl_code": undlCode, "dedate": dedate, "opttype": opttype}
if isavailable != "" {
body["isavailable"] = isavailable
func (c *Client) OptionList(ctx context.Context, undlCode, dedate, opttype string, isavailable bool) (any, error) {
body := map[string]any{
"undl_code": undlCode, "dedate": dedate, "opttype": opttype,
"isavailable": strconv.FormatBool(isavailable),
}
var out struct {
OptionList any `json:"option_list"`
}
if err := c.post(ctx, "/api/data/option_list", body, &out); err != nil {
return nil, err
}
return out.OptionList, nil
return c.postField(ctx, "/api/data/option_list", body, "option_list")
}
func (c *Client) HisContractList(ctx context.Context, market string) (any, error) {
var out struct {
Contracts any `json:"contracts"`
}
if err := c.post(ctx, "/api/data/his_contract_list", map[string]any{"market": market}, &out); err != nil {
return nil, err
}
return out.Contracts, nil
return c.postField(ctx, "/api/data/his_contract_list", map[string]any{"market": market}, "contracts")
}
func (c *Client) OptionIV(ctx context.Context, optioncode string) (any, error) {
var out struct {
IV any `json:"iv"`
}
if err := c.post(ctx, "/api/data/option_iv", map[string]any{"optioncode": optioncode}, &out); err != nil {
return nil, err
}
return out.IV, nil
return c.postField(ctx, "/api/data/option_iv", map[string]any{"optioncode": optioncode}, "iv")
}
type BSMPriceRequest struct {
OptionType string `json:"optionType"`
ObjectPrices string `json:"objectPrices"`
StrikePrice float64 `json:"strikePrice"`
RiskFree float64 `json:"riskFree"`
Sigma float64 `json:"sigma"`
Days int `json:"days"`
Dividend float64 `json:"dividend"`
OptionType string
ObjectPrices any // float64 或 []float64
StrikePrice float64
RiskFree float64
Sigma float64
Days int
Dividend float64
}
func (c *Client) BSMPrice(ctx context.Context, req BSMPriceRequest) (any, error) {
var out struct {
Price any `json:"price"`
prices := req.ObjectPrices
if vals, ok := req.ObjectPrices.([]float64); ok {
parts := make([]string, len(vals))
for i, v := range vals {
parts[i] = strconv.FormatFloat(v, 'f', -1, 64)
}
prices = strings.Join(parts, ",")
}
if err := c.post(ctx, "/api/data/bsm_price", req, &out); err != nil {
return nil, err
}
return out.Price, nil
return c.postField(ctx, "/api/data/bsm_price", map[string]any{
"optionType": req.OptionType, "objectPrices": prices, "strikePrice": req.StrikePrice,
"riskFree": req.RiskFree, "sigma": req.Sigma, "days": req.Days, "dividend": req.Dividend,
}, "price")
}
type BSMIVRequest struct {
@@ -535,13 +340,7 @@ type BSMIVRequest struct {
}
func (c *Client) BSMIV(ctx context.Context, req BSMIVRequest) (any, error) {
var out struct {
IV any `json:"iv"`
}
if err := c.post(ctx, "/api/data/bsm_iv", req, &out); err != nil {
return nil, err
}
return out.IV, nil
return c.postField(ctx, "/api/data/bsm_iv", req, "iv")
}
type LocalDataRequest struct {
@@ -554,18 +353,12 @@ type LocalDataRequest struct {
}
func (c *Client) LocalData(ctx context.Context, req LocalDataRequest) (any, error) {
var out struct {
Data any `json:"data"`
}
if err := c.post(ctx, "/api/data/local_data", req, &out); err != nil {
return nil, err
}
return out.Data, nil
return c.postField(ctx, "/api/data/local_data", req, "data")
}
func (c *Client) SubscribeQuote(ctx context.Context, stockCode, period, dividendType string) (*SubscribeResult, error) {
body := map[string]any{"stock_code": stockCode, "period": period, "dividend_type": dividendType}
var out SubscribeResult
body := map[string]any{"stock_code": stockCode, "period": period, "dividend_type": dividendType}
if err := c.post(ctx, "/api/data/subscribe_quote", body, &out); err != nil {
return nil, err
}

View File

@@ -1,4 +1,4 @@
// Package sdk 是 QMT_API.py HTTP 服务的 Go 客户端。
//
// 默认地址 http://127.0.0.1:10086所有已注册接口都需要请求头 X-Token
// 用法sdk.New(baseURL, token, timeout),账户类型默认 stock资金账号由服务端环境变量决定
package sdk

View File

@@ -3,45 +3,25 @@ package sdk
import "context"
func (c *Client) ExtData(ctx context.Context, extdataname, stockcode string, deviation int) (any, error) {
var out struct {
Value any `json:"value"`
}
body := map[string]any{"extdataname": extdataname, "stockcode": stockcode, "deviation": deviation}
if err := c.post(ctx, "/api/ext/ext_data", body, &out); err != nil {
return nil, err
}
return out.Value, nil
return c.postField(ctx, "/api/ext/ext_data", map[string]any{
"extdataname": extdataname, "stockcode": stockcode, "deviation": deviation,
}, "value")
}
func (c *Client) ExtDataRank(ctx context.Context, extdataname, stockcode string, deviation int) (any, error) {
var out struct {
Rank any `json:"rank"`
}
body := map[string]any{"extdataname": extdataname, "stockcode": stockcode, "deviation": deviation}
if err := c.post(ctx, "/api/ext/ext_data_rank", body, &out); err != nil {
return nil, err
}
return out.Rank, nil
return c.postField(ctx, "/api/ext/ext_data_rank", map[string]any{
"extdataname": extdataname, "stockcode": stockcode, "deviation": deviation,
}, "rank")
}
func (c *Client) GetFactorValue(ctx context.Context, factorname, stockcode string, deviation int) (any, error) {
var out struct {
Value any `json:"value"`
}
body := map[string]any{"factorname": factorname, "stockcode": stockcode, "deviation": deviation}
if err := c.post(ctx, "/api/ext/get_factor_value", body, &out); err != nil {
return nil, err
}
return out.Value, nil
return c.postField(ctx, "/api/ext/get_factor_value", map[string]any{
"factorname": factorname, "stockcode": stockcode, "deviation": deviation,
}, "value")
}
func (c *Client) GetFactorRank(ctx context.Context, factorname, stockcode string, deviation int) (any, error) {
var out struct {
Rank any `json:"rank"`
}
body := map[string]any{"factorname": factorname, "stockcode": stockcode, "deviation": deviation}
if err := c.post(ctx, "/api/ext/get_factor_rank", body, &out); err != nil {
return nil, err
}
return out.Rank, nil
return c.postField(ctx, "/api/ext/get_factor_rank", map[string]any{
"factorname": factorname, "stockcode": stockcode, "deviation": deviation,
}, "rank")
}

View File

@@ -102,69 +102,47 @@ func (c *Client) styleOrder(ctx context.Context, path string, body map[string]an
return &out, nil
}
func (c *Client) OrderLots(ctx context.Context, stock string, lots int, style string, price float64, accID string) (*StyleOrderResult, error) {
return c.styleOrder(ctx, "/api/trade/order_lots", styleBody(stock, style, price, accID, "lots", lots))
func (c *Client) OrderLots(ctx context.Context, stock string, lots int, style string, price float64) (*StyleOrderResult, error) {
return c.styleOrder(ctx, "/api/trade/order_lots", map[string]any{"stock": stock, "lots": lots, "style": style, "price": price})
}
func (c *Client) OrderValue(ctx context.Context, stock string, value float64, style string, price float64, accID string) (*StyleOrderResult, error) {
return c.styleOrder(ctx, "/api/trade/order_value", styleBody(stock, style, price, accID, "value", value))
func (c *Client) OrderValue(ctx context.Context, stock string, value float64, style string, price float64) (*StyleOrderResult, error) {
return c.styleOrder(ctx, "/api/trade/order_value", map[string]any{"stock": stock, "value": value, "style": style, "price": price})
}
func (c *Client) OrderPercent(ctx context.Context, stock string, percent float64, style string, price float64, accID string) (*StyleOrderResult, error) {
return c.styleOrder(ctx, "/api/trade/order_percent", styleBody(stock, style, price, accID, "percent", percent))
func (c *Client) OrderPercent(ctx context.Context, stock string, percent float64, style string, price float64) (*StyleOrderResult, error) {
return c.styleOrder(ctx, "/api/trade/order_percent", map[string]any{"stock": stock, "percent": percent, "style": style, "price": price})
}
func (c *Client) OrderTargetValue(ctx context.Context, stock string, tarValue float64, style string, price float64, accID string) (*StyleOrderResult, error) {
return c.styleOrder(ctx, "/api/trade/order_target_value", styleBody(stock, style, price, accID, "tar_value", tarValue))
func (c *Client) OrderTargetValue(ctx context.Context, stock string, tarValue float64, style string, price float64) (*StyleOrderResult, error) {
return c.styleOrder(ctx, "/api/trade/order_target_value", map[string]any{"stock": stock, "tar_value": tarValue, "style": style, "price": price})
}
func (c *Client) OrderTargetPercent(ctx context.Context, stock string, tarPercent float64, style string, price float64, accID string) (*StyleOrderResult, error) {
return c.styleOrder(ctx, "/api/trade/order_target_percent", styleBody(stock, style, price, accID, "tar_percent", tarPercent))
func (c *Client) OrderTargetPercent(ctx context.Context, stock string, tarPercent float64, style string, price float64) (*StyleOrderResult, error) {
return c.styleOrder(ctx, "/api/trade/order_target_percent", map[string]any{"stock": stock, "tar_percent": tarPercent, "style": style, "price": price})
}
func (c *Client) OrderShares(ctx context.Context, stock string, shares int, style string, price float64, accID string) (*StyleOrderResult, error) {
return c.styleOrder(ctx, "/api/trade/order_shares", styleBody(stock, style, price, accID, "shares", shares))
func (c *Client) OrderShares(ctx context.Context, stock string, shares int, style string, price float64) (*StyleOrderResult, error) {
return c.styleOrder(ctx, "/api/trade/order_shares", map[string]any{"stock": stock, "shares": shares, "style": style, "price": price})
}
func styleBody(stock, style string, price float64, accID, key string, val any) map[string]any {
body := map[string]any{"stock": stock, key: val, "price": price}
if style != "" {
body["style"] = style
}
if accID != "" {
body["accId"] = accID
}
return body
func (c *Client) FuturesBuyOpen(ctx context.Context, stock string, amount int, style string, price float64) (*StyleOrderResult, error) {
return c.styleOrder(ctx, "/api/trade/futures/buy_open", map[string]any{"stock": stock, "amount": amount, "style": style, "price": price})
}
func (c *Client) futures(ctx context.Context, path, stock string, amount int, style string, price float64, accID string) (*StyleOrderResult, error) {
body := map[string]any{"stock": stock, "amount": amount, "price": price}
if style != "" {
body["style"] = style
}
if accID != "" {
body["accId"] = accID
}
return c.styleOrder(ctx, path, body)
func (c *Client) FuturesBuyCloseTdayFirst(ctx context.Context, stock string, amount int, style string, price float64) (*StyleOrderResult, error) {
return c.styleOrder(ctx, "/api/trade/futures/buy_close_tdayfirst", map[string]any{"stock": stock, "amount": amount, "style": style, "price": price})
}
func (c *Client) FuturesBuyOpen(ctx context.Context, stock string, amount int, style string, price float64, accID string) (*StyleOrderResult, error) {
return c.futures(ctx, "/api/trade/futures/buy_open", stock, amount, style, price, accID)
func (c *Client) FuturesBuyCloseYdayFirst(ctx context.Context, stock string, amount int, style string, price float64) (*StyleOrderResult, error) {
return c.styleOrder(ctx, "/api/trade/futures/buy_close_ydayfirst", map[string]any{"stock": stock, "amount": amount, "style": style, "price": price})
}
func (c *Client) FuturesBuyCloseTdayFirst(ctx context.Context, stock string, amount int, style string, price float64, accID string) (*StyleOrderResult, error) {
return c.futures(ctx, "/api/trade/futures/buy_close_tdayfirst", stock, amount, style, price, accID)
func (c *Client) FuturesSellOpen(ctx context.Context, stock string, amount int, style string, price float64) (*StyleOrderResult, error) {
return c.styleOrder(ctx, "/api/trade/futures/sell_open", map[string]any{"stock": stock, "amount": amount, "style": style, "price": price})
}
func (c *Client) FuturesBuyCloseYdayFirst(ctx context.Context, stock string, amount int, style string, price float64, accID string) (*StyleOrderResult, error) {
return c.futures(ctx, "/api/trade/futures/buy_close_ydayfirst", stock, amount, style, price, accID)
func (c *Client) FuturesSellCloseTdayFirst(ctx context.Context, stock string, amount int, style string, price float64) (*StyleOrderResult, error) {
return c.styleOrder(ctx, "/api/trade/futures/sell_close_tdayfirst", map[string]any{"stock": stock, "amount": amount, "style": style, "price": price})
}
func (c *Client) FuturesSellOpen(ctx context.Context, stock string, amount int, style string, price float64, accID string) (*StyleOrderResult, error) {
return c.futures(ctx, "/api/trade/futures/sell_open", stock, amount, style, price, accID)
}
func (c *Client) FuturesSellCloseTdayFirst(ctx context.Context, stock string, amount int, style string, price float64, accID string) (*StyleOrderResult, error) {
return c.futures(ctx, "/api/trade/futures/sell_close_tdayfirst", stock, amount, style, price, accID)
}
func (c *Client) FuturesSellCloseYdayFirst(ctx context.Context, stock string, amount int, style string, price float64, accID string) (*StyleOrderResult, error) {
return c.futures(ctx, "/api/trade/futures/sell_close_ydayfirst", stock, amount, style, price, accID)
func (c *Client) FuturesSellCloseYdayFirst(ctx context.Context, stock string, amount int, style string, price float64) (*StyleOrderResult, error) {
return c.styleOrder(ctx, "/api/trade/futures/sell_close_ydayfirst", map[string]any{"stock": stock, "amount": amount, "style": style, "price": price})
}
type TaskResult struct {
@@ -172,45 +150,37 @@ type TaskResult struct {
TaskID any `json:"taskId"`
}
func (c *Client) task(ctx context.Context, path, taskID, accountType string) (*TaskResult, error) {
body := map[string]any{"taskId": taskID}
if accountType != "" {
body["accountType"] = accountType
}
func (c *Client) CancelTask(ctx context.Context, taskID string) (*TaskResult, error) {
return c.task(ctx, "/api/trade/cancel_task", taskID)
}
func (c *Client) PauseTask(ctx context.Context, taskID string) (*TaskResult, error) {
return c.task(ctx, "/api/trade/pause_task", taskID)
}
func (c *Client) ResumeTask(ctx context.Context, taskID string) (*TaskResult, error) {
return c.task(ctx, "/api/trade/resume_task", taskID)
}
func (c *Client) task(ctx context.Context, path, taskID string) (*TaskResult, error) {
var out TaskResult
if err := c.post(ctx, path, body, &out); err != nil {
if err := c.post(ctx, path, map[string]any{"taskId": taskID, "accountType": c.accountType}, &out); err != nil {
return nil, err
}
return &out, nil
}
func (c *Client) CancelTask(ctx context.Context, taskID, accountType string) (*TaskResult, error) {
return c.task(ctx, "/api/trade/cancel_task", taskID, accountType)
}
func (c *Client) PauseTask(ctx context.Context, taskID, accountType string) (*TaskResult, error) {
return c.task(ctx, "/api/trade/pause_task", taskID, accountType)
}
func (c *Client) ResumeTask(ctx context.Context, taskID, accountType string) (*TaskResult, error) {
return c.task(ctx, "/api/trade/resume_task", taskID, accountType)
}
func (c *Client) DoOrder(ctx context.Context) (map[string]any, error) {
var out map[string]any
if err := c.post(ctx, "/api/trade/do_order", map[string]any{}, &out); err != nil {
if err := c.post(ctx, "/api/trade/do_order", nil, &out); err != nil {
return nil, err
}
return out, nil
}
func (c *Client) TradeDetailData(ctx context.Context, account, datatype string) ([]map[string]string, error) {
body := map[string]any{
"account": c.Account(account),
"datatype": datatype,
}
func (c *Client) TradeDetailData(ctx context.Context, datatype string) ([]map[string]string, error) {
var out struct {
Data []map[string]string `json:"data"`
}
if err := c.post(ctx, "/api/trade/trade_detail_data", body, &out); err != nil {
if err := c.post(ctx, "/api/trade/trade_detail_data", map[string]any{"account": c.accountType, "datatype": datatype}, &out); err != nil {
return nil, err
}
if out.Data == nil {
@@ -219,84 +189,61 @@ func (c *Client) TradeDetailData(ctx context.Context, account, datatype string)
return out.Data, nil
}
func (c *Client) ValueByOrderID(ctx context.Context, orderID, accountType, datatype string) (map[string]string, error) {
body := map[string]any{"orderId": orderID, "accountType": accountType, "datatype": datatype}
func (c *Client) ValueByOrderID(ctx context.Context, orderID, datatype string) (map[string]string, error) {
var out struct {
OrderID string `json:"orderId"`
Data map[string]string `json:"data"`
Data map[string]string `json:"data"`
}
body := map[string]any{"orderId": orderID, "accountType": c.accountType, "datatype": datatype}
if err := c.post(ctx, "/api/trade/value_by_order_id", body, &out); err != nil {
return nil, err
}
return out.Data, nil
}
func (c *Client) LastOrderID(ctx context.Context, account, datatype string) (any, error) {
body := map[string]any{"account": c.Account(account), "datatype": datatype}
func (c *Client) LastOrderID(ctx context.Context, datatype string) (any, error) {
var out struct {
LastOrderID any `json:"last_order_id"`
}
if err := c.post(ctx, "/api/trade/last_order_id", body, &out); err != nil {
if err := c.post(ctx, "/api/trade/last_order_id", map[string]any{"account": c.accountType, "datatype": datatype}, &out); err != nil {
return nil, err
}
return out.LastOrderID, nil
}
func (c *Client) CanCancelOrder(ctx context.Context, orderID, accountType string) (any, error) {
body := map[string]any{"orderId": orderID, "accountType": accountType}
func (c *Client) CanCancelOrder(ctx context.Context, orderID string) (any, error) {
var out struct {
CanCancel any `json:"can_cancel"`
}
if err := c.post(ctx, "/api/trade/can_cancel_order", body, &out); err != nil {
if err := c.post(ctx, "/api/trade/can_cancel_order", map[string]any{"orderId": orderID, "accountType": c.accountType}, &out); err != nil {
return nil, err
}
return out.CanCancel, nil
}
func (c *Client) contractList(ctx context.Context, path, accID string) ([]map[string]string, error) {
body := map[string]any{}
if accID != "" {
body["accId"] = accID
}
func (c *Client) contractList(ctx context.Context, path string) ([]map[string]string, error) {
var out struct {
Data []map[string]string `json:"data"`
}
if err := c.post(ctx, path, body, &out); err != nil {
if err := c.post(ctx, path, nil, &out); err != nil {
return nil, err
}
return out.Data, nil
}
func (c *Client) DebtContract(ctx context.Context, accID string) ([]map[string]string, error) {
return c.contractList(ctx, "/api/trade/debt_contract", accID)
func (c *Client) DebtContract(ctx context.Context) ([]map[string]string, error) {
return c.contractList(ctx, "/api/trade/debt_contract")
}
func (c *Client) AssureContract(ctx context.Context, accID string) ([]map[string]string, error) {
return c.contractList(ctx, "/api/trade/assure_contract", accID)
func (c *Client) AssureContract(ctx context.Context) ([]map[string]string, error) {
return c.contractList(ctx, "/api/trade/assure_contract")
}
func (c *Client) EnableShortContract(ctx context.Context, accID string) ([]map[string]string, error) {
return c.contractList(ctx, "/api/trade/enable_short_contract", accID)
func (c *Client) EnableShortContract(ctx context.Context) ([]map[string]string, error) {
return c.contractList(ctx, "/api/trade/enable_short_contract")
}
func (c *Client) IPOData(ctx context.Context, typ string) (any, error) {
var out struct {
Data any `json:"data"`
}
if err := c.post(ctx, "/api/trade/ipo_data", map[string]any{"type": typ}, &out); err != nil {
return nil, err
}
return out.Data, nil
return c.postField(ctx, "/api/trade/ipo_data", map[string]any{"type": typ}, "data")
}
func (c *Client) NewPurchaseLimit(ctx context.Context, accid string) (any, error) {
body := map[string]any{}
if accid != "" {
body["accid"] = accid
}
var out struct {
Data any `json:"data"`
}
if err := c.post(ctx, "/api/trade/new_purchase_limit", body, &out); err != nil {
return nil, err
}
return out.Data, nil
func (c *Client) NewPurchaseLimit(ctx context.Context) (any, error) {
return c.postField(ctx, "/api/trade/new_purchase_limit", nil, "data")
}