Synthetic Control Methods for Evaluating Trading Strategies
Seri ini telah lama membahas satu jalur menuju edge palsu: seleksi. Deflated Sharpe Ratio menilai pemenang dari suatu pencarian. Probability of Backtest Overfitting menilai pencariannya sendiri. Hasil negatif yang jujur adalah yang terjadi ketika keduanya diterapkan pada strategi yang memang ingin Anda perdagangkan. Perangkat itu menjawab satu pertanyaan dengan baik: apakah saya menemukan ini karena terlalu sering mencarinya?
Perangkat itu tidak menyentuh jalur kedua yang sepenuhnya berbeda: confounding. Anda mengubah satu hal — menerapkan algoritma eksekusi baru, mengganti parameter, atau bereaksi terhadap suatu regime — lalu performa meningkat. Tidak ada pencarian. Tidak ada masalah multiple testing. Namun peningkatan itu tetap mungkin tidak ada hubungannya dengan Anda, karena volatilitas berlipat ganda pada minggu saat Anda menerapkannya. Deflasi sebesar apa pun tidak dapat menangkapnya, karena deflasi mengoreksi banyak percobaan sementara Anda hanya menjalankan satu.
Synthetic Control Method (SCM), yang dikembangkan oleh Abadie dan Gardeazabal (2003) lalu disempurnakan oleh Abadie, Diamond, dan Hainmueller (2010, 2015), menyerang confounding secara langsung. Metode ini membangun counterfactual — kombinasi berbobot dari instrumen yang tidak Anda sentuh, dipilih agar mengikuti instrumen yang diberi treatment dengan dekat sebelum intervensi. Divergensi keduanya setelah intervensi menjadi estimasi efek Anda. Yang penting, SCM memiliki kriteria falsifikasi yang memberi tahu kapan counterfactual yang kredibel tidak dapat dihasilkan, serta p-value berbasis permutasi yang tidak mengharuskan Anda mempercayai cerita asimtotik apa pun.
Mengapa Alternatif yang Jelas Gagal

Perbandingan sebelum-sesudah mencampuradukkan intervensi dengan semua hal lain yang berubah pada tanggal tersebut. Perbandingan dengan satu instrumen benchmark gagal karena tidak ada satu aset pun yang mengikuti aset Anda — ini adalah Single Instrument Trap dari arah sebaliknya: jika struktur idiosinkratik satu instrumen dapat memalsukan edge, struktur idiosinkratik satu instrumen juga dapat memalsukan sebuah control. Donor pool SCM adalah jawaban formal atas keberatan itu: alih-alih memilih satu aset pembanding, biarkan data periode sebelum intervensi memilih keranjang berbobot.
Difference-in-differences layak dibahas lebih dari satu kalimat karena merupakan alternatif yang nyaris tepat. DiD membandingkan perubahan unit yang diberi treatment dengan perubahan kelompok control, dan mengidentifikasi efek hanya di bawah parallel trends: tanpa intervensi, treatment dan control akan bergerak bersama. Dalam pasar keuangan, asumsi itu hampir tidak dapat dipertahankan — aset berbeda dalam beta, regime volatilitas, tingkat likuiditas, dan jalur relatifnya berubah-ubah. SCM mengganti asumsi dengan objek yang di-fit: alih-alih mengasumsikan control yang bergerak paralel, SCM membangun control lalu menunjukkan seberapa baik control itu benar-benar mengikuti. Jika hasilnya buruk, Anda diminta berhenti.
Metode

