惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Securelist
C
Cybersecurity and Infrastructure Security Agency CISA
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
S
Security Affairs
Hacker News: Ask HN
Hacker News: Ask HN
L
Lohrmann on Cybersecurity
PCI Perspectives
PCI Perspectives
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cyber Attacks, Cyber Crime and Cyber Security
Recent Commits to openclaw:main
Recent Commits to openclaw:main
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
MyScale Blog
MyScale Blog
月光博客
月光博客
W
WeLiveSecurity
T
Threat Research - Cisco Blogs
Martin Fowler
Martin Fowler
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Recorded Future
Recorded Future
The GitHub Blog
The GitHub Blog
Webroot Blog
Webroot Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
TaoSecurity Blog
TaoSecurity Blog
P
Proofpoint News Feed
Google DeepMind News
Google DeepMind News
F
Full Disclosure
U
Unit 42
Jina AI
Jina AI
博客园 - 司徒正美
阮一峰的网络日志
阮一峰的网络日志
L
LINUX DO - 最新话题
宝玉的分享
宝玉的分享
大猫的无限游戏
大猫的无限游戏
The Hacker News
The Hacker News
The Last Watchdog
The Last Watchdog
T
Troy Hunt's Blog
腾讯CDC
T
Threatpost
H
Hacker News: Front Page
P
Palo Alto Networks Blog
博客园 - 聂微东
Last Week in AI
Last Week in AI
有赞技术团队
有赞技术团队
Help Net Security
Help Net Security
L
LINUX DO - 热门话题
N
News and Events Feed by Topic
人人都是产品经理
人人都是产品经理
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Spread Privacy
Spread Privacy

土法炼钢兴趣小组的算法知识备份

国密算法与国密 TLS 系列索引 【系统架构设计】架构质量属性:不只是"高可用高性能" 【系统架构设计百科】告警策略:如何避免"狼来了" 【系统架构设计】CQRS:读写分离的架构哲学 【系统架构设计】空间架构:极端扩展场景的解法 【系统架构设计】微服务架构深度审视:优势、代价与适用边界 【系统架构设计】扩展性原理:水平、垂直与对角扩展 【系统架构设计】无状态设计:扩展的第一步也是最难的一步 【系统架构设计】缓存架构:从本地到分布式的多级缓存体系 【系统架构设计】管道与过滤器:Unix 哲学的架构表达 【系统架构设计】复杂性管理:架构的核心战场 【系统架构设计】消息队列架构:异步解耦的设计与陷阱 【系统架构设计】CDN 架构:全球加速的设计原理 【系统架构设计】连接池设计:被忽视的性能杀手 【系统架构设计】弹性设计模式:熔断器、舱壁与超时 【系统架构设计】高可用设计模式:冗余、故障转移与仲裁 【系统架构设计】容量规划:从拍脑袋到数据驱动 【系统架构设计】数据库扩展:分库分表的工程实践与替代方案 【系统架构设计】SLO 工程:可靠性的量化管理 【系统架构设计】性能建模:用数学思维分析系统瓶颈 【系统架构设计】混沌工程:主动验证系统的韧性 【系统架构设计】零拷贝与内存映射:数据搬运的极致优化 【系统架构设计】线程模型:从 thread-per-request 到协程 【系统架构设计】容灾架构:多活与灾备设计 【系统架构设计】数据库性能模式:索引、查询与连接管理 【系统架构设计】数据建模:从关系范式到文档模型的真实权衡 【系统架构设计】吞吐量优化:批处理、流水线与并发模型 【系统架构设计】流处理架构:从批处理到实时的范式迁移 【系统架构设计】搜索引擎架构:倒排索引之上的系统设计 【系统架构设计】时序数据架构:监控与 IoT 的存储设计 【系统架构设计】数据迁移与版本化:在线不停机的数据演进 【系统架构设计】数据湖与数据仓库:分析架构的演进路线 【系统架构设计】API 网关设计:入口层的职责边界 【系统架构设计】应用层数据一致性模式:在正确性与性能之间走钢丝 【系统架构设计】多模数据库选型:Polyglot Persistence 的工程实践 【系统架构设计】服务发现与注册:动态拓扑的基础设施 【系统架构设计】配置管理架构:从配置文件到配置中心 【系统架构设计】全链路压测:大规模系统的性能验证 【系统架构设计】幂等性设计:分布式环境下的安全重试 【系统架构设计】契约测试与 Schema 演进:服务间的信任协议 【系统架构设计】长连接与推送架构:WebSocket、SSE 与 MQTT 【系统架构设计】延迟分析:从 P50 到 P999 的全链路追踪 【系统架构设计百科】DDD 战术模式:聚合、实体与值对象 【系统架构设计百科】防腐层与开放主机服务:系统集成的 DDD 方案 【系统架构设计百科】领域事件与事件风暴:从业务到架构的桥梁 【系统架构设计百科】CQRS + Event Sourcing 完整实战:从领域建模到部署 【系统架构设计百科】DDD 与微服务:用领域模型划分服务边界 【系统架构设计】DDD 战略设计:限界上下文与上下文映射 【系统架构设计百科】认证架构:从 Session 到 JWT 到 OIDC 【系统架构设计】API 设计哲学:REST vs GraphQL vs gRPC 的真实权衡 排序算法专题:从 TimSort 到并行排序 【密码学百科】国密算法体系:SM2/SM3/SM4/SM9 全景解读 【密码学百科】承诺方案:Pedersen 承诺、向量承诺与多项式承诺 【密码学百科】不经意传输与隐私信息检索:OT、OT 扩展与 PIR 【密码学百科】门限密码学:门限签名、门限解密与分布式密钥生成 完美哈希:从理论到 gperf 实践 【密码学百科】安全多方计算:从 Yao 的混淆电路到实用 MPC 【密码学百科】同态加密:从 Paillier 到全同态加密(FHE) 【密码学百科】零知识证明系统:zk-SNARKs、zk-STARKs 与 Bulletproofs 【密码学百科】概率论与密码分析:生日攻击、差分分析与线性分析 【密码学百科】计算复杂性与归约:密码安全性证明的基石 【密码学百科】秘密共享:Shamir 方案、VSS 与安全多方计算入口 【密码学百科】椭圆曲线代数:Weierstrass 方程、点群运算与曲线选择 【密码学百科】离散对数与配对密码学:从 DLP 到 BLS 签名 【密码学百科】格密码数学基础:SVP、LWE 与格基约化 【密码学百科】抽象代数:群、环、域的密码学视角 【密码学百科】有限域算术:GF(2^n) 运算与在 AES/ECC 中的应用 【密码学百科】数论进阶:二次剩余、椭圆曲线上的 Weil 配对 【密码学百科】密码学简史:从凯撒密码到量子时代 【密码学百科】威胁模型与安全目标:CIA 三要素之外 【密码学百科】Kerckhoffs 原则与现代密码设计哲学 【密码学百科】随机性:密码学的基石 【密码学百科】信息论入门:熵、完美保密与 Shannon 定理 【密码学百科】分组密码原理:Feistel 网络与 SPN 结构 【密码学百科】AES 逐步拆解:SubBytes 到 MixColumns 的数学 【密码学百科】分组密码工作模式全览:ECB/CBC/CTR/OFB/CFB 【密码学百科】流密码:RC4 的兴衰与 ChaCha20 的崛起 【密码学百科】密码学哈希函数:MD5→SHA-2→SHA-3 的进化之路 【密码学百科】MAC 与 HMAC:消息认证的正确姿势 【密码学百科】认证加密(AEAD):GCM、ChaCha20-Poly1305 与 OCB 【密码学百科】密钥派生函数:HKDF、PBKDF2、Argon2 与密码存储 【密码学百科】公钥密码的数论基础:模运算、群、原根 【密码学百科】RSA 从原理到攻击:教科书 RSA 为什么不安全 【密码学百科】Diffie-Hellman 密钥交换与离散对数问题 【密码学百科】椭圆曲线密码学(ECC):从几何直觉到点群运算 【密码学百科】数字签名:ECDSA、EdDSA 与 Schnorr 签名 【密码学百科】现代密钥交换:X25519、ECDHE 与前向保密 【密码学百科】混合加密与 KEM/DEM 范式:ECIES 与 HPKE 【密码学百科】填充方案:PKCS#1 v1.5、OAEP 与 PSS 【密码学百科】TLS 协议全解析:从握手到 0-RTT 【密码学百科】PKI 与数字证书:信任链的构建与崩塌 【密码学百科】密码认证协议:从 SRP 到 OPAQUE 【密码学百科】零知识证明入门:如何证明你知道而不泄露 【密码学百科】安全信道构造:Noise 协议框架与 Signal 协议 【密码学百科】密钥管理工程:HSM、KMS 与密钥生命周期 【密码学百科】侧信道攻击:从时序攻击到功耗分析 【密码学百科】密码学实现陷阱:三层漏洞分类、审计工具链与系统性预防 密码敏捷性:如何设计可升级的密码系统 【密码学百科】OpenSSL/BoringSSL 架构剖析:ENGINE、Provider 与 FIPS 模块 排序基准测试:用数据说话
【量化交易】另类数据:新闻、舆情、链上数据、卫星图
2026-05-01 · via 土法炼钢兴趣小组的算法知识备份

传统量化研究的输入是行情和基本面:日 K、Tick、财报、宏观。这些数据有一个共同点——它们以监管机构和交易所规定的节奏被批量发布,所有人同时拿到,价格里早就反映了一遍又一遍。真正难赚的钱,不在”今天的收盘价”里,而在那些没有被定价完整的角落:一篇刚刚挂在公司官网的招聘公告、一艘油轮在霍尔木兹海峡掉头、Tether 凌晨在 Tron 链上增发两亿、一家连锁零售公司停车场卫星图同比少了 30% 的车流。

这一类不来自交易所、不来自财报系统、需要自己动手才能拿到、并且常常带着合规和工程双重门槛的数据,业内统称为另类数据(Alternative Data,简称 Alt Data)。它和传统数据不是替代关系,而是补充关系:另类数据通常颗粒度细、时效性高、覆盖窄、噪声大、成本高、合规复杂;传统数据正相反。把另类数据用好,需要先承认这个事实,再围绕它设计采集、清洗、对齐、版本化的全套工程体系。

这一篇要讨论的就是这一整条战线。范围限定在能在工程上落地的几类:新闻与舆情、社交媒体、卫星与物联网(IoT)、链上数据(On-Chain)、网页与电商爬取、信用卡与电子支付。每一类都会拆成三层来讲:数据本身长什么样、能从哪里拿、工程化时要注意什么。最后专门用一节讨论怎么把这些”形态各异”的数据,整合进与上一篇 《特征仓库与因子治理》 兼容的工业级特征库。

本文不构成投资建议;爬取与个人数据涉及法律边界,请自行评估。文中提到的所有数据源、商业产品、协议接口仅用于说明工程方案,不代表对任何具体厂商、平台、代币的推荐。所有代码段在 Python 3.11 + transformers 4.41 + web3.py 6.20 + pandas 2.2 下验证可运行,仅作演示用,不要在生产环境直接使用。


