
这份2000-2022年上市公司对外开放程度数据包我前前后后用了差不多一个多星期才彻底吃透。最初拿到它是因为研究需要引入上市公司国际化程度的控制变量结果发现手头现有的数据库要么是截面数据要么区间对不上要么指标口径完全不是我想要的。后来找到这份资源它同时包含原始数据、计算代码和最终结果正好覆盖我需要的时间跨度解决了我最头疼的从哪拿数据怎么算出口占比这两大问题。简单介绍一下这份数据的价值它基于沪深A股上市公司公开披露的年报信息整理了2000年至2022年共23个年度的对外开放相关字段并通过统一的代码逻辑计算出了一个适合面板数据回归的对外开放程度指标。也就是说不管你是做公司金融、国际贸易与企业国际化研究还是写论文需要一个现成的企业层面开放度变量这份数据都可以直接接入。我后续会详细拆解它的构成、指标背后的度量逻辑、计算流程以及实际使用时容易踩的坑希望能帮你省下那些重复造轮子的时间。1. 这份数据包的真实构成先弄清楚里面有哪些东西拿到数据包第一步不是急着跑回归而是先把目录结构和字段搞清楚。很多朋友上来就merge结果变量对不上、年份不连续回头又找我排查其实都是忽略了文件设计逻辑。1.1 数据文件的组织方式与使用逻辑整个数据包解压后大致是这么几个部分目录/文件内容说明使用阶段原始数据/上市公司基础财务数据、分地区收入数据原始导出文件数据清洗与核验计算代码/包含Stata和Python两个版本的计算脚本自行复现时直接运行结果数据/清洗合并后生成的面板数据文件dta/csv实证回归时直接读取它把文件按输入-处理-输出三层展开这一点对我这种喜欢验证每一步逻辑的人来说非常友好。我能先看原始数据长什么样再跑一遍代码最后对照结果数据是否一致整个流程是可审计的。这里要提醒一句不要只看最终结果文件就直接写回归代码至少花半小时把原始数据里的缺失模式和年份覆盖情况摸清楚。因为结果数据中的缺失值大量来自早期年份上市公司信息披露不完整这个背景信息会直接影响你后续做描述性统计时对样本量的判断。我刚开始没注意结果跑最小二乘回归时一次性丢掉了近两成样本折腾了半天才意识到问题不在模型而在数据筛选。1.2 对外开放程度的具体指标口径与字段解释数据中的核心变量是foc_d_i对外开放程度综合指标和几个辅助变量。其中最重要的基础指标是境外收入占营业总收入的比例再结合是否具有境外业务虚拟变量以及外资持股比例做交叉补全。具体关键字段如下stkcd股票代码用于与CSMAR、Wind等其他数据集匹配year会计年度覆盖2000-2022foc_revenue_ratio境外收入占比取值为0-1foc_dummy是否有境外业务1为有0为无foc_foreign_share外资持股比例来自前十大股东中境外法人或自然人持股合计foc_d_i对外开放程度综合得分范围0-100用于回归分析我在实际做论文回归时直接使用foc_d_i作为被解释变量或解释变量都没有问题。不过要注意不同指标的分布差异很大。比如早期2000到2005年foc_revenue_ratio的缺失率可能超过40%因为当时有不少公司只披露境内收入没单独拆分海外部分。如果你直接删掉缺失值样本就会明显向大型出口企业倾斜产生样本选择偏误。这一点在后文我会专门讲处理策略。2. 对外开放程度的度量逻辑为什么是这套指标而不是别的方法很多人会用出口额占营业收入比重来代表企业对外开放程度这个思路没有错但它只覆盖了出口这一个维度。数据包中的综合指标其实重新定义了度量框架需要理解背后的逻辑。2.1 主流测量方法的三种思路对比学术界对企业对外开放程度的量化大体可以归为三种路径出口强度法用境外收入/出口额占营业总收入的比重来衡量。优点是数据容易获取上市公司年报基本都会披露分地区收入缺点是忽略了很多仅有非出口形式国际化经营的企业比如境外子公司、技术授权、跨国并购等。国际化深度法参考国际化深度指标即海外子公司数量、海外资产占比、海外雇员占比等。理论上最能反映企业融入全球市场的真实深度但问题是数据极难获取尤其是2000-2010年的披露很不规范手工搜集成本极高。综合评分法将多种原始信息统一标准化后合成综合指标。样本覆盖面更广兼顾了企业出口行为和外资参与度同时缓解了单一指标口径过窄的问题。这份数据包采用的是第三条路径的简化和优化版核心逻辑是境外收入占比作为连续变量保留如果该值缺失但公司在年报中明确提到有境外业务比如境外子公司收入或以分地区披露但未列金额则用foc_dummy和外资持股等辅助信息插补最终形成**主指标foc_revenue_ratio辅助指标foc_dummy综合指标foc_d_i**三层结构既照顾了数据连续性又不牺牲指标解释力。2.2 选取综合指标的依据与边界条件综合指标foc_d_i的计算方式实际上是先对foc_revenue_ratio进行95%分位缩尾处理再进行极差标准化将其转换为0-100的数值同时引入两个微调项一是如果企业当年聘用了境外高管或存在境外直接投资加5分二是如果企业完全没有境外业务则直接记为0分。这个设计有个很明显的优势它区分了没披露和确实没有境外业务这两种不同状态。如果是纯粹用境外收入占比没披露和等于0在数据里长一个样但经济含义完全不同。综合指标则可以通过foc_dummy把披露了但没有境外业务的企业正确归零防止下拉缺失值造成假零值。边界条件是这套指标只在上市公司层面有效不适用于非上市公司或金融行业银行保险类公司的对外开放逻辑与非金融企业差异太大。如果你用的时候恰好把金融类公司放进样本建议直接剔掉或者单独做稳健性检验。我个人的习惯是全样本跑一次剔除金融业再跑一次对比系数方向与显著性是否一致一致才敢往下写。3. 从枯燥的年报数据到最终指标核心计算流程全拆解这一节是数据包的核心价值所在也是我花时间最多的部分。很多人手里有原始数据但不会算卡在第二步处理。数据包自带的代码实现了整套清洗、合并和计算逻辑我在此把关键步骤逐一拆开讲一遍。3.1 原始数据导入与清洗的关键操作首先一定要把股票代码统一格式。CSMAR导出的股票代码有时是纯数字有时带后缀比如600519.SHWind的格式又不一样。代码里用了格式统一函数这在合并多个数据源时非常必要。输入数据需要做五个关键处理按顺序分别为将财务数据和分地区收入数据分别导入统一日期格式对股票代码做标准化处理删除字母后缀仅保留6位数字代码剔除2000年之前上市的公司非必须看研究设计剔除ST及退市公司样本回归时通常剔除按照stkcd和year唯一标识去重保留首次出现值有些公司的年报会对应两个不同的数据库记录比如注册资本变更后乱入一条重复记录不去重会导致多对多合并你的样本量会莫名其妙翻倍。不少朋友遇到合并后样本量远超实际公司数量的情况原因就在这里。3.2 对外开放程度指标的代码实现我用Stata和Python分别跑过这套逻辑核心代码逻辑是相通的。以下是Stata版本中计算境外收入占比的核心部分* 以stock code和year为唯一匹配键合并财务数据与收入明细 merge 1:1 stkcd year using foreign_revenue_data.dta * 剔除没有匹配上的非上市公司数据 keep if _merge 3 * 生成对外开放程度基础指标境外收入/营业总收入 gen foc_revenue_ratio foreign_revenue / total_revenue if ...... replace foc_revenue_ratio 0 if foc_revenue_ratio . foreign_revenue 0 * 生成是否存在境外业务虚拟变量 gen foc_dummy (foc_revenue_ratio 0) if foc_revenue_ratio ! . replace foc_dummy 1 if ......Python版本逻辑也是如此我用pandas的merge加上groupby操作实现同样结果import pandas as pd import numpy as np # 数据读取与合并 fina pd.read_csv(fina_data.csv, dtype{stkcd: str}) foreign pd.read_csv(foreign_revenue.csv, dtype{stkcd: str}) # 关键匹配键为股票代码年份 df pd.merge(fina, foreign, on[stkcd, year], howinner) # 计算对外开放程度基础指标 df[foc_revenue_ratio] df[foreign_revenue] / df[total_revenue] df[foc_revenue_ratio] df[foc_revenue_ratio].replace([np.inf, -np.inf], np.nan) # 缺失值处理境外收入为0时比值直接赋0 df.loc[df[foreign_revenue].fillna(0) 0, foc_revenue_ratio] 0注意一点merge之前最好用df[stkcd].str.zfill(6)把股票代码统一补到6位数字否则000001和1会被当成两个不同的公司这是我早期吃过亏的地方。3.3 数据质量核验怎么确认算出来的结果是对的代码跑完不等于数据可靠关键要核验。数据包附带了一段质量核验脚本它的逻辑就是对照原始年报公开数据随机抽样验证。具体核验方法我建议分三步第一步核对总样本量。2000-2022年A股上市公司累计大概在5000家左右如果你算出来只有2000条说明合并逻辑丢了大量样本如果超过8000条则可能存在重复匹配或合并键设错。第二步抽查特定公司年度值。比如你知道某公司在某年境外收入占比大概是多少就直接筛选它的记录看代码值是否一致误差超过0.01就要回头检查计算逻辑。第三步看变量分布。foc_revenue_ratio的分布应呈右偏态即在0附近集中尾部逐步减少。如果大量企业等于1或者整体均匀分布大概率是数据处理出了问题。数据包很贴心地把校验结果也附在了文件里你可以直接对比自己跑出来的结果与原始结果文件是否完全一致。如果一致说明复现成功。4. 用这套数据做实证研究适用场景与最容易踩的坑数据本身是死工具怎么用出价值才是关键。这一节我结合自己做实证的经验总结这套数据在主流量化研究里的典型应用方式以及实际跑数据时最容易遇到的那些问题。4.1 适合延伸的研究方向与常见模型对外开放程度在企业金融和公司治理研究中的使用频率很高常见的有以下几类对外开放与企业绩效以foc_d_i为核心解释变量研究它对企业全要素生产率、利润率或股价表现的影响。样本区间正好覆盖中国加入世贸组织前后的关键时间段有较强的政策含义但这个话题要注意避免涉及时政讨论。数字化与企业国际化用数字化转型指数与对外开放程度做交互项检验数字化能力对海外市场拓展的放大效应。我最近就在做这个方向。ESG表现与国际化经营对外开放程度作为调节变量或分组变量观察企业环境、社会与治理表现在不同国际化水平下的定价差异。在模型设定上因为对外开放程度是典型的公司层面特征变量基本都用面板固定效应模型控制公司与年份固定效应标准误聚类到公司层面。可以参考以下Stata结构xtset stkcd year xtreg y foc_d_i x1 x2 i.year, fe vce(cluster stkcd)在Python中用linearmodels包也能实现类似操作核心原则是企业和年份双向固定效应不能省否则估计系数会被遗漏变量严重干扰。4.2 缺失值、极端值与样本选择处理经验分享这套数据最大的坑集中在缺失值处理上。前面提过2000-2005年境外收入披露不全早期缺失率明显偏高。很多人直接丢掉缺失值结果样本严重偏向了那些规模大、国际化程度高的企业。我的经验做法是缺失但明确提到境外业务先用foc_dummy标为1再用行业同年度平均值插补foc_revenue_ratio这样可以保留样本量又不至于把缺失值当成0。完全不披露分地区收入如果公司年报中连分地区信息都没有大概率境外业务占比极低。可以稳健性检验中用0填充。极端值处理foc_revenue_ratio小于0或大于1的异常值直接删除大于0.9的做缩尾处理到95%分位数。如果不对极端值做处理回归系数会被少数超高国际化企业严重影响。因为早期数据含有大量0值我建议在回归中额外控制一个是否披露境外收入的虚拟变量这样能把真正的0和缺失填补的0区分开减少估计偏误。这个细节很多文献里不提但在审稿人眼中是加分项。4.3 稳健性检验的替代指标建议如果能拿到不同口径的数据强烈建议换指标做一套稳健性检验。除了数据包里的foc_revenue_ratio还可以尝试用境外所得税占比反推收入结构部分企业会在报表附注中披露境外分支机构的所得税贡献这是很好的替代数据。用海外子公司数量可以通过企查查或年报关联交易列表手工构建。虽然工作量较大但样本如果有500家以上足以支撑子样本检验。用外币收入折算比例部分上市公司会用不同币种披露收入结构这项数据可以用来构造连续型的国际化深度指标。我自己的经验是主回归用foc_d_i稳健性检验换foc_revenue_ratio和foc_dummy三个指标结果方向一致审稿人那边基本不会在这个环节刁难你。5. 最后聊聊我在实际操作中的几点体会这套数据真正帮我省下的不只是整理时间更是对对外开放程度这个看似简单概念的重新理解。没有哪个指标是完美的境外收入占比简洁但遗漏了国际化深度综合评分全面但解释稍弱。数据包把两种思路都做出来了让研究者可以根据自己的场景灵活选择。有两个小技巧算是我自己趟出来的经验分享一下。第一个是关于代码的可复现性。拿到数据后别急着跑结果先修改路径设置保证原始数据、代码和结果三个文件夹的相对路径不出错。我建议直接把整个文件夹放到一个固定的项目目录里并在代码开头用cd或设置干净的工作目录。否则改一次路径就要改几十个地方很容易出错。第二个是关于数据的分年使用。2000到2005年数据质量相对弱近年来质量明显提升。如果你的研究不涉及早期阶段建议直接使用2010年之后的子样本数据完整度会高很多。如果需要全样本建议在回归中加入年份固定效应和分行业趋势项用来吸收早期信息披露质量差异带来的系统性影响。另外提醒一句数据包中的foc_d_i是标准化后的综合得分它的大小只在相对意义上可比不能直接解读为对外开放程度的绝对水平。在论文写作时最好说明指标是经过标准化处理的这样读者才不至于误解数值的含义。最后说一句如果做论文用这份数据引用或致谢时最好注明数据来源和计算逻辑既是对数据整理者的尊重也方便其他研究者复核结果。数据整理不易且用且珍惜。