Strategi ini menggunakan sistem rata-rata bergerak untuk menentukan arah tren saat ini dan membuat posisi panjang atau pendek sesuai dengan tren. Ketika rata-rata bergerak naik, kepercayaan dalam panjang lebih tinggi, jadi pergi panjang. Ketika rata-rata bergerak turun, kepercayaan dalam pendek lebih tinggi, jadi pergi pendek. Strategi ini terutama menggunakan sistem rata-rata bergerak untuk menentukan arah tren pasar, yang termasuk dalam strategi tren berikut.
Menghitung rata-rata bergerak tertimbang vwma sebagai indikator rata-rata bergerak untuk periode tertentu (default 400 periode).
Tentukan apakah rata-rata bergerak vwma naik, jika naik, atur sinyal panjang tren naik; jika turun, atur sinyal pendek tren turun.
Ketika uptrend benar, pergi panjang; ketika downtrend benar, tutup panjang dan pergi pendek.
Hitung strategi return bar_pnl dan buy & hold return bar_bh untuk setiap bar.
Berdasarkan timestamp kuartal dan tahunan, hitung return strategi kuartal_pnl, return tahunan tahun_pnl dan buy & hold return quarter_bh, tahun_bh yang sesuai.
Tampilkan laba strategi triwulanan vs laba beli & tahan dalam tabel.
Keuntungan utama dari strategi ini adalah:
Mudah dioperasikan, menentukan tren pasar dengan moving average, mudah dipahami.
Mengikuti tren mengurangi kerugian di pasar non-trend.
Beberapa parameter yang dapat disesuaikan. terutama menyesuaikan periode rata-rata bergerak, mudah untuk diuji dan dioptimalkan.
Tabel pengembalian intuitif untuk menunjukkan hasilnya dengan jelas.
Tambahkan buy & hold return dalam tabel untuk perbandingan, menunjukkan hasil yang berlebihan.
Posisi meja yang fleksibel, mudah diintegrasikan dengan strategi lain.
Ada juga beberapa risiko:
Performa yang kurang baik di pasar bull jangka panjang dibandingkan dengan buy & hold.
Bisa menambahkan kondisi filter seperti memecahkan high sebelumnya untuk mengurangi transaksi.
Rata-rata bergerak memiliki kemampuan penyesuaian kurva yang buruk, mungkin melewatkan titik balik tren.
Tidak ada mekanisme stop loss, risiko penarikan besar.
Untuk tabel, dapat menambahkan metrik risiko seperti rasio tajam, penarikan maksimum.
Strategi dapat dioptimalkan dalam aspek berikut:
Mengoptimalkan parameter rata-rata bergerak, menyesuaikan periode berdasarkan rezim pasar.
Tambahkan filter seperti memecahkan tinggi sebelumnya untuk mengurangi whipsaws.
Cobalah berbagai jenis rata-rata bergerak, seperti WMA, DEMA dll.
Tambahkan mekanisme stop loss, seperti stop dinamis atau ukuran posisi.
Meningkatkan isi tabel, menambahkan metrik seperti rasio ketajaman, penarikan maksimum.
Gabungkan dengan indikator lain seperti MACD, Bollinger Bands untuk menentukan tren.
Mengoptimalkan ukuran posisi, menyesuaikan posisi secara dinamis berdasarkan kondisi pasar.
Uji pada produk yang berbeda, temukan ruang lingkup aplikasi terbaik.
Strategi perdagangan moving average relatif sederhana dan mudah. Ini mengikuti tren dengan menentukan tren menggunakan moving average, dengan kontrol penarikan yang baik, cocok untuk pedagang yang mengikuti tren. Masih ada ruang besar untuk optimasi, seperti sistem moving average, mekanisme stop loss, ukuran posisi, dll untuk membuatnya dapat disesuaikan dengan lingkungan pasar yang kompleks. Desain tabel membandingkan strategi return to buy & hold, menunjukkan kelebihan return secara intuitif. Kerangka kerja dan desain tabel strategi ini dapat memberikan beberapa referensi yang baik bagi pedagang 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)