一、什么是另类数据

1.1 定义边界

工业界使用另类数据这个术语已经超过十年。这里采用一个对工程友好的定义:任何不通过交易所、监管机构、上市公司常规披露渠道直接获得的、需要二次采集或加工才能用于投资决策的数据。这个定义把握住了三个关键点:

  1. 来源在体系外。它不是 Tick、不是日线、不是季报、不是央行数据库的官方表格。
  2. 需要二次加工。原始形态多半不能直接送进因子矩阵。新闻是文本,卫星是图像,链上是字节码,需要中间一层把它转成时间序列或截面数据。
  3. 目的是投资决策。同样一份卫星图,地理学者用来研究城市化是研究数据,被对冲基金用来预测沃尔玛季度营收就是另类数据。

业内常见的细分维度有按主体(机构发布、用户生成、机器/传感器、链上、交易/支付)和按形态(文本、图像、地理位置、网络流量、链上事件)。这两套维度互不冲突,常常组合使用。本文采用前者作为主线,因为它直接对应不同的合规与工程模式。

另类数据分类树

图中下半部分的象限是工程化决策时的核心权衡:alpha 衰减半衰期(横轴)和获取成本/合规复杂度(纵轴)。象限的位置不是绝对的,而是当下市场的经验位置。新闻情感落在右上角是因为它早就被广泛使用、衰减很快,但获取容易;卫星停车场落在左下角是因为公开数据少,要么 Orbital Insight、Planet 这种厂商按月付费,要么自己买原始影像跑 CV 模型。

1.2 与传统数据的真正区别

把另类数据和传统数据并列起来比较,有几个差异是工程上必须正视的:

  • 时间戳的语义不同。日 K 的时间戳就是收盘那一刻;新闻的时间戳要区分发生时间、首次报道时间、首次进入数据源的时间、信号处理完成时间,这四个时间在 PIT 对齐时差别巨大。
  • 覆盖率残缺。Compustat 覆盖了几乎所有美股上市公司,而招聘数据可能只能覆盖到 LinkedIn 上挂职位的几千家公司,剩下的全是 NaN。模型必须能容忍稀疏样本。
  • 样本选择有偏。能被卫星拍到的停车场只有那些大型连锁的露天店;能被信用卡数据捕获的消费只是被特定收单机构清算的那部分;能在 WSB 被讨论的标的只有美国零售投资者关心的散户股。任何全市场推论都要警惕外推风险。
  • 结构不稳定。一家美国信用卡数据厂商可能在某个季度突然丢失某家银行的数据源,覆盖率从 12% 跌到 4%。链上数据每次硬分叉、每次 EIP 升级都可能改变事件的语义。研究者必须把”数据源结构变化”作为一阶问题来处理。
  • 法律风险显性。爬取个人数据、未授权访问数据库、违反平台 Robots、违反 GDPR/CCPA、违反《个人信息保护法》《数据安全法》,每一项都能直接带来法律责任。传统数据这块顶多是数据厂商的合同条款问题。

1.3 alpha 衰减是这一战线的核心规律

另类数据的一个朴素事实是:一类数据从被某只基金独家发现,到被大多数对冲基金都用上、再到散户产品都跟进,时间窗口极短。Eric Falkenstein 等人的实证研究、AQR 的多篇白皮书、López de Prado 在《Advances in Financial Machine Learning》里反复强调的一点是:alpha 不是凭空消失的,是被使用过程一点点磨平的。

新闻情感是衰减最经典的案例。RavenPack 在 2003 年前后开始商业化新闻情感数据,当时使用它的基金能拿到稳定的 IR;到 2015 年前后,几乎所有美股股票多空基金都接入了新闻情感数据,再加上 Twitter API 的开放,文本情感作为一个独立因子的 IR 已经接近 0.2 以下。今天还能从中赚钱的,要么是结合事件分类的细分用法(比如盈利预告、并购传闻、产能事件),要么是结合订单流的事件驱动短线策略,单独的”情感分加权多头”在大多数市场上已经不再赚钱。

链上数据是当下还在窗口期的代表。2018-2021 年间,Glassnode、CryptoQuant 把”交易所余额、巨鲸地址、稳定币流向”系列因子做成商业化产品,BitMEX 资金费率、Coinbase 溢价等结构化指标一度有显著的 alpha。今天币圈头部基金已经普遍使用,但因为 web3 数据对非加密圈仍有较高的认知门槛,相关因子在加密资产横截面上仍有可观的统计显著性。

理解 alpha 衰减的工程含义,是这一篇所有后续讨论的前提。新数据值得投入,但要把”数据源寿命”作为风险管理的一部分写进研究流程。

1.4 一条经验上的判别准则

并不是所有”听起来很另类”的数据都值得投入。判别一个新数据源是否值得做工程化,可以参考下面这条经验准则:先问四个问题。

  • 这份数据是否有清晰的”经济因果”链路连到价格?比如停车场车流到零售公司营收到毛利到股价,每一环都能解释。如果只能说”它和股价历史上相关性 0.3”,没有因果链路,大概率是噪声。
  • 这份数据的覆盖率是否随时间稳定?历史回测稳定不等于未来稳定,但历史不稳定的数据未来稳定的概率很低。
  • 数据采购或采集的边际成本是否可承受?把覆盖率再扩大 50% 需要多花多少钱、多招多少人。
  • 这份数据被同行用上之前还有多少时间?先发优势时间过短的数据,工程化投入往往收不回来。

四个问题至少要有三个明确”是”,再启动工程化。这个判别经验的依据是过去十年另类数据行业的整体落地率:上规模的产品里有大约一半在 12 个月内进入广泛使用并开始 alpha 衰减,大多数没有过这个判别的项目最终沦为”做了一份漂亮 PPT”的成本中心。


二、新闻与舆情

2.1 数据形态与时效

新闻这一类信号,从工程角度可以分成三层:

  • 官方公告。上市公司在交易所披露的临时公告、定期报告、问询函回复。A 股是巨潮资讯网(cninfo.com.cn)和上交所、深交所披露易;港股是 HKEX News;美股是 SEC EDGAR。这一层时间戳最权威,但内容滞后。
  • 新闻通讯社。彭博(Bloomberg)、路透(Reuters)、道琼斯通讯社(Dow Jones Newswire)、新华社、财联社、第一财经、华尔街见闻、雪球、东方财富网(东财)。这一层时间戳精确到秒,部分到毫秒,是真正可以做事件驱动短线的数据。
  • 二级转载与舆论。门户网站、自媒体、微信公众号、知乎、推特、雪球评论。这一层信噪比最差,但有时反映”市场关注度”这种弱信号。

时间戳处理是新闻数据工程化的第一道关。RavenPack 的字段中专门区分了 timestamp_TMSTAMP_UTCtimestamp_DETECTED_UTCtimestamp_RPNA_DATE_UTC,分别代表事件原始时间、被识别处理的时间、归档日期。研究时如果错把后者当作前者,回测里”我提前 10 分钟看到新闻”和”我落后 30 分钟看到新闻”的结果可以差出几十个 bp。

A 股语境下的几个常见时效陷阱:

  • 巨潮资讯发布与上交所/深交所披露易发布之间,存在分钟级延迟。
  • 财联社、华尔街见闻往往比官方公告早几分钟到十几分钟,但其消息真伪需要权衡。
  • 雪球用户评论早于新闻媒体的情况在小盘股上常见。这是市场关注度泄露,不是真正意义上的”提前知道”,回测时不要直接当作事前信号。

2.2 NLP 嵌入与中文情感打分

文本要变成能用的因子,最朴素的两步:分类与嵌入。

分类层面,业内做法有两种主流:基于关键词规则的快速判别、基于预训练模型的细分类。规则法适合”这是不是公告”、“这是不是关于新能源车”这种粗粒度问题,依赖人工词典维护;模型法适合细粒度的事件类型识别,比如把”盈利预告超预期 / 减持公告 / 关联交易”做成多分类。

嵌入层面,自从 BERT 出现,文本表示已经是把句子或者段落映射到一个向量。中文金融文本上常见的开源模型:

  • IDEA-CCNL/Erlangshen-Roberta-330M-Sentiment:中文情感分类的常用 baseline,三分类(正面/中性/负面)。
  • bardsai/finance-sentiment-zh-base:金融语料微调的中文情感模型。
  • FinBERT(中文版有多家社区版本):在金融文本上微调过,但样本规模和质量参差,自己跑评估再决定。

下面给出一段最小可运行的代码,用 transformers 跑批量中文新闻的情感分。这段代码不追求工程化,仅演示如何把一份新闻 DataFrame 转成情感时间序列:

import pandas as pd
import torch
from transformers import AutoTokenizer, AutoModelForSequenceClassification

MODEL = "IDEA-CCNL/Erlangshen-Roberta-330M-Sentiment"
device = "cuda" if torch.cuda.is_available() else "cpu"

tokenizer = AutoTokenizer.from_pretrained(MODEL)
model = AutoModelForSequenceClassification.from_pretrained(MODEL).to(device).eval()

LABELS = {0: "neg", 1: "neu", 2: "pos"}

@torch.no_grad()
def score_batch(texts, max_len=256, batch_size=32):
    """对一批中文文本计算情感概率。返回 DataFrame: [neg, neu, pos]。"""
    out = []
    for i in range(0, len(texts), batch_size):
        chunk = texts[i:i + batch_size]
        enc = tokenizer(
            chunk, return_tensors="pt", padding=True,
            truncation=True, max_length=max_len,
        ).to(device)
        logits = model(**enc).logits
        probs = torch.softmax(logits, dim=-1).cpu().numpy()
        out.append(probs)
    import numpy as np
    arr = np.concatenate(out, axis=0)
    return pd.DataFrame(arr, columns=["neg", "neu", "pos"])

def aggregate_to_daily(news_df: pd.DataFrame) -> pd.DataFrame:
    """
    news_df 必须包含: stock_id, ts (UTC timezone-aware), title, body
    返回按 (stock_id, date) 聚合的 sentiment 因子。
    """
    text = (news_df["title"].fillna("") + "。" + news_df["body"].fillna("")).tolist()
    scores = score_batch(text)
    df = pd.concat([news_df.reset_index(drop=True), scores], axis=1)

    # 关键: 用文章时间戳所属交易日,而不是入库日
    df["date"] = df["ts"].dt.tz_convert("Asia/Shanghai").dt.date

    agg = df.groupby(["stock_id", "date"]).agg(
        n_news=("title", "size"),
        sent=("pos", "mean"),
        sent_neg=("neg", "mean"),
        # 加权: 标题往往更具信号
        sent_w=("pos", lambda s: (s * (df.loc[s.index, "title"].str.len().clip(0, 64))).sum()
                / df.loc[s.index, "title"].str.len().clip(0, 64).sum().clip(min=1)),
    ).reset_index()
    return agg

