Strategi Dagangan Trend Berdasarkan Purata Bergerak

Penulis:ChaoZhang, Tarikh: 2023-10-30 15:53:25
Tag:

img

Ringkasan

Strategi ini menggunakan sistem purata bergerak untuk menentukan arah trend semasa dan membuat kedudukan panjang atau pendek mengikut trend. Apabila purata bergerak naik, keyakinan dalam panjang lebih tinggi, jadi pergi panjang. Apabila purata bergerak turun, keyakinan dalam pendek lebih tinggi, jadi pergi pendek. Strategi ini terutamanya menggunakan sistem purata bergerak untuk menentukan arah trend pasaran, yang tergolong dalam strategi trend berikut.

Logika Strategi

  1. Mengira purata bergerak bertingkat vwma sebagai penunjuk purata bergerak untuk tempoh tertentu (default 400 tempoh).

  2. Tentukan sama ada purata bergerak vwma meningkat, jika meningkat, tetapkan isyarat panjang; jika jatuh, tetapkan isyarat pendek.

  3. Apabila trend menaik adalah benar, pergi panjang; apabila trend menurun adalah benar, tutup panjang dan pergi pendek.

  4. Mengira strategi balik bar_pnl dan beli & memegang balik bar_bh untuk setiap bar.

  5. Mengikut cap waktu suku dan tahunan, mengira pulangan strategi suku_pnl, pulangan tahunan tahun_pnl dan pulangan beli & tahan yang sepadan suku_bh, tahun_bh.

  6. Tunjukkan pulangan strategi suku tahunan berbanding pulangan beli & tahan dalam jadual.

Analisis Kelebihan

Kelebihan utama strategi ini ialah:

  1. Mudah untuk beroperasi. Tentukan trend pasaran dengan purata bergerak, mudah difahami.

  2. Baik dalam mengawal pengeluaran, mengikuti trend mengurangkan kerugian di pasaran yang tidak trend.

  3. Ada beberapa parameter yang boleh disesuaikan, terutama menyesuaikan tempoh purata bergerak, mudah diuji dan dioptimumkan.

  4. Jadual pulangan intuitif untuk menunjukkan hasil dengan jelas.

  5. Tambah beli & tahan pulangan dalam jadual untuk perbandingan, menunjukkan pulangan yang berlebihan.

  6. Kedudukan meja yang fleksibel, mudah diintegrasikan dengan strategi lain.

Analisis Risiko

Terdapat juga beberapa risiko:

  1. Performa yang kurang baik dalam pasaran lembu jangka panjang berbanding dengan beli & pegang.

  2. Risiko tinggi dalam pasaran yang terhad boleh menambah keadaan penapis seperti memecahkan tinggi sebelum ini untuk mengurangkan transaksi.

  3. Purata bergerak mempunyai keupayaan pemasangan lengkung yang lemah, mungkin terlepas titik perubahan trend. Boleh menguji pelbagai jenis purata bergerak.

  4. Tiada mekanisme stop loss, risiko pengeluaran yang besar, boleh menetapkan stop loss dinamik atau saiz kedudukan.

  5. Untuk jadual, boleh menambah metrik risiko seperti nisbah tajam, pengeluaran maksimum.

Arahan pengoptimuman

Strategi ini boleh dioptimumkan dalam aspek berikut:

  1. Mengoptimumkan parameter purata bergerak, menyesuaikan tempoh berdasarkan rejimen pasaran.

  2. Tambah penapis seperti memecahkan tinggi sebelumnya untuk mengurangkan whipsaws.

  3. Cuba pelbagai jenis purata bergerak, seperti WMA, DEMA dan lain-lain

  4. Tambah mekanisme stop loss, seperti berhenti dinamik atau saiz kedudukan.

  5. Menguatkan kandungan jadual, menambah metrik seperti nisbah tajam, pengeluaran maksimum.

  6. Gabungkan dengan penunjuk lain seperti MACD, Bollinger Bands untuk menentukan trend.

  7. Mengoptimumkan saiz kedudukan, menyesuaikan kedudukan secara dinamik berdasarkan keadaan pasaran.

  8. Uji pada produk yang berbeza, cari skop aplikasi terbaik.

Kesimpulan

Strategi perdagangan purata bergerak adalah agak mudah dan mudah. Ia mengikuti trend dengan menentukan trend menggunakan purata bergerak, dengan kawalan penarikan yang baik, sesuai untuk peniaga yang mengikuti trend. Masih ada ruang yang besar untuk pengoptimuman, seperti sistem purata bergerak, mekanisme hentian kerugian, saiz kedudukan dan lain-lain untuk menjadikannya dapat disesuaikan dengan persekitaran pasaran yang kompleks. Reka bentuk jadual membandingkan pulangan strategi untuk membeli & memegang, menunjukkan pulangan berlebihan secara intuitif. Kerangka kerja dan reka bentuk jadual strategi ini dapat memberikan rujukan yang baik untuk peniaga kuantitatif.


