Tushare金融数据与AI智能体结合:构建自动化金融数据分析工作流
1. 项目概述当金融数据遇上智能体编程如果你是一名金融从业者、量化爱好者或者只是对市场数据感兴趣的程序员那么“如何高效、稳定地获取和处理金融数据”这个问题大概率是你绕不开的痛点。传统的做法可能是手动爬取财经网站或者依赖一些封装不完善的第三方库过程往往伴随着数据源不稳定、字段不统一、清洗工作量大等一系列麻烦。最近我在GitHub上看到一个名为“StanleyChanH/Tushare-Finance-Skill-for-Claude-Code”的项目它提供了一个非常巧妙的思路将国内知名的金融数据接口Tushare与新兴的AI编程助手Claude Code或类似智能体的能力相结合构建一个自动化、智能化的金融数据工作流。简单来说这个项目的核心价值在于它试图将“获取数据”这个动作从“写代码调用API”的层面提升到“用自然语言描述需求由AI自动生成并执行代码”的层面。想象一下你不再需要记忆Tushare繁杂的API参数或者为数据清洗写一堆pandas操作你只需要告诉AI“帮我获取过去一年沪深300指数的日线行情并计算其20日和60日移动平均线”然后一套完整的、可运行的代码就呈现在你面前甚至可以直接执行并返回整理好的DataFrame。这不仅仅是效率的提升更是工作模式的革新尤其适合那些数据分析思维强但编码经验相对薄弱的金融研究者或者希望将精力更集中于策略逻辑而非数据工程的量化开发者。这个项目本质上是一个“技能”Skill或“工具集”Toolkit的封装它明确了Tushare这个数据源的能力边界并将其以智能体如Claude Code能够理解和调用的方式进行了标准化描述。接下来我将从项目设计思路、核心实现细节、实操搭建过程以及避坑指南四个方面为你彻底拆解这个项目并分享如何将其应用到你的实际工作中。2. 核心设计思路与架构解析2.1 为什么是Tushare Claude Code要理解这个项目的设计首先要明白这两个核心组件为何能珠联璧合。Tushare的优势与定位Tushare是一个提供国内股票、基金、期货、期权等金融数据的老牌Python库。它的优势非常明显数据相对规范、接口稳定、涵盖A股市场核心数据。对于国内量化分析来说它是比爬取东方财富、新浪财经等网站更可靠、更合规的选择。然而它的使用门槛在于第一需要注册获取token第二API接口众多参数复杂需要查阅文档第三返回的数据往往需要进一步的清洗、转换和整合才能用于分析。Claude Code及智能体的赋能Claude Code或者更广义地说基于大语言模型的代码生成智能体如Cursor、GitHub Copilot、通义灵码等其核心能力是理解自然语言意图并生成、解释、调试代码。但它有一个局限它的知识截止于某个时间点且对于需要特定凭证如Tushare Token或依赖特定外部服务实时数据接口的任务它无法凭空创造。它不知道你的Tushare Token是什么也不清楚Tushare Pro接口最新的细微变动。项目的桥梁作用因此“Tushare-Finance-Skill-for-Claude-Code”项目扮演的正是“桥梁”角色。它做了以下几件关键事封装与抽象将Tushare复杂的API调用封装成一系列更简洁、更功能化的函数或“工具”。上下文提供在给Claude Code的提示Prompt中清晰地定义了这些工具的名称、功能描述、输入参数和输出格式。这相当于给了AI一本“Tushare工具使用说明书”。环境与认证管理它提供了管理Tushare Token等敏感信息的最佳实践建议如使用环境变量并确保生成的代码能在正确的环境中运行。模式引导它设计了一种交互模式让用户可以用自然语言提出数据需求AI根据“说明书”选择正确的工具生成代码用户审核后执行形成一个闭环。这种设计思路的核心是“授人以渔”。它不是提供一个死板的、固定功能的数据查询网站而是提供了一套方法论和基础组件让你能借助AI的能力灵活地应对千变万化的数据获取需求。2.2 技能Skill的标准化定义一个能被智能体良好理解的“技能”需要被标准化地定义。通常这遵循类似“函数签名”或“OpenAI Function Calling”的格式。在这个项目中一个Tushare技能可能被定义为如下结构{ “name”: “get_stock_daily”, “description”: “获取A股个股的日线行情数据。支持复权因子调整。”, “parameters”: { “type”: “object”, “properties”: { “ts_code”: { “type”: “string”, “description”: “股票代码格式如 ‘000001.SZ’” }, “start_date”: { “type”: “string”, “description”: “开始日期格式 ‘YYYYMMDD’” }, “end_date”: { “type”: “string”, “description”: “结束日期格式 ‘YYYYMMDD’” }, “adj”: { “type”: “string”, “enum”: [“None”, “qfq”, “hfq”], “description”: “复权类型None(不复权) qfq(前复权) hfq(后复权)” } }, “required”: [“ts_code”, “start_date”] }, “returns”: { “description”: “返回一个pandas DataFrame包含日期、开盘价、最高价、最低价、收盘价、成交量等字段。” } }关键点解析name工具的唯一标识AI会根据它来调用。description用自然语言清晰描述工具功能这是AI理解该工具用途的关键。parameters详细定义每个参数的名字、类型、描述、是否必填、可选值等。描述字段至关重要它直接指导AI如何理解用户自然语言中的信息并映射到参数上。例如用户说“我要茅台去年的股价”AI需要能从“茅台”联想到ts_code’600519.SH’从“去年”推导出start_date和end_date。returns说明输出是什么帮助AI在生成代码后能向用户解释将会得到什么结果。一个完整的项目会包含多个这样的技能定义覆盖行情数据、基本面数据、财务数据、宏观经济数据等Tushare的主要模块。注意在实际项目中这些定义可能以JSON文件、Python字典列表或特定框架如LangChain的Tool类的形式存在。核心思想是提供一份结构化的“能力清单”给AI。2.3 工作流设计从自然语言到数据结果定义了技能之后整个工作流是如何运转的呢一个典型的、理想化的流程如下用户输入用户在智能体界面如Claude Code的聊天框输入“分析一下宁德时代和比亚迪最近三个月的股价波动情况计算每日收益率和滚动波动率。”意图解析与工具匹配AIClaude Code接收到这条消息。它首先利用内置的代码理解能力结合项目提供的“Tushare技能定义列表”解析用户的意图。它会识别出关键词“宁德时代”、“比亚迪” - 需要股票代码映射“最近三个月” - 需要计算起止日期“股价” - 需要日线行情数据“收益率”、“波动率” - 需要进行金融计算。代码生成AI判断需要调用get_stock_daily这个技能可能调用两次分别获取两只股票的数据。然后它会生成类似以下的Python代码块import tushare as ts import pandas as pd import numpy as np from datetime import datetime, timedelta # 设置Token假设已通过环境变量配置 pro ts.pro_api() # 计算日期 end_date datetime.now().strftime(‘%Y%m%d’) start_date (datetime.now() - timedelta(days90)).strftime(‘%Y%m%d’) # 获取宁德时代数据 ndsd_daily pro.daily(ts_code‘300750.SZ’, start_datestart_date, end_dateend_date) ndsd_daily[‘trade_date’] pd.to_datetime(ndsd_daily[‘trade_date’]) ndsd_daily.set_index(‘trade_date’, inplaceTrue) ndsd_daily.sort_index(inplaceTrue) ndsd_daily[‘return’] ndsd_daily[‘close’].pct_change() ndsd_daily[‘rolling_vol_20d’] ndsd_daily[‘return’].rolling(window20).std() * np.sqrt(252) # 年化波动率 # 获取比亚迪数据 byd_daily pro.daily(ts_code‘002594.SZ’, start_datestart_date, end_dateend_date) # ... (类似的数据处理与计算) # 可以在这里进行数据合并、对比分析或可视化 print(f“宁德时代数据概览\n{ndsd_daily[[‘close’, ‘return’, ‘rolling_vol_20d’]].tail()})用户审核与执行生成的代码会展示给用户。用户可以检查代码逻辑是否正确比如股票代码映射对不对计算是否符合预期确认无误后在集成的Python环境中执行这段代码。结果交付与迭代代码执行后结果如打印的输出、生成的图表、内存中的DataFrame会返回给用户。如果用户不满意可以进一步提出要求“把波动率画个图对比一下”AI会在此基础上生成新的代码调用绘图库。这个流程将数据获取、清洗、计算的复杂性封装在了AI与预定义技能的交互背后用户只需关注“想要什么分析”。3. 核心实现细节与关键技术点3.1 Tushare Pro接口的深度封装策略原生的Tushare Pro接口虽然功能强大但直接让AI调用存在一些问题。项目的核心工作之一就是对其进行“友好化”封装。1. 参数简化与智能默认值 Tushare的某些接口参数很多但常用参数可能就几个。封装时可以为常用场景设置智能默认值。def get_index_daily(index_code‘000300.SH’, # 默认沪深300 start_dateNone, # 若为None则自动计算为一年前 end_dateNone, # 若为None则为今天 fields‘ts_code,trade_date,open,high,low,close,vol,amount’): “”“获取指数日线行情”“” pro ts.pro_api() if start_date is None: start_date (datetime.now() - timedelta(days365)).strftime(‘%Y%m%d’) if end_date is None: end_date datetime.now().strftime(‘%Y%m%d’) df pro.index_daily(ts_codeindex_code, start_datestart_date, end_dateend_date, fieldsfields) # 后续自动进行日期格式转换、排序等基本清洗 df[‘trade_date’] pd.to_datetime(df[‘trade_date’]) df.sort_values(‘trade_date’, inplaceTrue) return df这样当用户问“给我沪深300指数数据”时AI调用这个封装函数即使不指定日期也能返回最近一年的常用字段数据体验更流畅。2. 数据清洗与标准化管道 Tushare返回的数据格式相对固定但为了分析方便通常需要一系列标准化操作。封装函数可以内置这些管道。def get_and_clean_daily(ts_code, start_date, end_date, adjNone): raw_df pro.daily(ts_codets_code, start_datestart_date, end_dateend_date) # 1. 重命名列使其更符合通用习惯可选 # 2. 转换日期列为datetime类型并设为索引 raw_df[‘trade_date’] pd.to_datetime(raw_df[‘trade_date’]) raw_df.set_index(‘trade_date’, inplaceTrue) raw_df.sort_index(inplaceTrue) # 3. 处理复权因子如果adj参数被指定 if adj: # 这里可能需要调用Tushare的复权因子接口进行复杂计算 # 封装此逻辑对外提供简单的adj参数 pass # 4. 确保数值列类型正确 for col in [‘open’, ‘high’, ‘low’, ‘close’, ‘vol’, ‘amount’]: raw_df[col] pd.to_numeric(raw_df[col], errors‘coerce’) return raw_df通过内置清洗逻辑保证AI每次获取的数据都是“分析就绪”状态省去了用户反复编写相同清洗代码的麻烦。3. 错误处理与友好提示 网络超时、Token失效、参数错误是常见问题。封装函数需要包含健壮的错误处理并将技术性错误信息转化为AI和用户都能理解的友好提示。def safe_tushare_call(api_func, **kwargs): “”“安全的Tushare调用封装”“” try: df api_func(**kwargs) if df is None or df.empty: return None, “查询成功但未返回数据。请检查查询条件如日期范围、代码是否正确。” return df, None except Exception as e: # 根据异常类型返回不同的友好信息 if “token” in str(e).lower(): return None, “Tushare Token认证失败请检查环境变量TU_SHARE_TOKEN是否设置正确。” elif “timeout” in str(e).lower(): return None, “网络请求超时请稍后重试。” else: # 记录详细日志但返回简化信息 logging.error(f“Tushare调用失败: {e}”) return None, f“数据接口调用失败{str(e)[:100]}” # 截取部分错误信息这样当AI生成的代码执行出错时它能得到一个清晰的文本提示并可以将其转达给用户而不是一个让用户困惑的Python异常栈。3.2 面向Claude Code的提示工程让Claude Code这类智能体很好地运用这些封装好的技能提示词的设计是关键。这不仅仅是提供函数定义列表。1. 系统提示词设计 在对话开始时需要给AI一个明确的“角色”和“能力范围”设定。你是一个专业的金融数据分析助手擅长使用Python的Tushare库获取和处理中国金融市场数据。你已经拥有以下一组专门封装的Tushare工具函数请根据用户的需求选择并组合使用这些工具来生成Python代码。工具列表 [此处插入JSON格式的技能定义列表]重要工作原则生成代码前先思考用户需求对应需要调用哪些工具。生成的代码必须是完整、可独立运行的片段。必须包含必要的import语句如import tushare as ts, pandas as pd。绝对不要在你的回复中假设或硬编码Tushare Pro的Token。Token应通过环境变量TU_SHARE_TOKEN获取代码中应体现为ts.pro_api(tokenos.getenv(‘TU_SHARE_TOKEN’))。对于股票、指数等代码如果用户提供的是简称如‘茅台’、‘沪深300’你需要将其转换为标准的Tushare代码格式如‘600519.SH’ ‘000300.SH’。如果无法确定请在代码中注释说明或询问用户。生成的代码应包含基本的数据检查和简单的打印输出让用户能直观看到结果。现在请开始帮助用户。这个系统提示明确了AI的职责、可用资源、安全规范Token处理和交互逻辑。2. 上下文管理与多轮对话 一个复杂的分析任务可能需要多轮对话。例如用户先要了数据然后说“画个图”。AI需要记住上一轮代码中获取的数据变量名。虽然Claude Code有一定上下文记忆能力但在提示中引导其维护“会话状态”会更可靠。可以在每轮AI生成代码后要求其用自然语言总结一下当前工作区有哪些重要的DataFrame变量及其含义供下一轮参考。3. 代码生成风格约束 在提示中约束代码风格能提升生成代码的可读性和一致性。使用有意义的变量名如stock_daily_df而非df1。在复杂的操作如合并多个股票数据、计算衍生指标后添加简要的注释。优先使用pandas的向量化操作避免低效的循环。结果展示时使用.head()、.tail()或.describe()来提供数据概览避免打印整个巨大的DataFrame。3.3 安全与配置管理金融数据和API Token是敏感信息。项目必须提供安全的使用指南。1. Token管理最佳实践绝对禁止硬编码反复强调生成的代码中绝不能出现真实的Token字符串。环境变量指导用户将Token设置在系统环境变量中如TU_SHARE_TOKEN。这是最安全、最便携的方式。配置文件次级选择对于复杂项目可以使用.env文件通过python-dotenv加载或单独的配置文件但确保该文件被加入.gitignore避免提交到版本库。在代码中体现所有生成的代码模板都必须从环境变量读取Tokenpro ts.pro_api(tokenos.getenv(‘TU_SHARE_TOKEN’))并在前面加上import os。2. 数据缓存与限流考虑 Tushare Pro接口有调用频率限制。在封装函数中可以考虑加入简单的缓存机制避免在交互式探索中重复请求相同数据。from functools import lru_cache import hashlib lru_cache(maxsize128) def get_daily_cached(ts_code, start_date, end_date): “”“带缓存的日线数据获取”“” # 利用参数生成一个缓存键 cache_key f“{ts_code}_{start_date}_{end_date}” # 实际实现中可以将DataFrame序列化到本地文件或内存缓存 # 这里简化为直接调用 return pro.daily(ts_codets_code, start_datestart_date, end_dateend_date)同时在提示词中告知AI对于需要大量历史数据的请求建议用户分阶段获取或者提醒用户注意API调用限制。4. 从零搭建你的智能金融数据助手4.1 环境准备与基础配置假设你已经在本地或云环境拥有一个Python工作空间并且可以访问Claude Code或类似的智能编程助手。步骤1安装核心依赖创建一个新的虚拟环境是良好的习惯。# 创建并激活虚拟环境以conda为例 conda create -n finance_ai python3.9 conda activate finance_ai # 安装核心库 pip install tushare pandas numpy # 如果需要进行可视化安装matplotlib或plotly pip install matplotlib plotly步骤2获取并配置Tushare Token访问Tushare官网注册账号。在个人中心获取你的接口Token一串由字母数字组成的字符串。配置环境变量Linux/macOS在终端执行export TU_SHARE_TOKEN‘你的token’。为了永久生效可以将其添加到~/.bashrc或~/.zshrc文件中。Windows在命令提示符执行setx TU_SHARE_TOKEN “你的token”或在系统属性中设置用户环境变量。在Python脚本/Notebook中临时设置不推荐长期使用import os os.environ[‘TU_SHARE_TOKEN’] ‘你的token’步骤3验证Tushare基础功能在Python中运行以下代码测试环境是否正常import tushare as ts import os token os.getenv(‘TU_SHARE_TOKEN’) if not token: print(“错误未找到环境变量 TU_SHARE_TOKEN”) else: pro ts.pro_api(token) # 尝试获取一个简单数据如沪深300指数基本信息 try: df pro.index_basic(market‘SSE’) print(“Tushare连接成功指数数量”, df.shape[0]) print(df.head()) except Exception as e: print(f“连接失败{e}”)4.2 构建技能定义库这是项目的核心资产。建议创建一个独立的Python模块如tushare_skills.py来存放所有封装函数和技能定义。tushare_skills.py示例骨架import tushare as ts import pandas as pd import numpy as np import os from datetime import datetime, timedelta from typing import Optional, Dict, Any import logging logging.basicConfig(levellogging.INFO) logger logging.getLogger(__name__) # 初始化Tushare Pro接口从环境变量读取Token def get_pro_api(): token os.getenv(‘TU_SHARE_TOKEN’) if not token: raise ValueError(“环境变量 ‘TU_SHARE_TOKEN’ 未设置。请先配置你的Tushare Token。”) return ts.pro_api(token) pro get_pro_api() # —————— 技能1获取股票日线行情基础版 —————— def skill_get_stock_daily(ts_code: str, start_date: str, end_date: Optional[str] None, adj: Optional[str] None) - pd.DataFrame: “”“ 获取单只股票的日线行情数据并进行基础清洗。 Args: ts_code: 股票代码如 ‘000001.SZ’ start_date: 开始日期格式 ‘YYYYMMDD’ end_date: 结束日期格式 ‘YYYYMMDD’。默认为今日。 adj: 复权类型可选 ‘None’不复权 ‘qfq’前复权 ‘hfq’后复权。默认为None。 Returns: 一个清洗后的pandas DataFrame索引为交易日datetime包含OHLCV等字段。 “”“ if end_date is None: end_date datetime.now().strftime(‘%Y%m%d’) try: # 调用Tushare接口 df pro.daily(ts_codets_code, start_datestart_date, end_dateend_date) if df.empty: logger.warning(f“未查询到股票 {ts_code} 在 {start_date} 到 {end_date} 的数据。”) return pd.DataFrame() # 基础清洗 df[‘trade_date’] pd.to_datetime(df[‘trade_date’]) df.set_index(‘trade_date’, inplaceTrue) df.sort_index(inplaceTrue) # 复权处理此处为简化示例真实复权逻辑更复杂可能需调用其他接口 if adj ‘qfq’ or adj ‘hfq’: logger.info(f“复权因子处理{adj}功能需额外实现当前返回原始数据。”) # 实际项目中应在此集成Tushare的复权因子接口计算 # 重命名列使其更直观可选 df.rename(columns{ ‘open’: ‘Open’, ‘high’: ‘High’, ‘low’: ‘Low’, ‘close’: ‘Close’, ‘vol’: ‘Volume’, ‘amount’: ‘Amount’ }, inplaceTrue) return df except Exception as e: logger.error(f“获取股票 {ts_code} 日线数据失败{e}”) raise # —————— 技能2获取股票基本信息 —————— def skill_get_stock_basic(ts_code: Optional[str] None, list_status: str ‘L’) - pd.DataFrame: “”“获取股票列表基本信息。可筛选上市状态。”“” # … 实现代码 … pass # —————— 技能3获取指数日线行情 —————— def skill_get_index_daily(index_code: str ‘000300.SH’, start_date: str, end_date: Optional[str] None) - pd.DataFrame: “”“获取指数日线行情。”“” # … 实现代码 … pass # —————— 将技能定义为AI可理解的格式 —————— # 这里用一个字典列表来模拟“技能定义”在实际与AI框架集成时可能需转换为特定的Tool对象。 SKILL_DEFINITIONS [ { “name”: “get_stock_daily”, “description”: “获取A股个股的日线行情数据开盘价、最高价、最低价、收盘价、成交量、成交额。支持指定日期范围和复权类型基础。返回清洗后的DataFrame。”, “function”: skill_get_stock_daily, # 关联到实际的Python函数 “parameters”: { “ts_code”: {“type”: “string”, “description”: “股票代码标准格式如 ‘000001.SZ’ (平安银行) 或 ‘600519.SH’ (贵州茅台)”}, “start_date”: {“type”: “string”, “description”: “开始日期格式必须为 ‘YYYYMMDD’例如 ‘20230101’。”}, “end_date”: {“type”: “string”, “description”: “结束日期格式 ‘YYYYMMDD’。如果不提供默认为今天。”, “optional”: True}, “adj”: {“type”: “string”, “description”: “复权类型。可选 ‘None’ (不复权) ‘qfq’ (前复权) ‘hfq’ (后复权)。默认为None。”, “optional”: True} } }, { “name”: “get_stock_basic_info”, “description”: “获取一只或所有A股股票的基本信息包括股票代码、名称、上市日期、所属行业、市场类型等。”, “function”: skill_get_stock_basic, “parameters”: { “ts_code”: {“type”: “string”, “description”: “股票代码。如果为空则返回所有股票的基本信息。”, “optional”: True}, “list_status”: {“type”: “string”, “description”: “上市状态L (上市) D (退市) P (暂停上市)。默认为L。”, “optional”: True} } }, # … 添加更多技能定义 … ]这个模块提供了可调用的函数和结构化的技能描述是连接AI与Tushare的桥梁。4.3 与Claude Code的集成实践目前Claude Code或Cursor等智能体并没有一个官方的、标准化的“插件”或“技能”安装方式。集成主要依靠“上下文提示”。以下是两种实践方法方法一对话式提示适用于简单、临时的任务打开Claude Code或类似工具。在新的对话中直接将tushare_skills.py中SKILL_DEFINITIONS列表的内容或者其精简描述以及前面提到的系统提示词粘贴到对话开头。然后直接提出你的数据需求。例如“我已经为你提供了Tushare工具集的定义。现在请帮我获取贵州茅台600519.SH和招商银行600036.SH从2023年1月1日到2023年12月31日的日线收盘价并计算它们在这段时间内的每日收益率相关系数。”AI会根据你提供的工具定义和系统提示生成相应的代码。你复制代码到你的Python环境中执行即可。方法二创建可重用的提示模板文件推荐创建一个文本文件如finance_ai_prompt.txt将完整的系统提示词、技能定义、使用规范都写进去。当开始一个新的金融数据分析会话时打开这个文件将其内容复制为对话的“第一条消息”。后续的所有对话都基于这个强大的上下文进行。这种方法避免了每次都要重新粘贴技能定义。方法三结合脚本的半自动化进阶你可以编写一个简单的本地脚本作为你和AI之间的“代理”。脚本读取finance_ai_prompt.txt作为前缀。脚本接收你的自然语言查询。脚本将“前缀 你的查询”组合后调用OpenAI API或Claude API的Chat Completion功能。脚本解析API返回的响应提取其中的代码块。脚本自动在隔离的Python环境中执行该代码块并将结果文本、图表返回给你。 这种方式实现了更高程度的自动化但开发复杂度也更高。实操心得在初期强烈推荐使用方法二。它简单有效能让你专注于定义好技能和提示词。你会发现一份编写良好的提示模板文件其价值不亚于代码本身。你可以不断迭代这个文件根据AI的反馈补充更多示例、约束条件和最佳实践。4.4 一个完整的数据分析案例让我们模拟一个从需求到结果的完整过程展示这个工作流的威力。用户需求“对比一下新能源车板块比如宁德时代和比亚迪和传统汽车板块比如上汽集团在过去一年内的股价表现计算它们的累计收益率并画在一个图里看看趋势。”AI在接收到系统提示和技能定义后的思考与行动需求解析需要三只股票300750.SZ 002594.SZ 600104.SH过去一年的日线数据。需要计算每只股票的累计收益率从期初到每一天。需要将三条累计收益率曲线画在同一张图上进行对比。工具选择调用三次get_stock_daily技能或一个能处理多只股票的增强版技能。需要pandas进行数据计算需要matplotlib进行绘图。代码生成import tushare as ts import pandas as pd import matplotlib.pyplot as plt import os from datetime import datetime, timedelta # 初始化 pro ts.pro_api(tokenos.getenv(‘TU_SHARE_TOKEN’)) # 定义股票列表和名称映射 stocks { ‘300750.SZ’: ‘宁德时代’, ‘002594.SZ’: ‘比亚迪’, ‘600104.SH’: ‘上汽集团’ } # 计算日期范围 end_date datetime.now().strftime(‘%Y%m%d’) start_date (datetime.now() - timedelta(days365)).strftime(‘%Y%m%d’) # 存储各股票数据的字典 data_frames {} for ts_code, name in stocks.items(): print(f“正在获取 {name}({ts_code}) 的数据...”) try: df pro.daily(ts_codets_code, start_datestart_date, end_dateend_date) if df.empty: print(f“ 警告{name} 无数据跳过。”) continue # 基础清洗和计算 df[‘trade_date’] pd.to_datetime(df[‘trade_date’]) df.set_index(‘trade_date’, inplaceTrue) df.sort_index(inplaceTrue) # 计算每日收益率和累计收益率 df[‘daily_return’] df[‘close’].pct_change() df[‘cumulative_return’] (1 df[‘daily_return’]).cumprod() - 1 # 只保留我们需要的列 df df[[‘close’, ‘cumulative_return’]] df.rename(columns{‘cumulative_return’: name}, inplaceTrue) data_frames[name] df[name] except Exception as e: print(f“ 获取 {name} 数据时出错{e}”) # 合并累计收益率数据 if data_frames: cumulative_returns_df pd.concat(data_frames, axis1) # 可能日期不完全对齐pandas会处理 cumulative_returns_df cumulative_returns_df.ffill().dropna() # 前向填充并删除起始NaN print(“\n累计收益率数据预览最后5行”) print(cumulative_returns_df.tail()) # 绘图 plt.figure(figsize(14, 7)) for col in cumulative_returns_df.columns: plt.plot(cumulative_returns_df.index, cumulative_returns_df[col], labelcol, linewidth2) plt.title(‘新能源车 vs 传统汽车过去一年累计收益率对比’, fontsize16) plt.xlabel(‘日期’, fontsize12) plt.ylabel(‘累计收益率’, fontsize12) plt.legend(fontsize12) plt.grid(True, linestyle‘--’, alpha0.7) plt.xticks(rotation45) plt.tight_layout() plt.show() else: print(“未能获取到任何有效数据。”)用户执行与结果用户将这段代码复制到Jupyter Notebook或Python脚本中运行确保已设置Token。代码会获取数据、计算并绘制出一张三条曲线对比的趋势图。用户可以直接观察到宁德时代和比亚迪的累计收益率波动可能更大而上汽集团相对平稳从而获得直观的洞察。这个案例展示了如何将一个复杂的、多步骤的数据获取、处理和可视化任务通过自然语言指令转化为一段可执行的、专业的代码。用户无需关心Tushare API的具体参数、pandas数据合并的细节或matplotlib绘图的语法。5. 常见问题、避坑指南与进阶技巧在实际操作中你肯定会遇到各种问题。以下是我在实践过程中总结的一些典型问题和解决方案。5.1 数据获取与接口问题问题1AI生成的代码执行时报错‘pro’ is not defined或Token验证失败。原因AI生成的代码可能遗漏了Tushare Pro接口的初始化语句或者Token获取方式不对。解决方案在系统提示词中反复强调初始化步骤并提供一个标准的代码模板。检查你的环境变量TU_SHARE_TOKEN是否设置正确。可以在终端输入echo $TU_SHARE_TOKEN(Linux/macOS) 或echo %TU_SHARE_TOKEN%(Windows) 来验证。在代码开头强制添加以下片段import tushare as ts import os import sys token os.getenv(‘TU_SHARE_TOKEN’) if not token: print(“错误请设置环境变量 TU_SHARE_TOKEN”) sys.exit(1) pro ts.pro_api(token)问题2获取的数据是空的Empty DataFrame。原因股票/指数代码格式错误。Tushare要求后缀.SH(上交所) 或.SZ(深交所)。查询的日期范围内没有交易日如周末、节假日。股票已退市或暂停上市。排查技巧代码格式化在技能定义中强调代码格式并让AI在生成代码后先尝试用pro.stock_basic()或pro.index_basic()验证代码是否存在。日期检查让AI在生成代码时添加一个简单的日期有效性检查或提示。例如如果用户输入“去年”AI应计算出具体的起止日期并打印出来方便用户核对。错误处理如3.1节所示在封装函数中加入友好的空数据检查和提示。问题3Tushare接口调用频率超限。原因Tushare Pro不同积分等级有每分钟/每日调用次数限制。在交互式探索中频繁请求容易触发限制。应对策略缓存如前所述实现数据缓存层对相同参数的请求直接返回本地缓存。批量请求对于需要多只股票数据的情况指导AI使用Tushare的批量接口如pro.daily本身支持多个ts_code以逗号分隔而不是循环调用单只股票接口。速率控制在封装函数中加入time.sleep()但注意这会降低交互速度。更好的方法是提示用户“当前操作可能需要较多API调用建议分步进行或使用本地缓存数据”。5.2 AI提示与代码生成问题问题4AI不理解我的自然语言描述生成的代码牛头不对马嘴。原因提示词不够精确或者AI对金融术语的理解有偏差。优化方法提供示例在系统提示词中加入几个“用户提问 - AI代码”的示例对。例如示例1 用户“我想看贵州茅台最近100个交易日的股价” AI应生成调用get_stock_daily(ts_code‘600519.SH’, start_date…, end_date…)的代码并计算100个交易日对应的起始日期。 示例2 用户“计算沪深300指数2023年的年化波动率” AI应生成获取指数日线、计算日收益率、再计算标准差和年化的代码。细化参数描述在技能定义的parameters的description字段里尽可能详细地描述输入格式和含义。例如对于ts_code描述可以写“股票代码必须是Tushare标准格式。沪市股票以.SH结尾如‘600519.SH’代表贵州茅台深市股票以.SZ结尾如‘000001.SZ’代表平安银行。如果用户只提供了名称或代码你需要进行转换或询问用户确认。”分步引导对于复杂需求不要期望AI一次生成完美代码。可以先让它生成数据获取部分验证无误后再让它基于已获取的数据进行下一步计算。问题5AI生成的代码效率低下或有bug。原因AI可能采用一些直观但低效的写法或者忽略了一些边界情况。审查与修正代码审查始终将AI生成的代码视为“初稿”。运行前花一分钟快速浏览代码检查是否有明显的错误如变量名拼写错误、循环逻辑问题。性能提示在系统提示词中加入性能建议如“避免在循环内部调用Tushare接口应使用批量接口或外部循环”、“使用pandas的向量化操作替代for循环处理数据列”。边界条件提示AI考虑数据可能为空的边界情况并在代码中添加if df.empty:的判断和处理。5.3 项目维护与进阶方向1. 技能库的持续丰富 基础的行情数据只是开始。你可以逐步将更多Tushare模块封装成技能财务数据利润表、资产负债表、现金流量表。市场参考资金流向、融资融券、沪深港通持股。宏观行业CPI、PPI、PMI、行业分类数据。特色数据龙虎榜、大宗交易、限售解禁。 每增加一个技能你的智能助手的能力就强大一分。2. 从代码生成到自动化执行 如前所述可以开发一个本地代理程序将“用户输入 - AI生成代码 - 自动执行 - 返回结果”的流程自动化。这需要处理代码安全执行如使用subprocess或沙箱、结果捕获和格式化展示等问题。3. 集成可视化与报告生成 引导AI不仅生成数据处理代码还能生成高质量的可视化图表使用matplotlib,seaborn,plotly甚至组合多个图表生成一份简单的HTML分析报告。4. 结合其他数据源 Tushare主要覆盖A股。你的智能助手可以扩展集成其他数据源如国际市场yfinance(雅虎财经) 获取美股、港股、加密货币数据。另类数据新闻舆情、社交媒体情绪通过其他API。本地数据库连接你本地的历史数据库进行混合查询。 这需要你在技能定义中清晰地说明每个技能的数据源和适用范围。5. 构建专属的金融AI智能体 利用像LangChain、LlamaIndex这样的AI应用框架你可以更系统地将Tushare技能、其他工具如计算器、网络搜索、记忆模块和LLM核心组合起来构建一个专属的、能够进行多轮复杂对话和推理的金融数据分析智能体。这才是这个项目理念的终极形态。这个项目“StanleyChanH/Tushare-Finance-Skill-for-Claude-Code”更像是一个启发性的起点。它展示了一种可能性通过精心的设计和封装我们可以将专业的数据工具“翻译”成AI能理解的语言从而极大地降低金融数据分析的技术门槛让从业者能更专注于市场逻辑和策略本身而不是繁琐的数据工程。