这段代码的几个工程要点值得展开:

  • 文本截断到 256 token,是 BERT 系列模型的常用上限。中文新闻段落较长时建议先做摘要或抽首段。
  • 时区一定要显式处理。新闻时间戳来自不同源,常见时区有 UTC、America/New_York、Asia/Shanghai。错位会让一条夜里 22 点的财经快讯被算到第二天,错过一整天的事件驱动机会。
  • 聚合到日频再喂给因子模型只是最朴素的用法。事件驱动策略需要保留分钟级或 tick 级的时间戳,并和成交数据做事件研究(Event Study)对齐。
  • 上面的”加权情感”是用标题长度截断作为权重的简化版本。工业实现里常见的权重还包括:来源权威度(彭博 > 财联社 > 自媒体)、文章覆盖度(被多家媒体报道权重更高)、相关度(NER 抽取后判断主体是否真的是该公司)。

2.3 中文舆情的几个特殊性

A 股的舆情数据有一些和美股显著不同的点:

  • 散户驱动。雪球、东方财富股吧、淘股吧上散户讨论的密度远高于美股 Reddit。这部分内容信噪比低,但在小盘股上和情绪有真实相关。
  • 媒体生态分裂。财联社、华尔街见闻、第一财经走专业路线;微信公众号、抖音财经走流量路线。两类内容混合后必须先做来源加权。
  • 监管敏感。涉及监管处罚、问询函、立案的内容,关键词命中后必须高优处理。这类事件对小盘股的短期收益冲击远大于情感分本身。
  • 审查与删除。某些舆情数据存在事后被删除的可能,必须在采集时就保留原始 HTML 快照,不能依赖后续可重复访问。

工程实现上,建议把情感打分和事件分类做成两条独立的流水线。前者输出连续值,后者输出离散事件标签。最终因子可以是两者的组合:在没有事件触发时使用情感分平滑值;事件触发时切到事件因子。

2.4 事件研究的标准模板

新闻类因子真正能挖到 alpha 的地方,是事件研究(Event Study)。事件研究的标准模板可以归纳成下面几步:

  1. 事件标定。先根据规则或模型把每条新闻打成事件类型标签,例如:盈利预告超预期、并购公告、监管处罚、产能扩张、高管变动、回购公告、可转债公告、股东增减持。每个事件类型都要有清晰的纳入与排除规则。
  2. 事件窗与估计窗。事件窗(event window)通常是 \([-T_1, +T_2]\),比如 \([-1, +5]\) 个交易日;估计窗(estimation window)取事件前更长一段,比如 \([-120, -10]\),用于估计正常收益(normal return)的基准模型。
  3. 正常收益建模。最简单是市场模型:\(R_{i,t} = \alpha_i + \beta_i R_{m,t} + \varepsilon_{i,t}\),在估计窗内估出 \(\alpha, \beta\),再外推到事件窗。更精细的可以用 Fama-French 三因子或五因子。
  4. 异常收益与累积\(AR_{i,t} = R_{i,t} - \hat{R}_{i,t}\);累积异常收益(CAR)\(CAR_i = \sum_{t \in event} AR_{i,t}\)
  5. 统计检验。横截面 t 检验、Patell 标准化检验、BMP(Boehmer-Musumeci-Poulsen)检验都常用。要警惕事件聚集(cross-sectional dependence)导致的标准误低估。

A 股语境下,事件研究里几个经常踩坑的地方:

  • 停牌问题。重大事件公告往往伴随停牌,停牌期间的”收益”是 0 但其实信息没释放。事件窗要在停牌结束日之后重新计时。
  • 涨跌停限制。10% 涨跌停限制让事件冲击在单日不能完全释放,必须把事件窗拉长到涨停打开后一两日,否则会低估事件效应。
  • 披露时间。A 股公告允许在收盘后到次日开盘前披露,事件日的定义要明确是”公告日”还是”次一交易日”,两者对短窗 CAR 的结果差别很大。
  • 监管节点。问询函、立案调查这类负面事件常常引发交易所关注,伴随监管措施,二阶事件的效应需要单独剥离。

2.5 来源加权与时间衰减

实际生产中,单条新闻的情感分往往不直接喂给模型,而是先聚合成”过去 N 小时的滚动情感分”,并按下面两个权重做加权:

  • 来源权威度权重。彭博、路透、新华社、三大证券报、上市公司官方公告,权重最高;财联社、华尔街见闻、第一财经次之;自媒体、转载源更低。权重表需要人工维护,建议季度复核一次。
  • 时间衰减权重。新闻信息有半衰期,常用指数衰减:\(w_t = e^{-\lambda (t_0 - t)}\),其中 \(\lambda\) 由数据决定。短线策略 \(\lambda\) 可以让半衰期等于 30 分钟到 2 小时,事件驱动中线策略可以是 1 到 3 个交易日。
  • 去重权重。同一事件被多家媒体报道,权重不应线性叠加。常用做法是按 simhash 聚成同一事件簇,每簇内取代表权重最高的那条,其余权重折半。

下面这个函数把来源加权和时间衰减串起来,作为前面 aggregate_to_daily 的工业化版本:

import numpy as np
import pandas as pd

SOURCE_WEIGHT = {
    "bloomberg": 1.0, "reuters": 1.0, "xinhua": 0.9,
    "cs": 0.8, "stcn": 0.8, "cnstock": 0.8,
    "cls": 0.7, "wallstreetcn": 0.7, "yicai": 0.7,
    "xueqiu_official": 0.5, "weibo_finance": 0.4,
    "self_media": 0.3,
}

def rolling_sentiment(news_df: pd.DataFrame, half_life_hours: float = 6.0) -> pd.DataFrame:
    """
    news_df: 已经包含 [stock_id, ts(UTC), source, pos, neg, neu]
    输出: 每分钟一档的滚动情感分。
    """
    df = news_df.copy()
    df["sw"] = df["source"].map(SOURCE_WEIGHT).fillna(0.2)
    df["raw"] = df["pos"] - df["neg"]
    df = df.sort_values(["stock_id", "ts"])

    lam = np.log(2) / (half_life_hours * 3600)
    out = []
    for sid, g in df.groupby("stock_id"):
        ts = g["ts"].view("int64") // 10**9
        score = g["raw"].to_numpy() * g["sw"].to_numpy()
        # O(N) 指数加权前缀
        ema = np.zeros_like(score, dtype=float)
        prev_t = ts.iloc[0]; prev_v = 0.0
        for i, (t, s) in enumerate(zip(ts, score)):
            decay = np.exp(-lam * (t - prev_t)) if i > 0 else 1.0
            prev_v = prev_v * decay + s
            ema[i] = prev_v
            prev_t = t
        g = g.assign(ema=ema)
        out.append(g)
    return pd.concat(out, ignore_index=True)

这段实现的几个细节:

  • 使用 O(N) 指数加权而不是 O(N²) 的窗口求和,时间复杂度对实时流水线友好。
  • half_life_hours 是研究侧需要按策略调出来的超参,不是普适常数。
  • 来源权重表 SOURCE_WEIGHT 应该单独维护成 yaml 或数据库表,不要硬编码在代码里,方便不重启服务热更新。
  • 实际生产里还要叠加”主体相关度”过滤:一篇标题提了某只股票、正文却讲的是行业整体,对单标的的情感贡献应该折算。常见做法是用 NER + 共指消解判断该股票在文中的位置和频次,得到 relevance ∈ [0, 1],作为乘性权重接到 sw 之后。

2.6 中文金融文本上微调情感模型的几个建议

通用情感模型(Erlangshen、bge-zh、阿里通义、百度文心)在金融文本上常见的几类系统性误判:

  • 把”业绩超预期”判为中性。原因是通用语料里这种短语出现频率低,模型缺少先验。
  • 把”减持完毕”判为正面。原因是”完毕”这一类表”事情结束”的词在通用语料里偏正面。
  • 把”问询函”判为中性。监管事件需要专门标注。
  • 对”涨幅”、“跌幅”等数字敏感词的方向理解颠倒。

工程上修这类问题的标准做法是构造一份 5000-20000 条的金融文本人工标注数据,做 LoRA 或全参数微调。标注规范要把”情感”和”事件类别”分开两个字段,模型多任务训练。在中文金融语料上的实证,多任务 LoRA 比单任务全参微调收敛更快、过拟合更少。


三、社交媒体

3.1 Twitter(X)、Reddit、雪球的角色定位

社交媒体作为另类数据,本质是把”市场关注度”和”零售情绪”显式化。它的信号强度有两个上限:

第一个上限是参与人群。推特覆盖的金融讨论以美股为主,A 股极少;雪球、股吧覆盖 A 股;Reddit 的 r/wallstreetbets(WSB)覆盖美股散户;Discord 和 Telegram 是币圈的主战场。任何跨市场推论都要谨慎。

第二个上限是话题特性。社交媒体放大的是”易于传播的故事”,复杂业务、长周期投资、价值投资标的天然没声音。这些声音对应的可观测量级,主要是”meme 行情”——以 GameStop(GME)、AMC、BBBY 为代表的美股零售股逼空行情。

从因子化角度,社交媒体的可用信号有:

  • 提及频次(Mention Volume)。单位时间内某个 ticker 的出现次数。已知会有显著的横截面差异,但提前量很有限,多数信号和股价同步。
  • 提及变化率。比频次本身更具预测性,特别是在小盘股和高 retail share 标的上。
  • 情感倾向。短文本(推文 280 字)的情感打分噪声大,需要对具体语境定制模型,通用情感模型常常误判金融行话。
  • 参与者结构。新出现的账号 vs 老账号、关注者数量、过往发言准确率,可以做成账号信用分。

3.2 数据采购与采集的现实

2023 年 X(Twitter)API 改革后,免费层基本无法用于学术研究和商业研究。Basic 层 100 美元/月、Pro 层 5000 美元/月、Enterprise 层数万美元起。三方厂商如 Bright Data、Apify 提供爬取服务,但合规风险由使用方承担。学术研究领域的 Decahose 也已经停止。这导致 2023 年之后的 Twitter 数据可得性比 2020 年差了一个数量级。

Reddit 通过 Pushshift 历史归档曾是最大的开放数据源,2023 年 Reddit 收紧 API 后 Pushshift 公共服务关停,目前只有 academictorrents 上的旧归档可用,新数据需要自己通过 Reddit API(按调用付费)抓。

雪球的开放程度低于美国同类平台,没有官方 API。研究者通常通过爬虫采集,但需要注意《雪球用户协议》《数据安全法》《个人信息保护法》对个人发表内容的合规要求。雪球用户的发帖历史属于”用户公开发布的信息”,对其做聚合统计的法律边界相对清晰;但批量获取、转售、用于个人 ID 画像则越界。

工程化采集时,下面几条是底线:

  • 严格遵守 Robots 协议。
  • 控制速率,避免对目标站点造成可观测的额外负载。
  • 不绕过登录墙、不破解付费墙、不规避反爬措施到法律意义上的”擅自侵入”程度。
  • 不存储个人身份信息(PII);如果必须存储 user_id,做单向哈希。
  • 数据用途限定在内部研究,不转售。

