第八章:另类数据——卫星图像、信用卡消费、供应链数据
说到另类数据,我脑子里第一个蹦出来的画面,是2018年那次做农产品期货的惨痛经历。
当时我盯着USDA的月度报告,觉得大豆库存数据没问题。结果呢?一家做卫星图像的公司提前两周就发现,巴西马托格罗索州的农田收割进度比官方数据快了整整18%。等我反应过来,行情已经走了大半。
嗯,从那以后,我对另类数据的态度就变了。
说白了,另类数据就是那些传统金融数据源之外的信息。交易所的行情、上市公司的财报、央行的利率决议——这些是传统数据。而卫星拍的照片、超市收银台的小票、港口吊桥的起落次数——这些就是另类数据。
它们有个共同特点:比官方数据更快,比市场共识更真实。
8.1 卫星图像数据:从太空看经济
卫星图像的应用,我个人觉得是另类数据里最性感的。
你想想看,一颗卫星每天绕地球飞十几圈,拍下分辨率0.3米的照片。它能看清什么?
- 加油站的油罐车数量
- 沃尔玛停车场的车辆密度
- 农田的植被指数(NDVI)
- 港口的集装箱堆积量
- 工厂的烟囱是否冒烟
我在项目中遇到过最经典的案例,是跟踪一家大型零售商的库存情况。传统方法是什么?等季报。但季报出来的时候,股价早就反应完了。
我们用卫星图像数这家零售商全国200多家门店的停车场车辆数。每周更新一次,比季报提前6-8周。
核心逻辑:停车场车辆数 → 客流量 → 销售额 → 库存周转
这个链条里,卫星图像是第一个信号源。
具体怎么做?我给你们看一段简化版的代码思路:
# 伪代码:卫星图像处理流程
def process_satellite_image(image_path):
# 1. 加载图像
img = load_image(image_path)
# 2. 识别停车场区域(基于地理坐标裁剪)
parking_lot = crop_region(img, coordinates)
# 3. 车辆检测(用预训练的YOLO模型)
cars = detect_vehicles(parking_lot, model='yolo_v8')
# 4. 计算密度
density = len(cars) / parking_lot.area
# 5. 与历史基线对比
z_score = (density - baseline_mean) / baseline_std
return z_score # 正数表示客流量高于正常水平
这里有个坑,我曾经踩过——天气因素。下雨天停车场车辆数会明显下降,但这不代表销售额下降。所以一定要做天气校正。
避坑指南:我曾经因为没做天气校正,连续三周给出错误的信号。后来加入了NOAA的天气数据做协变量,准确率从62%提升到了89%。
8.2 信用卡消费数据:最真实的消费脉搏
信用卡数据,说白了就是消费行为的实时快照。
传统上我们看什么?社会消费品零售总额,月度发布,滞后30天。而信用卡数据呢?每天更新,T+1就能拿到。
我合作过一家数据供应商,他们聚合了全美超过1亿张信用卡的脱敏交易记录。你能看到什么?
- 耐克门店的周度销售额变化
- 星巴克早餐时段的客单价
- 亚马逊Prime会员的续费率
- 航空公司的机票预订量
举个例子。2022年Q3,市场普遍预期Target的营收增长5%。但信用卡数据显示,Target的消费金额已经连续4周下滑,同比转负。
我当时的策略很简单:做空Target的股票,同时做多沃尔玛。因为信用卡数据显示,消费者正在从Target转向沃尔玛——典型的降级消费。
结果呢?Target财报出来,营收增长-2%,股价当天跌了13%。
个人经验:信用卡数据最值钱的地方,不是绝对值,而是趋势变化。我习惯看4周移动平均的同比增速,比单周数据稳定得多。
处理信用卡数据时,要注意几个问题:
- 样本偏差——信用卡用户本身就有偏,低收入群体覆盖率低
- 季节性——黑五、圣诞、返校季,这些效应要剥离
- 数据清洗——退款、欺诈交易、大额异常值,都要处理
# 信用卡数据清洗示例
def clean_credit_card_data(df):
# 移除退款交易(金额为负且标记为refund)
df = df[~df['transaction_type'].isin(['refund', 'chargeback'])]
# 剔除极端异常值(超过99.5分位数)
upper_limit = df['amount'].quantile(0.995)
df = df[df['amount'] <= upper_limit]
# 季节性调整(用去年同期的数据做基准)
df['seasonal_factor'] = df.groupby('store_id')['amount'] \
.transform(lambda x: x.shift(52))
df['adjusted_amount'] = df['amount'] / df['seasonal_factor']
return df
8.3 供应链数据:看得见的物流网络
供应链数据,是我最近两年花精力最多的领域。
为什么?因为疫情之后,供应链成了最大的不确定性来源。谁先拿到供应链数据,谁就掌握了定价权。
供应链数据有哪些来源?
| 数据源 | 具体指标 | 更新频率 | 领先时间 |
|---|---|---|---|
| 港口数据 | 集装箱吞吐量、船舶等待时间 | 每日 | 领先财报4-8周 |
| 物流追踪 | 卡车运输时长、仓库库存 | 实时 | 领先财报2-4周 |
| 海关数据 | 进出口报关单、关税支付 | 每周 | 领先财报6-12周 |
| 供应商数据 | 订单取消率、交货延迟天数 | 每日 | 领先财报8-12周 |
我记得有一次,一家做消费电子的公司,股价一直在涨。但供应链数据显示,他们在越南的供应商交货延迟天数从5天飙升到了23天。
这意味着什么?意味着他们的产品没法按时交付。营收要出问题。
我当时做空了这只股票。两周后,公司发布盈利预警,股价跌了28%。
核心指标:我建议重点关注「订单取消率」和「交货延迟天数」这两个指标。它们比营收数据领先至少一个季度。
供应链数据的处理,有个难点——数据异构。港口数据是CSV格式,物流追踪是API接口,海关数据可能是PDF扫描件。你需要一个统一的数据管道。
# 供应链数据聚合示例
class SupplyChainAggregator:
def __init__(self):
self.sources = {
'port': PortDataSource(),
'logistics': LogisticsAPI(),
'customs': CustomsPDFParser()
}
def get_leading_indicator(self, company_id):
# 从三个数据源分别获取信号
port_score = self.sources['port'].get_delay_score(company_id)
logistics_score = self.sources['logistics'].get_on_time_rate(company_id)
customs_score = self.sources['customs'].get_import_volume(company_id)
# 加权合成综合指标
composite = (0.4 * port_score +
0.35 * logistics_score +
0.25 * customs_score)
return composite
注意:供应链数据的时间戳对齐是个大问题。港口数据可能是UTC时间,物流数据是当地时间,海关数据是工作日历。我建议统一转为Unix时间戳,再按交易日对齐。
8.4 三种数据的融合策略
单独用某一种另类数据,效果有限。真正的价值在于融合。
我举个例子。假设你要判断一家零售商的业绩:
- 卫星图像告诉你:停车场车辆数下降了12%
- 信用卡数据告诉你:同店销售额下降了8%
- 供应链数据告诉你:仓库库存增加了15%
三个信号指向同一个方向——这家公司要出问题。而且每个信号都领先于财报。
我个人习惯的做法是:
- 先用卫星图像做初筛(覆盖面广,但精度一般)
- 再用信用卡数据做验证(精度高,但样本有偏)
- 最后用供应链数据做确认(领先性强,但获取成本高)
三个信号一致,才下重注。
下面这张图,是我自己常用的另类数据融合框架:
这个框架的核心思想是:不要依赖单一信号。每个数据源都有噪声,但三个独立信号同时出错的概率极低。
我的建议:刚开始接触另类数据,不要贪多。选一个你最熟悉的行业,找两到三个数据源,跑通一个完整的信号链。比什么都想做、什么都做不深要强得多。
另类数据这个领域,说白了就是信息不对称的套利。谁先拿到真实数据,谁就能在价格发现中占得先机。但要注意,数据质量比数据数量重要一百倍。我见过太多人,花大价钱买了垃圾数据,最后亏得比谁都惨。
嗯,今天就聊到这里。记住:卫星图像看趋势,信用卡数据看验证,供应链数据看确认。三个信号对齐,再动手不迟。