Logo
热心市民王先生

实施指南

技术研究 人工智能 LLM

本章节提供详细的代码示例和配置说明,帮助你快速搭建一个基于 OpenBB + AI 的投资助手。

快速开始:30 分钟搭建最小可用版本

本章节提供详细的代码示例和配置说明,帮助你快速搭建一个基于 OpenBB + AI 的投资助手。


环境准备

系统要求

  • Python: 3.10 - 3.13
  • 操作系统: macOS、Linux、Windows (WSL2 推荐)
  • 内存: 至少 4GB RAM
  • 网络: 可访问 OpenAI API 或其他 LLM 服务

安装步骤

1. 创建虚拟环境

# 创建项目目录
mkdir openbb-ai-assistant
cd openbb-ai-assistant

# 创建虚拟环境
python -m venv venv

# 激活虚拟环境
# macOS/Linux:
source venv/bin/activate
# Windows:
# venv\Scripts\activate

2. 安装核心依赖

# 安装 OpenBB 平台(包含所有常用扩展)
pip install openbb

# 安装 LangChain 和 OpenAI 集成
pip install langchain langchain-openai langgraph

# 安装 MCP 支持
pip install openbb-mcp

# 安装 Streamlit(用于 Web 界面)
pip install streamlit plotly

3. 验证安装

# test_installation.py
from openbb import obb

# 测试数据获取
print("测试 OpenBB 安装...")
result = obb.equity.price.historical("AAPL", interval="1d", limit=5)
df = result.to_dataframe()
print(df.head())
print("✅ OpenBB 安装成功!")

运行测试:

python test_installation.py

方案 A 实施代码

1. MCP 服务器配置

创建 mcp_server.py

#!/usr/bin/env python3
"""
OpenBB MCP Server
将 OpenBB 平台封装为 MCP 服务器,供 AI Agent 调用
"""

from openbb import obb
from openbb_mcp.server import create_mcp_server

# 创建 MCP 服务器实例
mcp = create_mcp_server(
    obb=obb,
    name="OpenBB Financial Data Server",
    description="提供股票、加密货币、宏观经济等金融数据的 MCP 服务器"
)

if __name__ == "__main__":
    # 启动 MCP 服务器
    print("启动 OpenBB MCP 服务器...")
    mcp.run()

2. AI Agent 实现

创建 investment_assistant.py

#!/usr/bin/env python3
"""
AI 投资助手
基于 LangChain 和 OpenBB MCP 的智能投资分析助手
"""

import os
from typing import List, Dict, Any
from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
from langchain_core.messages import HumanMessage, SystemMessage

# 设置 API Key
os.environ["OPENAI_API_KEY"] = "your-openai-api-key"

class InvestmentAssistant:
    """投资助手核心类"""
    
    def __init__(self):
        # 初始化 LLM
        self.llm = ChatOpenAI(
            model="gpt-4o",
            temperature=0.2  # 金融分析需要更确定性的输出
        )
        
        # 初始化工具(这里假设 MCP 工具已加载)
        self.tools = self._load_tools()
        
        # 创建 ReAct Agent
        self.agent = create_react_agent(
            model=self.llm,
            tools=self.tools
        )
        
        # 系统提示词
        self.system_prompt = """你是一位专业的 AI 投资顾问,具备以下能力:

1. **数据分析**:能够获取和分析股票、ETF、加密货币等资产的历史价格和基本面数据
2. **投资分析**:可以进行基本面分析、技术分析、投资组合分析
3. **风险评估**:能够识别投资风险并提供风险提示
4. **市场洞察**:了解宏观经济趋势对市场的影响

**重要准则**:
- 始终基于数据提供分析,不主观臆断
- 明确区分事实和分析观点
- 投资有风险,分析仅供参考,不构成具体投资建议
- 对于不确定的信息,坦诚告知用户

使用工具获取数据时,优先选择最相关的数据源。"""

    def _load_tools(self) -> List[Any]:
        """加载 MCP 工具"""
        # 在实际实现中,这里应该连接到 MCP 服务器
        # 简化示例:返回空列表,实际项目中需要集成 MCP
        from langchain_core.tools import tool
        
        @tool
