Signal 8 — Intraday Seasonality
| Thuộc tính | Giá trị |
|---|---|
| Phân loại | Temporal / Calendar Effect |
| Khung thời gian | Intraday 15–30 phút buckets |
| Paper gốc | Heston-Korajczyk-Sadka (2010) |
| Loại dữ liệu | Multi-year intraday OHLCV |
| Hướng giao dịch | Long/Short theo bucket |
| Capacity | Cao |
Logic. Group dữ liệu lịch sử theo (hour, minute) bucket và tính expected return + Sharpe cho mỗi bucket. Trade các bucket có Sharpe > 1.0 với hướng phù hợp (ví dụ: VN30F có pattern reversal 30 phút cuối phiên). Cập nhật map seasonality mỗi quý.
Code Python.
python
def seasonality_map(df, return_col='ret_15m'):
"""df cần có DatetimeIndex và cột return."""
df = df.copy()
df['bucket'] = df.index.strftime('%H:%M')
grouped = df.groupby('bucket')[return_col].agg(['mean', 'std', 'count'])
grouped['sharpe'] = grouped['mean'] / grouped['std'] * np.sqrt(252 * 26)
return grouped
def seasonality_signal(now_bucket, season_map, sharpe_threshold=1.0):
if now_bucket not in season_map.index:
return 0
row = season_map.loc[now_bucket]
if row['sharpe'] > sharpe_threshold:
return 1
if row['sharpe'] < -sharpe_threshold:
return -1
return 0QuantConnect setup. Trong Initialize, load season_map từ ObjectStore (hoặc tính từ history). Schedule entry/exit theo TimeRules.At(hour, minute) cho mỗi bucket signal-positive. Cảnh báo overfitting: yêu cầu tối thiểu 30 observations/bucket và t-stat > 2.5 trước khi trade.