package sdk import ( "context" "fmt" ) type Tick struct { LastPrice float64 LastClose float64 Raw map[string]any } 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"` } 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"` } type SubscribeResult struct { Status string `json:"status"` SubID any `json:"sub_id"` } 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 } 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 } 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 } 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 } 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 } func (c *Client) Sector(ctx context.Context, sector string, realtime string) ([]any, error) { body := map[string]any{"sector": sector} if realtime != "" { body["realtime"] = realtime } var out struct { Stocks []any `json:"stocks"` } if err := c.post(ctx, "/api/data/sector", body, &out); err != nil { return nil, err } return out.Stocks, nil } func (c *Client) Industry(ctx context.Context, industry string) ([]any, error) { var out struct { Stocks []any `json:"stocks"` } if err := c.post(ctx, "/api/data/industry", map[string]any{"industry": industry}, &out); err != nil { return nil, err } return out.Stocks, nil } func (c *Client) StockListInSector(ctx context.Context, sectorname string) ([]any, error) { var out struct { Stocks []any `json:"stocks"` } if err := c.post(ctx, "/api/data/stock_list_in_sector", map[string]any{"sectorname": sectorname}, &out); err != nil { return nil, err } return out.Stocks, nil } 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 } 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 } 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 } 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 } func (c *Client) HistoryData(ctx context.Context, req HistoryDataRequest) (any, error) { if req.Len == 0 { req.Len = 10 } if req.SkipPaused == "" { req.SkipPaused = "true" } var out map[string]any if err := c.post(ctx, "/api/data/history_data", req, &out); err != nil { return nil, err } 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 } 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 } 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 { return nil, err } out := make(map[string]Tick, len(raw)) for code, v := range raw { tick := Tick{Raw: map[string]any{}} if m, ok := v.(map[string]any); ok { tick.Raw = m tick.LastPrice = asFloat(mapField(m, "lastPrice", "last_price", "LastPrice")) tick.LastClose = asFloat(mapField(m, "lastClose", "last_close", "LastClose")) } out[code] = tick } return out, nil } 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 } 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 } func (c *Client) TimetagToDatetime(ctx context.Context, timetag int64, format string) (any, error) { body := map[string]any{"timetag": timetag} 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 } 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 } func (c *Client) TradingDates(ctx context.Context, stockcode, startDate, endDate, period string, count int) ([]any, error) { body := map[string]any{"stockcode": stockcode, "start_date": startDate, "end_date": endDate, "period": period} if count != 0 { body["count"] = count } var out struct { Dates []any `json:"dates"` } if err := c.post(ctx, "/api/data/trading_dates", body, &out); err != nil { return nil, err } return out.Dates, nil } 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 } 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 } 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, 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) 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 } 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) 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 } 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 } 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 } 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 } 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 } 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"` } 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 } if msg, ok := out["error"].(string); ok && msg != "" { return nil, &BusinessError{Message: msg} } return out["data"], nil } 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"` } 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 } if msg, ok := out["error"].(string); ok && msg != "" { return nil, &BusinessError{Message: msg} } return out["data"], nil } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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"` } func (c *Client) BSMPrice(ctx context.Context, req BSMPriceRequest) (any, error) { var out struct { Price any `json:"price"` } if err := c.post(ctx, "/api/data/bsm_price", req, &out); err != nil { return nil, err } return out.Price, nil } type BSMIVRequest struct { OptionType string `json:"optionType"` ObjectPrices float64 `json:"objectPrices"` StrikePrice float64 `json:"strikePrice"` OptionPrice float64 `json:"optionPrice"` RiskFree float64 `json:"riskFree"` Days int `json:"days"` Dividend float64 `json:"dividend"` } 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 } type LocalDataRequest struct { StockCode string `json:"stock_code"` StartTime string `json:"start_time,omitempty"` EndTime string `json:"end_time,omitempty"` Period string `json:"period,omitempty"` DividType string `json:"divid_type,omitempty"` Count int `json:"count"` } 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 } 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 if err := c.post(ctx, "/api/data/subscribe_quote", body, &out); err != nil { return nil, err } return &out, nil } func (c *Client) UnsubscribeQuote(ctx context.Context, subID int) (*SubscribeResult, error) { var out SubscribeResult if err := c.post(ctx, "/api/data/unsubscribe_quote", map[string]any{"sub_id": subID}, &out); err != nil { return nil, err } return &out, nil }