3月量化总结

剥离行业beta

这个alpha是从论坛看来的,
核心模板如下:

1
2
3
total_trend = <ts_op/>(clean_data_A, 30);
alpha_trend = <ts_op/>(group_neutralize(clean_data_B, sector), 30);
signal = total_trend - alpha_trend;

alpha_trend 是一种行业风险,然后从 total_trend 中将风险剥离。
clean_data_A 和 clean_data_B 可以是同一字段,但是我后来发现clean_data_B使用risk和other中的字段,表现很好。

几个实例

data_A和data_B可供选择的数据集有很多,institution,other,risk,model,pv,fnd都跑出来了不错的alpha

1
2
3
4
5
6
7
8
data_A = quantity_institutional_shares_acquired;
data_B = residualized_return_india_equity_universe;
clean_data_A = ts_backfill(data_A, 30);
clean_data_B = ts_backfill(data_B, 30);
total_trend = ts_zscore(clean_data_A, 30);
alpha_trend = ts_zscore(group_neutralize(clean_data_B, sector), 30);
signal = total_trend - alpha_trend;
group_rank(signal, sector)

Sharpe 2.79
Turnover 28.51%
Fitness 1.86
Returns 12.73%
Drawdown 3.99%
Margin 8.93‱

在other数据集中,data_B使用oth335_combined_all_region_hedge也取得了不错的表现:

Sharpe 2.34
Turnover 20.59%
Fitness 1.82
Returns 12.41%
Drawdown 8.50%
Margin 12.06‱

还有用other+model进行构造的,beta_relative_to_country这个数据字段本身就代表了一种beta。

1
2
3
4
5
6
7
8
data_A = oth335_combined_all_region_hedge;
data_B = beta_relative_to_country;
clean_data_A = ts_backfill(data_A, 10);
clean_data_B = ts_backfill(data_B, 10);
total_trend = ts_av_diff(clean_data_A, 55);
alpha_trend = ts_av_diff(group_neutralize(clean_data_B, sector), 55);
signal = total_trend - alpha_trend;
group_scale(signal, sector)

Sharpe 2.82
Turnover 17.72%
Fitness 2.71
Returns 16.38%
Drawdown 5.65%
Margin 18.50‱

deepseek对这个alpha的经济学逻辑解释:
如果一只股票变得对市场(国家指数)更敏感(beta 上升),那么它未来的收益中会更多来自市场上涨,而不是真正的 alpha。
在对冲模型中,我们想要的是真正的、不依赖市场上涨的收益来源。
因此,剔除 beta 相对行业上升的股票,可以避免买入“伪趋势”——即只是因为市场敏感度提高而看起来变好的股票。

但是这个模板主要生效在IND TOP500,在USA尝试过几个数据集,没什么信号。

条件动量模板

condition = clean_data_pos - clean_data_neg
这里的pos和neg来自sentiment字段
核心逻辑:raw_signal = (if_else(condition > 0, returns, 0), 5),这只股票在过去一段时间里,只有在“多头显著强于空头”的时期,它的收益才被计入信号;其他时期的收益被忽略。

1
2
3
4
5
6
7
8
data_pos = snt21_5pos_min;
data_neg = snt21_3neg_mean;
clean_data_pos = ts_backfill(data_pos,5);
clean_data_neg = ts_backfill(data_neg,5);
condition = clean_data_pos - clean_data_neg;
raw_signal=ts_decay_linear(if_else(condition > 0, returns, 0), 5);
smooth_sig = -group_scale( raw_signal, industry);
smooth_sig

Sharpe 2.78
Turnover 24.38%
Fitness 2.09
Returns 13.78%
Drawdown 6.48%
Margin 11.30‱

这个alpha是IND TOP500的sent21来的。也是这个模板使我第一次解锁了IND的sent字段,但是因为returns是一个pv字段,pv用多了会警告,所以产出的alpha不多,点完塔就没有再提交了。

这个模板还可以改进成分析师形态,我用在USA尝试了一下,效果还是不错的,但是PC太高了,而且margin较低。
下面就是一个例子:

1
2
3
4
5
data = anl44_netprofit_rep_best_eeps_nxt_yr;
clean_data = ts_backfill(data,10);
condition = clean_data;
raw_signal=ts_zscore(if_else(condition > 0, returns, 0), 120);
-group_rank(raw_signal, industry)

Sharpe 2.03
Turnover 77.91%
Fitness 0.84
Returns 13.20%
Drawdown 5.44%
Margin 3.39‱

情绪+波动率复合

来自论坛的模板,sigmod其实就是rank
然后这个log我替换成了
模板: log(1 + sigmoid(ts_zscore(, )) * sigmoid(ts_zscore(, )))

| 占位符 | 可选值 | 说明 |
|--------|--------|------|
| `<sentiment_field/>` | 情绪字段 | 情绪数据 |
| `<volatility_field/>` | `option8_*`, 波动率字段 | 波动率数据 |
| `<d1/>` | `30`, `66` | 情绪窗口 |
| `<d2/>` | `30`, `66` | 波动率窗口 |

核心信号:

1
2
3
4
raw_signal = multiply(
ts_mean(clean_sent_data, 60),
ts_mean(clean_vol_data, 5)
)

信号 = 长期最强多头情绪 × 短期做空兴趣.当最强多头情绪和短期做空兴趣同时处于高位时,代表该股票处于多空博弈的临界点。这不是简单的“拥挤”,而是意见高度分歧、即将选择方向。

这个模板在3月主要是在EUR跑。

1
2
3
4
5
gp = group_cartesian_product(country, industry);
clean_sent_data = ts_backfill(snt21_4pos_max, 10);
clean_vol_data = ts_backfill(short_interest_europe_factor_score, 10);
raw_signal = multiply( ts_mean( clean_sent_data, 60), ts_mean(clean_vol_data, 5));
-group_neutralize(raw_signal, gp)

Sharpe 2.60
Turnover 4.67%
Fitness 1.94
Returns 6.98%
Drawdown 2.15%
Margin 29.85‱

1
2
3
4
5
6
7
8
gp = industry;
clean_sent_data = ts_backfill(vec_avg(oth553_recvalue), 10);
clean_vol_data = ts_backfill(vec_max(rsk60_last), 10);
z_sent = group_zscore(ts_mean(clean_sent_data, 30), gp);
z_vol = group_zscore(ts_mean(clean_vol_data, 30), gp);
raw_signal = add(z_sent, z_vol);
cross = -group_neutralize(winsorize(raw_signal, std=3), gp);
cross

Sharpe 2.00
Turnover 7.69%
Fitness 1.50
Returns 7.04%
Drawdown 6.58%
Margin 18.32‱