3.3 meme 行情的统计特征

GameStop 在 2021 年 1 月 27 日的逼空把”meme 行情”这个概念推到了所有量化研究者面前。事后多篇论文(如 Pedersen 2022、van der Beck & Jaunin 2021)整理出了几个稳定的统计特征:

  • 零售订单流是核心驱动。Robinhood 上的零售净流入和股价变化的同步相关达到 0.6 以上。
  • 提及量先于交易量。WSB 提及量在事件爆发前 1-3 天会出现明显异常,但这个异常不一定能转化为可交易的 alpha,因为入场点的选择决定了最终盈亏。
  • 空头利益(Short Interest)占自由流通股本的比例是 meme 候选标的的硬筛选条件。GME、AMC 当时分别在 100% 和 80% 以上。
  • 逼空行情的尾部远超正态。GME 在 2021 年 1 月 27 日单日上涨 134%。任何基于正态分布的风控都会在这种行情下失效。

把这些做成因子并不难,难的是把它做成风险管理工具而不是 alpha 来源——因为 meme 标的本身的容量极小,空头一旦被卷入,损失可以是无限的。Melvin Capital 的清盘是最直接的反面教材。

3.4 一个实用的简化指标

下面给一个最简的”市场关注度异常”指标,核心思路是把单日提及量除以过去 N 日的均值,再做对数化处理:

import numpy as np
import pandas as pd

def attention_score(mention_df: pd.DataFrame, lookback: int = 20) -> pd.DataFrame:
    """
    mention_df: columns = [date, stock_id, mentions]
    返回每日的关注度异常分。
    """
    df = mention_df.sort_values(["stock_id", "date"]).copy()
    df["ma"] = (
        df.groupby("stock_id")["mentions"]
          .transform(lambda s: s.rolling(lookback, min_periods=5).mean())
    )
    # 加 1 平滑,避免除零
    df["ratio"] = (df["mentions"] + 1) / (df["ma"] + 1)
    df["score"] = np.log(df["ratio"]).clip(-3, 3)
    # 横截面 z-score: 每日做一次
    df["score_xs"] = df.groupby("date")["score"].transform(
        lambda s: (s - s.mean()) / s.std(ddof=0).clip(min=1e-6)
    )
    return df[["date", "stock_id", "score", "score_xs"]]

这个指标的几个边界条件:

  • lookback=20 是经验值。窗口太短,节假日、周末的影响进入;窗口太长,趋势性的话题会被压平。
  • 横截面 z-score 是必要的:原始 score 在不同标的之间不可比,整体股市情绪上行时所有 score 都会偏高,必须横截面去均值。
  • 做事件驱动短线时,这个指标本身不是信号,而是过滤条件。真正的信号是”高 attention + 异常成交量 + 异常资金费率”的组合。

3.5 散户结构变化对信号有效性的影响

社交媒体类信号有一个常被忽略的特征:它的有效性强烈依赖于”散户在该市场的占比”。美股零售投资者占成交量约 20-25%(2021 年峰值约 30%),A 股零售投资者占成交量长期在 60-80%。直觉上 A 股的社媒信号应该更强,但实际上并不是这样:

  • A 股零售并不主要在公开社交平台上讨论交易,更多在微信群、QQ 群、私域社群里。这部分内容采集难度大、合规边界模糊、信噪比未必更高。
  • 雪球和股吧的活跃用户与真正贡献成交量的散户群体重合度并不高。前者偏中长期价值投资者,后者偏短线交易者。
  • A 股龙虎榜数据反映的是”机构席位与游资席位”的真实交易行为,比社媒情绪更直接,也更容易工程化。

这说明社媒类因子在不同市场上的应用方式不能照搬。在 A 股,把社媒数据作为”龙虎榜信号的辅助过滤”比单独使用更稳健;在美股,把 WSB / Twitter 信号与 Robinhood 持仓数据(已停止公开)的等价替代结合,效果更接近原始研究。


四、卫星与物联网

4.1 数据形态

卫星数据这条线有几个核心量:

  • 光学影像(Optical Imagery)。可见光波段拍摄的地表图像,分辨率从 30 米的 Landsat、10 米的 Sentinel-2,到 0.3 米的 WorldView-3、0.5 米的 PlanetScope。商业用途常见的是 0.5-3 米。
  • 合成孔径雷达(Synthetic Aperture Radar,SAR)。用雷达波代替可见光,能穿云、能在夜间工作,但解读门槛高于光学。Capella、ICEYE 是商业代表。
  • 夜光数据(Nighttime Lights)。VIIRS DNB(Visible Infrared Imaging Radiometer Suite Day/Night Band)每日全球覆盖,分辨率 750 米,是研究宏观经济活动密度的常用底层。
  • AIS 船舶位置数据。通过船载 AIS 信标和卫星接收,覆盖全球油轮、集装箱船、散货船。MarineTraffic、VesselFinder 是常见数据源。
  • 物联网传感器。停车场磁感线圈、加油站流量计、公路收费站、公共自行车系统。这一类数据来源更碎,常常需要按城市、按运营商单独谈合作。

4.2 几类经典用法

停车场车流量估算大型连锁商超的客流。Orbital Insight 在 2015-2018 年靠这个对沃尔玛、Costco、Home Depot 季度营收做提前预测,平均提前期 4-6 周。用 CNN 在卫星图像上数车,理论上简单,但工程上要解决遮挡(树荫、建筑阴影)、季节性变化、节假日效应、多云覆盖率等一系列问题。今天这个 alpha 在头部对冲基金间已经被广泛使用,单独用作多空已经磨平大半。

油轮跟踪估算原油库存与流向。AIS 数据加上船型库(DWT、Beam)可以反推某条航线的总运力变化,进一步推算到港、卸货、库存。Kpler、Vortexa 是商业化代表。这条线对应的因子在原油、成品油的方向性投机和 Brent-WTI 价差交易上仍有可用性,特别是地缘政治冲突期间,比如 2022 年俄乌战争后的”暗船队”流向跟踪。

夜光增长率估算地区经济活动。Henderson、Storeygard、Weil(2012)在 American Economic Review 上系统验证了夜光强度与 GDP 增长的相关性,相关系数在跨国面板上约 0.3-0.6。在中国应用上,夜光对县级经济活动跟踪的有效性被多篇国内学者文章验证。但这个信号衰减极慢——它捕获的是低频结构性信息,alpha 来源更多在 EM 资产配置上,而不是个股层面。

农作物长势通过 NDVI(Normalized Difference Vegetation Index)跟踪。USDA 的 CDL(Cropland Data Layer)每年更新一次,结合 Sentinel-2 影像可以估算大豆、玉米、小麦的长势异常,对农产品期货的方向性头寸有效。

工业开工率。钢厂、水泥厂、炼油厂的烟羽热信号在热红外波段可观测。Sentinel-3 SLSTR 和商业热红外卫星(如 SatVu)能反推产能利用率,对应大宗商品供给侧研究。

集装箱港口堆场。盐田港、洛杉矶/长滩港、鹿特丹港的集装箱堆放面积反映贸易景气。2021 年全球供应链危机期间,这一指标比官方港口运量数据提前 4-6 周。

4.3 采购与处理的现实

卫星数据的成本结构和大多数另类数据不同:原始数据成本高、处理成本更高。一份 0.5 米分辨率的 PlanetScope 影像,按平方公里计费可能在数美元到数十美元。要覆盖美国 1000 家沃尔玛门店一年 52 周的影像,原始数据成本就是六位数美元。再加上 GPU 训练 CNN 数车的算力成本、数据科学家工资,一个工业级停车场监测系统的年成本通常在七位数美元。

这个成本意味着:除非已经验证 alpha 显著且容量足够大,不要自建卫星图像处理流水线。中小型基金的现实选择是直接采购处理后的指标数据:

  • Orbital Insight Go:按月订阅,给特定股票池的客流指标。
  • Planet Labs:原始影像供应方,需要自己处理。
  • RS Metrics、SpaceKnow:行业聚焦的处理后指标。
  • Kpler、Vortexa:油气/能源专项。

物联网这条线的分散性更明显。一个常见实践是和数据 broker 合作,比如 Cuebiq、SafeGraph 提供基于手机定位(在用户授权的前提下)的客流数据,可以替代部分停车场卫星图。但 2022 年之后随着 Apple ATT(App Tracking Transparency)和 GDPR 监管收紧,这一类数据的覆盖率下降明显。

4.4 工程上的几个共性问题

不管来源是哪种,处理这一类数据时几个共性问题:

  • 空间-时间对齐。卫星轨道周期、云覆盖率、AIS 信号丢失等因素让数据天然有缺口。研究时必须显式处理 NaN,不能用前向填充糊弄过去。
  • 季节性。停车场流量有强烈的星期效应、节假日效应、天气效应。必须先建一套季节性基线(baseline),异常监测才有意义。
  • 数据生成过程变化。卫星升级、传感器漂移、AIS 法规变化都会让历史数据和当前数据不可比。版本化必须精细到传感器序列号、数据集版本号。
  • 覆盖率监控。每天自动跑一份”今天 vs 30 日均值”的覆盖率比较,覆盖率下降超过阈值要立即报警,这是另类数据流水线的标配。

4.5 一个停车场客流的最小处理范例

为了让上面的讨论落到工程实操层面,下面给一个”停车场客流”的简化处理流程。完整工业实现要复杂得多,这里抽出关键骨架,便于理解每一步在做什么:

import numpy as np
import pandas as pd
from datetime import timedelta

def normalize_parking(raw: pd.DataFrame) -> pd.DataFrame:
    """
    raw columns: [date, store_id, image_id, vehicle_count, cloud_cover, sat_id]
    返回: 按 (date, store_id) 归一化后的客流强度。
    """
    df = raw.copy()
    # 1. 云覆盖率 >= 30% 视为不可用
    df = df[df["cloud_cover"] < 0.30]
    # 2. 多颗卫星同日数据取中位数,避免单卫星偏差
    df = df.groupby(["date", "store_id"], as_index=False)["vehicle_count"].median()
    # 3. 季节基线: 同 store 过去 52 周同周几的中位数
    df["dow"] = pd.to_datetime(df["date"]).dt.dayofweek
    df = df.sort_values(["store_id", "date"])
    df["baseline"] = (
        df.groupby(["store_id", "dow"])["vehicle_count"]
          .transform(lambda s: s.shift(1).rolling(52, min_periods=12).median())
    )
    # 4. 异常: log(vehicle / baseline)
    df["anomaly"] = np.log((df["vehicle_count"] + 1) / (df["baseline"] + 1))
    df["anomaly"] = df["anomaly"].clip(-2, 2)
    return df