Setup dan Notasi
Pertimbangkan unit (aset, strategi, atau portofolio) yang diamati selama periode. Unit 1 adalah treated unit — aset atau strategi tempat Anda melakukan intervensi. Unit membentuk donor pool berisi unit tanpa treatment yang sebanding.
Misalkan menyatakan outcome treated unit pada waktu dengan intervensi, dan outcome tanpa intervensi. Treatment effect pada waktu adalah:
Kita mengamati secara langsung. Seluruh masalahnya adalah mengestimasi .
Membangun Synthetic Control
SCM mengestimasi sebagai rata-rata berbobot dari outcome donor:
di mana vektor bobot memenuhi untuk semua dan .
Dua kendala ini benar-benar penting. Keduanya memaksa synthetic control menjadi convex combination donor, sehingga mencegah extrapolation di luar support data. Regresi tanpa kendala dapat menghasilkan counterfactual yang dibangun dari posisi long 3,4x pada satu koin melawan short 2,4x pada koin lain — secara numerik cocok dengan sangat baik pada periode sebelum intervensi, tetapi counterfactual itu tidak mewakili portofolio yang dapat dimiliki siapa pun. Kendala convexity membuat counterfactual dapat ditafsirkan dan bobotnya sparse: biasanya hanya segelintir donor yang mendapat bobot nonzero, dan Anda dapat membacanya.
Pemilihan Bobot Optimal
Bobot dipilih untuk meminimalkan jarak antara treated unit dan synthetic control pada periode sebelum intervensi:
di mana adalah vektor karakteristik treated unit sebelum intervensi, adalah matriks karakteristik yang sama untuk donor pool, dan adalah matriks diagonal positive semi-definite yang memberikan tingkat kepentingan pada setiap prediktor.
dipilih melalui cross-validation: pilih sehingga yang dihasilkan meminimalkan mean squared prediction error (MSPE) outcome pada periode sebelum intervensi. Ini adalah nested optimization — loop luar atas dan penyelesaian berbatas di dalam untuk .
Variabel Prediktor untuk Aplikasi Trading
Jika Abadie et al. menggunakan GDP per kapita dan komposisi industri, aplikasi trading membutuhkan:
- Karakteristik return: rata-rata return, volatilitas, skewness, kurtosis selama periode sebelum intervensi
- Ukuran likuiditas: spread rata-rata, volume harian, rasio illiquidity Amihud
- Fitur microstructure: order flow imbalance, tingkat kedatangan transaksi, rasio quote-to-trade
- Eksposur faktor: beta terhadap faktor market, momentum, value, dan volatilitas
- Outcome tertunda: nilai PnL kumulatif pada beberapa tanggal sebelum intervensi
Outcome tertunda paling penting. Abadie et al. (2010) menunjukkan bahwa jika synthetic control cocok dengan treated unit pada outcome tertunda selama window panjang sebelum intervensi, secara implisit ia mengendalikan confounder yang tidak teramati di bawah model faktor linear — inilah alasan utama metode ini layak digunakan. Anda tidak diwajibkan menyebut confounder yang mendorong PnL. Anda diwajibkan menemukan donor yang juga terekspos terhadapnya.
Penerapannya

Skenario 1: Mengevaluasi Algoritma Eksekusi Baru
Anda menerapkan jadwal TWAP baru pada satu instrumen dan ingin mengetahui efeknya terhadap implementation shortfall. Metrik dan keluarga algoritmanya dibahas secara mendalam di tempat lain — lihat implementation shortfall dan TCA untuk dekomposisi biaya dan algoritma TWAP/VWAP/POV untuk scheduler-nya. Kontribusi SCM adalah lapisan evaluasi di atasnya: donor pool berupa instrumen yang masih menjalankan scheduler lama pada window yang sama, sehingga perubahan spread atau volume di seluruh venue berdampak pada treated dan donor secara bersamaan.
Periode sebelum intervensi: 60 hari trading sebelum pergantian. Periode setelah intervensi: 30 hari trading sesudahnya. Estimasi efeknya adalah gap:
Jika scheduler baru benar-benar mengurangi biaya, secara konsisten setelah — dan yang lebih penting, gap treated berada di luar cloud gap donor.
Skenario 2: Dampak Peristiwa Pasar
Perubahan fee schedule, pilot tick size, pajak transaksi, atau aturan circuit breaker berdampak pada satu venue. Treated unit: strategi Anda pada venue yang terdampak. Donor pool: pair yang sama pada venue yang tidak terdampak perubahan. Efek struktur biaya terhadap eksekusi dibahas terpisah dalam maker-taker fees dan rebate; SCM mengubah pernyataan "fill kami memburuk setelah perubahan" menjadi estimasi dengan null.
Skenario 3: Pergantian Strategi Bersyarat Regime
Anda beralih dari mean-reversion ke momentum pada satu aset ketika sinyal regime detection aktif. Apakah pergantian itu mengungguli strategi yang tetap? Donor pool: aset serupa ketika sinyal aktif tetapi Anda tidak beralih. Perhatikan jebakannya — jika sinyal regime aktif di seluruh pasar, donor Anda juga terkena treatment dan desainnya runtuh. Lihat aturan spillover di bawah.
Uji Placebo dan Inferensi

