Skill: coderwpf/baostock (version 1.0.3)

--- name: baostock description: BaoStock 免费A股数据平台 - 支持K线、财务数据、行业分类查询，无需注册即可使用。 version: 1.2.0 homepage: https://www.baostock.com metadata: {"clawdbot":{"emoji":"📊","requires":{"bins":["python3"]}}} --- # BaoStock（免费A股数据平台） [BaoStock](https://www.baostock.com) 是一个免费的开源中国A股证券数据平台。无需注册或API Key，返回 `pandas.DataFrame`。 ## 安装 ```bash pip install baostock --upgrade ``` 验证安装： ```bash python3 -c "import baostock as bs; lg = bs.login(); print(lg.error_msg); bs.logout()" ``` 预期输出：`login success!`。 ## 基本用法 每个会话必须以 `bs.login()` 开始，以 `bs.logout()` 结束： ```python import baostock as bs import pandas as pd # 登录系统 lg = bs.login() # ... 在此执行数据查询 ... # 登出系统 bs.logout() ``` 使用 `.get_data()` 从查询结果中获取DataFrame： ```python rs = bs.query_all_stock() df = rs.get_data() ``` ## 核心API ### 1. query_all_stock — 获取全部证券列表 获取指定交易日的全部股票/指数代码。 ```python # 获取指定日期所有证券代码 rs = bs.query_all_stock(day="2024-01-02") df = rs.get_data() # 返回字段: code(证券代码), tradeStatus(交易状态), code_name(证券名称) ``` - **day** — 日期字符串 `YYYY-MM-DD`（默认今天）。非交易日返回空DataFrame。 ### 2. query_history_k_data_plus — K线数据 获取历史K线数据（开高低收量 + 指标）。 ```python # 获取工商银行日K线数据 rs = bs.query_history_k_data_plus( "sh.601398", "date,code,open,high,low,close,volume,amount,pctChg", start_date="2024-01-01", end_date="2024-06-30", frequency="d", # 频率: d(日线), w(周线), m(月线), 5/15/30/60(分钟线) adjustflag="3" # 复权: 1(后复权), 2(前复权), 3(不复权，默认) ) df = rs.get_data() ``` **参数说明：** - **code** — 股票代码，格式 `sh.600000` 或 `sz.000001` - **fields** — 逗号分隔的字段名（见下方） - **start_date / end_date** — `YYYY-MM-DD` 格式 - **frequency** — `d`(日线), `w`(周线), `m`(月线), `5`/`15`/`30`/`60`(分钟线)。指数无分钟级数据。 - **adjustflag** — `1`(后复权), `2`(前复权), `3`(不复权，默认) **日线可用字段：** `date`(日期), `code`(证券代码), `open`(开盘价), `high`(最高价), `low`(最低价), `close`(收盘价), `preclose`(昨收价), `volume`(成交量), `amount`(成交额), `adjustflag`(复权标志), `turn`(换手率), `tradestatus`(交易状态), `pctChg`(涨跌幅), `peTTM`(滚动市盈率), `pbMRQ`(市净率), `psTTM`(滚动市销率), `pcfNcfTTM`(滚动市现率), `isST`(是否ST) **分钟线可用字段：** `date`(日期), `time`(时间), `code`(证券代码), `open`(开盘价), `high`(最高价), `low`(最低价), `close`(收盘价), `volume`(成交量), `amount`(成交额), `adjustflag`(复权标志) ### 3. query_trade_dates — 交易日历 ```python # 获取指定范围的交易日历 rs = bs.query_trade_dates(start_date="2024-01-01", end_date="2024-12-31") df = rs.get_data() # 返回字段: calendar_date(日历日期), is_trading_day(是否交易日) ``` ### 4. query_stock_industry — 行业分类 ```python # 获取全部股票行业分类 rs = bs.query_stock_industry() df = rs.get_data() # 返回字段: updateDate(更新日期), code(证券代码), code_name(证券名称), industry(行业), industryClassification(行业分类) ``` ### 5. query_stock_basic — 股票基本信息 ```python # 获取指定股票基本信息 rs = bs.query_stock_basic(code="sh.601398") df = rs.get_data() # 返回字段: code(证券代码), code_name(证券名称), ipoDate(上市日期), outDate(退市日期), type(类型), status(状态) ``` - **type** — `1` 股票, `2` 指数, `3` 其他 - **status** — `1` 上市, `0` 退市 ### 6. query_dividend_data — 分红信息 ```python # 获取指定股票分红数据 rs = bs.query_dividend_data(code="sh.601398", year="2023", yearType="report") df = rs.get_data() ``` - **yearType** — `report`(报告期) 或 `operate`(实施期) ### 7. 财务数据（季度） #### 盈利能力 ```python # 获取盈利能力指标（ROE、净利润率、毛利率等） rs = bs.query_profit_data(code="sh.601398", year=2023, quarter=4) df = rs.get_data() ``` #### 营运能力 ```python # 获取营运能力指标（存货周转率、应收账款周转率等） rs = bs.query_operation_data(code="sh.601398", year=2023, quarter=4) df = rs.get_data() ``` #### 成长能力 ```python # 获取成长能力指标（营收同比增长、净利润同比增长等） rs = bs.query_growth_data(code="sh.601398", year=2023, quarter=4) df = rs.get_data() ``` #### 偿债能力 ```python # 获取偿债能力指标（流动比率、速动比率等） rs = bs.query_balance_data(code="sh.601398", year=2023, quarter=4) df = rs.get_data() ``` #### 现金流 ```python # 获取现金流数据 rs = bs.query_cash_flow_data(code="sh.601398", year=2023, quarter=4) df = rs.get_data() ``` #### 杜邦分析 ```python # 获取杜邦分析数据（ROE分解：利润率×资产周转率×权益乘数） rs = bs.query_dupont_data(code="sh.601398", year=2023, quarter=4) df = rs.get_data() ``` ### 8. 指数数据 #### 指数成分股 ```python # 获取沪深300成分股 rs = bs.query_hs300_stocks() df = rs.get_data() # 获取上证50成分股 rs = bs.query_sz50_stocks() df = rs.get_data() # 获取中证500成分股 rs = bs.query_zz500_stocks() df = rs.get_data() ``` ## 完整示例: Download Daily K-Line Data and Save as CSV ```python import baostock as bs import pandas as pd # 登录系统 bs.login() # 获取贵州茅台2024年日K线数据（后复权） rs = bs.query_history_k_data_plus( "sh.600519", "date,code,open,high,low,close,volume,amount,pctChg,peTTM", start_date="2024-01-01", end_date="2024-12-31", frequency="d", adjustflag="2" # 后复权 ) df = rs.get_data() # 保存到CSV文件 df.to_csv("kweichow_moutai_2024.csv", index=False) print(df.head()) # 登出系统 bs.logout() ``` ## 股票代码格式 - 上海证券交易所: `sh.600000`, `sh.601398` - 深圳证券交易所: `sz.000001`, `sz.300750` - 北京证券交易所: `bj.430047` - 指数: `sh.000001`(上证综指), `sh.000300`(沪深300) ## 使用技巧 - **无需注册或API Key** — 直接调用 `bs.login()` 即可开始。 - 长时间不活动会话可能超时 — 重新调用 `bs.login()` 即可。 - **非线程安全** — 并行下载请使用 `multiprocessing`（多进程），而非threading（多线程）。 - 数据覆盖范围：A股自1990年至今。 - 财务数据按季度提供，报告期结束后约有2个月的延迟。 - Documentation: http://baostock.com/baostock/index.php/Python_API%E6%96%87%E6%A1%A3 --- ## 进阶示例 ### 批量下载多只股票数据 ```python import baostock as bs import pandas as pd bs.login() # 定义要下载的股票列表 stock_list = ["sh.600519", "sh.601398", "sz.000001", "sz.300750", "sh.601318"] all_data = [] for code in stock_list: # 获取日K线数据（前复权） rs = bs.query_history_k_data_plus( code, "date,code,open,high,low,close,volume,amount,pctChg,turn,peTTM,pbMRQ", start_date="2024-01-01", end_date="2024-06-30", frequency="d", adjustflag="1" # 前复权 ) df = rs.get_data() all_data.append(df) print(f"已下载 {code}，共 {len(df)} 条记录") # 合并所有数据 combined = pd.concat(all_data, ignore_index=True) combined.to_csv("multi_stock_baostock.csv", index=False) print(f"合并总记录数: {len(combined)}") bs.logout() ``` ### 获取全市场股票列表并筛选 ```python import baostock as bs import pandas as pd bs.login() # Get all securities for a specified date rs = bs.query_all_stock(day="2024-06-28") df = rs.get_data() # 筛选正常交易的股票（排除指数和停牌股） stocks = df[df["tradeStatus"] == "1"] # 筛选上海A股（sh.6开头） sh_stocks = stocks[stocks["code"].str.startswith("sh.6")] print(f"沪市A股: {len(sh_stocks)} 只") # 筛选深圳主板（sz.00开头） sz_main = stocks[stocks["code"].str.startswith("sz.00")] print(f"深圳主板: {len(sz_main)} 只") # 筛选创业板（sz.30开头） gem = stocks[stocks["code"].str.startswith("sz.30")] print(f"创业板: {len(gem)} 只") bs.logout() ``` ### 计算技术指标 ```python import baostock as bs import pandas as pd import numpy as np bs.login() # 获取平安银行日K线数据 rs = bs.query_history_k_data_plus( "sz.000001", "date,close,volume", start_date="2024-01-01", end_date="2024-12-31", frequency="d", adjustflag="1" ) df = rs.get_data() df["close"] = df["close"].astype(float) df["volume"] = df["volume"].astype(float) # 计算均线 df["MA5"] = df["close"].rolling(5).mean() df["MA10"] = df["close"].rolling(10).mean() df["MA20"] = df["close"].rolling(20).mean() # Calculate MACD ema12 = df["close"].ewm(span=12, adjust=False).mean() ema26 = df["close"].ewm(span=26, adjust=False).mean() df["DIF"] = ema12 - ema26 df["DEA"] = df["DIF"].ewm(span=9, adjust=False).mean() df["MACD"] = 2 * (df["DIF"] - df["DEA"]) # Calculate volume moving averages df["VOL_MA5"] = df["volume"].rolling(5).mean() df["VOL_MA10"] = df["volume"].rolling(10).mean() # 检测金叉/死叉信号 df["signal"] = 0 df.loc[(df["MA5"] > df["MA20"]) & (df["MA5"].shift(1) <= df["MA20"].shift(1)), "signal"] = 1 # 金叉 df.loc[(df["MA5"] < df["MA20"]) & (df["MA5"].shift(1) >= df["MA20"].shift(1)), "signal"] = -1 # 死叉 golden_cross = df[df["signal"] == 1] death_cross = df[df["signal"] == -1] print(f"金叉次数: {len(golden_cross)}, 死叉次数: {len(death_cross)}") print("金叉日期:", golden_cross["date"].tolist()) bs.logout() ``` ### 获取沪深300成分股并下载数据 ```python import baostock as bs import pandas as pd bs.login() # 获取沪深300成分股 rs = bs.query_hs300_stocks() hs300 = rs.get_data() print(f"沪深300共 {len(hs300)} 只成分股") # 下载前10只成分股的日K线数据 for _, row in hs300.head(10).iterrows(): code = row["code"] name = row["code_name"] rs = bs.query_history_k_data_plus( code, "date,code,close,pctChg,turn", start_date="2024-06-01", end_date="2024-06-30", frequency="d", adjustflag="1" ) df = rs.get_data() print(f"{name}({code}): {len(df)} records") bs.logout() ``` ### 获取财务数据并分析 ```python import baostock as bs import pandas as pd bs.login() # 获取多只银行股的盈利能力数据 bank_codes = ["sh.601398", "sh.601939", "sh.601288", "sh.600036", "sh.601166"] profit_data = [] for code in bank_codes: rs = bs.query_profit_data(code=code, year=2023, quarter=4) df = rs.get_data() if not df.empty: profit_data.append(df.iloc[0]) profit_df = pd.DataFrame(profit_data) # 查看ROE和净利润率 print(profit_df[["code", "roeAvg", "npMargin", "gpMargin"]]) # 获取成长能力数据 growth_data = [] for code in bank_codes: rs = bs.query_growth_data(code=code, year=2023, quarter=4) df = rs.get_data() if not df.empty: growth_data.append(df.iloc[0]) growth_df = pd.DataFrame(growth_data) # 查看营收增长率和净利润增长率 print(growth_df[["code", "YOYEquity", "YOYAsset", "YOYNI"]]) bs.logout() ``` ### 完整示例: Simple Backtesting Framework ```python import baostock as bs import pandas as pd import numpy as np bs.login() # 获取平安银行2023年日K线数据（前复权） rs = bs.query_history_k_data_plus( "sz.000001", "date,open,high,low,close,volume", start_date="2023-01-01", end_date="2023-12-31", frequency="d", adjustflag="1" ) df = rs.get_data() for col in ["open", "high", "low", "close", "volume"]: df[col] = df[col].astype(float) # 双均线策略回测 df["MA5"] = df["close"].rolling(5).mean() df["MA20"] = df["close"].rolling(20).mean() initial_cash = 100000 # 初始资金：10万 cash = initial_cash shares = 0 # 持有股数 trades = [] # 交易记录 for i in range(20, len(df)): # 金叉 buy signal if df["MA5"].iloc[i] > df["MA20"].iloc[i] and df["MA5"].iloc[i-1] <= df["MA20"].iloc[i-1]: if cash > 0: buy_price = df["close"].iloc[i] shares = int(cash / buy_price / 100) * 100 # 向下取整到手（100股） cost = shares * buy_price cash -= cost trades.append({"date": df["date"].iloc[i], "action": "BUY", "price": buy_price, "shares": shares, "cash": cash}) # 死叉 sell signal elif df["MA5"].iloc[i] < df["MA20"].iloc[i] and df["MA5"].iloc[i-1] >= df["MA20"].iloc[i-1]: if shares > 0: sell_price = df["close"].iloc[i] cash += shares * sell_price trades.append({"date": df["date"].iloc[i], "action": "SELL", "price": sell_price, "shares": shares, "cash": cash}) shares = 0 # 计算最终收益 final_value = cash + shares * df["close"].iloc[-1] total_return = (final_value - initial_cash) / initial_cash * 100 print(f"初始资金: {initial_cash:.2f}") print(f"最终组合价值: {final_value:.2f}") print(f"总收益率: {total_return:.2f}%") print(f"交易次数: {len(trades)}") for t in trades: print(f" {t['date']} {t['action']} {t['shares']} shares @ {t['price']:.2f}") bs.logout() ``` --- --- ## 🤖 AI Agent 高阶使用指南 对于 AI Agent，在使用该量化/数据工具时应遵循以下高阶策略和最佳实践，以确保任务的高效完成： ### 1. 数据校验与错误处理 在获取数据或执行操作后，AI 应当主动检查返回的结果格式是否符合预期，以及是否存在缺失值（NaN）或空数据。 * **示例策略**：在通过 API 获取数据框（DataFrame）后，使用 `if df.empty:` 进行校验；捕获 `Exception` 以防网络或接口错误导致进程崩溃。 ### 2. 多步组合分析 AI 经常需要进行宏观经济分析或跨市场对比。应善于将当前接口与其他数据源或工具组合使用。 * **示例策略**：先获取板块或指数的宏观数据，再筛选成分股，最后对具体标的进行深入的财务或技术面分析，形成完整的决策链条。 ### 3. 构建动态监控与日志 对于交易和策略类任务，AI 可以定期拉取数据并建立监控机制。 * **示例策略**：使用循环或定时任务检查特定标的的异动（如涨跌停、放量），并在发现满足条件的信号时输出结构化日志或触发预警。 --- ## 社区与支持 由 **大佬量化** 维护 — 量化交易教学与策略研发团队。 微信客服: **bossquant1** · [Bilibili](https://space.bilibili.com/48693330) · 搜索 **大佬量化** — 微信公众号 / Bilibili / 抖音


Security scan verdicts — ClawScan: suspicious | static analysis: clean | VirusTotal: clean | SkillSpector: clean (LOW)