def aggregate_to_brand(parking: pd.DataFrame, store_to_brand: pd.DataFrame) -> pd.DataFrame:
    """
    把门店级异常聚合到品牌级,权重为门店历史中位车流量。
    """
    merged = parking.merge(store_to_brand, on="store_id", how="inner")
    weights = (
        parking.groupby("store_id")["vehicle_count"].median().rename("w")
    )
    merged = merged.merge(weights, on="store_id", how="left")
    merged["wx"] = merged["anomaly"] * merged["w"]
    out = (
        merged.groupby(["date", "stock_id"])
              .agg(brand_signal=("wx", "sum"), w_sum=("w", "sum"))
    )
    out["brand_signal"] = out["brand_signal"] / out["w_sum"].clip(lower=1)
    return out.reset_index()[["date", "stock_id", "brand_signal"]]

注意几个隐含假设:

  • 季节基线用同周几中位数,而不是简单 N 日均值,因为零售流量有强烈的星期效应。
  • 多卫星数据先做日内合并,再进入时间序列,避免不同卫星过境时间不同造成的伪信号。
  • 品牌聚合权重用历史中位车流量,避免新店或小店主导信号。
  • clip(-2, 2) 是经验值,剔除显著的图像识别异常(比如施工期间整片停车场被占用)。

五、链上数据

5.1 链上数据的工程含义

加密资产的最大特点是结算系统本身就是公开数据库。每一笔转账、每一个合约调用、每一次状态变更都被记录在区块链上,可以被任何人重放。这让链上数据从工程上区别于其他另类数据——它不是”被采集到的”,是”原本就在那里、需要解码”。

但”原本就在那里”不等于”容易拿到”。要从原始链上数据得到有用的因子,要经过下面这条流水线:

链上数据采集与因子化架构

L1(数据源层)。完整数据需要归档节点(Archive Node),它存了从创世块到当前块的全部状态。Erigon 在以太坊主网当前需要约 8 TB SSD,Geth 需要更多。如果只关心交易和事件不关心历史状态,全节点(Full Node)就够,需要约 1.5 TB。中小研究团队的现实选择是租用 Alchemy、Infura、QuickNode 的 RPC 服务,按调用计费。

L2(同步与索引层)。把链上数据从节点同步到本地数据库。开源工具链中,cryo(Paradigm 出品)、ethereum-etlsubsquid 是常用选择。它们把 block、tx、receipt、log、trace 从节点导出成 Parquet 或 PostgreSQL,方便后续 SQL 查询。

L3(解码与聚合层)。原始事件日志只是 (address, topic0, topic1, topic2, topic3, data),要变成”USDT 从 A 转到 B 金额 X”需要 ABI 反序列化,ERC20、Uniswap V2/V3、Aave、Compound 各有自己的事件签名。地址聚类(Address Clustering)是把同一个实体(人或机构)控制的多个地址识别出来,常用启发式是 common-spend:同一笔交易的所有输入归属于同一实体(在 UTXO 模型上的 Bitcoin 直接适用,EVM 上需要更复杂的启发式)。

L4(因子层)。把聚合后的指标对齐到时间序列,进入特征仓库。链上常见因子:活跃地址数、NVT(Network Value to Transactions)、MVRV(Market Value to Realized Value)、稳定币净发行、交易所净流入、DEX 滑点曲线。

5.2 几个有信号价值的链上指标

交易所净流入。把所有已知归属于中心化交易所(CEX)的地址作为一个集合,统计每个区块内净流入(流入-流出)的总量。链上传统观点是:净流入大幅上升预示卖压增加,净流出预示惜售。Coinbase、Binance、Kraken 的标签数据是 Etherscan、Arkham、Nansen 等公司维护的核心资产之一。

稳定币净发行。Tether(USDT)、Circle(USDC)的发行和销毁是链上可观测的。USDT 在 Tron 上的增发往往和加密市场情绪同步,是宏观流动性指标。要小心的是 USDT 的发行不一定立即进入交易,可能滞留在发行方钱包数小时到数天。

巨鲸地址行为。把余额超过特定阈值(比如 BTC 1000 枚以上)的地址作为巨鲸集合,监控其转账行为。巨鲸向交易所大额转入往往是抛售前奏,但反向解读也常见——很多大额转账是冷热钱包内部调度,需要结合标签判断。

DEX 池子状态。Uniswap V3 的 slot0liquidity 在每次 swap 后都会更新,可以推算池子的实时滑点曲线。Curve 的 stableswap pool 偏移量可以监控稳定币失锚风险——2023 年 3 月硅谷银行事件后 USDC 短暂脱锚到 0.87,3pool 状态先于 CEX 价格出现剧烈偏移。

MEV 与三明治攻击。Mempool 中的待打包交易可被搜索者(searcher)用于抢跑。Flashbots 提供的 mev-inspect 数据集可以系统识别 sandwich、frontrun、arbitrage 三类 MEV。在做 DEX 交易策略时,MEV 暴露是必须考虑的一阶成本。

5.3 web3.py 拉链上指标

下面给一段最小可运行代码,用 web3.py 通过 RPC 拉取以太坊上某个 ERC20 代币的转账事件,并做最简单的”交易所净流入”统计。这段代码不带缓存、不带去重、不带容错,仅作演示:

import os
from typing import List, Set
import pandas as pd
from web3 import Web3
from eth_utils import to_checksum_address

RPC_URL = os.environ["ETH_RPC_URL"]   # e.g. https://eth-mainnet.g.alchemy.com/v2/<key>
USDC = to_checksum_address("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48")
TRANSFER_TOPIC = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"

# 已标记为 CEX 热钱包的地址子集(演示用,生产应使用更全面的标签库)
CEX_HOT_WALLETS: Set[str] = {
    to_checksum_address("0x28C6c06298d514Db089934071355E5743bf21d60"),  # Binance 14
    to_checksum_address("0x21a31Ee1afC51d94C2eFcCAa2092aD1028285549"),  # Binance 15
    to_checksum_address("0x71660c4005BA85c37ccec55d0C4493E66Fe775d3"),  # Coinbase 1
    to_checksum_address("0x503828976D22510aad0201ac7EC88293211D23Da"),  # Coinbase 2
}

w3 = Web3(Web3.HTTPProvider(RPC_URL))

def fetch_transfers(token: str, start: int, end: int, chunk: int = 2000) -> pd.DataFrame:
    """按区块分片拉 Transfer 事件,返回 DataFrame。"""
    rows = []
    for fr in range(start, end, chunk):
        to = min(fr + chunk - 1, end)
        logs = w3.eth.get_logs({
            "fromBlock": fr,
            "toBlock": to,
            "address": token,
            "topics": [TRANSFER_TOPIC],
        })
        for log in logs:
            from_addr = to_checksum_address("0x" + log["topics"][1].hex()[-40:])
            to_addr = to_checksum_address("0x" + log["topics"][2].hex()[-40:])
            value = int(log["data"], 16)
            rows.append((log["blockNumber"], log["transactionHash"].hex(),
                         from_addr, to_addr, value))
    df = pd.DataFrame(rows, columns=["block", "tx", "from", "to", "value"])
    df["value"] = df["value"] / 1e6  # USDC 是 6 位小数
    return df

def cex_net_inflow(transfers: pd.DataFrame, cex: Set[str]) -> pd.DataFrame:
    """CEX 净流入 = 流入 CEX - 从 CEX 流出。"""
    inflow = transfers[transfers["to"].isin(cex)].groupby("block")["value"].sum()
    outflow = transfers[transfers["from"].isin(cex)].groupby("block")["value"].sum()
    net = (inflow.subtract(outflow, fill_value=0)
                  .rename("cex_net_inflow").reset_index())
    return net

# 用法示例
# tail = w3.eth.block_number
# transfers = fetch_transfers(USDC, tail - 200, tail)
# net = cex_net_inflow(transfers, CEX_HOT_WALLETS)

这段代码在工程上要补足的点:

  • 实际生产环境需要使用归档节点和增量同步,而不是每次都按区块号拉。
  • get_logs 的区块范围限制因 RPC 商而异,Alchemy 默认 2000,Infura 默认 10000。
  • 重组(Reorg)安全:以太坊上即使 PoS 后偶发 reorg,建议落库的数据滞后最终化区块至少 64 个。
  • 标签数据是这条流水线最值钱的资产之一。Etherscan、Nansen、Arkham 的标签库覆盖差异巨大,能否拿到高质量标签直接决定指标的信噪比。
  • 多链支持时,每条链都要单独跑一份索引器。Solana 的账户模型完全不同,需要替换为 solana.py

5.4 链上数据的几个重要陷阱

  • 代理合约。许多 ERC20 是代理合约,token 实际地址和实现地址不同。不识别代理会让事件解码错位。
  • 包装代币。WBTC、stETH、cbETH 等是真实资产的链上影子,做余额统计时不能简单加总。
  • 批量交易。一笔交易可能包含上百个内部转账。如果只读 receipt 上的 Transfer 事件,会漏掉合约内部状态变化。
  • EIP-4844 与 L2。2024 年 3 月 EIP-4844 上线后,主网 calldata 的成本大幅下降,L2 数据可用性发生根本变化。所有”L2 活跃度”类指标在这个时点前后不可比。
  • MEV 与失败交易。失败交易仍消耗 gas、仍上链,但不应计入”成功活动”。指标计算要区分。
  • 预编译与系统合约。EIP-4337(账户抽象)下,UserOperation 不在传统 tx 序列里,需要单独跟踪 EntryPoint 合约的事件。忽略这条会让”链上活跃地址”指标在 2024 年后系统性低估。
  • 空投 farming 与女巫攻击。某些”活跃地址数”激增其实是单一团队批量铸造钱包薅羊毛,把这类地址聚类为”同一实体”才能把指标还原成真实活跃用户。

5.5 一个稳定币流向的因子样例

下面给一个常用因子的最小实现:稳定币(USDT/USDC)从交易所流向 DeFi 协议的净规模。这个因子在加密资产横截面上反映”链上加杠杆意愿”,是研究 DeFi TVL 与币价 lead-lag 关系的常用输入:

import pandas as pd

DEFI_PROTOCOL_LABELS = {
    # Uniswap V3 router
    "0xE592427A0AEce92De3Edee1F18E0157C05861564": "uniswap_v3",
    # Aave V3 pool
    "0x87870Bca3F3fD6335C3F4ce8392D69350B4fA4E2": "aave_v3",
    # Compound V3 USDC
    "0xc3d688B66703497DAA19211EEdff47f25384cdc3": "compound_v3",
    # Curve 3pool
    "0xbEbc44782C7dB0a1A60Cb6fe97d0b483032FF1C7": "curve_3pool",
}

def stablecoin_to_defi(transfers: pd.DataFrame, cex: set, defi: set) -> pd.DataFrame:
    """
    transfers: USDT/USDC Transfer 事件,包含 [block, from, to, value, ts]
    返回: 每日 CEX -> DeFi 净流入金额。
    """
    df = transfers.copy()
    df["leg"] = "other"
    df.loc[df["from"].isin(cex) & df["to"].isin(defi), "leg"] = "cex_to_defi"
    df.loc[df["from"].isin(defi) & df["to"].isin(cex), "leg"] = "defi_to_cex"

    df["date"] = pd.to_datetime(df["ts"], unit="s").dt.floor("D")
    pivoted = df.pivot_table(
        index="date", columns="leg", values="value",
        aggfunc="sum", fill_value=0,
    )
    pivoted["net_to_defi"] = (
        pivoted.get("cex_to_defi", 0) - pivoted.get("defi_to_cex", 0)
    )
    return pivoted.reset_index()