Inferensi SCM berbasis permutasi. Kasus umum untuk membangun null empiris melalui resampling, alih-alih mempercayai distribusi bentuk tertutup, dibahas dalam metode Monte Carlo dan bootstrap untuk backtest; berikut ini adalah konstruksi khusus SCM.
Placebo In-Time
Geser tanggal intervensi mundur ke periode sebelum intervensi — misalnya ke pertengahan — lalu jalankan ulang. Jika SCM menemukan "treatment effect" pada tanggal ketika tidak terjadi apa-apa, SCM menangkap divergensi yang sudah ada, bukan intervensi Anda. Synthetic control yang kredibel tidak menunjukkan efek pada tanggal intervensi palsu.
Placebo In-Space (Uji Permutasi)
Terapkan seluruh prosedur SCM pada setiap donor, dengan menganggap masing-masing secara bergantian sebagai treated unit:
- Untuk setiap donor , bangun synthetic control dari donor yang tersisa ditambah treated unit asli.
- Hitung gap setelah intervensi .
- Bandingkan gap treated unit dengan distribusi gap placebo.
P-value adalah sebuah rank:
di mana
Rasio, bukan gap mentah periode setelah intervensi, adalah statistik yang tepat: donor yang tidak pernah di-fit dengan baik akan menunjukkan gap besar setelah intervensi karena alasan yang tidak berkaitan dengan intervensi apa pun, dan membaginya dengan MSPE sebelum intervensi memberikan penalti tepat untuk kondisi itu.
Ini adalah langkah inferensial yang sama dengan yang dilakukan Deflated Sharpe Ratio — rangking kandidat Anda di dalam distribusi referensi empiris, bukan terhadap nol. DSR merangking pemenang terhadap null best-of-N di antara percobaan; SCM merangking treated unit terhadap null di antara unit. Estimator berbeda, disiplin sama, dan peringatan yang sama berlaku: dengan donor, p-value terkecil yang dapat dicapai adalah . Uji permutasi tidak dapat memberikan resolusi melampaui granularitasnya sendiri, sehingga donor pool kecil membatasi signifikansi yang berhak Anda klaim, betapapun besar efeknya terlihat.
Penyaringan Praktis
Abadie et al. merekomendasikan mengecualikan unit placebo dengan fit buruk sebelum intervensi — pre-MSPE lebih dari kali milik treated unit, dengan biasanya 2 hingga 20. Placebo dengan fit buruk memiliki penyebut kecil dan menghasilkan rasio MSPE yang sangat besar, mencemari distribusi referensi dan membuat treated unit tampak biasa saja. Laporkan rasio pada beberapa threshold; jika p-value hanya signifikan pada satu nilai tertentu, Anda menemukan tuning parameter, bukan efek.
Implementasi

