问题描述
以市销率为例,虽然查询到了聚宽平台市销率的计算公式:市销率TTM=(股票在指定交易日期的收盘价 当日人民币外汇牌价 截至当日公司总股本)/营业总收入TTM,但是还是不太理解,如当7月上旬中报数据还未出来,分母营业收入是采用的什么时期的数据,才一季报到中报是在哪个时点过渡的?
另外查询了和Wind的差异还是蛮大的,哪位大神可以解释一下吗?
解决方案
在 JoinQuant(聚宽)平台上进行量化回测时,财务数据和估值因子的准确性至关重要。针对您提出的关于市销率(PS_TTM)计算、未来函数以及与 Wind 数据差异的问题,以下是详细的解答:
1. 是否存在未来函数?
结论:只要正确使用 API,不存在未来函数。
在 JoinQuant 中,获取财务数据和估值数据通常使用 get_fundamentals(query, date) 函数。官方文档明确指出:
- 当传入
date参数时,系统会查询指定日期收盘后所能看到的最近的数据。 - 系统严格按照上市公司的**实际公告日期(Point in Time)**来匹配数据。这意味着,如果某公司在 8 月 15 日发布中报,那么在 8 月 14 日及之前的
date查询时,系统绝对不会提前使用中报的数据,而是继续使用一季报的数据。 - 因此,只要您在回测中按
date(通常是context.current_dt的前一天)查询,就不会引入未来函数。
2. 7月上旬中报未出时,分母(营业收入TTM)是如何取值的?何时过渡?
TTM(Trailing Twelve Months,滚动十二个月)的计算逻辑:
TTM 数据表示的是距离查询日期最近的连续 12 个月的财务数据。其标准计算公式通常为:
本期 TTM = 本期累计数据 + 上年年报数据 - 上年同期累计数据
具体到您的场景(7月上旬,中报未出):
- 取值时期:此时能看到的最新财报是一季报(Q1)。因此,营业收入 TTM 的计算方式为:
今年一季报营业收入 + 去年年报营业收入 - 去年一季报营业收入。这实际上代表了去年二季度到今年一季度的连续 12 个月的营业收入。 - 过渡时点:数据的过渡不是按自然月份划分的,而是严格按照该公司的“实际财报公告日”。如果该公司在 8 月 20 日晚间发布了中报,那么在 8 月 21 日的查询中,分母就会自动切换为基于中报计算的 TTM(即:
今年中报营业收入 + 去年年报营业收入 - 去年中报营业收入)。
3. 为什么和 Wind 的数据差异蛮大?
JoinQuant 与 Wind 等专业金融终端在某些估值因子上存在差异是正常的,主要由以下几个底层处理逻辑的不同导致:
- 总股本的取值时点不同:
- JoinQuant 的公式中明确写道:“截至当日公司总股本”。这意味着分子使用的是查询日当天的实际总股本(包含了期间可能的增发、配股等变动)。
- Wind 在某些默认视图下,可能会使用财报期末的总股本,或者采用不同的加权平均股本算法。
- 财报公告日的认定微调:
- 对于盘后或非交易日发布的财报,不同数据库对“生效日”的认定可能相差 1 个交易日。这会导致在财报发布窗口期,两边取到的 TTM 基础数据不同。
- 追溯调整的处理(Point in Time vs 追溯后):
- 上市公司经常会对历史财报进行追溯调整(例如会计准则变更、并购重组)。JoinQuant 为了量化回测的真实性,通常提供的是当时历史时点真实披露的数据(PIT 数据)。
- Wind 的某些界面默认展示的可能是追溯调整后的数据。用追溯后的数据计算历史 TTM,自然会与当时真实看到的 TTM 产生差异。
- 汇率取值标准:
- 对于 B 股或涉及外币的财务报表,外汇牌价的取值时间点(中间价、收盘价)不同平台也可能存在细微差别。
总结建议:
在量化回测中,逻辑的一致性和无未来函数比绝对数值与某个终端完全一致更重要。JoinQuant 的 PIT(Point in Time)架构正是为了保证回测的严谨性。如果您需要验证,可以尝试使用 get_fundamentals 提取特定日期的底层财务科目(如 operating_revenue),手动计算一次 TTM,即可清晰掌握平台的计算脉络。