按地域建证券池
用 country 参数筛出某个市场的全部股票,作为后续研究的基础池。适合做单一市场的横向比较;想做跨市场对比时,记得分别建池,不要把两个市场的代码混在一张表里算。
FinanceDatabase / Select & Search
筛选与搜索是 FinanceDatabase 的核心用法:Equities().select() 按国家/行业/板块/市值筛出一批股票,search() 按名称把一个名字换回证券代码。两者配合,就能把「我要研究哪一批标的」这件事先固定下来,再去接行情。需要提前说明的是,FinanceDatabase 只负责给出清单,不提供价格;筛完之后接行情源这一步省不掉,规划时间时要把这段算进去。
事实核验卡(核验日期 2026-09-29)
以上数字来自本站 2026-09-29 在 Windows + Python 3.11.9 + financedatabase 2.4.0 下的真实运行输出,不是从文章里转抄的;数据文件由上游持续更新,行数会变,以官方 PyPI 与 GitHub Release 为准。采集时 GitHub star 约 9,374(2026-09-29)。
Equities().select() 是 FinanceDatabase 里按维度筛股票的函数。参数本身很简单,真正容易出问题的是「取值怎么写」——写错了不会报错,只会给你一张空表。
| 参数 | 含义与取值口径 | 示例写法 | 适用场景 | 注意点 / 什么时候不用 |
|---|---|---|---|---|
country | 按国家筛选,取值需与数据源里的写法一致 | Equities().select(country="United States") | 想先圈定某一个市场的证券池 | 国家名写法与数据源不一致时会返回空表;多地上市的证券请结合返回的 country 列判断,别只看名字 |
sector | 按板块筛选,颗粒度比行业粗 | Equities().select(sector="Technology") | 做板块级横向比较、需要一组同板块标的时 | 同一板块内部差异可能很大;只想锁定细分行业时改用 industry,不要用 sector 硬凑 |
industry | 按行业筛选,颗粒度比 sector 细 | Equities().select(industry="Software - Infrastructure") | 做细分行业研究、需要一批可比公司时 | 行业名常带连字符与空格,容易拼错;更稳的做法是用 search() 先找到一只样本,再照抄它的 industry 取值 |
market_cap | 按市值规模档位筛选 | Equities().select(market_cap="Large Cap") | 想把范围限制在大盘股或小盘股时 | 市值本身随时间变化,档位字段可能滞后;重要决策前用行情源复核当前市值 |
| 多个参数一起传 | 条件同时生效,返回同时满足的证券 | Equities().select(country="United States", sector="Technology", market_cap="Large Cap") | 需要把市场、板块、规模同时收敛时 | 条件越多结果越少,很容易一次筛成空表;建议逐条加条件,每加一条打印一次行数观察变化 |
| 不传任何参数 | 返回该类别下的全部证券 | Equities().select() | 想先看数据覆盖范围,或导出一份全量清单时 | 结果可能很大,先看行数与列名,再决定要不要落盘或抽样 |
| 传了数据源里没有的取值 | 通常不报错,返回空 DataFrame | Equities().select(country="U.S.") | — | 空表不等于「没有这类证券」,先换一种写法核对取值,再确认上游是否可达 |
| 想按财务或技术指标筛 | 本库只做证券清单与元数据筛选,不含财务指标与技术指标 | — | — | 这类需求要另接财务数据接口或行情源,本库既没有价格字段也没有指标字段,不要在这里绕 |
country、sector、industry 原样抄下来当筛选条件。以官方 README 与 PyPI 页面为准。当你知道名字、但不知道代码时,在 FinanceDatabase 里筛选帮不上忙,search() 才是入口。它默认跨证券类别匹配,也可以用 database 参数限定在某类里找。
import financedatabase as fd # 跨类别按名称搜索 fd.Equities().search(name="Apple") # 指定在股票类内搜索 fd.Equities().search(name="Apple")
| 用法 | 示例 | 返回什么 | 适用场景 | 注意点 |
|---|---|---|---|---|
| 指定类别按名称搜索 | fd.Equities().search(name="Apple") | 该类别内的候选记录 | 只记得公司名,想先找到代码 | 不同类别可能出现同名或近似名称,按返回的类别列区分 |
| 指定类别搜索 | fd.Equities().search(name="Apple") | 只在指定类别内匹配 | 已经确定要股票,不想被基金、ETF 干扰 | database 的取值写法要与类别名称一致,否则同样会得到空结果 |
| 用名称片段搜索 | fd.Equities().search(name="Micro") | 名称中包含该片段的记录 | 只记得名字的前半段 | 片段越短命中越多,建议配合类别把范围收一收 |
| 搜索中文名称 | 按中文名直接搜 | 能否命中取决于上游是否收录中文名 | 想直接输中文查证券 | 上游以英文名为主,中文名常常搜不到;先换成英文名再试,别据此判断「没有这只证券」 |
| 名称带股份后缀 | 去掉 Inc、Ltd 之类后缀,只留主名 | 更可能命中主记录 | 全名怎么都搜不到时 | 后缀写法各数据源不统一,去掉后缀通常更稳 |
| 搜索结果有多条 | 按代码、交易所、国家几列交叉判断 | — | 遇到同名不同市场的证券 | 不要默认随手取到的那条就是目标;取错市场会让后面接的行情数据全部对不上 |
下面几段都可以直接粘进脚本跑,改一下条件取值即可。每段后面写了预期能看到什么,方便你判断是不是跑对了。
import financedatabase as fd
# 1) 美国科技股里的大盘股
us_large_tech = fd.Equities().select(
country="United States", sector="Technology", market_cap="Large Cap")
print(len(us_large_tech))预期输出:先打印出一个行数(具体数字随数据源变化)。如果打印出 0,先别下结论,按下面「空表排查」的顺序查一遍。
# 2) 某个细分行业的全部股票 software = fd.Equities().select(industry="Software - Infrastructure") print(software[["symbol", "name"]].head())
预期输出:一张只含代码与名称的小表,行数取决于该行业收录了多少只证券。
# 3) 按名称找代码 apple = fd.Equities().search(name="Apple") print(apple[["symbol", "name", "country"]].head())
预期输出:若干条候选,用 country 与 symbol 两列确认哪一条是你要的那只。
# 4) 先看列名,再决定用哪些字段 equities = fd.Equities().select(country="United States") print(equities.columns.tolist())
预期输出:返回列名清单。把它当成本页所有筛选的"字典"——你想用来筛选的字段,必须出现在这张列表里,否则说明它不在本库的元数据范围内。
# 5) 把筛选结果落盘,并记下筛选口径
import csv
equities.to_csv("universe.csv", index=False)
print("rows:", len(equities))预期输出:当前目录下多出一个 CSV 文件,终端打印出行数。这一步看起来不起眼,但它把「我当时的筛选口径」固定了下来——过一两周回头看,你还能知道这份清单是用什么条件、在哪一天跑出来的。
这是筛选环节最花时间的一类问题:不报错、不警告,只给你一张空表。下面这七种情况,排查顺序从上到下。
| 你以为 | 实际发生 | 怎么确认 | 注意点 |
|---|---|---|---|
| 条件写错了会报错提醒我 | 多数情况不报错,直接返回空 DataFrame | 每步都打印 len(df) 与 df.columns | 空结果是最"看起来正常"的异常,别只看有没有抛异常 |
| 国家名的几种写法都等价 | 取值必须与数据源里的写法一致,否则匹配不到 | 先用一只已知证券反查它的 country 取值,再照抄 | 以返回数据为准,不以常识或地图为准 |
| 多条件之间是"或"的关系 | 传入多个参数是同时满足(收敛),结果只会更少 | 一次只加一个条件,观察行数怎么变 | 条件越多越容易一次筛空,逐条加最省时间 |
| 行业名凭记忆拼一下就行 | 行业名常带连字符与空格,拼错就匹配不到 | 先用 search() 找到一只样本,再抄它的 industry | 宁可抄,不要拼 |
| market_cap 是当前实时市值 | 它是规模档位字段,且可能滞后于当前市值 | 与行情源里的当前市值做一次对照 | 用档位做粗筛可以,用它做精细判断要复核时效 |
| 筛不到就是"库里没有这只证券" | 也可能只是名称写法不同,或上游暂时不可达 | 换写法、换参数再查一次,并确认网络能访问上游 | 先排除写法与网络问题,再下"没有"的结论 |
| 筛出来的清单可以直接算收益 | 结果只有代码与元数据,没有任何价格字段 | 看返回列里是否存在价格类字段 | 价格必须另接行情源,本库不提供 |
筛选只是起步。下面这四步把"筛出一批代码"变成"一份能直接拿去接着用的清单",每步都写了预期输出,也标了在 FinanceDatabase 里这一步该看什么。
跑一次不传参数的全量查询,打印 df.columns.tolist()。预期的是一份列名清单;如果你的筛选维度不在里面,就说明这个维度要靠别的工具补,别在这里硬凑。
挑一只你熟悉的证券,用 search() 查出来,把它的 country、sector、industry 三个取值抄下来当条件。预期结果是条件写完后不再返回空表。
每次只加一个参数并 print(len(df))。预期输出是一条递减但非零的行数曲线;一旦掉到 0,说明刚加的那个条件写法有问题,回到上一步。
把结果存成 CSV,同时在脚本里写清筛选条件与执行日期。预期结果是别人拿到这份 CSV 也能复现你当时的筛选口径——这在数据会随时间变化时尤其重要。
| 拿到清单后你想做的事 | 下一步接什么 | 能直接拿到 | 拿不到 | 注意点 |
|---|---|---|---|---|
| 看价格走势与涨跌 | 各证券行情源 | 历史与当前价格 | — | 行情源与代码体系要能对上,先验一只再批量跑 |
| 算区间收益与波动率 | 行情源 + 计算脚本 | 收益率序列与统计量 | — | 复权口径、交易日历差异会直接影响结论 |
| 看财务指标 | 财务数据接口 | 财务三表与比率 | — | 本库不含财务指标,必须另接 |
| 做回测 | 回测框架 | 策略绩效指标 | — | 代码能对上,但行情与基准要自己准备 |
| 做行业横向比较 | 本库清单 + 财务或行情源 | 同行业可比公司名单 | — | 清单只能保证"同行业",可比性还要看规模与业务结构 |
| 做每日自动选股 | 本库 + 行情源 + 定时任务 | 每日候选池 | — | 本库只负责出池子,信号规则与调仓逻辑要自己定义 |
选型前先把"不能"看清楚。下面这些需求经常被误以为筛选能顺手解决,实际都得另接数据源。
| 你想做的事 | 能否用本库筛选完成 | 原因 | 替代路径 | 注意点 |
|---|---|---|---|---|
| 圈定某个国家、板块、行业的证券池 | 可以 | 这正是 Equities().select() 的设计用途 | — | 取值的写法要先核对 |
| 按市盈率、净资产收益率等财务指标筛 | 不可以 | 本库只存证券代码与元数据,不含财务指标 | 接财务数据接口后再本地过滤 | 两边的证券代码要先对齐 |
| 按均线、MACD 等技术指标筛 | 不可以 | 技术指标需要价格序列,本库没有价格 | 先取行情,再本地算指标过滤 | 指标口径要固定,否则每日结果会漂移 |
| 按当日涨幅、成交量筛 | 不可以 | 不含行情数据 | 行情源 + 本地过滤 | 注意行情源的延时与交易日历 |
| 算收益、回撤、夏普等绩效 | 不可以 | 绩效计算依赖价格序列 | 回测框架或绩效分析库 | 基准与无风险利率的口径要写清 |
| 搭建每日自动选股的候选池 | 可以出候选池 | 清单部分本库能提供,信号部分不能 | 本库 + 行情源 + 定时任务 | 本库只出池子,选股规则要自己定义并回测 |
| 用一句自然语言描述条件直接选股 | 不可以 | 本库是 Python 代码库,不是对话式接口 | 对话式工具或自建脚本 | 描述与代码的口径要能互相对照,否则结果无法复现 |
这些模式覆盖了大部分「先圈范围」的需求。每个模式都附了它不适合的场景,避免用错工具。在 FinanceDatabase 里,模式的差别其实就一句话:先确定市场与行业,再叠规模条件。计划把这套模式固化成脚本之前,先确认参数取值来自上游而不是凭记忆。
用 country 参数筛出某个市场的全部股票,作为后续研究的基础池。适合做单一市场的横向比较;想做跨市场对比时,记得分别建池,不要把两个市场的代码混在一张表里算。
用 industry 参数锁定细分行业,得到一组业务结构相近的标的,适合做行业内比较。注意行业分类是上游给定的,跨数据源的分类口径可能不同,换源后要重新核对名单。
用 search() 把公司名换成证券代码,这是接行情前必须走的一步。出现多条候选时,用国家与交易所字段确认目标,取错市场是后续数据全错的常见原因。
用 market_cap 把范围限制在大盘或小盘,适合先做一轮粗筛再叠加其他条件。档位是滞后字段,适合定方向,不适合做精细的规模排序。
把国家、板块、规模逐条加上去,每加一条看一眼行数。这个模式比一次写全所有条件更省排查时间,因为你能立刻知道是哪一条把结果筛没了。
把筛选结果存成 CSV 交给行情脚本或回测流程,是这套工具最典型的用法。导出时把筛选条件与日期一起记下来,否则过一段时间没人能复现这份清单。
下面每一条都给了判断标准,方便你在自己的脚本里对照检查,而不是只记住一句口号。
| 环节 | 建议 | 判断标准 | 注意点 |
|---|---|---|---|
| 取值核验 | 筛选前先用样本反查国家、板块、行业的确切写法 | 同一条条件重复跑两次结果一致 | 凭记忆写的取值是空表的主要来源 |
| 代码归属 | 同名代码要用国家与交易所字段区分 | 目标证券与所选记录的市场一致 | 不同市场的同名代码会让行情数据整体错位 |
| 条件收敛 | 逐条加条件,每加一条打印行数 | 行数递减但始终非零 | 一次写全条件出问题时很难定位是哪一条 |
| 字段时效 | 市值等字段视作快照,不当作实时值 | 与行情源的当前值做过一次对照 | 用于粗筛可以,用于精细判断要先复核 |
| 行情来源 | 拿到代码后另接行情或财务数据源 | 能按代码取到价格序列 | 本库不提供价格,这一步不能省 |
| 结果落盘 | 导出 CSV 并记录筛选条件与执行日期 | 别人能按记录复现同一份清单 | 数据会变,没有口径记录的清单过一段时间就失效 |
| 结果规模 | 先看行数再决定是抽样还是全量处理 | 下游脚本的处理能力覆盖得住 | 全量清单可能远超预期,落盘前先看行数 |
下表每一行都是 2026-09-29 在本机实跑的结果(financedatabase 2.4.0)。把它当参照系,可以快速判断自己的查询结果是否合理。
| 写法 | 实测命中行数 | 这类结果说明什么 |
|---|---|---|
不传任何参数(默认排除退市) | 102,314 | 默认口径,等于「在市标的」全集 |
不传参数且包含退市 | 112,718 | 把 10,404 行退市标的加回来后的全集 |
美国 + 信息技术 | 3,298 | 最常见的跨国+行业查询,量级合理 |
中国(排除退市) | 6,775 | country 是所属国家,不等于交易所在中国 |
中国 + only_primary_listing | 737 | 只剩 737 行,且几乎全是美国 OTC 代码——见下节 |
香港(排除退市) | 2,436 | 香港公司的清单,含在其它市场上市的条目 |
中国 + 香港 | 9,211 | 列表参数可传多个国家,按并集返回 |
中国 + 深交所代码 | 2,100 | 用 exchange 才能真正锁定 A 股板块 |
中国 + MIC=XSHG(上交所) | 1,523 | MIC 是 ISO 10383 代码,比 exchange 更规范 |
中国 + 人民币计价 | 3,553 | 按计价货币再收一次,可去掉海外上市的同名标的 |
中国 + Mega Cap | 38 | 6,775 行里只有 38 行是 Mega Cap 档 |
中国 + 公用事业 + Mega Cap | 0 | 合法条件但交集为空,返回空表而非报错 |
美国科技 + only_primary_listing | 1,253 | 美国标的同样被砍掉 62% |
0 行 不是报错——条件合法但交集为空时,select() 静默返回空表,不会抛异常;②only_primary_listing=True 那一行最能说明问题,细节见下一节。官方文档把 only_primary_listing 描述成「只看主上市」。实测下来,它的实现是剔除所有索引里带「点」的代码——而 A 股与港股的标准代码恰好全都带点,于是这条「去重」参数在中国股票上变成了反向筛选。
| 范围 | 不加该参数 | 加上该参数 | 被剔除比例 | 剩下的是什么 |
|---|---|---|---|---|
| 中国股票 | 6,775 行 | 737 行 | 89.1% | 几乎全是美国 OTC / 粉单代码,如 AACAF、AACG |
| 美国信息技术 | 3,298 行 | 1,253 行 | 62.0% | 不带点的本地代码(美股主板) |
exchange 或 mic 明确指定你要的市场(例如 exchange="SHZ" 得 2,100 行、mic="XSHG" 得 1,523 行),再结合 isin 或公司名做二次去重;不要指望 only_primary_listing 帮你完成这件事。search() 是类方法:先选类,再按列或索引匹配。下面每一条都是实跑出来的行为,其中前两条会返回全表而不是报错。
| 你写的 | 实测返回 | 原因 | 正确写法 |
|---|---|---|---|
equities.search(symbol="TSLA") | 112,718 行(全表),终端打印 symbol is not a valid column. | symbol 是索引不是列,条件被忽略 | equities.search(index="TSLA") |
equities.search(ticker="TSLA") | 112,718 行(全表),打印 ticker is not a valid column. | 列名写错只打印提示,不抛异常 | 先用 df.columns 确认真实列名 |
equities.search(index="0700") | 11 行 | 索引匹配是包含关系,不是精确相等 | 需要精确结果时配合 only_primary_listing 之外的过滤,或用 index=[...] 传列表 |
equities.search(index="tsla", case_sensitive=True) | 0 行 | 开启大小写敏感后小写查不到大写代码 | 默认的 case_sensitive=False 通常更省事 |
search() 之后先看 len(result)。如果行数等于该类全量,几乎可以肯定有一个条件被静默忽略了——这是本站实测里最容易自证错误的一个信号。常见参数有 country、sector、industry、market_cap,可以单独使用也可以组合使用。具体支持的参数与取值以官方 README 与 PyPI 页面为准;想确认某个字段能不能用来筛选,先打印返回结果的列名,再决定——列名是 FinanceDatabase 用起来最不费力的自检工具。
按名称模糊匹配,返回包含该名称片段的候选记录,因此一个关键词可能命中多条。匹配细节以官方实现为准;实际使用时建议配合 database 参数把范围限定在目标类别内。
不是。筛选返回的是证券代码与元数据(如名称、国家、行业、规模档位),不含任何价格字段。需要价格必须另接行情源,这一步本库不提供替代方案。
常见原因是取值写法与数据源不一致,或上游暂时不可达,而不是数据里真的没有。建议按「先核对取值写法、再确认网络与上游、最后才考虑确实没有」的顺序排查,具体可用取值以官方数据为准。
本库的数据覆盖以官方 README 声明为准,对 A 股的覆盖程度需要自己跑一次确认。如果目标是 A 股的行情与选股,本机已核验的财经数据类技能路线(如覆盖 A 股行情、问财选股方向的技能)是另一种选择,但要自行确认其数据源与授权前提。
不可以,清单里只有代码与元数据。要算收益、回撤或夏普,必须先把代码接到行情源取价格序列,再交给计算脚本或回测框架。代码与行情源的代码体系要先对齐,否则会出现取不到数据或取错标的的情况。