Kode di bawah hanya menggunakan numpy dan scipy agar mekanismenya terlihat. Alternatif production — SparseSC (Microsoft Research), pysyncon, SyntheticControlMethods — menangani edge case dan memiliki skalabilitas lebih baik.
Konstruksi Matriks Prediktor
import numpy as np
import pandas as pd
from scipy.optimize import minimize
def build_predictors(series: pd.Series, T0: int) -> np.ndarray:
"""
Extract predictor vector from pre-intervention data.
Features: mean return, volatility, skewness, kurtosis,
plus lagged outcome values at regular intervals.
"""
pre = series.iloc[:T0]
daily_ret = pre.diff().dropna()
stats = [
daily_ret.mean(),
daily_ret.std(),
daily_ret.skew(),
daily_ret.kurtosis(),
]
lag_indices = np.linspace(0, T0 - 1, 5, dtype=int)
lags = pre.iloc[lag_indices].values.tolist()
return np.array(stats + lags)
df di sini adalah panel cumulative return — treated unit pada kolom 0, donor pada kolom lainnya, satu baris per bar. Gunakan cumulative return, bukan level harga.
X1 = build_predictors(df["Treated"], T0).reshape(-1, 1) # (k x 1)
X0 = np.column_stack([ # (k x J)
build_predictors(df[col], T0) for col in df.columns[1:]
])
Optimasi Bobot
def solve_weights(
X1: np.ndarray,
X0: np.ndarray,
Y1_pre: np.ndarray,
Y0_pre: np.ndarray,
) -> np.ndarray:
"""
Solve for optimal synthetic control weights.
Nested optimization:
Outer: optimize V (predictor importance)
Inner: optimize w (donor weights) given V
"""
k = X1.shape[0]
J = X0.shape[1]
def solve_w_given_V(V_diag: np.ndarray) -> np.ndarray:
"""Inner: find w minimizing weighted predictor distance."""
V = np.diag(V_diag)
def objective(w):
gap = X1.flatten() - X0 @ w
return gap @ V @ gap
constraints = {"type": "eq", "fun": lambda w: np.sum(w) - 1.0}
bounds = [(0, 1)] * J
w0 = np.ones(J) / J
result = minimize(objective, w0, method="SLSQP",
bounds=bounds, constraints=constraints,
options={"maxiter": 1000, "ftol": 1e-12})
return result.x
def outer_objective(V_diag: np.ndarray) -> float:
"""Outer: minimize pre-period MSPE given V."""
w = solve_w_given_V(np.abs(V_diag))
return np.mean((Y1_pre - Y0_pre @ w) ** 2)
V0 = np.ones(k)
result = minimize(outer_objective, V0, method="Nelder-Mead",
options={"maxiter": 5000, "xatol": 1e-8})
return solve_w_given_V(np.abs(result.x))
Y1_pre = df["Treated"].iloc[:T0].values
Y0_pre = df.iloc[:T0, 1:].values
weights = solve_weights(X1, X0, Y1_pre, Y0_pre)
for col, w in zip(df.columns[1:], weights):
if w > 0.01:
print(f" {col}: {w:.4f}")
Gap series kemudian adalah df["Treated"].values - df.iloc[:, 1:].values @ weights, yang diplot terhadap tanggal intervensi bersama gap donor dari placebo run di bawah.
Uji Placebo
def run_placebo_tests(df: pd.DataFrame, T0: int) -> pd.DataFrame:
"""In-space placebo: treat each unit in turn as if intervened upon."""
results = []
all_columns = df.columns.tolist()
for placebo_col in all_columns:
donor_cols = [c for c in all_columns if c != placebo_col]
donor_df = df[donor_cols]
X1_p = build_predictors(df[placebo_col], T0).reshape(-1, 1)
X0_p = np.column_stack([
build_predictors(donor_df[c], T0) for c in donor_cols
])
w_p = solve_weights(
X1_p, X0_p,
df[placebo_col].iloc[:T0].values,
donor_df.iloc[:T0].values,
)
gap_p = df[placebo_col].values - donor_df.values @ w_p
mspe_pre = np.mean(gap_p[:T0] ** 2)
mspe_post = np.mean(gap_p[T0:] ** 2)
results.append({
"unit": placebo_col,
"mspe_pre": mspe_pre,
"mspe_post": mspe_post,
"mspe_ratio": mspe_post / mspe_pre if mspe_pre > 1e-10 else np.inf,
"gap_series": gap_p,
"is_treated": placebo_col == "Treated",
})
return pd.DataFrame(results)
placebo_results = run_placebo_tests(df, T0)
treated_pre = placebo_results.loc[placebo_results["is_treated"], "mspe_pre"].values[0]
filtered = placebo_results[placebo_results["mspe_pre"] <= 5 * treated_pre]
treated_ratio = filtered.loc[filtered["is_treated"], "mspe_ratio"].values[0]
p_value = (filtered["mspe_ratio"] >= treated_ratio).sum() / len(filtered)
print(f"MSPE ratio (treated): {treated_ratio:.2f} p = {p_value:.3f}")
Kalibrasi Estimator
Ada demonstrasi yang layak dijalankan dan ada demonstrasi yang layak ditolak. Menghasilkan data panel sintetis, menyuntikkan efek +0,3%/hari, memulihkan kira-kira +0,3%/hari, lalu menyajikannya sebagai bukti hanya membuktikan bahwa SLSQP konvergen. Ini bersifat sirkular, dan blog ini tidak mempublikasikannya.
Data sintetis berguna untuk kalibrasi — standar yang sama diterapkan dalam artikel DSR dan PBO, di mana null yang diketahui membuat statistik dapat dipercaya. Ada dua pemeriksaan, keduanya dijalankan pada data yang dihasilkan dari model faktor linear dengan jumlah donor dan panjang periode sebelum intervensi yang benar-benar Anda miliki:
- Power pada effect size yang diketahui. Suntikkan efek dengan magnitudo yang diketahui. Apakah gap setelah intervensi yang diestimasi memulihkannya, dan dengan error berapa? Turunkan effect size hingga pemulihan gagal — batas itu adalah efek terkecil yang dapat dideteksi geometri panel Anda, dan hasil nyata apa pun di bawahnya adalah noise terlepas dari p-value-nya.
- Size di bawah null sejati. Suntikkan tidak ada apa-apa. Jalankan seluruh pipeline placebo. P-value seharusnya kira-kira uniform pada , sehingga berada di bawah 0,10 sekitar 10% dari waktu pada pengambilan berulang. Jika hasil signifikan muncul jauh lebih sering, predictor set atau threshold filter Anda sedang menciptakan signifikansi dan pipeline rusak bahkan sebelum menyentuh data nyata.
Pemeriksaan 2 adalah yang sering dilewatkan dan paling penting. Jalankan itu terlebih dahulu.
Pertimbangan Praktis

