欢迎加入专注于财经数据与量化投研的【数据科学实战】知识星球!在这里,您将获取持续更新的《财经数据宝典》和《量化投研宝典》,这两部宝典相辅相成,为您在量化投研道路上提供明确指引。 《量化投研宝典》精选了业内持续维护且实用性强的开源工具(Backtrader、Qlib、VeighNa等),配合详细教程与代码示例,帮助您快速构建量化策略;《财经数据宝典》则汇集了多年财经数据维护经验,全面介绍从 AKShare、Tushare 到 Wind、iFind 等国内外数据源,并附有丰富的使用技巧。 无论您是量化投资新手还是经验丰富的研究者,星球社区都能帮您少走弯路,事半功倍,共同探索数据驱动的投资世界!
引言
你是否想过让 AI 帮你分析新闻情绪,自动判断股票买卖时机?随着大语言模型(LLM)技术的发展,将新闻情感分析融入量化交易已经成为现实。本文将介绍一个完整的 Python 实现方案,通过分析财经新闻的情感倾向来预测股票走势,并在苹果(AAPL)和微软(MSFT)股票上进行了 5 年的回测验证。
这个策略的核心思路很简单:当市场新闻偏向积极时买入,消极时卖出。但如何准确判断新闻情感?如何将情感转化为交易信号?让我们通过代码一步步实现。
方法论概述
整个交易系统包含五个核心步骤:
- 情感分析:使用预训练的 BERT 模型分析新闻标题的情感倾向
环境准备
首先安装必要的 Python 库:
pip install pandas numpy yfinance transformers scikit-learn matplotlib torch
步骤 1:数据收集与预处理
我们需要两类数据:股票价格数据和新闻数据。
import pandas as pd
import yfinance as yf # 用于获取股票数据
from transformers import pipeline # Hugging Face 的模型库
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import matplotlib.pyplot as plt
import numpy as np
import requests
import csv
# 设置 CSV 字段大小限制,处理大文本
csv.field_size_limit(10**7)
# 获取苹果公司股票数据(2020-2025)
stock_data = yf.download('AAPL', start='2020-01-01', end='2025-08-15')
# 处理多级列名
if isinstance(stock_data.columns, pd.MultiIndex):
stock_data.columns = stock_data.columns.droplevel(
1)
# 计算日收益率
stock_data['Returns'] = stock_data['Close'].pct_change()
# 获取财经新闻数据
news_url = 'https://huggingface.co/datasets/Zihan1004/FNSPID/resolve/main/FNSPID.csv'
response = requests.get(news_url, stream=True)
# 流式读取并筛选 AAPL 相关新闻
reader = csv.reader(line.decode('utf-8') for line in response.iter_lines())
header = next(reader)
stock_idx = header.index('Stock_symbol')
date_idx = header.index('Date')
title_idx = header.index('Article_title')
aapl_rows = []
for row in reader:
if row and len(row) > max(stock_idx, date_idx, title_idx):
if row[stock_idx] == 'AAPL':
aapl_rows.append(row)
news_data = pd.DataFrame(aapl_rows, columns=header)
news_data['Date'] = pd.to_datetime(news_data['Date'])
步骤 2:情感分析
使用预训练的 DistilBERT 模型分析新闻标题的情感:
# 初始化情感分析模型
sentiment_pipeline = pipeline('sentiment-analysis',
model='distilbert-base-uncased-finetuned-sst-2-english')
def get_sentiment(text):
"""
分析文本情感
返回值:正面情感为正数,负面情感为负数
"""
if pd.isna(text):
return 0 # 缺失文本视为中性
result = sentiment_pipeline(text)[0]
# 将情感转换为数值:正面为正,负面为负
if result['label'] == 'POSITIVE':
return result['score']
else:
return -result['score']
# 对所有新闻标题进行情感分析
news_data['Sentiment'] = news_data['Article_title'].apply(get_sentiment)
# 按日期聚合情感分数(取平均值)
sentiment_data = news_data.groupby('Date')['Sentiment'].mean().reset_index()
步骤 3:特征工程与模型训练
将情感数据与股票数据合并,构建预测模型:
# 重置索引以便合并
stock_data = stock_data.reset_index()
# 合并股票和情感数据
merged_data = pd.merge(stock_data, sentiment_data, on='Date', how='left')
merged_data['Sentiment'] = merged_data['Sentiment'].fillna(0) # 填充缺失值
merged_data = merged_data.set_index('Date')
# 创建标签:收益为正标记为 1(买入信号),否则为 0
merged_data['Label'] = (merged_data['Returns'] > 0).astype(int)
# 添加技术指标:5 日移动平均线
merged_data['MA_5'] = merged_data['Close'].rolling(5).mean()
# 准备特征和标签
features = merged_data[['Sentiment', 'MA_5']].dropna()
labels = merged_data['Label'].loc[features.index]
# 划分训练集和测试集(80/20 比例)
X_train, X_test, y_train, y_test = train_test_split(
features, labels, test_size=0.2, random_state=42
)
# 训练逻辑回归模型
model = LogisticRegression()
model.fit(X_train, y_train)
# 评估模型准确率
predictions = model.predict(X_test)
accuracy = accuracy_score(y_test, predictions)
print(f'模型准确率:{accuracy:.2f}')
步骤 4:策略回测
在微软(MSFT)股票上测试策略效果:
# 获取微软股票数据
stock_data_msft = yf.download('MSFT', start='2020-01-01', end='2025-08-15')
# 处理数据格式
if isinstance(stock_data_msft.columns, pd.MultiIndex):
stock_data_msft.columns = stock_data_msft.columns.droplevel(1)
stock_data_msft['Returns'] = stock_data_msft['Close'].pct_change()
# 获取微软相关新闻并分析情感(代码类似,此处省略详细过程)
# ...
# 使用训练好的模型预测交易信号
merged_data_msft['Signal'] = model.predict(
merged_data_msft[['Sentiment', 'MA_5']].dropna()
)
# 计算策略收益
merged_data_msft['Strategy_Return'] = (
merged_data_msft['Returns'] * merged_data_msft['Signal'].shift(1)
)
# 计算累计收益
cumulative_returns = (1 + merged_data_msft['Strategy_Return'].dropna()).cumprod()
final_return = cumulative_returns.iloc[-1]
print(f'策略累计收益:
{final_return:.2%}')
# 绘制累计收益曲线
plt.figure(figsize=(12, 6))
cumulative_returns.plot()
plt.title('策略累计收益曲线')
plt.xlabel('日期')
plt.ylabel('累计收益')
plt.grid(True)
plt.show()
实际案例分析
让我们看一个具体的交易案例:
# 查看某一天的交易决策
sample_date = '2024-07-17'
sample_data = merged_data_msft.loc[sample_date]
print(f"日期:{sample_date}")
print(f"收盘价:${sample_data['Close']:.2f}")
print(f"新闻情感分数:{sample_data['Sentiment']:.3f}")
print(f"5 日均线:${sample_data['MA_5']:.2f}")
print(f"交易信号:{'买入' if sample_data['Signal'] == 1 else '卖出'}")
# 可视化买卖信号
plt.figure(figsize=(14, 7))
plt.subplot(2, 1, 1)
merged_data_msft['Close']['2024-06':'2024-08'].plot(label='收盘价')
buy_signals = merged_data_msft[merged_data_msft['Signal'] == 1]['2024-06':'2024-08']
sell_signals = merged_data_msft[merged_data_msft['Signal'] == 0]['2024-06':'2024-08']
plt.scatter(buy_signals.index, buy_signals['Close'],
marker='^', color='green', s=100, label='买入信号')
plt.scatter(sell_signals.index, sell_signals['Close'],
marker='v', color='red', s=100, label='卖出信号')
plt.title('交易信号示例')
plt.legend()
plt.grid(True)
plt.subplot(2, 1, 2)
merged_data_msft['Sentiment'
]['2024-06':'2024-08'].plot(
kind='bar', color=['green' if x > 0 else 'red'
for x in merged_data_msft['Sentiment']['2024-06':'2024-08']]
)
plt.title('每日情感分数')
plt.ylabel('情感分数')
plt.tight_layout()
plt.show()
策略优化建议
为了提升策略表现,可以考虑以下改进:
- 多源数据融合:除了新闻标题,还可以分析社交媒体、分析师报告等
# 示例:加入止损逻辑
def enhanced_strategy(data, stop_loss=0.02):
"""
增强策略:加入 2% 止损
"""
positions = []
entry_price = None
for i in range(len(data)):
current_price = data['Close'].iloc[i]
signal = data['Signal'].iloc[i]
if signal == 1 and entry_price is None:
# 买入
entry_price = current_price
positions.append(1)
elif entry_price is not None:
# 检查止损
if current_price < entry_price * (1 - stop_loss):
# 触发止损,卖出
entry_price = None
positions.append(0)
elif signal == 0:
# 正常卖出信号
entry_price = None
positions.append(0)
else:
# 继续持有
positions.append(1)
else:
positions.append(0)
return positions
总结
本文介绍了一个完整的基于情感分析的量化交易策略,通过 Python 和预训练的 BERT 模型实现了从数据收集到策略回测的全流程。在 5 年的历史数据回测中,该策略在 MSFT 股票上实现了 107% 的累计收益。
虽然策略表现不及简单的买入持有(约 400% 收益),但它展示了 AI 技术在金融领域的应用潜力。通过分析新闻情感来辅助交易决策,可以捕捉到市场情绪的短期变化,为投资者提供额外的参考信号。
需要注意的是,任何量化策略都存在风险,实盘交易前务必进行充分的回测和风险评估。此外,还需要考虑交易成本、滑点等实际因素的影响。
参考文章
加入专注于财经数据与量化投研的知识星球【数据科学实战】,获取完整研究解析、详细回测框架代码实现和完整策略逻辑实操指南。财经数据与量化投研知识社区
核心权益如下:
- 赠送《财经数据宝典》完整文档,汇集多年财经数据维护经验
- 赠送《量化投研宝典》完整文档,汇集多年量化投研领域经验
- 赠送《PyBroker-入门及实战》视频课程,手把手学习量化策略开发
-
星球已有丰富内容积累,包括量化投研论文、财经高频数据、 PyBroker 视频教程、定期直播、数据分享和答疑解难。适合对量化投研和财经数据分析有兴趣的学习者及从业者。欢迎加入我们!