加载历史价格数据
历史市场价格通常以 OHLC+V 的形式出现 - 开盘价、最高价、最低价、收盘价、成交量。提供商可能返回额外字段,但这些是预期的列。
历史数据的粒度和数量因提供商和订阅状态而异。请访问他们的网站了解您的权限。
信息
这些示例假设 OpenBB 平台已在 Python 会话中初始化。
from openbb import obb
import pandas as pd
历史 OHLC 数据
Details
historical
函数位于每种资产类型的子模块下。在 openbb-equity
模块中。
help(obb.equity.price.historical)
- 此端点在所有函数中拥有最多的提供商。在撰写本文时,选择包括:
['alpha_vantage', 'cboe', 'fmp', 'intrinio', 'polygon', 'tiingo', 'tmx', 'tradier', 'yfinance']
-
通用参数已在所有数据源中标准化:
start_date
、end_date
、interval
。 -
默认间隔为
1d
(日线)。 -
历史数据的深度和粒度选择因提供商和订阅状态而异。请参考每个数据源的网站和文档了解您的具体权限。
-
尽管在
equity
模块中,但可能可以从同一端点获取其他资产类型,如货币或加密货币。 -
为了演示目的,我们将使用
openbb-yfinance
数据扩展。
# 获取日线数据
df_daily = obb.equity.price.historical(symbol="SPY", provider="yfinance")
print(df_daily.to_dataframe().head())
date open high low close volume
0 2023-01-03 385.54 387.77 380.82 380.82 76009200
1 2023-01-04 383.18 384.30 378.85 379.75 89063400
2 2023-01-05 382.26 383.17 380.30 380.68 80456100
3 2023-01-06 383.93 385.17 380.30 383.18 87531500
4 2023-01-09 385.17 386.74 383.93 385.17 75135600
指定日期范围
# 获取特定日期范围的数据
data = obb.equity.price.historical(
symbol="AAPL",
start_date="2023-01-01",
end_date="2023-12-31",
provider="yfinance"
)
df = data.to_dataframe()
print(f"数据范围: {df.index.min()} 到 {df.index.max()}")
print(f"总记录数: {len(df)}")
不同时间间隔
# 获取小时线数据
hourly_data = obb.equity.price.historical(
symbol="TSLA",
interval="1h",
provider="yfinance"
)
# 获取分钟线数据
minute_data = obb.equity.price.historical(
symbol="NVDA",
interval="5m",
provider="yfinance"
)
print("可用时间间隔:")
print("- 1m, 5m, 15m, 30m (分钟线)")
print("- 1h, 4h (小时线)")
print("- 1d (日线)")
print("- 1wk (周线)")
print("- 1mo (月线)")
多个股票代码
# 获取多个股票的数据
symbols = ["AAPL", "MSFT", "GOOGL", "AMZN"]
data = obb.equity.price.historical(
symbol=",".join(symbols),
provider="yfinance"
)
df = data.to_dataframe()
print("获取的股票数据:")
print(df.groupby('symbol').size())
数据处理示例
# 基本数据分析
data = obb.equity.price.historical("SPY", provider="yfinance")
df = data.to_dataframe()
# 计算日收益率
df['daily_return'] = df['close'].pct_change()
# 计算移动平均线
df['ma_20'] = df['close'].rolling(window=20).mean()
df['ma_50'] = df['close'].rolling(window=50).mean()
# 计算波动率
df['volatility'] = df['daily_return'].rolling(window=20).std() * (252**0.5)
print("数据统计:")
print(df[['close', 'daily_return', 'volatility']].describe())
不同提供商比较
# 比较不同提供商的数据
providers = ['yfinance', 'fmp', 'polygon']
symbol = "AAPL"
for provider in providers:
try:
data = obb.equity.price.historical(symbol=symbol, provider=provider)
df = data.to_dataframe()
print(f"{provider}: {len(df)} 条记录")
if not df.empty:
print(f" 日期范围: {df.index.min()} 到 {df.index.max()}")
except Exception as e:
print(f"{provider}: 错误 - {e}")
错误处理
def get_historical_data(symbol, provider="yfinance", **kwargs):
"""
安全获取历史数据的函数
"""
try:
data = obb.equity.price.historical(
symbol=symbol,
provider=provider,
**kwargs
)
# 检查警告
if data.warnings:
print(f"警告: {data.warnings}")
# 检查数据是否为空
df = data.to_dataframe()
if df.empty:
print(f"未找到 {symbol} 的数据")
return None
return df
except Exception as e:
print(f"获取 {symbol} 数据时出错: {e}")
return None
# 使用示例
df = get_historical_data("AAPL", start_date="2023-01-01")
if df is not None:
print(f"成功获取 {len(df)} 条记录")
最佳实践
- 选择合适的提供商:根据数据需求和订阅状态选择
- 合理设置日期范围:避免请求过多历史数据
- 处理缺失数据:检查并处理可能的数据缺口
- 缓存数据:对于重复使用的数据考虑本地缓存
- 错误处理:始终包含适当的错误处理逻辑
# 完整示例:获取并分析股票数据
def analyze_stock(symbol, days=252):
"""
获取并分析股票数据
"""
from datetime import datetime, timedelta
end_date = datetime.now()
start_date = end_date - timedelta(days=days)
data = obb.equity.price.historical(
symbol=symbol,
start_date=start_date.strftime("%Y-%m-%d"),
end_date=end_date.strftime("%Y-%m-%d"),
provider="yfinance"
)
df = data.to_dataframe()
# 基本统计
stats = {
'symbol': symbol,
'records': len(df),
'avg_price': df['close'].mean(),
'volatility': df['close'].pct_change().std() * (252**0.5),
'total_return': (df['close'].iloc[-1] / df['close'].iloc[0] - 1) * 100
}
return df, stats
# 使用示例
df, stats = analyze_stock("AAPL")
print("分析结果:", stats)