Memilih Donor Pool
Donor harus secara masuk akal sebanding dengan treated unit dan tidak terdampak oleh intervensi. Untuk pekerjaan eksekusi: algoritma yang sama pada instrumen serupa — sektor, desil market cap, dan tingkat likuiditas yang sama. Taksonomi tier dalam multi-symbol validation dapat digunakan langsung di sini; properti yang menjadikan instrumen sebagai uji robustness yang wajar juga menjadikannya donor pool yang wajar. Untuk peristiwa venue: instrumen yang sama pada venue yang tidak terkena perubahan.
Keluarkan unit dengan spillover. Jika perubahan algoritma pada satu instrumen mengubah quoting Anda pada instrumen berkorelasi, instrumen tersebut sebagian terkena treatment. Membiarkannya di dalam donor pool membuat synthetic control bias menuju jalur treated unit setelah intervensi dan mengecilkan estimasi menuju nol — cacat desain yang menciptakan hasil null semudah control yang buruk menciptakan hasil positif.
Fit Sebelum Intervensi Adalah Seluruh Argumennya
Kredibilitas SCM sepenuhnya bergantung pada fit periode sebelum intervensi. Laporkan MSPE sebelum intervensi dan tunjukkan fit-nya. Pre-fit yang buruk membatalkan semua hal setelah .
Abadie et al. (2015) menyatakan aturannya dengan jelas: jika tidak ada convex combination donor yang mereproduksi trajectory treated unit sebelum intervensi, jangan terapkan metode ini. Ini adalah kriteria falsifikasi yang jujur, dan lebih jarang dilakukan daripada seharusnya — kebanyakan estimator mengembalikan angka apa pun inputnya. SCM memberi tahu ketika counterfactual kredibel tidak dapat dihasilkan, dan respons yang benar adalah mempublikasikan kegagalan, bukan memperluas donor pool sampai fit membaik. Memperluas pool demi mengejar pre-fit adalah overfitting yang sama yang dibahas seri ini, hanya dipindahkan ke tahap konstruksi control.
Overfitting pada Panel Pendek
Kuantitas khusus SCM yang perlu diawasi adalah rasio donor terhadap observasi periode sebelum intervensi . Dengan bobot bebas yang di-fit pada titik, perfect pre-fit menjadi dapat dicapai secara konstruksi ketika mendekati — dan perfect pre-fit yang diperoleh dengan cara itu tidak membawa informasi. Pertahankan jauh lebih besar daripada ; jika strategi berjalan 30 hari sebelum perubahan dan Anda memiliki 20 donor kandidat, masalah Anda bukan SCM melainkan interpolasi. Mitigasinya:
- Regularisasi: SparseSC menambahkan penalti dan pada optimasi bobot.
- Batasi donor pool: lebih sedikit donor yang justifikasinya lebih baik mengungguli banyak donor — dengan biaya grid permutasi yang lebih kasar, karena juga menentukan p-value minimum. Ketegangan ini nyata dan tidak memiliki solusi sederhana.
- Augmented SCM: Ben-Michael, Feller, dan Rothstein (2021) menggunakan model outcome untuk mengoreksi bias ketika perfect pre-fit tidak dapat dicapai.
Non-Stationarity
Jalankan SCM pada cumulative return, jangan pernah pada level harga — level harga mengundang fit palsu. Pastikan gap sebelum intervensi memiliki mean nol dan stationary sebelum mempercayai divergensi setelah intervensi; machinery ADF dan Engle-Granger untuk itu, termasuk critical value yang dikoreksi saat menguji residual ter-fit alih-alih series yang diamati, dibahas dalam arbitraj statistik dan pairs trading.
Banyak Treated Unit
Deployment pada beberapa aset sekaligus merusak desain single-treated-unit. Ekstensinya: pooled SCM (rata-rata efek di antara treated unit) dan desain staggered adoption (Ben-Michael et al., 2022) untuk unit yang diberi treatment pada waktu berbeda.
Kapan Tidak Menggunakan SCM

