Strategi perdagangan rata-rata bergerak ganda menghasilkan sinyal perdagangan dengan menghitung rata-rata bergerak eksponensial (EMA) dari kerangka waktu yang berbeda untuk membentuk EMA cepat dan EMA lambat, dan mengamati salib emas dan salib kematian mereka.
Indikator inti dari strategi rata-rata bergerak ganda adalah EMA cepat dan EMA lambat. EMA cepat memiliki parameter default 12 hari, sedangkan EMA lambat memiliki parameter default 26 hari. Rumus untuk rata-rata bergerak eksponensial adalah:
EMA (t) = (C (t) - EMA (t-1)) x SF + EMA (t-1)
Di mana C (t) adalah harga penutupan hari ini, dan SF adalah faktor penyelarasan.
Aturan perdagangan adalah:
Masukkan posisi panjang pada silang emas dari EMA cepat yang melintasi EMA lambat dari bawah.
Masukkan posisi short pada death cross dari EMA cepat yang melintasi EMA lambat dari atas.
Posisi keluar pada divergensi EMA.
Dengan menangkap pola silang EMA, dapat mencerminkan tren pasar dan meningkatkan profitabilitas.
Sebagai strategi indikator teknis yang matang, strategi rata-rata bergerak ganda memiliki kekuatan berikut:
Logikanya jelas dan mudah dimengerti dan diterapkan.
Ini memberikan penilaian yang sangat akurat tentang penawaran dan permintaan pasar dan dengan demikian memiliki tingkat kemenangan yang relatif tinggi.
Hal ini secara efektif menyaring kebisingan pasar dan menangkap tren utama.
Hal ini dapat diterapkan di berbagai instrumen dan kerangka waktu.
Ini dapat dikombinasikan dengan indikator lain untuk memperkaya strategi.
Ini memiliki efisiensi pemanfaatan modal yang tinggi untuk perdagangan modal besar.
Ada juga keterbatasan tertentu dari strategi:
Ini gagal bereaksi terhadap pergerakan pasar yang intens seperti penjualan pasar beruang yang tajam.
Hal ini cenderung menghasilkan sinyal palsu yang sering dan whipsaws di sisi pasar rangebound.
Parameternya perlu dioptimalkan di pasar dan kerangka waktu yang berbeda.
Hal ini tidak dapat menentukan tingkat pembalikan tren yang tepat.
Risiko dapat dikurangi dengan menyesuaikan periode EMA, menambahkan filter tambahan dll untuk membuat strategi lebih kuat.
Strategi rata-rata bergerak ganda dapat ditingkatkan dari aspek berikut:
Masukkan indikator MACD untuk menilai kekuatan tren dan menghindari perdagangan yang salah.
Tambahkan volume perdagangan untuk mengkonfirmasi sinyal breakout yang benar.
Gabungkan dengan Bollinger Bands, pola candlestick untuk aturan masuk dan keluar yang lebih tepat.
Menggunakan pendekatan pembelajaran mesin seperti LSTM untuk mengoptimalkan parameter secara otomatis untuk kemampuan beradaptasi yang lebih baik.
Strategi perdagangan rata-rata bergerak ganda menangkap peluang perdagangan dari EMA golden crosses dan death crosses untuk menentukan titik pembalikan tren untuk keuntungan yang stabil. Dengan keuntungan kesederhanaan, efisiensi modal dan kemudahan implementasi, ini adalah pilihan yang disukai bagi pemula perdagangan algoritmik. Tetapi juga memiliki kelemahan tertentu seperti menghasilkan sinyal palsu. Lebih banyak indikator harus diperkenalkan untuk mengoptimalkannya untuk pasar dan lingkungan tertentu. Secara keseluruhan, ini adalah strategi indikator teknis yang sangat praktis dan berguna.
/*backtest start: 2022-11-24 00:00:00 end: 2023-11-30 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/ // © antondmt //@version=5 strategy("Returns & Drawdowns Table", "R & DD", true, calc_on_every_tick = false, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, process_orders_on_close = true) i_eq_to_dd = input.string("Compound Equity", "Mode", ["Simple Equity", "Compound Equity", "Drawdown"], group = "R & DD Table") i_precision = input.int(2, "Return Precision", group = "R & DD Table") i_headers_col = input.color(#D4D4D4, "Headers Color", group = "R & DD Table") i_headers_text_col = input.color(color.black, "Headers Text Color", group = "R & DD Table") i_pos_col = input.color(color.green, "Positive Color", group = "R & DD Table") i_neg_col = input.color(color.red, "Negative Color", group = "R & DD Table") i_zero_col = input.color(#DDDDDD, "Zero Color", group = "R & DD Table") i_cell_text_col = input.color(color.white, "Cell Text Color", group = "R & DD Table") // TIME { var month_times = array.new_int(0) // Array of all month times new_month = month(time) != month(time[1]) if(new_month or barstate.isfirst) array.push(month_times, time) var year_times = array.new_int(0) new_year = year(time) != year(time[1]) if (new_year or barstate.isfirst) array.push(year_times, time) //} // SIMPLE EQUITY CALCULATIONS { // Simple equity is strictly calculated from start to end of each month/year equity. There is no compound var monthly_simp_pnls = array.new_float(0) // Array of all monthly profits and losses var yearly_simp_pnls = array.new_float(0) if(i_eq_to_dd == "Simple Equity") var initial_monthly_equity = strategy.equity // Starting equity for each month cur_month_pnl = nz((strategy.equity - initial_monthly_equity) / initial_monthly_equity) // Current month's equity change if(new_month or barstate.isfirst) initial_monthly_equity := strategy.equity array.push(monthly_simp_pnls, cur_month_pnl) else array.set(monthly_simp_pnls, array.size(monthly_simp_pnls) - 1, cur_month_pnl) var initial_yearly_equity = strategy.equity cur_year_pnl = nz((strategy.equity - initial_yearly_equity) / initial_yearly_equity) if (new_year or barstate.isfirst) initial_yearly_equity := strategy.equity array.push(yearly_simp_pnls, cur_year_pnl) else array.set(yearly_simp_pnls, array.size(yearly_simp_pnls) - 1, cur_year_pnl) // } // COMPOUND EQUITY CALCULATIONS { // Compound equity is strictly calculated based on equity state from the beginning of time until the end of each month/year equity. It shows the exact equity movement through time var monthly_comp_pnls = array.new_float(0) // Array of all monthly profits and losses var yearly_comp_pnls = array.new_float(0) if(i_eq_to_dd == "Compound Equity") var initial_equity = strategy.equity cur_month_pnl = nz((strategy.equity - initial_equity) / initial_equity) // Current month's equity change if(new_month or barstate.isfirst) array.push(monthly_comp_pnls, cur_month_pnl) else array.set(monthly_comp_pnls, array.size(monthly_comp_pnls) - 1, cur_month_pnl) cur_year_pnl = nz((strategy.equity - initial_equity) / initial_equity) if (new_year or barstate.isfirst) array.push(yearly_comp_pnls, cur_year_pnl) else array.set(yearly_comp_pnls, array.size(yearly_comp_pnls) - 1, cur_year_pnl) // } // DRAWDOWN CALCULATIONS { // Drawdowns are calculated from highest equity to lowest trough for the month/year var monthly_dds = array.new_float(0) // Array of all monthly drawdowns var yearly_dds = array.new_float(0) if (i_eq_to_dd == "Drawdown") total_equity = strategy.equity - strategy.openprofit var cur_month_dd = 0.0 var m_ATH = total_equity // Monthly All-Time-High (ATH). It is reset each month m_ATH := math.max(total_equity, nz(m_ATH[1])) m_drawdown = -math.abs(total_equity / m_ATH * 100 - 100) / 100 // Drawdown at current bar if(m_drawdown < cur_month_dd) cur_month_dd := m_drawdown if(new_month or barstate.isfirst) cur_month_dd := 0.0 m_ATH := strategy.equity - strategy.openprofit array.push(monthly_dds, 0) else array.set(monthly_dds, array.size(monthly_dds) - 1, cur_month_dd) var cur_year_dd = 0.0 var y_ATH = total_equity y_ATH := math.max(total_equity, nz(y_ATH[1])) y_drawdown = -math.abs(total_equity / y_ATH * 100 - 100) / 100 if(y_drawdown < cur_year_dd) cur_year_dd := y_drawdown if (new_year or barstate.isfirst) cur_year_dd := 0.0 y_ATH := strategy.equity - strategy.openprofit array.push(yearly_dds, 0) else array.set(yearly_dds, array.size(yearly_dds) - 1, cur_year_dd) // } // TABLE LOGIC { var main_table = table(na) table.clear(main_table, 0, 0, 13, new_year ? array.size(year_times) - 1 : array.size(year_times)) main_table := table.new(position.bottom_right, columns = 14, rows = array.size(year_times) + 1, border_width = 1) t_set_headers() => // Sets time headers of the table // Set month headers table.cell(main_table, 0, 0, "", text_color = i_headers_text_col, bgcolor = i_headers_col) table.cell(main_table, 1, 0, "Jan", text_color = i_headers_text_col, bgcolor = i_headers_col) table.cell(main_table, 2, 0, "Feb", text_color = i_headers_text_col, bgcolor = i_headers_col) table.cell(main_table, 3, 0, "Mar", text_color = i_headers_text_col, bgcolor = i_headers_col) table.cell(main_table, 4, 0, "Apr", text_color = i_headers_text_col, bgcolor = i_headers_col) table.cell(main_table, 5, 0, "May", text_color = i_headers_text_col, bgcolor = i_headers_col) table.cell(main_table, 6, 0, "Jun", text_color = i_headers_text_col, bgcolor = i_headers_col) table.cell(main_table, 7, 0, "Jul", text_color = i_headers_text_col, bgcolor = i_headers_col) table.cell(main_table, 8, 0, "Aug", text_color = i_headers_text_col, bgcolor = i_headers_col) table.cell(main_table, 9, 0, "Sep", text_color = i_headers_text_col, bgcolor = i_headers_col) table.cell(main_table, 10, 0, "Oct", text_color = i_headers_text_col, bgcolor = i_headers_col) table.cell(main_table, 11, 0, "Nov", text_color = i_headers_text_col, bgcolor = i_headers_col) table.cell(main_table, 12, 0, "Dec", text_color = i_headers_text_col, bgcolor = i_headers_col) table.cell(main_table, 13, 0, str.tostring(i_eq_to_dd), text_color = i_headers_text_col, bgcolor = i_headers_col) // Set year headers for i = 0 to array.size(year_times) - 1 table.cell(main_table, 0, i + 1, str.tostring(year(array.get(year_times, i))), text_color = i_headers_text_col, bgcolor = i_headers_col) t_set_months() => // Sets inner monthly data of the table display_array = switch i_eq_to_dd "Simple Equity" => monthly_simp_pnls "Compound Equity" => monthly_comp_pnls => monthly_dds for i = 0 to array.size(month_times) - 1 m_row = year(array.get(month_times, i)) - year(array.get(year_times, 0)) + 1 m_col = month(array.get(month_times, i)) m_color = array.get(display_array, i) == 0 ? color.new(i_zero_col, transp = 30) : array.get(display_array, i) > 0 ? color.new(i_pos_col, transp = 30) : color.new(i_neg_col, transp = 30) table.cell(main_table, m_col, m_row, str.tostring(math.round(array.get(display_array, i) * 100, i_precision)), bgcolor = m_color, text_color = i_cell_text_col) t_set_years() => // Sets inner yearly data of the table display_array = switch i_eq_to_dd "Simple Equity" => yearly_simp_pnls "Compound Equity" => yearly_comp_pnls => yearly_dds for i = 0 to array.size(year_times) - 1 y_color = array.get(display_array, i) == 0 ? color.new(i_zero_col, transp = 30) : array.get(display_array, i) > 0 ? color.new(i_pos_col, transp = 20) : color.new(i_neg_col, transp = 20) table.cell(main_table, 13, i + 1, str.tostring(math.round(array.get(display_array, i) * 100, i_precision)), bgcolor = y_color, text_color = i_cell_text_col) t_set_headers() t_set_months() t_set_years() // } // PLACE YOUR STRATEGY CODE HERE { // This is a sample code of a working strategy to show the table in action fastLength = input(12) slowlength = input(26) MACDLength = input(9) MACD = ta.ema(close, fastLength) - ta.ema(close, slowlength) aMACD = ta.ema(MACD, MACDLength) delta = MACD - aMACD if (ta.crossover(delta, 0)) strategy.entry("MacdLE", strategy.long, comment = "MacdLE") if (ta.crossunder(delta, 0)) strategy.entry("MacdSE", strategy.short, comment = "MacdSE") // }