4、重复拍卖模型:重复销售法(Repeat Sales Model)

聊到艺术品估值,很多人第一反应是「找个专家看一眼」。但专家也有看走眼的时候,对吧?我做了这么多年量化模型,最深的体会是:数据不会骗人,但数据太少会骗人

重复销售法,说白了就是盯住同一件作品,看它两次拍卖之间的价格变化。你想想看,同一幅画,2010年卖了100万,2015年卖了150万,这50%的涨幅就是最真实的回报率。不用管什么流派、尺寸、艺术家名气,因为作品本身没变,变的只是市场情绪。

核心思想: 同一件艺术品在两次拍卖中的价格差异,完全归因于市场整体走势。个体差异被「同一件作品」这个条件完美控制了。

4.1 原理:为什么重复销售法靠谱?

传统hedonic模型需要控制一大堆特征——尺寸、题材、技法、艺术家年龄……说实话,我早期做hedonic模型时,光特征工程就折腾了两个月。而且有些特征根本量化不了,比如「这幅画的构图是否和谐」。

重复销售法绕开了这个坑。它的逻辑很简单:

  • 同一件作品,所有物理特征不变
  • 两次拍卖,价格变化只反映市场波动
  • 多件作品,取平均就能得到市场指数

数学上,我们假设作品 i 在时间 t 的价格为 Pit,那么:

ln(P_it) = α_t + β_i + ε_it

其中 αt 就是我们要估计的市场指数,βi 是作品个体效应。两次拍卖相减,βi 就消掉了:

ln(P_i,t2) - ln(P_i,t1) = α_t2 - α_t1 + (ε_i,t2 - ε_i,t1)

嗯,这里要注意:这个模型假设两次拍卖之间的时间间隔内,作品没有发生任何变化。比如没有修复、没有重新装裱、没有损坏。我在项目中遇到过一幅画,第一次拍卖时品相完好,第二次拍卖前被水泡过,价格直接腰斩。这种数据必须剔除。

⚠ 重要提醒: 重复销售法对数据质量要求极高。同一件作品的两次拍卖必须精确匹配,包括作品名称、尺寸、材质、签名位置等。我曾经因为两幅同名但尺寸不同的作品没区分开,导致指数计算出现严重偏差。

4.2 构建重复拍卖数据集

这一步是体力活,也是技术活。我习惯把流程分成四个阶段:

  1. 数据清洗:从拍卖行数据库提取所有成交记录,去重、标准化作品名称
  2. 匹配对生成:按作品唯一标识(如作品ID、艺术家+名称+尺寸)进行自连接
  3. 时间筛选:只保留两次拍卖时间不同的记录,且间隔至少6个月
  4. 异常剔除:剔除价格变化超过10倍或低于0.1倍的极端值

给你看一段我常用的Python代码,用于生成重复销售对:

import pandas as pd
import numpy as np

# 假设df包含字段:work_id, sale_date, price_usd
# 按作品ID分组,筛选出现次数≥2的作品
repeat_works = df.groupby('work_id').filter(lambda x: len(x) >= 2)

# 对每个作品,按时间排序,生成相邻拍卖对
def generate_pairs(group):
    group = group.sort_values('sale_date')
    pairs = []
    for i in range(len(group)-1):
        pairs.append({
            'work_id': group.iloc[i]['work_id'],
            't1': group.iloc[i]['sale_date'],
            't2': group.iloc[i+1]['sale_date'],
            'p1': group.iloc[i]['price_usd'],
            'p2': group.iloc[i+1]['price_usd']
        })
    return pd.DataFrame(pairs)

pairs_df = repeat_works.groupby('work_id').apply(generate_pairs).reset_index(drop=True)

# 计算对数收益率
pairs_df['log_return'] = np.log(pairs_df['p2'] / pairs_df['p1'])
pairs_df['interval_years'] = (pairs_df['t2'] - pairs_df['t1']).dt.days / 365.25
💡 个人经验: 匹配时别只看作品名称。我建议加上「艺术家ID + 作品名称 + 尺寸(精确到厘米)」三个字段联合匹配。有些作品名称一样,但尺寸不同,其实是两幅不同的画。

4.3 计算市场指数

有了重复销售对,接下来就是回归。我们用OLS估计每个时间段的 αt

import statsmodels.api as sm

