本文将详细介绍如何使用Python对接StockTV期货市场API,并提供完整的代码示例和最佳实践。
一、环境准备
1.1 安装依赖
pip install requests websocket-client pandas numpy
1.2 获取API Key
联系官方获取密钥:Telegram @CryptoRzz
二、基础配置
import requests
import json
import websocket
import threading
import time
# API配置
API_KEY = "YOUR_API_KEY" # 替换为实际API密钥
BASE_URL = "https://api.stocktv.top"
WS_URL = "wss://ws-api.stocktv.top"
# 期货品种映射表
SYMBOL_MAP = {
"CL": "WTI原油",
"GC": "黄金",
"SI": "白银",
"NG": "天然气",
"ZS": "大豆",
"ZC": "玉米",
"HG": "铜"
}
# 交易所映射表
EXCHANGE_MAP = {
"CME": "芝加哥商品交易所",
"NYMEX": "纽约商品交易所",
"ICE": "洲际交易所",
"LME": "伦敦金属交易所"
}
三、REST API实现
3.1 获取期货市场列表
def get_futures_list(category=None):
"""获取期货市场列表"""
url = f"{BASE_URL}/futures/list"
params = {"key": API_KEY}
if category:
params["category"] = category
try:
response = requests.get(url, params=params)
if response.status_code == 200:
data = response.json()
if data["code"] == 200:
print("期货市场列表获取成功:")
for item in data["data"]:
print(f"{SYMBOL_MAP.get(item['symbol'], item['symbol'])} "
f"({item['symbol']}) - {EXCHANGE_MAP.get(item['exchange'], item['exchange'])}: "
f"最新价 {item['lastPrice']}, 涨跌 {item['change']} ({item['changePercent']}%)")
else:
print(f"API返回错误: {data['message']}")
else:
print(f"请求失败,状态码: {response.status_code}")
except Exception as e:
print(f"获取期货列表时发生错误: {str(e)}")
# 示例:获取能源类期货
get_futures_list(category="energy")
3.2 查询指定期货行情
def get_futures_quote(symbol):
"""获取指定期货行情"""
url = f"{BASE_URL}/futures/querySymbol"
params = {"key": API_KEY, "symbol": symbol}
try:
response = requests.get(url, params=params)
if response.status_code == 200:
data = response.json()
if data["code"] == 200:
quote = data["data"]
print(f"\n{symbol} ({SYMBOL_MAP.get(symbol, '未知品种')}) 行情:")
print(f"交易所: {EXCHANGE_MAP.get(quote['exchange'], quote['exchange'])}")
print(f"最新价: {quote['lastPrice']}")
print(f"涨跌: {quote['change']} ({quote['changePercent']}%)")
print(f"开盘: {quote['open']}, 最高: {quote['high']}, 最低: {quote['low']}")
print(f"买一价: {quote['bid']}, 卖一价: {quote['ask']}")
print(f"成交量: {quote['volume']}, 持仓量: {quote['openInterest']}")
print(f"结算价: {quote['settlement']}, 前收盘: {quote['prevClose']}")
print(f"交易时间: {quote['tradingHours']}, 到期日: {quote['expiryDate']}")
else:
print(f"API返回错误: {data['message']}")
else:
print(f"请求失败,状态码: {response.status_code}")
except Exception as e:
print(f"获取期货行情时发生错误: {str(e)}")
# 示例:获取WTI原油行情
get_futures_quote("CL")
3.3 获取K线数据
def get_futures_kline(symbol, interval="15m", limit=100):
"""获取期货K线数据"""
url = f"{BASE_URL}/futures/kline"
params = {
"key": API_KEY,
"symbol": symbol,
"interval": interval,
"limit": limit
}
try:
response = requests.get(url, params=params)
if response.status_code == 200:
data = response.json()
if data["code"] == 200:
print(f"\n{symbol} 的K线数据 ({interval}):")
for i, kline in enumerate(data["data"]):
if i < 5: # 只显示前5条
timestamp = kline["timestamp"] / 1000 # 转换为秒
dt = time.strftime("%Y-%m-%d %H:%M", time.localtime(timestamp))
print(f"{dt} - 开: {kline['open']}, 高: {kline['high']}, "
f"低: {kline['low']}, 收: {kline['close']}, "
f"量: {kline['volume']}")
print(f"...共 {len(data['data'])} 条数据")
else:
print(f"API返回错误: {data['message']}")
else:
print(f"请求失败,状态码: {response.status_code}")
except Exception as e:
print(f"获取K线数据时发生错误: {str(e)}")
# 示例:获取WTI原油15分钟K线
get_futures_kline("CL", interval="15m")
五、高级功能实现
5.1 数据缓存策略
from cachetools import TTLCache
class FuturesDataCache:
def __init__(self, maxsize=100, ttl=60):
"""初始化数据缓存"""
self.cache = TTLCache(maxsize=maxsize, ttl=ttl)
def get_quote(self, symbol):
"""获取期货行情(带缓存)"""
# 检查缓存
if symbol in self.cache:
return self.cache[symbol]
# 从API获取
url = f"{BASE_URL}/futures/querySymbol"
params = {"key": API_KEY, "symbol": symbol}
try:
response = requests.get(url, params=params)
if response.status_code == 200:
data = response.json()
if data["code"] == 200:
quote = data["data"]
# 更新缓存
self.cache[symbol] = quote
return quote
else:
print(f"API返回错误: {data['message']}")
return None
else:
print(f"请求失败,状态码: {response.status_code}")
return None
except Exception as e:
print(f"获取期货行情时发生错误: {str(e)}")
return None
# 使用示例
cache = FuturesDataCache()
quote = cache.get_quote("CL")
if quote:
print(f"WTI原油最新价: {quote['lastPrice']}")
5.2 实时数据处理器
class RealTimeDataProcessor:
def __init__(self):
self.data_buffer = {}
self.batch_size = 10
self.last_process_time = 0
def add_data(self, symbol, data):
"""添加实时数据到缓冲区"""
if symbol not in self.data_buffer:
self.data_buffer[symbol] = []
self.data_buffer[symbol].append(data)
# 检查是否达到批处理条件
current_time = time.time()
if (len(self.data_buffer[symbol]) >= self.batch_size or
current_time - self.last_process_time > 1):
self.process_data(symbol)
self.last_process_time = current_time
def process_data(self, symbol):
"""处理缓冲区的数据"""
if symbol not in self.data_buffer or not self.data_buffer[symbol]:
return
data_points = self.data_buffer[symbol]
# 计算统计指标
prices = [d["last"] for d in data_points]
volumes = [d["volume"] for d in data_points]
avg_price = sum(prices) / len(prices)
max_price = max(prices)
min_price = min(prices)
total_volume = sum(volumes)
print(f"\n{symbol} 实时数据统计 (最近 {len(data_points)} 个更新):")
print(f"平均价格: {avg_price:.2f}, 最高: {max_price:.2f}, 最低: {min_price:.2f}")
print(f"总成交量: {total_volume}")
# 清空缓冲区
self.data_buffer[symbol] = []
# 修改WebSocket客户端的on_message方法
def on_message(self, ws, message):
try:
data = json.loads(message)
if "channel" in data:
symbol = data["channel"].split(":")[1]
quote = data["data"]
# 添加到实时数据处理器
processor.add_data(symbol, {
"last": quote["last"],
"volume": quote["volume"],
"timestamp": quote["timestamp"]
})
except Exception as e:
print(f"处理实时数据时出错: {str(e)}")
# 初始化实时数据处理器
processor = RealTimeDataProcessor()
官方API文档:stocktv.top/
技术支持:support@stocktv.top