/*backtest
start: 2022-10-23 00:00:00
end: 2023-10-29 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © Dannnnnnny

//@version=4
strategy(title="Quarterly Returns in Strategies vs Buy & Hold", initial_capital= 1000, overlay=true,default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, commission_value = 0.1)
maLength= input(400)

wma= vwma(hl2,maLength)
uptrend= rising(wma, 5)
downtrend= falling(wma,5)

plot(wma)

if uptrend
    strategy.entry("Buy", strategy.long)
else
    strategy.close("Buy")//

///////////////////
// QUARTERLY TABLE //
enableQuarterlyTable = input(title="Enable Quarterly Return table", type=input.bool, defval=false)
enableCompareWithMarket = input(title="Compare with Market Benchmark", type=input.bool, defval=false)
table_position = input(title="Table Position", type=input.string, defval='bottom_right', options=['bottom_right','bottom_left','top_right', 'top_left'])
precision = 2
new_quarter = ceil(month(time)/3)  != ceil(month(time[1])/3)
new_year  = year(time)  != year(time[1])

eq = strategy.equity

bar_pnl = eq / eq[1] - 1
bar_bh = (close-close[1])/close[1]

cur_quarter_pnl = 0.0
cur_year_pnl  = 0.0
cur_quarter_bh = 0.0
cur_year_bh  = 0.0

// Current Quarterly P&L
cur_quarter_pnl := new_quarter ? 0.0 : 
                 (1 + cur_quarter_pnl[1]) * (1 + bar_pnl) - 1 
cur_quarter_bh := new_quarter ? 0.0 : 
                 (1 + cur_quarter_bh[1]) * (1 + bar_bh) - 1

// Current Yearly P&L
cur_year_pnl := new_year ? 0.0 : 
                 (1 + cur_year_pnl[1]) * (1 + bar_pnl) - 1
cur_year_bh := new_year ? 0.0 : 
                 (1 + cur_year_bh[1]) * (1 + bar_bh) - 1

// Arrays to store Yearly and Quarterly P&Ls
var quarter_pnl  = array.new_float(0)
var quarter_time = array.new_int(0)
var quarter_bh  = array.new_float(0)

var year_pnl  = array.new_float(0)
var year_time = array.new_int(0)
var year_bh  = array.new_float(0)

end_time = false

end_time:= time_close + (time_close - time_close[1]) > timenow or barstate.islastconfirmedhistory

if (not na(cur_quarter_pnl[1]) and (new_quarter or end_time))
    if (end_time[1])
        array.pop(quarter_pnl)
        array.pop(quarter_time)
        
    array.push(quarter_pnl , cur_quarter_pnl[1])
    array.push(quarter_time, time[1])
    array.push(quarter_bh , cur_quarter_bh[1])

if (not na(cur_year_pnl[1]) and (new_year or end_time))
    if (end_time[1])
        array.pop(year_pnl)
        array.pop(year_time)
        
    array.push(year_pnl , cur_year_pnl[1])
    array.push(year_time, time[1])
    array.push(year_bh , cur_year_bh[1])

// Quarterly P&L Table    
var quarterly_table = table(na)

getCellColor(pnl, bh)  => 
    if pnl > 0
        if bh < 0 or pnl > 2 * bh
            color.new(color.green, transp = 20)
        else if pnl > bh
            color.new(color.green, transp = 50)
        else
            color.new(color.green, transp = 80)
    else
        if bh > 0 or pnl < 2 * bh
            color.new(color.red, transp = 20)
        else if pnl < bh
            color.new(color.red, transp = 50)
        else
            color.new(color.red, transp = 80)

if (end_time and enableQuarterlyTable)
    quarterly_table := table.new(table_position, columns = 14, rows = array.size(year_pnl) + 1, border_width = 1)

    table.cell(quarterly_table, 0,  0, "",     bgcolor = #cccccc)
    table.cell(quarterly_table, 1,  0, "Q1",  bgcolor = #cccccc)
    table.cell(quarterly_table, 2,  0, "Q2",  bgcolor = #cccccc)
    table.cell(quarterly_table, 3,  0, "Q3",  bgcolor = #cccccc)
    table.cell(quarterly_table, 4,  0, "Q4",  bgcolor = #cccccc)
    table.cell(quarterly_table, 5,  0, "Year", bgcolor = #999999)


    for yi = 0 to array.size(year_pnl) - 1
        table.cell(quarterly_table, 0,  yi + 1, tostring(year(array.get(year_time, yi))), bgcolor = #cccccc)
        
        y_color = getCellColor(array.get(year_pnl, yi), array.get(year_bh, yi))
        table.cell(quarterly_table, 5, yi + 1, enableCompareWithMarket ? tostring(round(array.get(year_pnl, yi) * 100, precision)) + " (" + tostring(round(array.get(year_bh, yi) * 100, precision)) + ")" : tostring(round(array.get(year_pnl, yi) * 100, precision)), bgcolor = y_color, text_color=#bfbfbf)
        
    for mi = 0 to array.size(quarter_time) - 1
        m_row   = year(array.get(quarter_time, mi))  - year(array.get(year_time, 0)) + 1
        m_col   = ceil(month(array.get(quarter_time, mi)) / 3)
        m_color = getCellColor(array.get(quarter_pnl, mi), array.get(quarter_bh, mi))
        
        table.cell(quarterly_table, m_col, m_row, enableCompareWithMarket ?  tostring(round(array.get(quarter_pnl, mi) * 100, precision)) + " (" + tostring(round(array.get(quarter_bh, mi) * 100,precision)) +")" : tostring(round(array.get(quarter_pnl, mi) * 100, precision)), bgcolor = m_color, text_color=#bfbfbf)

Lebih lanjut