查看全集:💎Quantopia量化分析56讲
本案例选取科技行业ETF(XLK)与金融行业ETF(XLF)进行多维比较,通过完整的分析流程演示金融数据分析方法。我们将重点关注:
# 获取2018-2020年历史数据
def fetch_comparison_data():
tickers = ['XLK', 'XLF']
data = yf.download(tickers, start='2018-01-01', end='2020-01-01')
return data['Close'].dropna() # 确保数据清洁
etf_close = fetch_comparison_data()
# 计算收益率
returns = etf_close.pct_change().dropna()
xlk_returns = returns['XLK']
xlf_returns = returns['XLF']
print("XLK收益特征:")
print(xlk_returns.describe())
print("\nXLF收益特征:")
print(xlf_returns.describe())
统计量 | XLK | XLF |
均值 | 0.0008 | 0.0005 |
标准差 | 0.0132 | 0.0145 |
峰度 | 1.82 | 2.35 |
偏度 | -0.31 | 0.05 |
其中:
risk_free_rate = 0.0002 # 假设无风险利率
def sharpe_ratio(returns):
excess_return = returns.mean() - risk_free_rate
return excess_return / returns.std()
print(f"XLK夏普比率: {sharpe_ratio(xlk_returns):.4f}")
print(f"XLF夏普比率: {sharpe_ratio(xlf_returns):.4f}")
(etf_close / etf_close.iloc0 * 100).plot(figsize=(10,6))
plt.title('ETF价格走势标准化比较')
plt.ylabel('标准化价格(基准=100)')
plt.show()
def enhanced_normality_check(data, name):
plt.figure(figsize=(8,4))
stats.probplot(data, plot=plt)
plt.title(f'{name} Q-Q图')
plt.show()
k2, p = stats.normaltest(data)
print(f'{name}正态检验: p值={p:.4f}')
enhanced_normality_check(xlk_returns, 'XLK')
enhanced_normality_check(xlf_returns, 'XLF')
# 根据正态性结果选择检验方法
if stats.normaltest(xlk_returns).pvalue > 0.05 and stats.normaltest(xlf_returns).pvalue > 0.05:
test_method = 'F-test'
_, p_var = stats.f_oneway(xlk_returns, xlf_returns)
else:
test_method = 'Levene'
_, p_var = stats.levene(xlk_returns, xlf_returns)
print(f'使用{test_method}检验方差齐性: p值={p_var:.4f}')
t_stat, p_mean = stats.ttest_ind(xlk_returns, xlf_returns, equal_var=(p_var > 0.05))
print(f'均值差异检验结果: t统计量={t_stat:.2f}, p值={p_mean:.4f}')
sns.jointplot(x=xlk_returns, y=xlf_returns, kind='hex')
plt.suptitle('XLK与XLF收益联合分布')
plt.tight_layout()
window_size = 20 # 交易日窗口
plt.figure(figsize=(10,6))
xlk_returns.rolling(window_size).std().plot(label='XLK波动率')
xlf_returns.rolling(window_size).std().plot(label='XLF波动率')
plt.title('滚动20日波动率对比')
plt.legend()
def analyze_tail_risk(returns, name):
tail_threshold = returns.quantile(0.95)
tail_events = returns[returns > tail_threshold]
print(f'{name}极端收益特征:')
print(f'发生次数: {len(tail_events)}')
print(f'平均收益: {tail_events.mean():.4f}')
print(f'最大收益: {tail_events.max():.4f}\n')
analyze_tail_risk(xlk_returns, 'XLK')
analyze_tail_risk(xlf_returns, 'XLF')
correlation = xlk_returns.corr(xlf_returns)
print(f'收益相关系数: {correlation:.4f}')
plt.figure(figsize=(8,6))
sns.regplot(x=xlk_returns, y=xlf_returns, line_kws={'color':'red'})
plt.title('收益率散点图与回归线')
基于分析结果,我们得出以下投资建议:
分析维度 | XLK特征 | XLF特征 |
收益能力 | 日均收益更高 | 绝对收益波动更大 |
风险特征 | 波动率较低 | 极端收益事件更多 |
分布形态 | 左偏明显 | 接近对称分布 |
风险调整收益 | 夏普比率优势显著 | 需优化风险控制 |
延伸思考:
# 综合对比可视化
fig, ax = plt.subplots(2,2, figsize=(14,10))
# 收益分布对比
sns.kdeplot(xlk_returns, ax=ax[0,0], fill=True, label='XLK')
sns.kdeplot(xlf_returns, ax=ax[0,0], fill=True, label='XLF')
ax[0,0].set_title('收益分布对比')
# 累计收益对比
(etf_close/etf_close.iloc[0]).plot(ax=ax[0,1])
ax[0,1].set_title('累计收益走势')
# 波动率对比
pd.DataFrame({'XLK': xlk_returns.rolling(20).std(),
'XLF': xlf_returns.rolling(20).std()}).plot(ax=ax[1,0])
ax[1,0].set_title('滚动波动率')
# 相关性热力图
sns.heatmap(returns.corr(), annot=True, ax=ax[1,1])
ax[1,1].set_title('收益相关性矩阵')
plt.tight_layout()
本案例完整展示了从数据获取到深入分析的完整流程,投资者可基于此框架:
通过本案例,读者不仅掌握了ETF比较的技术方法,更重要的是建立了将统计分析工具应用于实际投资决策的完整思维框架。