背景
最近有个需求:做一个跨市场行情看板,需要同时展示印度、马来西亚、日韩等几个海外市场的股票列表和涨跌排行,再加一个 BTC/ETH 的实时价格面板。
本来想分头找数据源,后来图省事直接用了一个接口聚合的。刚好整理下对接过程中的几个点和踩过的坑。
接口概览
Base URL 是 https://api.stocktv.top,鉴权方式就是 URL 加一个 key 参数,所有响应 JSON,结构统一是 {code, message, data}。
我用到的就四个接口:
/stock/stocks--- 按国家拉股票列表,带分页/stock/updownList--- 涨跌排行榜/crypto/lastPrice--- 加密货币最新报价/market/currency--- 外汇汇率列表
官网文档地址:https://pao.stocktv.top/
1. 股票列表接口
GET /stock/stocks?countryId=14&pageSize=10&page=1&key=YOUR_KEY
参数很简单:countryId(国家ID)、pageSize、page。
这里 countryId 需要提前知道。当时查文档发现支持的几个国家 ID:
| countryId | 国家 | 标识 |
|---|---|---|
| 14 | 印度 | IN |
| 42 | 马来西亚 | MY |
| 韩国、日本、美国等 | ... | ... |
返回结构:
json
{
"code": 200,
"data": {
"records": [
{
"symbol": "TCS",
"name": "Tata Consultancy Services Ltd",
"last": 3890.55,
"chg": 25.30,
"chgPct": 0.65,
"high": 3910.00,
"low": 3865.20,
"volume": 2345678,
"open": false,
"technicalDay": "strong_buy",
"performanceYtd": 12.5,
"countryNameTranslated": "India"
}
],
"total": 1000,
"size": 10,
"current": 1,
"pages": 100
}
}
数据比较全,基本面和业绩统计都在一条记录里了。不过注意 open 字段是 boolean,拿到后需要处理一下开盘/收盘状态的展示逻辑。
2. 涨跌排行榜
GET /stock/updownList?countryId=14&type=1&key=YOUR_KEY
type 取值:1 涨幅榜、2 跌幅榜、3 涨停榜、4 跌停榜,默认返回前 50 条。
返回字段和股票列表接口基本一致,可以直接复用同一个 DTO:
java
@Data
public class StockItem {
private Long id;
private String symbol;
private String name;
private Double last;
private Double chg;
private Double chgPct;
private Double high;
private Double low;
private Long volume;
private Boolean open;
private String technicalDay;
private String technicalWeek;
private Double performanceYtd;
private String countryNameTranslated;
private String flag;
// getters/setters 省略
}
3. 加密货币价格
获取 BTC 和 ETH 的 USDT 交易对最新价:
GET /crypto/lastPrice?symbols=BTCUSDT,ETHUSDT&key=YOUR_KEY
最多一次传 100 个交易对,逗号分隔。返回非常轻量:
json
{
"code": 200,
"data": [
{ "symbol": "BTCUSDT", "price": "66630.20" },
{ "symbol": "ETHUSDT", "price": "3307.74" }
]
}
4. Spring Boot 中的封装
java
@Service
public class MarketDataService {
private final RestTemplate restTemplate = new RestTemplate();
private static final String BASE_URL = "https://api.stocktv.top";
private final String apiKey;
public MarketDataService(@Value("${market.api.key}") String apiKey) {
this.apiKey = apiKey;
}
public JsonNode getStockList(int countryId, int page, int pageSize) {
String url = String.format(
"%s/stock/stocks?countryId=%d&page=%d&pageSize=%d&key=%s",
BASE_URL, countryId, page, pageSize, apiKey
);
return restTemplate.getForObject(url, JsonNode.class);
}
public JsonNode getUpDownList(int countryId, int type) {
String url = String.format(
"%s/stock/updownList?countryId=%d&type=%d&key=%s",
BASE_URL, countryId, type, apiKey
);
return restTemplate.getForObject(url, JsonNode.class);
}
public JsonNode getCryptoPrices(String... symbols) {
String symbolStr = String.join(",", symbols);
String url = String.format(
"%s/crypto/lastPrice?symbols=%s&key=%s",
BASE_URL, symbolStr, apiKey
);
return restTemplate.getForObject(url, JsonNode.class);
}
}
5. 踩过的坑
- 开盘状态字段 :
open是 boolean,直接Boolean.getBoolean()拿不到,得用asBoolean()(JacksonJsonNode)或注意 getter 命名。 - 涨跌幅需拼接 % :WebSocket 推送里
pcp字段返回的数值不含百分号,前端渲染时要自己拼。 - K 线 interval 命名 :股票用的是
P1D、PT15M这种 ISO 8601 Duration 格式,外汇和加密货币用的是5m、1h这种短格式,别搞混了。
附:其他可用的接口
除了上面我用到的,这个接口还提供了:
- K 线 :
/stock/kline?pid=&interval=--- 支持 PT5M ~ P1M - IPO 日历 :
/stock/getIpo?countryId= - 公司信息 :
/stock/companies?countryId= - 国际新闻 :
/stock/news?pageSize=&page= - 外汇 :
/market/currencyList、/market/chart - 期货 :
/futures/list、/futures/kline - 加密货币完整数据 :
/crypto/getKlines、/crypto/getTrades - WebSocket 实时推送 :
wss://ws-api.stocktv.top/connect?key=
有需要可以直接看文档,或者 联系获取 Key。