Strategi arbitraj emas dan perak


Tarikh penciptaan: 2026-03-12 11:50:47 Akhirnya diubah suai: 2026-03-12 11:50:47
Salin: 0 Bilangan klik: 22
2
fokus pada
413
Pengikut

Strategi arbitraj emas dan perak Strategi arbitraj emas dan perak

ZSCORE, RSI, ATR, SMA, EMA

Arbitrase Statistik Z-Score: Permainan Matematik Perbandingan Harga Emas dan Perak

Ini bukan strategi trend-following biasa. Strategi penipuan statistik XAG/XAU adalah berdasarkan pada satu hipotesis utama: harga emas dan perak mempunyai hubungan pulangan nilai purata jangka panjang. Apabila Z-Score menembusi ± 2 standard deviasi, harga menyimpang ke tahap maksimum dalam erti statistik, dan peluang untuk menangkap pulangan masuk.

20 nisbah standardisasi kitaran: lebih tepat daripada analisis kaitan tradisional

Inti strategi ini adalah untuk membina model nisbah harga standardisasi. Dengan 20 kitaran SMA untuk XAG dan XAU, kemudian standardisasi dengan 3 kitaran EMA, kemudian mengira nisbah dan melonggarkannya dengan 3 kitaran EMA. Proses ini lebih stabil daripada nisbah harga sederhana dan dapat menyaring kebisingan jangka pendek dengan berkesan. Apabila Z-Score nisbah standardisasi melebihi julat ± 2, yang menunjukkan bahawa harga semasa menyimpang dari rata-rata sejarah lebih dari 2 perbezaan standard, secara statistik merupakan peristiwa kebarangkalian kecil, memberikan peluang untuk kembali ke nilai purata.

Penapis RSI: 50 garis pemisah yang bijak

Berbeza dengan isyarat RSI over-buy over-sell tradisional, RSI = 50 digunakan sebagai syarat penapisan kosong. RSI <50 dibenarkan untuk melakukan lebih banyak, RSI> 50 dibenarkan untuk melakukan lebih sedikit. Logik reka bentuk ini jelas: membeli menunggu rebound apabila relatif lemah, menjual menunggu pemulihan apabila relatif kuat.

3:8 ATR RRR: Matematik dijangka positif

Tetapan berhenti adalah 3 kali ATR, tetapan berhenti adalah 8 kali ATR, nisbah risiko-keuntungan mencapai 1:2.67. Reka bentuk ini adalah berdasarkan ciri-ciri statik: kebarangkalian pulangan rata-rata lebih tinggi, tetapi perlu diberikan ruang kesalahan yang mencukupi. ATR 14 kitaran memastikan tahap stop loss dapat menyesuaikan diri dengan perubahan turun naik pasaran.

Senario yang boleh digunakan: pasaran goyah lebih baik daripada pasaran trend

Strategi penarikan statistik berfungsi dengan baik dalam keadaan goyah berlawanan arah, kerana pada masa ini ciri-ciri pulangan nilai rata-rata lebih jelas. Dalam pasaran trend unilateral, harga mungkin menyimpang dari nilai rata-rata untuk masa yang lama, menyebabkan strategi menghadapi risiko pulangan yang lebih besar. Ia disyorkan untuk digunakan apabila kadar turun naik pasaran sederhana, tidak ada trend unilateral yang jelas.

Petunjuk Risiko: Kekurangan Model Statistik

Hubungan statistik sejarah tidak menjamin kesinambungan masa depan. Perbandingan harga emas dan perak mungkin mengalami penyimpangan jangka panjang kerana perubahan struktur bekalan dan permintaan, perbezaan dasar monetari dan lain-lain. Strategi mempunyai risiko kerugian berturut-turut, terutamanya semasa perubahan struktur pasaran.

Kod 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")