用Python+akshare+智谱GLM-4打造智能股票分析助手的全流程指南
最近在量化投资圈里,越来越多的个人开发者开始尝试将AI大模型与传统金融分析工具结合。作为一名长期关注Python在金融领域应用的开发者,我发现用akshare获取数据+智谱GLM-4进行分析的组合,确实能帮我们快速搭建一个实用的个人股票分析工具。不同于市面上的商业软件,这种DIY方案最大的优势是完全可定制——你可以根据自己的投资风格调整分析维度,还能随时接入最新的AI能力。
1. 环境准备与工具链选择
在开始构建之前,我们需要明确整个技术栈的组成。核心组件包括:
- 数据层:akshare作为免费、开源的金融数据接口
- 分析层:智谱GLM-4大模型提供自然语言处理能力
- 交互层:Streamlit构建轻量级Web界面
- 可视化:Plotly生成交互式K线图表
先确保安装必要的Python库:
pip install akshare plotly streamlit langchain关于GLM-4的API访问,需要先在智谱AI平台注册获取API Key。这里有个小技巧:注册时选择"开发者"身份,通常能获得更多免费调用额度。拿到API Key后,建议将其保存在环境变量中而非直接硬编码在脚本里:
import os os.environ['ZHIPU_API_KEY'] = 'your_api_key_here'2. 数据获取与处理模块设计
akshare提供了丰富的A股市场数据接口,但实际使用中我发现几个需要注意的要点:
- 股票代码格式:akshare要求输入不带市场前缀的纯数字代码,比如"600519"而非"SH600519"
- 复权处理:获取历史K线数据时,
adjust参数建议设为"qfq"(前复权)以获得更准确的趋势分析 - 频率控制:避免频繁调用接口,建议对获取的数据进行本地缓存
改进后的数据获取函数可以这样实现:
import akshare as ak from datetime import datetime, timedelta import pandas as pd import streamlit as st @st.cache_data(ttl=3600) # 缓存1小时 def get_stock_data(stock_code, days=90): """获取股票历史数据并自动处理异常""" try: end_date = datetime.now().strftime('%Y%m%d') start_date = (datetime.now() - timedelta(days=days)).strftime('%Y%m%d') df = ak.stock_zh_a_hist( symbol=stock_code, period="daily", start_date=start_date, end_date=end_date, adjust="qfq" ) # 统一列名格式 df.columns = ['日期', '开盘', '收盘', '最高', '最低', '成交量', '成交额', '振幅', '涨跌幅', '涨跌额', '换手率'] return df except Exception as e: st.error(f"数据获取失败: {str(e)}") return None3. 可视化与交互界面优化
Plotly的Candlestick图表虽然直观,但我们可以通过以下增强使其更具分析价值:
- 添加5日、20日均线辅助判断短期趋势
- 用不同颜色标注放量上涨/下跌的交易日
- 支持图表缩放和十字线查看具体数值
改进后的K线图生成代码:
import plotly.graph_objects as go from plotly.subplots import make_subplots def create_kline_chart(df, stock_code): """创建增强版K线图表""" # 计算均线 df['MA5'] = df['收盘'].rolling(5).mean() df['MA20'] = df['收盘'].rolling(20).mean() fig = make_subplots(rows=2, cols=1, shared_xaxes=True, vertical_spacing=0.05, row_heights=[0.7, 0.3]) # K线主图 fig.add_trace(go.Candlestick( x=df['日期'], open=df['开盘'], high=df['最高'], low=df['最低'], close=df['收盘'], name='K线' ), row=1, col=1) # 均线 fig.add_trace(go.Scatter( x=df['日期'], y=df['MA5'], line=dict(color='orange', width=1), name='5日均线' ), row=1, col=1) fig.add_trace(go.Scatter( x=df['日期'], y=df['MA20'], line=dict(color='blue', width=1), name='20日均线' ), row=1, col=1) # 成交量副图 colors = ['red' if row['收盘'] >= row['开盘'] else 'green' for _, row in df.iterrows()] fig.add_trace(go.Bar( x=df['日期'], y=df['成交量'], marker_color=colors, name='成交量' ), row=2, col=1) fig.update_layout( title=f'{stock_code} 技术分析图表', xaxis_rangeslider_visible=False, height=800 ) return fig4. 智能分析模块深度整合
GLM-4的优势在于能理解金融语境,但要让其给出高质量建议,提示工程(Prompt Engineering)非常关键。经过多次测试,我发现包含以下元素的提示模板效果最佳:
- 明确的分析框架:要求模型按特定结构输出
- 关键指标计算:预先计算好技术指标供模型参考
- 新闻情感分析:对获取的新闻做简单预处理
优化后的分析函数:
from langchain.prompts import PromptTemplate from langchain.chat_models import ChatOpenAI from langchain.chains import LLMChain def generate_analysis_report(stock_code, df, news_df): """生成股票分析报告""" # 技术指标计算 latest = df.iloc[-1] ma5 = df['收盘'].rolling(5).mean().iloc[-1] ma20 = df['收盘'].rolling(20).mean().iloc[-1] rsi14 = compute_rsi(df['收盘'], 14) # 新闻摘要 news_summary = "\n".join([ f"{i+1}. {row['新闻标题']} ({row['发布时间']})" for i, row in news_df.iterrows() ]) template = """作为专业股票分析师,请基于以下数据为{stock_code}提供投资分析: **技术指标**: - 最新价: {close_price} - 5日均线: {ma5} - 20日均线: {ma20} - RSI(14): {rsi} - 近期波动范围: {low_price} ~ {high_price} **近期新闻**: {news} 请按以下结构提供专业分析: 1. 趋势判断:当前处于什么趋势(上涨/下跌/盘整),关键支撑/阻力位 2. 量价分析:成交量与价格变动的关系 3. 技术信号:出现的买入/卖出信号 4. 新闻影响:重大新闻对股价的潜在影响 5. 操作建议:短期(1周)和中期(1月)的具体建议 6. 风险提示:需要警惕的主要风险""" prompt = PromptTemplate( input_variables=["stock_code", "close_price", "ma5", "ma20", "rsi", "low_price", "high_price", "news"], template=template ) llm = ChatOpenAI( model="glm-4", temperature=0.7, max_tokens=2000 ) chain = LLMChain(llm=llm, prompt=prompt) return chain.run({ "stock_code": stock_code, "close_price": latest['收盘'], "ma5": round(ma5, 2), "ma20": round(ma20, 2), "rsi": round(rsi14, 2), "low_price": df['最低'].min(), "high_price": df['最高'].max(), "news": news_summary }) def compute_rsi(prices, window=14): """计算相对强弱指数(RSI)""" deltas = prices.diff() gains = deltas.clip(lower=0) losses = -deltas.clip(upper=0) avg_gain = gains.rolling(window).mean() avg_loss = losses.rolling(window).mean() rs = avg_gain / avg_loss return 100 - (100 / (1 + rs))5. 完整应用集成与部署
将所有模块整合到Streamlit应用中时,合理的界面布局能极大提升使用体验。建议采用标签页(Tab)形式组织不同功能:
import streamlit as st def main(): st.set_page_config(page_title="AI股票助手", layout="wide") st.title("📈 AI股票分析助手") with st.sidebar: stock_code = st.text_input("输入股票代码(如600519):", "600519") analysis_days = st.slider("分析周期(天):", 30, 365, 90) st.markdown("> 提示:首次查询可能需要几秒时间加载数据") tab1, tab2, tab3 = st.tabs(["技术图表", "基本面", "AI分析"]) with tab1: df = get_stock_data(stock_code, analysis_days) if df is not None: fig = create_kline_chart(df, stock_code) st.plotly_chart(fig, use_container_width=True) with tab2: info = ak.stock_individual_info_em(symbol=stock_code) st.dataframe(info) with tab3: news_df = ak.stock_news_em(symbol=stock_code).head(5) if st.button("生成AI分析报告"): with st.spinner("AI分析中..."): report = generate_analysis_report(stock_code, df, news_df) st.markdown(report) if __name__ == "__main__": main()部署时,可以使用以下命令启动应用:
streamlit run stock_assistant.py对于长期运行的需求,建议使用PM2等进程管理器保持应用稳定运行:
pm2 start "streamlit run stock_assistant.py" --name stock_ai6. 实际使用技巧与优化方向
经过一段时间的实际使用,我总结出几个提升分析效果的经验:
数据更新策略:
- 盘后更新:在收盘后30分钟再获取数据,确保所有交易数据完整
- 定时刷新:对长期运行的应用,设置每2小时自动刷新一次数据
提示工程优化:
# 在提示模板中添加以下内容能提高分析质量 """ 请特别注意: - 当RSI超过70时提示超买风险 - 股价突破20日均线且成交量放大视为积极信号 - 负面新闻需评估其对行业的影响程度 """性能优化技巧:
- 对历史数据使用
st.cache_data缓存 - 将新闻数据存储在本地SQLite数据库中避免重复获取
- 使用
asyncio并发获取不同类型的数据
- 对历史数据使用
扩展功能设想:
- 添加自选股列表和价格提醒功能
- 集成更多技术指标计算(如MACD、布林带)
- 增加行业对比分析模块
- 实现定期自动生成投资组合报告
这个项目最让我满意的地方是它的灵活性和可扩展性——你可以根据个人需求随时添加新功能。比如最近我就在尝试接入财务数据接口,让AI能结合财报进行分析。整个开发过程中,GLM-4对金融术语的理解能力确实令人印象深刻,相比通用大模型能给出更专业的建议。