工程上的几点说明:

  • DeFi 标签集合需要持续维护。新增协议、合约升级(地址变化)、L2 部署都要纳入。
  • 统计单位是稳定币本币(USDT 或 USDC),不需要换算到 USD,因为 1 USDT ≈ 1 USDC ≈ 1 USD 的近似在此场景下足够。
  • 这个因子的解读要警惕跨链桥流量。从 Ethereum 主网到 Arbitrum 的流量要单独跟踪,不能简单累加为”全市场杠杆”。

六、网页与电商

6.1 这一战线能做什么

爬取网页是另类数据最古老、最广泛的方式。对量化研究有价值的几类:

  • 电商商品价格与库存。亚马逊(Amazon)、京东、淘宝、天猫的商品页面包含价格、销量、评价数、SKU 库存提示。聚合后可以用作消费类标的的高频景气指标。
  • 招聘信息。LinkedIn、Indeed、Glassdoor、智联招聘、BOSS 直聘上的职位发布数和具体岗位,反映企业扩张节奏。半导体公司的 EE 招聘、互联网公司的算法岗招聘是行业景气的领先指标。
  • 航班与酒店。OAG、Cirium 的航班数据,OTA(Online Travel Agency)的酒店价格和入住率,反映航空、旅游业的需求景气。
  • App 下载与 DAU。Sensor Tower、data.ai(前 App Annie)、QuestMobile 提供 App 排行榜和估算的活跃数据。
  • 官方网站变更。公司网站新增产品页、修改高管页、修改服务条款,可以是事件信号。
  • 社交点评。大众点评、美团、Yelp 上的商家点评数和评分。

6.2 合规边界

爬取的合规边界是这一战线的核心问题。中文语境下需要同时关注:

  • 《数据安全法》(2021 年 9 月施行)对重要数据出境、敏感数据处理的规定。
  • 《个人信息保护法》(2021 年 11 月施行)对用户身份、行为数据的处理要求。
  • 《反不正当竞争法》对违反商业道德、利用技术手段进行不正当竞争的禁止。
  • 各平台《用户协议》中对自动化访问、批量采集、转售数据的禁止条款。
  • 《刑法》第 285 条”非法侵入计算机信息系统罪”、第 286 条”非法获取计算机信息系统数据罪”对绕过反爬措施的刑事责任。

历史上有几个标志性案例值得理解边界:

  • 大众点评诉百度地图案(2017)。法院认定百度地图大量抓取大众点评点评内容并展示,构成不正当竞争。判决核心逻辑是”实质性替代”和”搭便车”。
  • LinkedIn vs hiQ Labs 案(美国,2017-2022)。第九巡回法院最终判决爬取公开网页不构成《计算机欺诈与滥用法》(CFAA)项下的非法访问。但 hiQ 仍然在合同法层面败诉。
  • 国内”晟品诉抖音”案、“今日头条诉新浪微博”案,均涉及爬取与不正当竞争的边界。

工程实施上的几条底线:

  • 只爬公开页面,不绕过登录、不绕过付费墙、不解密 API 签名到法律意义上”破解”程度。
  • 遵守 Robots。robots.txt 不是法律,但违反它在举证时是不利证据。
  • 限速。把目标站点 QPS 控制在不会被对方系统识别为异常负载的水平。
  • 不存 PII。不缓存 user_id、邮箱、手机号、用户头像。
  • 不用于二次销售。爬来的数据用于内部研究和对内信号,不向外部合作方转售或在产品中暴露原文。
  • 保留可重放的法律审计日志。哪个 IP、哪个时间、访问哪个 URL,能在被起诉时给出”我做了哪些事”的证据。

6.3 几个工程上的共性套路

爬虫流水线的工程模式相对成熟:

  • 任务调度。用 Scrapy / Airflow / Prefect 把”今日要爬的 URL 列表”作为任务队列。
  • 代理池。家庭住宅 IP 代理服务(如 Bright Data、Oxylabs)能避免被目标站点识别为机房 IP。但代理使用本身合规风险更高。
  • 指纹反爬。现代反爬识别 TLS 指纹、JA3 指纹、JS 指纹。底线选择是用 Playwright/Puppeteer 模拟真实浏览器,但成本是 CPU 和延迟。
  • 变更检测。目标页面 DOM 结构变化是日常。CI 里加一份”对比昨日字段是否齐全”的校验,发现解析失败立即报警。
  • 去重与增量。基于 URL hash + 内容 hash 的双层去重,避免重复入库。
  • 多版本归档。原始 HTML 和解析后字段都要落库,方便重放和模型迭代。

6.4 招聘数据的一个简单建模

招聘数据是网页类数据中信号噪声比较高的一类。下面给一个在 A 股语境下用过的简化建模:

import pandas as pd
import numpy as np

def hiring_growth_factor(jobs_df: pd.DataFrame, window: int = 90) -> pd.DataFrame:
    """
    jobs_df columns: [date, stock_id, n_open_jobs]
    返回: 招聘异常增长因子,按日横截面 z-score。
    """
    df = jobs_df.sort_values(["stock_id", "date"]).copy()
    g = df.groupby("stock_id")
    df["base"] = g["n_open_jobs"].transform(
        lambda s: s.shift(1).rolling(window, min_periods=30).median()
    )
    df["growth"] = (df["n_open_jobs"] - df["base"]) / df["base"].clip(lower=1)
    df["growth"] = df["growth"].clip(-1, 5)

    df["zscore"] = df.groupby("date")["growth"].transform(
        lambda s: (s - s.median()) / (s.std(ddof=0).clip(min=1e-6))
    )
    return df[["date", "stock_id", "growth", "zscore"]]

要点:

  • 用中位数而不是均值做基线,因为招聘有强季节性、容易被几次大规模批量招聘扰动。
  • clip(-1, 5) 截断异常值,防止小公司从 1 个职位涨到 10 个被算作 +900%。
  • 横截面 z-score 必须在同一交易日内做,跨日做会引入时间序列趋势。
  • 信号有效性主要在中盘股的中长期(季度级),不适合做高频。

6.5 三个值得长期关注的网页数据子方向

工程化能落地、合规风险相对可控、长期具有信号价值的子方向,按经验排序:

  • 招聘趋势。劳动市场的领先性强于消费市场,对科技、半导体、新能源行业景气有早期信号。LinkedIn、Glassdoor、智联招聘、BOSS 直聘的公开页面是公开数据。
  • 产品定价。零售品类的价格变化在毛利率层面提前于报表披露。同一 SKU 的滚动价格曲线,对消费品研究是高质量输入。
  • 门店开闭。连锁餐饮、零售品牌的官网”门店查询”页面变化,可以推算扩张节奏。Wendy’s、Chipotle、瑞幸、海底捞这种重门店模型的标的尤其适用。

不建议长期投入的子方向:

  • App 排行榜爬取。Sensor Tower、QuestMobile 已经把这部分做成商业化产品,自建成本高、收益边际低。
  • 社交媒体情感原始爬取。X API 收紧后成本激增,除非已经有合规通道,自建得不偿失。
  • 个人 PII 类数据。任何涉及个人身份的爬取都不建议碰,合规风险远大于潜在收益。

七、信用卡与电子支付

7.1 美国市场的成熟数据源

美国对冲基金能用的支付类另类数据源已经相当成熟:

  • Yodlee(Envestnet 旗下)。聚合了大约 1500 万美国消费者的银行账户和信用卡账单数据,按消费品类、商家、地理位置切分。基金研究使用的是经过去标识化、聚合的版本,比如 “AMZN 上周末线上消费同比 +15%”。
  • Earnest Research(已被 Verisk 收购)。提供类似的聚合消费数据,对零售业、消费品细分行业覆盖较好。
  • Second Measure / Bloomberg Second Measure。基于美国信用卡和借记卡数据的商家级消费指标。
  • Facteus。提供 ATM、信用卡、借记卡数据,覆盖维度更细。

这些数据的使用范式是:基金按月或按年付订阅费,得到去标识化的聚合时间序列,按商家或品牌跟踪营收同比。麦当劳的销售季报发布前一周到三周,就可以从这些数据里看到大致方向。AlphaSense、AlternativeData.org 维护过这一类厂商的目录。

实证上,Froot 等多位学者的研究显示:信用卡数据对美国消费类股票的季报营收预测,在事件前 4 周相关系数能稳定在 0.4-0.7。一些头部对冲基金(如 Citadel、Two Sigma、PointSeven)2015-2018 年间从这里获得了显著的 alpha,到 2020 年后已经基本被广泛使用,alpha 衰减明显。

7.2 中国市场的可得性

中国市场上类似数据的可得性比美国差得多,原因是结构性的:

  • 中国主要消费支付通过支付宝、微信支付完成,两家公司不对外提供消费明细级别的聚合数据产品。
  • 银联拥有信用卡级数据,但对外服务以”消费指数”等宏观聚合形式为主,不提供商家级细分。
  • 银行各自的零售数据归集在 CBIRC(金融监管总局)框架下,对外开放级别有限。
  • 美团、京东、拼多多自己掌握平台 GMV 数据,但只对外披露季报口径,不提供更高频的商家级数据。
  • 第三方数据公司(如易观、QuestMobile)提供 App 行为指标,更接近活跃度而非真实消费金额。

这意味着 A 股研究中”信用卡级消费数据”基本不可得。可替代的手段是:

  • App DAU/MAU 估算。Sensor Tower、QuestMobile 的活跃度指标,对互联网公司的营收有一定相关。
  • 物流单量。某些第三方提供国内物流总单量、各电商平台单量的估算。
  • 公开的高频宏观指标。BCI(中国褐皮书国际)、PMI 分项、汽车厂家公布的批发零售数据。

合规上需要注意,《个人信息保护法》对消费数据的处理要求显著严于美国 CCPA,未经用户授权获取消费明细在中国是明确违法的。任何声称提供”信用卡级消费数据”的国内来源,都需要追溯其原始授权链路。

7.3 工程化使用的几个原则

不管是用美国的 Yodlee 还是中国的替代源,几条工程化原则通用:

  • 必须用厂商提供的”快照时间戳”。供应商内部数据有 7-30 天的修订期。今天看到的”上周一消费指标”在两周后可能被修订 5%。所有研究必须基于”我在 t 时刻能看到的版本”,而不是”现在能看到的最新版本”。
  • 覆盖率公开。要求供应商公开”覆盖了多少消费者、占总人口比例、地理分布、年龄分布”。覆盖率显著的偏移(比如疫情期间老年用户的样本流失)会让指标在某些时段不可比。
  • 横截面比较优于纵向比较。同一份数据在同一行业内做横截面排序,比看绝对值时间序列更稳健,因为系统性偏差会被横截面差异部分抵消。
  • 结合公司自身披露做对齐。已发财报的季度可以做”消费指标 vs 实际营收”的回归校准,看出供应商口径与会计口径的系统性差异。