Cocok untuk: intervensi diskret dan terdefinisi dengan baik pada tanggal yang diketahui; donor pool yang wajar berisi unit tanpa treatment yang sebanding; intervensi yang tidak diantisipasi sebelumnya, karena antisipasi menggerakkan treated unit sebelum dan melanggar identifikasi.
Kurang cocok untuk: treatment kontinu, seperti parameter yang bergeser selama berminggu-minggu; kondisi tanpa pembanding yang benar-benar tidak terkena treatment; evaluasi high-frequency ketika signal-to-noise ratio mengalahkan estimasi bobot.
Kesimpulan

Seleksi dan confounding adalah mode kegagalan yang berbeda dan membutuhkan instrumen yang berbeda. DSR dan PBO menilai pencarian. SCM menilai counterfactual, dan merupakan satu-satunya alat dalam seri ini yang menangani kondisi ketika Anda hanya menjalankan satu eksperimen tetapi tetap tidak dapat mempercayai hasilnya.
Alasan memilihnya daripada benchmark ad-hoc bukan karena menghasilkan efek yang lebih besar — sering kali justru lebih kecil — tetapi karena SCM dapat menolak. Jika tidak ada convex combination donor yang mengikuti instrumen Anda sebelum intervensi, SCM mengatakannya dan Anda berhenti. Jika gap treated berada di dalam cloud donor, placebo p-value mengatakannya dan Anda melaporkan null. Dua jalan keluar itu adalah nilai metode ini, dan tulisan SCM tanpa pre-period MSPE serta placebo p-value telah melewatkan satu-satunya bagian yang menjadikannya lebih dari chart dua garis yang menyebar.
Bacaan Lanjutan
- Abadie, A., Diamond, A., & Hainmueller, J. (2010). "Synthetic Control Methods for Comparative Case Studies." Journal of the American Statistical Association, 105(490), 493-505.
- Abadie, A. (2021). "Using Synthetic Controls: Feasibility, Data Requirements, and Methodological Aspects." Journal of Economic Literature, 59(2), 391-425.
- Ben-Michael, E., Feller, A., & Rothstein, J. (2021). "The Augmented Synthetic Control Method." Journal of the American Statistical Association, 116(536), 1789-1803.
- Cunningham, S. (2021). Causal Inference: The Mixtape. Chapter 10: Synthetic Control. Available at mixtape.scunning.com.
- Microsoft Research. SparseSC: Sparse Synthetic Controls. github.com/microsoft/SparseSC.
Penulis
Trading-systems engineer
Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.