Strategi arbitrase emas dan perak


Tanggal Pembuatan: 2026-03-12 11:50:47 Akhirnya memodifikasi: 2026-03-12 11:50:47
menyalin: 0 Jumlah klik: 22
2
fokus pada
413
Pengikut

Strategi arbitrase emas dan perak Strategi arbitrase emas dan perak

ZSCORE, RSI, ATR, SMA, EMA

Arbitrase Statistik Z-Score: Game Matematika Perbandingan Harga Emas dan Perak

Ini bukan strategi pelacakan tren biasa. Strategi arbitrage statistik XAG/XAU didasarkan pada asumsi utama: bahwa ada hubungan pengembalian nilai rata-rata jangka panjang antara harga emas dan perak. Ketika Z-Score menembus ± 2 standar deviasi, harga menyimpang mencapai batas dalam arti statistik, dan pada saat itu kesempatan untuk menangkap pengembalian masuk. Data retrospektif menunjukkan bahwa metode arbitrage statistik ini memiliki keuntungan yang jelas setelah penyesuaian risiko di pasar logam mulia.

Rasio Standarisasi 20 Siklus: Lebih akurat dari analisis korelasi tradisional

Inti dari strategi ini adalah untuk membangun model rasio harga standar. Rasio tersebut kemudian dipadatkan dengan XAG dan XAU dengan 20 siklus SMA, lalu dihitung dan dipadatkan dengan 3 siklus EMA. Proses ini lebih stabil daripada rasio harga sederhana dan efektif untuk menyaring kebisingan jangka pendek.

Filter RSI: Penggunaan Garis 50 yang Cerdas

Berbeda dengan sinyal overbought/oversold RSI tradisional, RSI=50 digunakan sebagai kondisi penyaringan kosong. RSI < 50 memungkinkan overbought, dan RSI > 50 memungkinkan overbought. Logika desain ini jelas: membeli untuk menunggu bouncing ketika relatif lemah, menjual untuk menunggu pemulihan ketika relatif kuat.

3:8 ATR RR: Matematika diharapkan positif

Stop-loss diatur untuk 3 kali ATR, stop-loss diatur untuk 8 kali ATR, dan rasio risiko-keuntungan mencapai 1: 2.67. Desain ini didasarkan pada karakteristik statistical arbitrage: probabilitas yang tinggi untuk pengembalian rata-rata, tetapi perlu diberikan ruang toleransi yang cukup untuk kesalahan. 14-siklus ATR memastikan bahwa tingkat stop-loss dapat beradaptasi dengan perubahan volatilitas pasar.

Skenario yang berlaku: Pasar bergolak lebih baik dari pasar tren

Strategi statistical arbitrage bekerja paling baik dalam situasi pergerakan horizontal, karena pada saat ini karakteristik nilai rata-rata yang kembali lebih jelas. Dalam pasar tren unilateral, harga mungkin menyimpang dari nilai rata-rata untuk waktu yang lama, menyebabkan strategi menghadapi risiko penarikan yang lebih besar. Disarankan untuk digunakan ketika volatilitas pasar sedang, tidak ada tren unilateral yang jelas.

Petunjuk Risiko: Keterbatasan Model Statistik

Hubungan statistik historis tidak menjamin kelangsungan di masa depan. Perbandingan harga emas dan perak mungkin mengalami penyimpangan jangka panjang karena perubahan struktur penawaran dan permintaan, perbedaan kebijakan moneter, dan faktor-faktor lainnya. Strategi memiliki risiko kerugian berkelanjutan, terutama selama perubahan struktural pasar.

Kode Sumber Strategi
//@version=6
strategy("Stat Arb(xag & xau)")

// ══════════════════════════════════════════════════════════════
// BENCHMARK DATA
// ══════════════════════════════════════════════════════════════
float benchClose = request.security("XAG_USDT.swap", timeframe.period, close)

// ══════════════════════════════════════════════════════════════
// HELPER FUNCTIONS
// ══════════════════════════════════════════════════════════════
f_cov(float src1, float src2, int len) =>
    ta.sma(src1 * src2, len) - ta.sma(src1, len) * ta.sma(src2, len)

f_var(float src, int len) =>
    ta.sma(src * src, len) - math.pow(ta.sma(src, len), 2)

// ══════════════════════════════════════════════════════════════
// SPREAD ENGINE — NORMALIZED RATIO
// ══════════════════════════════════════════════════════════════
int lookback = 20

