一、先定位 BSE 在接口里的身份
StockTV 把所有市场挂在国家 ID + 交易所 ID 两层下面,印度是 countryId=14,BSE 本身是 exchangeId=74(NSE 是 46,别写错)。
| 市场 | countryId | exchangeId | 代表指数 |
|---|---|---|---|
| 印度 NSE | 14 | 46 | Nifty 50 |
| 印度 BSE | 14 | 74 | S&P BSE SENSEX |
后面所有 BSE 请求都带着这俩参数走。
二、拿到 BSE 股票池,取到 pid
K 线接口不吃 symbol,吃内部 pid,所以第一步先把 BSE 股票列表拉下来,把 id 记下来。
python
import requests
BASE = "https://api.stocktv.top"
KEY = "YOUR_KEY" # 联系官方拿:https://t.me/stocktvpaopao
COUNTRY_ID = 14
BSE_ID = 74
def fetch_bse_list(page=1, page_size=20):
url = f"{BASE}/stock/stocks"
params = {
"countryId": COUNTRY_ID,
"exchangeId": BSE_ID,
"page": page,
"pageSize": page_size,
"key": KEY
}
r = requests.get(url, params=params, timeout=5)
r.raise_for_status()
return r.json()
data = fetch_bse_list()
for s in data["data"]["records"][:5]:
print(s["id"], s["symbol"], s["name"])
返回的 id 就是后面 /stock/kline 要的 pid。比如 Reliance 在 BSE 也有挂牌,用 symbol=RELIANCE 走 /stock/queryStocks 也能反查 pid。
三、拉 K 线(/stock/kline)
接口:GET /stock/kline?pid=xxx&interval=xxx&key=xxx
interval 给的是 ISO 8601 duration 风格:
PT5M/PT15M/PT1H→ 短周期P1D→ 日线
python
def fetch_kline(pid, interval="P1D", limit=100):
url = f"{BASE}/stock/kline"
params = {"pid": pid, "interval": interval, "key": KEY}
r = requests.get(url, params=params, timeout=5)
r.raise_for_status()
return r.json()
# 举个栗子:TCS(假设 pid=xxx,先用 /queryStocks 查一下真实 pid)
kline = fetch_kline(pid=41602, interval="P1D")
print(kline["data"][:3])
返回一般是 time / open / high / low / close / volume 这一组,直接能喂给图表库。
💡 BSE 有些老牌股票(Tata、Reliance、Infosys)日线数据跨度很长,做均线/布林带回测够用;短线策略建议走
PT5M或PT15M,但要注意印度交易时段是 UTC+5:30,不是北京时间,做时间戳转换时别踩坑。
四、挂到前端 K 线(KChat)上
后端拿到 K 线 JSON 之后,前端随便挑一个轻量图表都能接。下面用 TradingView Lightweight Charts(体积小、专为 K 线优化)示意:
js
// 假设 /api/bse/kline?pid=xxx&interval=P1D 返回 [{t,o,h,l,c,v}]
const raw = await fetch(`/api/bse/kline?pid=${pid}&interval=P1D`).then(r => r.json());
const data = raw.data.map(b => ({
time: b.t / 1000, // 秒级
open: b.o,
high: b.h,
low: b.l,
close: b.c,
}));
const chart = LightweightCharts.createChart(document.getElementById('tv'), { width: 800, height: 500 });
const candlestick = chart.addCandlestickSeries();
candlestick.setData(data);
如果你项目里已经用了 ECharts,思路一样------dataset 塞进去,series 用 candlestick 类型就行。整个链路:
BSE /stock/stocks → 拿 pid
↓
/stock/kline → JSON (ohlc+v)
↓
后端透传 / 缓存
↓
Lightweight Charts / ECharts 渲染
五、想让 K 线动起来:WebSocket 补实时
光日线还不够,做盯盘的话 K 线最右一根得跟着 tick 推。StockTV 的 WS 地址是 wss://ws-api.stocktv.top/connect?key=xxx,连上后 subscribe 对应的 pid 就行:
json
{"action": "subscribe", "pids": [41602]}
前端收到 push 后自己改最后一根 candle 的 close / high / low / volume,比轮询优雅多了。BSE 那边延迟官方标"毫秒级",实测得看你机房位置,新加坡/孟买节点会稳一点。
六、几个 BSE 特有的小坑
- 同一只票 NSE 和 BSE 都有,pid 不一样、价格也略有价差,套利党会关心这个,普通展示别混。
- Sensex(BSESN) 是指数不是股票,走
/stock/indices?countryId=14单独拿,pid 和个股不在一个表里。 - 接口限流 ------
key是明文挂 URL 的,生产别把 key 写前端,走后端中转,否则容易被刷。
访问凭证申请和文档入口在这:官网 https://pao.stocktv.top/ ,对接中遇到字段含义不清的也可以直接去 https://t.me/stocktvpaopao 。下一篇打算把"NSE vs BSE 价差监控"那个小 demo 写完,有兴趣接着看。
要不要下一篇直接把 WebSocket + 动态 K 线(最后一 candle 实时刷新) 那段补齐?BSE 的 Sensex 做指数联动那个玩法也挺适合当 demo 的。