# 构建哑变量矩阵:每个时间段一个哑变量
# 假设我们有T个时间段(比如按季度划分)
T = 40  # 10年,每季度一个
dummies = np.zeros((len(pairs_df), T))

for idx, row in pairs_df.iterrows():
    t1_idx = get_quarter_index(row['t1'])  # 自定义函数
    t2_idx = get_quarter_index(row['t2'])
    dummies[idx, t1_idx] = -1  # 卖出时哑变量为-1
    dummies[idx, t2_idx] = 1   # 买入时哑变量为1

# 去掉第一个时间段作为基准
X = dummies[:, 1:]
y = pairs_df['log_return'].values

model = sm.OLS(y, X).fit()
alpha_estimates = model.params

# 计算指数值(基准时间段设为100)
index_values = np.zeros(T)
index_values[0] = 100
for t in range(1, T):
    index_values[t] = index_values[t-1] * np.exp(alpha_estimates[t-1])

跑完回归,你会得到一条市场指数曲线。我2018年用这个方法算过中国当代艺术市场,发现2008-2012年那波暴涨暴跌,指数从100冲到280,又跌回120。跟实际市场感受完全吻合。

关键点: 指数值代表的是「相对于基准期的价格水平」。比如指数150,意味着市场整体比基准期涨了50%。个体作品的收益率,就是它自己的对数收益率减去同期市场指数的对数收益率。

4.4 个体作品收益率计算

市场指数是「平均」,个体作品是「个体」。两者的差值,就是超额收益:

# 计算每件作品的超额收益
pairs_df['market_return'] = pairs_df.apply(
    lambda row: np.log(index_values[get_quarter_index(row['t2'])] / 
                       index_values[get_quarter_index(row['t1'])]), 
    axis=1
)
pairs_df['excess_return'] = pairs_df['log_return'] - pairs_df['market_return']

# 按作品聚合,得到每件作品的长期超额收益
work_performance = pairs_df.groupby('work_id')['excess_return'].mean().reset_index()
work_performance.columns = ['work_id', 'avg_excess_return']

这个超额收益,才是我们真正关心的东西。它告诉你:这幅画跑赢市场了吗?

我个人的经验是,超额收益在±5%以内的作品,基本可以视为「跟随市场」。超过±15%的,要么是黑马,要么是泡沫。2019年我跟踪过一批年轻艺术家的作品,其中一位的超额收益连续三年超过20%,后来果然被大画廊签约了。

💡 避坑指南: 我曾经用重复销售法算某位艺术家的作品收益率,发现异常高。后来一查,原来他早期作品被低估,后期突然被市场认可,但中间间隔了15年。这种「长间隔」数据会放大收益率,建议设置最大间隔不超过10年。

4.5 知识体系总览

下面这张图,是我自己梳理的重复销售法完整流程。你看一眼就能明白整个逻辑链条:

重复销售法知识体系 数据准备 拍卖记录清洗 匹配对生成 作品ID+尺寸匹配 回归建模 OLS估计α_t 市场指数 指数曲线(基准=100) 个体收益率 超额收益计算 最终输出 市场指数 + 个体超额收益排名 核心逻辑:同一作品两次拍卖 → 价格变化 → 分解为市场效应 + 个体效应 关键参数 最小间隔6月 | 最大间隔10年

4.6 几个必须注意的坑

做重复销售法这么多年,我踩过的坑不少。挑几个典型的说说:

  • 样本选择偏差:只有频繁交易的作品才能进入模型。那些「只卖过一次」的作品被排除在外。这意味着指数可能偏向流动性好的作品,而低估了冷门作品的表现。
  • 时间聚集效应:同一件作品在短期内频繁交易,可能是投机行为。我建议剔除一年内重复交易的数据,这些大多是短线炒作。
  • 价格区间偏差:高价作品和低价作品的波动率不同。如果样本中高价作品占比过高,指数会被拉偏。可以按价格分层计算,再加权平均。
⚠ 特别注意: 重复销售法假设两次拍卖之间的市场波动是「均匀」的。但现实中,市场可能在某个季度暴涨,另一个季度暴跌。如果间隔太长,这个假设就不成立了。我一般把间隔控制在3年以内,超过5年的数据会打折扣处理。

好了,重复销售法就讲到这里。这套方法虽然简单,但非常实用。我自己的投资组合里,有30%的仓位就是靠这个模型筛选出来的。数据不会说谎,关键是你怎么用它。

专注资料整理