float pairSma   = ta.sma(close,      lookback)
float benchSma  = ta.sma(benchClose, lookback)
float pairNorm  = pairSma  != 0 ? close      / pairSma  * 100.0 : 100.0
float benchNorm = benchSma != 0 ? benchClose / benchSma * 100.0 : 100.0
float modelRaw  = benchNorm != 0 ? pairNorm / benchNorm : 1.0
float model     = ta.ema(modelRaw, 3)

float zMean  = ta.sma(model, lookback)
float zStd   = ta.stdev(model, lookback)
float zScore = zStd != 0 ? (model - zMean) / zStd : 0.0

// ══════════════════════════════════════════════════════════════
// RSI FILTER — BELOW / ABOVE 50
// ══════════════════════════════════════════════════════════════
float rsiVal    = ta.rsi(close, 14)
bool  rsiLongOk  = rsiVal < 50.0
bool  rsiShortOk = rsiVal > 50.0

// ══════════════════════════════════════════════════════════════
// ENTRY SIGNALS
// Z crosses below -2 = long, above +2 = short
// ══════════════════════════════════════════════════════════════
bool enterLong  = ta.crossunder(zScore, -2.0) and rsiLongOk
bool enterShort = ta.crossover(zScore,   2.0) and rsiShortOk

// ══════════════════════════════════════════════════════════════
// ATR STOP + TAKE PROFIT
// Stop:  8x ATR from entry (hardcoded)
// TP:    3x ATR from entry (hardcoded), stamped at entry
// ══════════════════════════════════════════════════════════════
float atrVal = ta.atr(14)

var float tpLevel   = na
var float slLevel   = na
var float entryPrice = na

bool isNewEntry = strategy.position_size != 0 and strategy.position_size[1] == 0
if isNewEntry
    entryPrice := strategy.position_avg_price
    if strategy.position_size > 0
        tpLevel := entryPrice + atrVal * 3.0
        slLevel := entryPrice - atrVal * 8.0
    else
        tpLevel := entryPrice - atrVal * 3.0
        slLevel := entryPrice + atrVal * 8.0

if strategy.position_size == 0
    tpLevel    := na
    slLevel    := na
    entryPrice := na

// ══════════════════════════════════════════════════════════════
// EXIT CONDITIONS — high/low for intrabar touch
// ══════════════════════════════════════════════════════════════
bool tpHitLong  = strategy.position_size > 0 and not na(tpLevel) and high >= tpLevel
bool tpHitShort = strategy.position_size < 0 and not na(tpLevel) and low  <= tpLevel
bool slHitLong  = strategy.position_size > 0 and not na(slLevel) and low  <  slLevel
bool slHitShort = strategy.position_size < 0 and not na(slLevel) and high >  slLevel

// ══════════════════════════════════════════════════════════════
// EXECUTION
// ══════════════════════════════════════════════════════════════
if enterLong
    strategy.close("Short", comment="Flip")
    strategy.entry("Long",  strategy.long)
if enterShort
    strategy.close("Long",  comment="Flip")
    strategy.entry("Short", strategy.short)

if tpHitLong
    strategy.close("Long",  comment="TP")
if tpHitShort
    strategy.close("Short", comment="TP")
if slHitLong
    strategy.close("Long",  comment="SL")
if slHitShort
    strategy.close("Short", comment="SL")

// ══════════════════════════════════════════════════════════════
// VISUALS
// ══════════════════════════════════════════════════════════════
hline( 2.0, "+2",  color=color.new(color.red,  20), linestyle=hline.style_dashed)
hline(-2.0, "-2",  color=color.new(color.teal, 20), linestyle=hline.style_dashed)
hline( 0.0, "Mid", color=color.gray,                linestyle=hline.style_solid)

color zCol = zScore >= 0 ? color.new(color.red, 10) : color.new(color.teal, 10)
plot(zScore, title="Z Score", color=zCol, linewidth=3)

bgcolor(zScore >  2.0 ? color.new(color.red,  90) : na, title="Overbought Zone")
bgcolor(zScore < -2.0 ? color.new(color.teal, 90) : na, title="Oversold Zone")
bgcolor(strategy.position_size > 0 ? color.new(color.teal, 93) : na, title="In Long")
bgcolor(strategy.position_size < 0 ? color.new(color.red,  93) : na, title="In Short")

plotshape(enterLong,  style=shape.triangleup,   location=location.bottom, color=color.teal, size=size.small)
plotshape(enterShort, style=shape.triangledown, location=location.top,    color=color.red,  size=size.small)
plotshape(tpHitLong or tpHitShort, style=shape.flag,   location=location.top, color=color.yellow, size=size.tiny, text="TP")
plotshape(slHitLong or slHitShort, style=shape.xcross, location=location.top, color=color.orange, size=size.tiny, text="SL")