7.4 nowcast 的标准建模

信用卡数据最常见的应用是季度营收 nowcast。建模标准模板如下:

  1. 特征构造\(x_{i,t}\) 是公司 \(i\) 在季度 \(t\) 内累计到当前的信用卡支出指标(同比变化或环比变化),按周或按日更新。
  2. 目标变量\(y_{i,t}\) 是公司公布的季度营收同比变化,事后才知道。
  3. 滚动训练。在每个截面日,用过去 \(K\) 个季度的 \((x, y)\) 配对样本训练一个线性或 GBM 模型,外推当前季度的 \(\hat{y}_{i,t}\)
  4. 校准。把 \(\hat{y}\) 与 sell-side consensus 比较,差值作为 surprise 因子。
  5. 事件应用。临近财报发布日,按 surprise 排名做横截面多空,事件后清仓。

实证上这套模板在 2015-2018 年间的美国零售股、餐饮股上的多空收益最高能到年化 8-12%。2020 年后随着数据广泛使用,alpha 衰减到年化 2-4%,但依然显著。这种”先看到、再消失”的轨迹是另类数据 alpha 衰减的标准曲线。

值得提醒的是:信用卡数据并不能等同于公司全部营收。Yodlee 等聚合源覆盖的样本是有偏的(年轻、城市、网购占比高),与实际营收存在系统性偏移。把这种偏移当作误差忽略可以,但不能假设它是常数——在疫情、节假日、促销季它会显著变化,回归模型如果不处理这一点会出现稳定的预测偏差。


八、Alt 数据的工程化

最后这一节回到工程问题:怎么把上面这些形态各异的数据,整合到一个能稳定支撑研究、回测、信号生产的体系里。这里的”工程化”不是一句”上 Kafka 就行”能糊弄过去的,要解决五个具体问题:清洗、嵌入、对齐、版本化、与传统因子整合。

8.1 清洗

另类数据的清洗规则按数据形态分:

文本类

  • 去 HTML、去模板、去广告。新闻网页里超过一半的字符是导航栏、推荐位、版权声明,必须先剥离。
  • 编码统一到 UTF-8。中文环境常见 GBK/GB2312/UTF-8 混用,必须显式指定编码再解码。
  • 实体识别(NER)抽取主体。一篇报道宁德时代的新闻可能也提到比亚迪、特斯拉,做主体级因子时必须先抽取。
  • 去重。爬虫和聚合源经常拿到同一篇内容多次,按 simhash 或 minhash 去重。

图像类

  • 时间戳归一到 UTC,并保留卫星过境时间。
  • 云覆盖率元数据必须保留,超过阈值(比如 30%)的影像直接丢弃。
  • 同一个目标的不同卫星影像必须做地理校准(georectification),不能直接像素级对比。

链上

  • 重组安全。所有指标的”已确认”版本必须等区块最终化(finality)。以太坊 PoS 后约 12-15 分钟,BTC 至少 6 个块。
  • 去重。同一笔交易在重组中可能上链两次,按 (chain, tx_hash) 去重。
  • 单位归一。USDC 是 6 位小数,DAI 是 18 位小数,所有金额必须按代币 decimals 归一。

数值类(信用卡、招聘)

  • 异常值检测。来自合作方的数据如果突然出现”昨天某商家消费翻 100 倍”,大概率是数据源 bug,必须有自动告警。
  • 缺失填充。链上掉块、API 限频、源系统故障都会导致缺口。前向填充、线性插值、显式 NaN 留存,要按因子语义选择。

8.2 嵌入

文本和图像在送入因子模型前,要先做表征学习。常见做法:

  • 文本嵌入BAAI/bge-large-zh-v1.5BAAI/bge-m3 是当前中文语义检索的通用 baseline,输出 768 或 1024 维向量。金融文本可以再做 LoRA 微调。
  • 图像嵌入。CLIP(OpenAI / OpenCLIP)的 ViT-L/14 模型在大多数遥感任务上是合理的起点,输出 768 维向量。
  • 时间序列嵌入。链上活动序列、AIS 轨迹序列可以用 Transformer 或 TCN 做自监督预训练,得到固定长度的向量表征。

嵌入向量入库后,可以走两条路:直接作为高维特征进 LightGBM/XGBoost;或者先用 PCA/UMAP 降维,再做线性因子。前者预测力强、可解释性差,后者可解释性强、预测力弱。

8.3 对齐

对齐是这条流水线最关键的工程问题。Point-In-Time(PIT)原则要求:在任意 t 时刻,研究能看到的因子值必须等价于”如果系统当时已上线,t 时刻它会输出什么”。另类数据的 PIT 比传统财报数据更难,因为:

  • 数据进入流水线本身就有延迟。新闻被抓取到入库可能滞后秒级到分钟级;卫星影像从过境到下载可能滞后几小时;信用卡数据可能滞后几天。
  • 数据有修订(revision)。供应商可能在 t+5 天才完成对 t 这天数据的最终修订。
  • 不同数据源的时间戳精度不同。新闻精确到秒,信用卡聚合到天,卫星按过境频次。

工程上必须把”事件时间”(event time)和”采集时间”(ingestion time)分离,并显式记录两个时间戳。所有回测查询都按”在采集时间 ≤ t 的数据中,事件时间 = t’ 的最新版本”做。这就是上一篇 《特征仓库与因子治理》 里讨论的 bitemporal 表的标准用法。

8.4 版本化

另类数据流水线有四个层次的版本要追踪:

  • 数据源版本。供应商 A 在 2024Q3 把覆盖率从 12% 调到 8%,所有依赖此源的下游因子都受影响。要在数据源元数据里显式记录这一版本。
  • 解析器版本。同一份原始数据,解析逻辑变化(比如新增 NER、修复 ABI 错位)会改变下游特征。parser_version 是必须带的字段。
  • 模型版本。文本嵌入用的是 bge-large-zh-v1.5 还是 v2.0?情感分用的是 Erlangshen 还是 FinBERT?模型升级一次,下游所有特征要回填。
  • 特征版本。最终落库的特征本身要打 schema 版本和 semantic 版本两个标签。

只要这四层有一个版本变了,下游回测就有”今天的数据和昨天的数据是同一组吗”的隐患。规范的做法是把版本元数据做成不可变记录,每条特征行都带 (data_version, parser_version, model_version, feature_version) 四元组。

8.5 与传统因子库整合

另类数据因子最终要和传统因子(动量、价值、规模、波动率、流动性)放在一起做组合优化、风险归因。整合时几个工程模式:

  • 两库分离,统一接口。原始数据和因子分别落在两个域:alt-data domain 和 traditional-factor domain,只通过统一的 feature store API 暴露给下游。这样 alt-data 团队和 factor 团队的迭代节奏可以独立。
  • 共享 universe 与 trading calendar。所有因子(不管来源)必须按同一个 universe 和同一个交易日历对齐。如果 alt-data 因子在节假日有更新而其他因子没有,就要明确 fillna 策略。
  • 风险归因预留接口。Barra 风格的多因子风险模型默认接受”暴露 + 收益”输入。alt-data 因子要变成行业归因的一部分,必须先在历史上跑出稳定的 IC,再纳入风险模型重新估计因子收益矩阵。
  • alpha 衰减监控。这一类因子的衰减比传统因子快得多。流水线必须每天自动跑一份”过去 1 个月、3 个月、12 个月的 IC vs 全样本 IC”对比,明显衰减时及时下架。
  • 去相关与正交化。alt-data 因子之间、alt-data 与传统因子之间的相关性需要在每月做一次重新评估。常用做法是对每个 alt-data 因子,先回归到风格因子和行业因子上,取残差作为”纯净”alt-data 暴露。残差才是真正应该进风险预算的部分。

8.6 一段串起来的最终样例

下面这段代码把上面几节连起来:从原始新闻 + 链上 USDT 流入两路数据,经过情感打分和聚合,落到一份带版本元数据的 Parquet,模拟最终入特征库的形态:

import pandas as pd

def write_feature_partition(
    df: pd.DataFrame,
    feature_name: str,
    data_version: str,
    parser_version: str,
    model_version: str,
    feature_version: str,
    out_dir: str,
):
    """把因子按 (date, feature_name) 分区写到 Parquet。"""
    required = {"date", "stock_id", "value", "ingestion_ts"}
    assert required.issubset(df.columns), f"missing cols: {required - set(df.columns)}"

    df = df.copy()
    df["feature_name"] = feature_name
    df["data_version"] = data_version
    df["parser_version"] = parser_version
    df["model_version"] = model_version
    df["feature_version"] = feature_version

    # 按日期分区,方便增量加载
    for d, sub in df.groupby("date"):
        path = f"{out_dir}/feature={feature_name}/date={d}/part.parquet"
        sub.to_parquet(path, index=False)

# 用法
# news_factor = aggregate_to_daily(news_df).rename(columns={"sent_w": "value"})
# news_factor["ingestion_ts"] = pd.Timestamp.utcnow()
# write_feature_partition(
#     news_factor[["date", "stock_id", "value", "ingestion_ts"]],
#     feature_name="news_sent_w",
#     data_version="cls-financial-2025Q1",
#     parser_version="parser_v3.2",
#     model_version="erlangshen-roberta-330m-2024-08",
#     feature_version="v1.0",
#     out_dir="/data/features",
# )

这段写入逻辑虽然简单,背后承担的是”任何下游回测都能精确追溯到当时使用的数据源版本和模型版本”。一旦研究者在 2027 年想重现 2025 年的某次回测,他需要的就是这套元数据。没有它,alt-data 就会沦为”看着像能用、谁也不能保证它当时输出过什么”的不可信资产。

8.7 监控与回滚

另类数据流水线和传统数据流水线最大的差别在于”故障是常态,不是异常”。一个工业级系统至少要监控下面几类指标:

  • 覆盖率。每天每个数据源、每个标的的样本数,与过去 30 日均值比较。下降超过 50% 自动报警。
  • 延迟。事件时间到入库时间的延迟分布。p95、p99 延迟突变是上游故障的早期信号。
  • 漂移。情感分、链上指标在横截面上的分布漂移。Population Stability Index(PSI)超过 0.2 就要怀疑模型或数据源发生变化。
  • 去重率。如果某一天去重前后样本数比平时高一个数量级,往往是采集程序进入死循环抓重复内容。
  • 解析错误率。HTML 结构变化、ABI 变化、字段缺失,解析器要把错误率显式输出到监控。

回滚机制必须双向。常规情况下数据按”事件时间 + 采集时间”递增写入;发现历史数据有错误时,要支持按 (data_version, time_range) 维度做回滚和重算,并把”重算前的版本”和”重算后的版本”都保留,方便回测端选择。

8.8 alt-data 流水线的最小可用清单