def get_stock_price(symbol: str, period: str = "1y") -> str:
    """获取股票历史价格数据"""
    from openbb import obb
    result = obb.equity.price.historical(symbol, interval="1d")
    df = result.to_dataframe()
    return f"获取到 {symbol}{len(df)} 条价格记录,时间范围:{df.index[0]}{df.index[-1]}"
        
        @tool
        def get_financial_statements(symbol: str) -> str:
            """获取公司财务报表"""
            from openbb import obb
            try:
                result = obb.equity.fundamental.balance_sheet(symbol)
                df = result.to_dataframe()
                return f"{symbol} 最新资产负债表:总资产 {df['total_assets'].iloc[0]}"
            except:
                return f"无法获取 {symbol} 的财务数据"
        
        return [get_stock_price, get_financial_statements]

    def chat(self, user_message: str, history: List[Dict] = None) -> str:
        """
        处理用户查询
        
        Args:
            user_message: 用户输入的消息
            history: 对话历史(可选)
            
        Returns:
            AI 助手的回复
        """
        messages = [SystemMessage(content=self.system_prompt)]
        
        # 添加历史对话
        if history:
            for msg in history:
                if msg["role"] == "user":
                    messages.append(HumanMessage(content=msg["content"]))
                else:
                    messages.append(SystemMessage(content=msg["content"]))
        
        # 添加当前消息
        messages.append(HumanMessage(content=user_message))
        
        # 调用 Agent
        response = self.agent.invoke({"messages": messages})
        
        # 提取最后一条 AI 消息
        ai_message = response["messages"][-1]
        return ai_message.content

# 交互式运行
if __name__ == "__main__":
    assistant = InvestmentAssistant()
    
    print("=" * 60)
    print("🤖 AI 投资助手已启动")
    print("=" * 60)
    print("输入 'quit' 或 'exit' 退出")
    print("-" * 60)
    
    history = []
    
    while True:
        user_input = input("\n👤 你:")
        
        if user_input.lower() in ["quit", "exit", "退出"]:
            print("\n👋 再见!")
            break
        
        try:
            response = assistant.chat(user_input, history)
            print(f"\n🤖 助手:{response}")
            
            # 更新历史
            history.append({"role": "user", "content": user_input})
            history.append({"role": "assistant", "content": response})
            
            # 限制历史长度
            if len(history) > 10:
                history = history[-10:]
                
        except Exception as e:
            print(f"\n❌ 错误:{e}")

3. Streamlit Web 界面

创建 app.py

#!/usr/bin/env python3
"""
Streamlit Web 界面
提供友好的可视化交互体验
"""

import streamlit as st
import plotly.graph_objects as go
from openbb import obb

st.set_page_config(
    page_title="AI 投资助手",
    page_icon="📈",
    layout="wide"
)

# 初始化 Session State
if "messages" not in st.session_state:
    st.session_state.messages = []

if "assistant" not in st.session_state:
    # 延迟导入避免启动时加载
    from investment_assistant import InvestmentAssistant
    st.session_state.assistant = InvestmentAssistant()

st.title("📈 AI 投资助手")
st.markdown("基于 OpenBB 金融数据平台和 GPT-4 的智能投资分析助手")

# 侧边栏
with st.sidebar:
    st.header("⚙️ 设置")
    
    st.subheader("数据源配置")
    st.info("当前使用 OpenBB 默认数据源")
    
    st.subheader("功能")
    if st.button("🗑️ 清空对话"):
        st.session_state.messages = []
        st.rerun()
    
    st.markdown("---")
    st.markdown("**支持的查询类型:**")
    st.markdown("- 股票价格查询")
    st.markdown("- 财务数据分析")
    st.markdown("- 投资组合分析")
    st.markdown("- 宏观经济洞察")

# 主界面
st.markdown("### 💬 对话")

# 显示历史消息
for message in st.session_state.messages:
    with st.chat_message(message["role"]):
        st.markdown(message["content"])

# 用户输入
user_input = st.chat_input("输入你的投资问题...")

if user_input:
    # 显示用户消息
    with st.chat_message("user"):
        st.markdown(user_input)
    
    st.session_state.messages.append({"role": "user", "content": user_input})
    
    # 生成回复
    with st.chat_message("assistant"):
        with st.spinner("🤔 正在分析..."):
            try:
                response = st.session_state.assistant.chat(
                    user_input, 
                    st.session_state.messages[:-1]
                )
                st.markdown(response)
                st.session_state.messages.append({
                    "role": "assistant", 
                    "content": response
                })
            except Exception as e:
                st.error(f"分析出错:{e}")

# 快速操作区
st.markdown("---")
st.markdown("### ⚡ 快速操作")

col1, col2, col3, col4 = st.columns(4)

with col1:
    if st.button("📊 AAPL 分析"):
        user_input = "分析苹果公司(AAPL)的投资价值和财务状况"
        st.rerun()

with col2:
    if st.button("📈 市场概览"):
        user_input = "最近一周美股市场表现如何?"
        st.rerun()

with col3:
    if st.button("💰 BTC 价格"):
        user_input = "比特币最近的价格走势如何?"
        st.rerun()

with col4:
    if st.button("🏦 美联储政策"):
        user_input = "美联储最近的货币政策对市场有什么影响?"
        st.rerun()

