使用StockTV API获取印度股票数据:完整Python实战指南
本文将详细介绍如何通过StockTV API对接印度股票市场数据,涵盖从环境准备到实时数据获取的完整流程。
一、印度股票市场特点
印度作为全球增长最快的主要经济体之一,其金融市场具有以下显著特征:
- 双交易所体系:国家证券交易所(NSE)占全印交易量90%,孟买证券交易所(BSE)是亚洲最老交易所
- 核心指数:NSE的Nifty 50指数和BSE的Sensex 30指数
- 交易时间:09:15-15:30 IST(UTC+5:30),含午休12:00-12:15
- 特色数据:期权链、外国机构持仓(FII/DII数据)、IPO发行文件等
二、环境准备与配置
1. 获取API密钥
首先需要访问StockTV开发者门户注册账号并创建应用,获取API密钥(格式示例:MY4b781f618e3f43c4b055f25fa61941ad)。
2. 安装依赖库
python
pip install requests websocket-client pandas pytz
3. 基础配置
python
import requests
import pandas as pd
from pytz import timezone
# 基础配置
API_KEY = "YOUR_API_KEY" # 替换为实际密钥
BASE_URL = "https://api.stocktv.top"
INDIA_COUNTRY_ID = 14 # 印度国家ID固定为14
NSE_EXCHANGE_ID = 46 # NSE交易所代码
BSE_EXCHANGE_ID = 74 # BSE交易所代码
三、核心API接口详解
1. 获取印度股票列表
python
def get_indian_stocks(api_key, page_size=100, exchange_id=46):
"""获取印度股票列表"""
url = f"{BASE_URL}/stock/stocks"
params = {
"key": api_key,
"countryId": INDIA_COUNTRY_ID,
"exchangeId": exchange_id, # 46 for NSE, 74 for BSE
"pageSize": page_size
}
response = requests.get(url, params=params)
response.raise_for_status()
data = response.json()
# 提取关键字段
stocks = [{
"symbol": item["symbol"],
"name": item["name"],
"last_price": item["last"],
"exchange": "NSE" if exchange_id == 46 else "BSE"
} for item in data["data"]["records"]]
return stocks
# 使用示例
stocks = get_indian_stocks(API_KEY)
for stock in stocks[:5]: # 显示前5只股票
print(f"{stock['name']}({stock['symbol']}): {stock['last_price']}")
2. 获取实时行情数据
python
def get_real_time_quote(api_key, symbol, exchange="NSE"):
"""获取单只股票实时行情"""
url = f"{BASE_URL}/stock/queryStocks"
params = {
"key": api_key,
"symbol": symbol,
"exchange": exchange,
"countryId": INDIA_COUNTRY_ID
}
response = requests.get(url, params=params)
data = response.json()
if data["data"]:
stock_data = data["data"][0]
return {
"symbol": stock_data["symbol"],
"name": stock_data["name"],
"last": stock_data["last"],
"change": stock_data.get("pc", 0), # 涨跌额
"change_percent": stock_data.get("pcp", 0), # 涨跌幅
"volume": stock_data.get("volume", 0)
}
return None
# 获取Reliance Industries实时行情
reliance_quote = get_real_time_quote(API_KEY, "RELIANCE")
print(f"信实工业: {reliance_quote}")
3. 获取K线数据(历史数据)
python
def get_kline_data(api_key, pid, interval="PT15M"):
"""
获取股票历史K线数据
pid: 股票唯一ID(从股票列表接口获取)
interval: 时间粒度 PT5M(5分钟)/PT1H(小时线)/P1D(日线)
"""
url = f"{BASE_URL}/stock/kline"
params = {
"key": api_key,
"pid": pid,
"interval": interval
}
response = requests.get(url, params=params)
data = response.json()
# 转换为DataFrame并处理时间戳
df = pd.DataFrame(data["data"])
df["time"] = pd.to_datetime(df["time"], unit="ms")
# 转换为印度时区
ist = timezone('Asia/Kolkata')
df["time"] = df["time"].dt.tz_localize('UTC').dt.tz_convert(ist)
return df[["time", "open", "high", "low", "close", "volume"]]
# 使用示例(需要先获取股票的pid)
kline_data = get_kline_data(API_KEY, pid=7310, interval="PT1H") # 1小时K线
print(kline_data.head())
4. 获取印度指数数据
python
def get_india_indices(api_key):
"""获取印度主要指数数据"""
url = f"{BASE_URL}/stock/indices"
params = {
"key": api_key,
"countryId": INDIA_COUNTRY_ID,
"flag": "IN"
}
response = requests.get(url, params=params)
data = response.json()
indices = []
for index in data["data"]:
if index["name"] in ["Nifty 50", "SENSEX"]:
indices.append({
"name": index["name"],
"last": index["last"],
"change": index.get("chg", 0),
"change_percent": index.get("chgPct", 0)
})
return indices
# 获取指数数据
indices = get_india_indices(API_KEY)
for index in indices:
print(f"{index['name']}: {index['last']} ({index['change_percent']}%)")
四、WebSocket实时数据订阅
对于需要低延迟实时数据的应用,WebSocket是更好的选择:
python
import websocket
import json
import threading
class IndiaMarketWebSocket:
def __init__(self, api_key):
self.api_key = api_key
self.ws_url = f"wss://ws-api.stocktv.top/connect?key={api_key}"
self.symbol_map = {}
def on_message(self, ws, message):
"""处理实时推送消息"""
data = json.loads(message)
if data.get("type") == "stock":
symbol = data["symbol"]
print(f"实时行情 [{symbol}] 价格: {data['last']} 涨跌幅: {data['pcp']}%")
elif data.get("type") == "index":
print(f"指数更新 {data['name']}: {data['last']} ({data['chgPct']}%)")
def on_error(self, ws, error):
print(f"WebSocket错误: {error}")
def on_close(self, ws, close_status_code, close_msg):
print("WebSocket连接关闭")
def on_open(self, ws):
print("WebSocket连接成功")
# 可以在此订阅特定股票
subscribe_msg = {
"action": "subscribe",
"countryId": INDIA_COUNTRY_ID,
"symbols": ["RELIANCE", "TCS", "INFY"],
"indices": ["NSEI"]
}
ws.send(json.dumps(subscribe_msg))
def start(self):
"""启动WebSocket连接"""
ws = websocket.WebSocketApp(
self.ws_url,
on_message=self.on_message,
on_error=self.on_error,
on_close=self.on_close
)
ws.on_open = self.on_open
# 在独立线程中运行
self.ws_thread = threading.Thread(target=ws.run_forever)
self.ws_thread.daemon = True
self.ws_thread.start()
# 启动实时数据订阅
market_ws = IndiaMarketWebSocket(API_KEY)
market_ws.start()
五、高级功能示例
1. 获取IPO新股日历
python
def get_ipo_calendar(api_key, ipo_type=1):
"""
获取印度IPO日历
ipo_type: 1=即将上市, 2=已上市
"""
url = f"{BASE_URL}/stock/getIpo"
params = {
"key": api_key,
"countryId": INDIA_COUNTRY_ID,
"type": ipo_type
}
response = requests.get(url, params=params)
return response.json()
# 获取即将上市的IPO
upcoming_ipos = get_ipo_calendar(API_KEY, ipo_type=1)
print("即将上市的IPO:")
for ipo in upcoming_ipos['data'][:3]:
print(f"- {ipo['company']} ({ipo['symbol']})")
2. 获取涨跌幅排行榜
python
def get_top_gainers(api_key, list_type=1):
"""
获取涨跌幅排行榜
list_type: 1=涨幅榜, 2=跌幅榜
"""
url = f"{BASE_URL}/stock/updownList"
params = {
"key": api_key,
"countryId": INDIA_COUNTRY_ID,
"type": list_type
}
response = requests.get(url, params=params)
return response.json()
# 获取涨幅榜前十
top_gainers = get_top_gainers(API_KEY, list_type=1)
print("今日涨幅前十:")
for stock in top_gainers['data'][:10]:
print(f"{stock['name']}: {stock.get('chgPct', 0)}%")
六、最佳实践与注意事项
1. 错误处理与重试机制
python
from tenacity import retry, stop_after_attempt, wait_exponential
import logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
@retry(stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=4, max=10))
def safe_api_call(url, params, timeout=10):
"""带重试机制的API调用"""
try:
response = requests.get(url, params=params, timeout=timeout)
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
logger.error(f"API请求失败: {e}")
raise
2. 时区处理
印度使用IST时区(UTC+5:30),所有时间数据需要正确转换:
python
def convert_to_ist(utc_timestamp):
"""将UTC时间戳转换为印度时区"""
ist = timezone('Asia/Kolkata')
utc_time = pd.to_datetime(utc_timestamp, unit='ms').tz_localize('UTC')
return utc_time.tz_convert(ist)
# 使用示例
ist_time = convert_to_ist(1719817200000)
print(f"印度时间: {ist_time}")
3. 频率限制注意事项
- REST API:≤10次/分钟
- WebSocket:实时推送(延迟<1秒)
- 建议使用连接池和适当的延迟避免触发限制
七、完整示例:获取Nifty 50成分股数据
python
def get_nifty50_analysis(api_key):
"""获取Nifty 50成分股并分析"""
# 获取印度股票列表
all_stocks = get_indian_stocks(api_key, page_size=200)
# 筛选Nifty 50成分股(根据名称关键词)
nifty_stocks = [
stock for stock in all_stocks
if any(keyword in stock['name'] for keyword in ['Nifty', 'SENSEX'])
]
# 获取每只股票的详细数据
analysis_results = []
for stock in nifty_stocks[:10]: # 限制数量避免频繁调用
try:
detail = get_real_time_quote(api_key, stock['symbol'])
if detail:
analysis_results.append(detail)
except Exception as e:
logger.warning(f"获取{stock['name']}数据失败: {e}")
# 按涨跌幅排序
sorted_results = sorted(
analysis_results,
key=lambda x: x.get('change_percent', 0),
reverse=True
)
return sorted_results
# 执行分析
results = get_nifty50_analysis(API_KEY)
for i, stock in enumerate(results, 1):
print(f"{i}. {stock['name']}: {stock['change_percent']}%")
总结
通过StockTV API,我们可以方便地获取印度股票市场的实时行情、历史数据、指数信息等。本文提供了完整的Python实现示例,涵盖了从基础数据获取到高级功能的各个方面。在实际应用中,建议注意API调用频率限制、正确处理时区问题,并实现适当的错误处理机制。
对于更高级的需求如期权链数据、机构持仓信息等,可以参考StockTV官方文档进一步开发。