把这一篇所有讨论收束成一份”最小可用清单”,给准备启动这条战线的团队:

  1. 选定 1-2 类数据源,明确法律合规边界,签合同或确认许可范围。
  2. 搭原始数据落库:分区策略以 (source, event_date) 为主键,原始 payload 和解析字段双写。
  3. 实现解析器版本化和模型版本化。版本元数据进入每条特征行。
  4. 实现 ingestion_ts 与 event_ts 双时间戳,所有下游查询走 PIT 接口。
  5. 把 universe 和 trading calendar 与传统因子库共享。
  6. 监控覆盖率、延迟、漂移、去重率、解析错误率五大指标,自动报警。
  7. 回测前置一个 alpha 衰减自检:过去 1/3/12 个月 IC vs 全样本 IC 对比报告。
  8. 风险归因接口预留:因子载荷可以喂给 Barra 风格风险模型。
  9. 文档化数据字典:每个字段的来源、更新频率、修订规则、缺失含义、单位、时区。
  10. 灾备:原始数据备份至少两个独立位置,避免供应商单点失效。

走完这十步,alt-data 才算真正变成可以放心给研究员用的”基础设施”。在此之前任何”alpha 来自另类数据”的说法都需要打折听。

8.9 团队组织上的几个观察

最后从团队组织角度补一个观察:alt-data 这条战线对组织能力的要求和传统量化团队不同。它需要”工程能力 ≈ 研究能力”的双重投入,而不是”工程为研究服务”的单向支持关系。

具体表现:

  • 数据工程师必须对金融语义有理解。不能只把它当 ETL 任务做。否则上游字段含义变了,工程师按”和昨天一样跑”的标准看不出来,下游研究员发现时已经回测错了几周。
  • 研究员必须会写工程代码。至少要能写得出能落库的解析逻辑,而不是把 jupyter notebook 扔给工程师 reimplement。两边来回沟通的成本远大于让研究员承担一定的工程负担。
  • 法务必须前置。每接入一个新数据源,法务在签合同前评估数据使用范围、出境合规、二次使用边界。等到上线再补合规的后果通常是项目被叫停。
  • 风控必须懂 alpha 衰减。一个跑了三个月的 alt-data 因子突然开始跑输基准,是数据问题、模型问题,还是 alpha 衰减?这个判断需要风控有能力做横截面归因,而不只是看 PnL。

具备这些条件的团队,alt-data 才能真正成为长期资产;否则,做出来的更多是”给 LP 看的故事”,而不是能赚钱的因子。


我对这一战线的看法

另类数据这条线最常见的两类错误:一是过度乐观——觉得只要拿到独家数据,alpha 就来了。事实是数据采购成本只占总成本的小头,工程化、清洗、对齐、版本化的工作量是数据本身的 5-10 倍,而 alpha 衰减意味着即便走完所有这些工作,得到的因子半衰期也常常以季度为单位。二是过度保守——觉得另类数据”门槛高、不规范、合规风险大”,于是干脆不碰。这同样是错的,因为传统数据上的 alpha 已经被几代量化研究者磨得很薄,在一个量化竞争已经如此激烈的市场里不去开辟新数据维度,等于把战场限定在所有人都已饱和的区域。

正确的姿态是把另类数据当成基础设施来建:选两到三类自己有能力 sustain 的数据源(比如新闻 + 链上,或者卫星 + 招聘),花 6 到 12 个月把它从原始数据到特征库的全链路打通。第一个版本不要奢望产生显著 alpha,目标是让流水线”稳定运行、PIT 严格、版本可追溯”。在这个基础上做因子研究和事件驱动策略,比起”去采购一份贵的数据再发现没法落地”健康得多。

A 股语境下的特殊性更明显:链上数据天然不适用,信用卡级数据基本不可得,卫星和物联网在合规与采购成本上门槛较高,新闻和舆情、招聘是最现实的起点。把这两条线做扎实,已经能把整个研究体系的输入端拉开和大多数同行的差距。

最后一点:另类数据不是孤立的”加分项”,而是会反过来重塑研究流程的”基础设施变更”。一旦把链上 / 新闻 / 招聘任何一类数据真正接入特征仓库,研究员的提问方式都会随之变化——从”这个因子是不是显著”变成”这个事件类型在过去 5 年的累积异常收益是不是稳健”。后者的提问方式天然更接近真实交易,也更难被同行以纯数学手段复制。这才是另类数据这条战线值得长期投入的根本原因。


风险提示

本文讨论的是另类数据的采集、处理、工程化方法,不构成任何投资建议。所有具体数据源、商业产品、协议接口、代币标的、交易所均为公开信息列举,不代表对任何具体厂商、平台、代币或服务的推荐。爬取网页、调用第三方 API、处理用户生成内容涉及《数据安全法》《个人信息保护法》《反不正当竞争法》及目标平台用户协议的合规边界,使用者须自行评估并承担法律责任。文中代码均为最小可运行示例,未经工业级压力测试,不要在生产环境直接使用。文中提到的链上代币、加密资产、衍生品具有高波动性,可能导致全部本金亏损。任何实盘使用都需自行承担风险,包括但不限于:模型对未来分布失效、数据源中断、合规边界变化、极端事件下系统不可用。


九、参考资料

论文

  • Henderson, J. V., Storeygard, A., & Weil, D. N. (2012). Measuring Economic Growth from Outer Space. American Economic Review, 102(2), 994-1028.
  • Pedersen, L. H. (2022). Game On: Social Networks and Markets. Journal of Financial Economics.
  • van der Beck, P., & Jaunin, C. (2021). The Equity Market Implications of the Retail Investment Boom. Swiss Finance Institute Research Paper.
  • Bradley, D., Hanousek Jr, J., Jame, R., & Xiao, Z. (2021). Place Your Bets? The Value of Investment Research on Reddit’s WallStreetBets. SSRN.
  • Tetlock, P. C. (2007). Giving Content to Investor Sentiment: The Role of Media in the Stock Market. Journal of Finance, 62(3), 1139-1168.
  • Chen, H., De, P., Hu, Y., & Hwang, B. H. (2014). Wisdom of Crowds: The Value of Stock Opinions Transmitted Through Social Media. Review of Financial Studies, 27(5), 1367-1403.
  • Da, Z., Engelberg, J., & Gao, P. (2011). In Search of Attention. Journal of Finance, 66(5), 1461-1499.
  • Liu, X., Yang, H., Chen, Q., et al. (2020). FinBERT: A Pre-trained Financial Language Representation Model for Financial Text Mining. IJCAI.

书籍

  • López de Prado, M. (2018). Advances in Financial Machine Learning. Wiley. 第 2-3 章关于另类数据的工程化论述。
  • Denev, A., & Amen, S. (2020). The Book of Alternative Data: A Guide for Investors, Traders and Risk Managers. Wiley.
  • Kolanovic, M., & Krishnamachari, R. T. (2017). Big Data and AI Strategies: Machine Learning and Alternative Data Approach to Investing. JPMorgan Quantitative and Derivatives Strategy.
  • Antweiler, W., & Frank, M. Z. (2004). Is All That Talk Just Noise? The Information Content of Internet Stock Message Boards. Journal of Finance.

规范与文档

  • 《中华人民共和国数据安全法》(2021 年 9 月施行)。
  • 《中华人民共和国个人信息保护法》(2021 年 11 月施行)。
  • 《中华人民共和国反不正当竞争法》。
  • 中华人民共和国《刑法》第 285 条、第 286 条。
  • General Data Protection Regulation (GDPR), Regulation (EU) 2016/679.
  • California Consumer Privacy Act (CCPA), Cal. Civ. Code § 1798.100.
  • Computer Fraud and Abuse Act (CFAA), 18 U.S.C. § 1030.
  • Ethereum Yellow Paper (Wood, G., 2024 update)。
  • EIP-20: Token Standard、EIP-721: NFT Standard、EIP-4844: Shard Blob Transactions。

数据源与工具

  • RavenPack News Analytics、Bloomberg News、Refinitiv News Analytics:商业化新闻情感数据。
  • 巨潮资讯网、上交所披露易、深交所披露易、SEC EDGAR、HKEX News:官方公告原始数据。
  • 财联社、华尔街见闻、雪球、东方财富网:中文金融媒体与社区。
  • Twitter/X API、Reddit API、Pushshift Archive:社交媒体历史数据。
  • Planet Labs、Maxar、Capella Space、Sentinel-2、Landsat-9、VIIRS DNB:卫星影像与遥感。
  • Orbital Insight、RS Metrics、SpaceKnow、Kpler、Vortexa:处理后的遥感与航运指标。
  • Yodlee、Earnest Research、Second Measure、Facteus:美国信用卡与电子支付聚合数据。
  • 银联消费指数、Sensor Tower、QuestMobile、易观:中国可得的替代消费数据。
  • Etherscan、Arkham、Nansen、Glassnode、CryptoQuant、Dune Analytics:链上数据平台。
  • web3.pycryoethereum-etlsubsquidmev-inspect:链上数据采集开源工具。
  • HuggingFace Transformers、bge 系列嵌入模型、Erlangshen、FinBERT:文本与情感模型。
  • Scrapy、Playwright、Bright Data、Apify:网页采集工具。

上下篇导航

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。

2026-05-01 · quant

【量化交易】量化交易全景:从信号到订单的工程链路

量化交易不是策略写得好就能赚钱,更难的是把数据、特征、因子、信号、组合、执行、风控、复盘这八段链路在工程上连成一条不漏数据、不串时间、不丢订单的流水线。本文是【量化交易】系列的总目录与读图,给出八段链路的输入输出、失败模式、不变量清单,并用研究流程图把从一个想法到一笔实盘订单之间所有该过的卡点串起来。

2026-05-01 · quant

【量化交易】市场结构:交易所、做市商、暗池、ECN

系统梳理全球市场结构(Market Structure)的工程图景:从证券交易所、衍生品交易所、加密交易所,到做市商、暗池、ECN/ATS,再到 Maker-Taker 收费、PFOF、Reg NMS 与 MiFID II 的监管影响;给出量化策略选择交易场所的判断框架与基于 ccxt 的多交易所行情聚合代码。

2026-05-01 · quant

【量化交易】市场微结构:订单簿、价差、流动性、冲击

系统讲解市场微结构的核心概念与可计算工具:限价订单簿的数据模型、报价/有效/已实现价差、Roll 模型、四维流动性度量、Kyle's lambda、订单流不平衡(OFI)、Almgren-Chriss 框架下的临时与永久冲击、PIN 与 VPIN、Hawkes 过程,并给出基于 polars 的 L2 增量处理与系数估计代码。

2026-05-01 · quant

【量化交易】订单类型与执行语义:限价、市价、IOC、FOK、冰山

把 Limit、Market、IOC、FOK、Iceberg、Stop、MOO/MOC 这些常被混为一谈的订单类型还原为价格、数量、时效、可见性、触发五个独立维度,并对照 A 股、港股、美股、CME、Binance 五个市场的实际语义差异,给出量化系统中的订单工厂、状态机与风控前置校验的工程实现。