# 数据可视化示例
st.markdown("---")
st.markdown("### 📊 数据可视化")

symbol = st.text_input("输入股票代码", value="AAPL")
if st.button("获取价格图表"):
    try:
        result = obb.equity.price.historical(symbol, interval="1d", limit=30)
        df = result.to_dataframe()
        
        fig = go.Figure(data=[go.Candlestick(
            x=df.index,
            open=df['open'],
            high=df['high'],
            low=df['low'],
            close=df['close']
        )])
        
        fig.update_layout(
            title=f"{symbol} 最近 30 天价格走势",
            yaxis_title='价格 (USD)',
            xaxis_title='日期'
        )
        
        st.plotly_chart(fig, use_container_width=True)
    except Exception as e:
        st.error(f"获取数据失败:{e}")

运行应用

1. 启动 MCP 服务器(终端 1)

python mcp_server.py

2. 启动 AI 助手(CLI 模式,终端 2)

python investment_assistant.py

3. 启动 Web 界面(终端 3)

streamlit run app.py

打开浏览器访问 http://localhost:8501


方案 B 实施要点

1. OpenBB Workspace 集成

如果选择方案 B,需要:

  1. 注册 OpenBB Workspace:访问 https://pro.openbb.co 注册账户
  2. 连接后端:在 Workspace 中配置自定义后端 URL
  3. 配置 widgets.json
{
  "widgets": [
    {
      "id": "ai_analysis",
      "name": "AI 投资分析",
      "type": "chat",
      "endpoint": "http://your-backend.com/api/analysis",
      "params": {
        "symbol": "string",
        "query_type": "string"
      }
    }
  ]
}

2. 后端 API 实现

创建 backend_api.py

from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from investment_assistant import InvestmentAssistant

app = FastAPI()
assistant = InvestmentAssistant()

class AnalysisRequest(BaseModel):
    symbol: str
    query: str

@app.post("/api/analysis")
async def analyze(request: AnalysisRequest):
    try:
        result = assistant.chat(f"分析 {request.symbol}: {request.query}")
        return {"success": True, "result": result}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=8000)

配置说明

环境变量

创建 .env 文件:

# OpenAI API Key
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxx

# OpenBB 配置(可选)
OPENBB_API_KEY=your-openbb-key

# 其他数据源 API Key(可选)
POLYGON_API_KEY=your-polygon-key
ALPHA_VANTAGE_API_KEY=your-av-key

数据源配置

OpenBB 支持通过配置文件自定义数据源优先级:

# ~/.openbb/platform_settings.json
{
    "preferences": {
        "equity_price_historical": {
            "provider": "yfinance"
        },
        "equity_fundamental": {
            "provider": "fmp"
        }
    }
}

故障排除

常见问题

1. OpenBB 安装失败

# 升级 pip
pip install --upgrade pip

# 安装编译依赖(macOS)
brew install cmake

# 使用 conda(如果 pip 安装失败)
conda install -c conda-forge openbb

2. API Key 错误

# 检查 API Key 是否设置
import os
print(os.getenv("OPENAI_API_KEY"))

# 或者在代码中直接设置
import openai
openai.api_key = "your-key"

3. 数据获取超时

# 增加超时时间
obb.equity.price.historical("AAPL", timeout=30)

性能优化

1. 数据缓存

from functools import lru_cache

@lru_cache(maxsize=100)
def get_cached_price(symbol: str):
    return obb.equity.price.historical(symbol)

2. 异步处理

import asyncio

async def fetch_multiple(symbols: List[str]):
    tasks = [fetch_price(symbol) for symbol in symbols]
    return await asyncio.gather(*tasks)

安全建议

  1. API Key 管理:使用环境变量或密钥管理服务,不要硬编码
  2. 输入验证:对用户输入进行验证,防止注入攻击
  3. 速率限制:实施 API 调用速率限制,避免滥用
  4. 数据隐私:敏感数据加密存储,遵循相关法规

扩展方向

  1. 多语言支持:添加中文、英文等多语言界面
  2. 语音交互:集成语音识别和合成
  3. 推送通知:监控价格变动并推送提醒
  4. 回测功能:添加策略回测能力
  5. 社交功能:分享分析观点和组合

本章小结

本章提供了完整的实施指南,包括:

  1. 环境准备:Python 3.10+、依赖安装、配置验证
  2. 代码实现:MCP 服务器、AI Agent、Streamlit 界面
  3. 运行指南:多终端启动、访问方式
  4. 配置说明:环境变量、数据源配置
  5. 故障排除:常见问题解决方案

按照本指南,你可以在 30 分钟内搭建一个最小可用的 OpenBB + AI 投资助手,并在数小时内扩展到功能完整的产品原型。


参考资料