aksharetools:大模型智能体框架agno可直接获取A股金融数据
原创内容第889篇,专注智能量化投资、个人成长与财富自由。
今天说说金融智能体开发。
智能体开发需要一个多agent框架。这样的框架,现在太多了,langchain, langgraph,autogen,crewai等等,还有各种低代码平台。
我找到一个轻量级的多模态的智能体框架平台:Agno。
使用akshare封装成函数集:AShareTools,这样对大模型直接提问:
from agno.agent import Agentfrom agno.tools.yfinance import YFinanceToolsfrom akshare_tools import AShareToolsfrom utils import get_modelagent = Agent(model=get_model(name='qwen'),tools=[AShareTools(enable_all=True)],instructions=["Use tables to display data.","Only include the table in your response. No other text.",],debug_mode=False,)# Getting chunks in a variablerun_response = agent.run("获取sz000001,sh600519的最新股价", stream=True)for chunk in run_response:for char in chunk.content:print(char, end='', flush=True) # 关键参数:end=''取消换行,flush=True立即刷新#time.sleep(0.05) # 调整这个值控制打字速度(单位:秒)

import jsonfrom datetime import datetime, timedeltaimport pandas as pdimport akshare as akfrom agno.tools import Toolkitfrom agno.utils.log import log_debugclass AShareTools(Toolkit):"""AShareTools is a toolkit for getting financial data from A-share markets using akshare.Note: Symbols should include market prefix (e.g., sh600000 for Shanghai, sz000001 for Shenzhen).Args:stock_price (bool): Whether to get the current stock price.company_info (bool): Whether to get company information.stock_fundamentals (bool): Whether to get stock fundamentals.income_statements (bool): Whether to get income statements.key_financial_ratios (bool): Whether to get key financial ratios.analyst_recommendations (bool): Whether to get analyst recommendations.company_news (bool): Whether to get company news.technical_indicators (bool): Whether to get technical indicators.historical_prices (bool): Whether to get historical prices.enable_all (bool): Whether to enable all tools."""def __init__(self,stock_price: bool = True,company_info: bool = False,stock_fundamentals: bool = False,income_statements: bool = False,key_financial_ratios: bool = False,analyst_recommendations: bool = False,company_news: bool = False,technical_indicators: bool = False,historical_prices: bool = False,enable_all: bool = False,**kwargs,):super().__init__(name="ashare_tools", **kwargs)if stock_price or enable_all:self.register(self.get_current_stock_price)if company_info or enable_all:self.register(self.get_company_info)if stock_fundamentals or enable_all:self.register(self.get_stock_fundamentals)if income_statements or enable_all:self.register(self.get_income_statements)if key_financial_ratios or enable_all:self.register(self.get_key_financial_ratios)if analyst_recommendations or enable_all:self.register(self.get_analyst_recommendations)if company_news or enable_all:self.register(self.get_company_news)if technical_indicators or enable_all:self.register(self.get_technical_indicators)if historical_prices or enable_all:self.register(self.get_historical_stock_prices)def get_current_stock_price(self, symbol: str) -> str:code = symbol[2:]"""Get the current stock price for a given A-share symbol.Args:symbol (str): The stock symbol with market prefix (e.g., sh600000).Returns:str: Current price formatted to 4 decimal places or error message."""try:log_debug(f"Fetching current price for {symbol}")# Get all A-share spot data and filter by symboldf = ak.stock_zh_a_spot_em()#print(df)sub = df[df['代码'] == code]['最新价']#print(sub)current_price = sub.values[0]#print(current_price)return f"{current_price:.4f}" if current_price else f"Could not fetch price for {symbol}"except Exception as e:return f"Error fetching current price for {symbol}: {e}"def get_company_info(self, symbol: str) -> str:"""Get company information for a given A-share symbol.Args:symbol (str): The stock symbol with market prefix.Returns:str: JSON containing company profile."""try:code = symbol[2:] # Remove market prefixinfo_df = ak.stock_individual_info_em(symbol=code)info = dict(zip(info_df['item'], info_df['value']))# Get real-time price separatelyprice_df = ak.stock_zh_a_spot_em()price_data = price_df[price_df['代码'] == symbol].iloc[0]company_info = {"Name": info.get('公司名称', 'N/A'),"Symbol": symbol,"Current Price": f"{price_data['最新价']} CNY","Sector": info.get('所属行业', 'N/A'),"Industry": info.get('行业分类', 'N/A'),"Market Cap": f"{price_data['总市值']} CNY","PE Ratio": info.get('市盈率', 'N/A'),"EPS": info.get('每股收益', 'N/A'),"Website": info.get('公司主页', 'N/A'),"Business Scope": info.get('经营范围', 'N/A')}return json.dumps(company_info, indent=2, ensure_ascii=False)except Exception as e:return f"Error fetching company info for {symbol}: {e}"def get_historical_stock_prices(self, symbol: str, period: str = "1mo", interval: str = "1d") -> str:"""Get historical prices for a given A-share symbol.Args:symbol (str): Stock symbol with market prefix.period (str): Historical period (1d, 1mo, etc.).interval (str): Data interval (not fully implemented for akshare).Returns:str: JSON formatted historical data."""try:log_debug(f"Fetching historical prices for {symbol}")code = symbol[2:]# Convert period to start/end datesend_date = datetime.now().strftime("%Y%m%d")period_map = {"1d": 1, "5d": 5, "1mo": 30,"3mo": 90, "6mo": 180, "1y": 365}start_date = (datetime.now() - timedelta(days=period_map.get(period, 30))).strftime("%Y%m%d")df = ak.stock_zh_a_daily(symbol=code, start_date=start_date, end_date=end_date, adjust="qfq")return df[['日期', '开盘', '收盘', '最高', '最低', '成交量']].to_json(orient="records")except Exception as e:return f"Error fetching historical prices for {symbol}: {e}"def get_stock_fundamentals(self, symbol: str) -> str:"""Get fundamental data for a given A-share symbol.Args:symbol (str): Stock symbol with market prefix.Returns:str: JSON formatted fundamental data."""try:code = symbol[2:]indicator_df = ak.stock_a_lg_indicator(stock=code)latest = indicator_df.iloc[-1].to_dict()fundamentals = {"symbol": symbol,"PE Ratio": latest.get('市盈率'),"PB Ratio": latest.get('市净率'),"Dividend Yield": latest.get('股息率'),"ROE": latest.get('净资产收益率'),"Total Market Cap (CNY)": latest.get('总市值')}return json.dumps(fundamentals, indent=2, ensure_ascii=False)except Exception as e:return f"Error getting fundamentals for {symbol}: {e}"def get_income_statements(self, symbol: str) -> str:"""Get income statements for a given A-share symbol.Args:symbol (str): Stock symbol with market prefix.Returns:str: JSON formatted income statements."""try:code = symbol[2:]df = ak.stock_financial_report_sina(stock=code, symbol="利润表")return df.to_json(orient="records")except Exception as e:return f"Error fetching income statements for {symbol}: {e}"def get_key_financial_ratios(self, symbol: str) -> str:"""Get key financial ratios for a given A-share symbol.Args:symbol (str): Stock symbol with market prefix.Returns:str: JSON formatted financial ratios."""try:code = symbol[2:]df = ak.stock_financial_analysis_indicator(symbol=code)return df.to_json(orient="records")except Exception as e:return f"Error fetching financial ratios for {symbol}: {e}"def get_analyst_recommendations(self, symbol: str) -> str:"""Get analyst recommendations (placeholder - akshare lacks direct equivalent).Args:symbol (str): Stock symbol.Returns:str: JSON formatted message."""return json.dumps({"info": "Analyst recommendations not available via akshare"}, indent=2)def get_company_news(self, symbol: str, num_stories: int = 3) -> str:"""Get company news for a given A-share symbol.Args:symbol (str): Stock symbol.num_stories (int): Number of news items to return.Returns:str: JSON formatted news items."""try:code = symbol[2:]news_df = ak.stock_news_em(symbol=code)return news_df.head(num_stories).to_json(orient="records")except Exception as e:return f"Error fetching news for {symbol}: {e}"def get_technical_indicators(self, symbol: str, period: str = "3mo") -> str:"""Get technical indicators for a given A-share symbol.Args:symbol (str): Stock symbol.period (str): Historical period.Returns:str: JSON formatted technical data."""try:code = symbol[2:]df = ak.stock_zh_a_daily(symbol=code, period=period, adjust="qfq")return df[['日期', '收盘', '成交量', 'MA5', 'MA10', 'MA20']].to_json(orient="records")except Exception as e:return f"Error fetching technical indicators for {symbol}: {e}"
AGI相关的代码在AGI星球更新:
昨天咱们更新了aitrader_core的1.1版本:年化收益226.9%,最大回撤12.7%,本地运行toml策略,aitrader核心代码发布(python代码+数据下载)
有些同学问,与完全开源的aitrader框架版本的区别?这里做一下说明:框架版本基于wxpython做智能量化平台的gui,回测数据和引擎都是通过api在服务器上完成。
涉及到回测引擎(因子表达式,deap因子挖掘,机器学习建模以及回测引擎等核心代码,每周五在星球更新)
星球部分策略,设定了需要积分才能下载。这个积分是给策略的作者。
如何获得积分?
1、用户加入星球,并绑定会员之后,会获得20积分。每次续费再新增20积分。
3、发布策略,设定“积分查看”,其他同学下载后,积分归作者所有。
3、在论坛发布高质量的贴子即可(可获5,10,15,20等积分)。
4、给同学提供高质量的答案。
比如今天新发布的两个策略:

代码和策略下载:AI量化实验室——2025量化投资的星辰大海
扩展 • 历史文章
EarnMore(赚得更多)基于RL的投资组合管理框架:一致的股票表示,可定制股票池管理。(附论文+代码)
年化收益200%+的策略集 | 实时板块资金热力图 「aitrader 5.0系统代码发布」
机器学习驱动的策略开发通过流程 | 普通人阶层跃迁的可能路径?
年化30.24%,最大回撤19%,综合动量多因子评分策略再升级(python代码+数据)
三秒钟创建一个年化28%,夏普比1.25的策略(python系统已开放源代码下载)
会员专属策略可以直接下载了,多个十年年化30+%策略集|polars重构因子引擎(代码+数据下载)
6年年化收益46%,最大回撤率为16%的策略(附python代码)
