Двойная стратегия торговли скользящей средней генерирует торговые сигналы путем расчета экспоненциальных скользящих средних (EMAs) различных временных рамок для формирования быстрой EMA и медленной EMA, а также наблюдения за их золотыми крестами и смертными крестами. Она длинна, когда быстрая EMA пересекает более медленной EMA, и коротка, когда быстрая EMA пересекает ниже медленной EMA. Эта стратегия фиксирует точки обратного тренда скользящих средних и является широко используемой следующей стратегией.
Основными показателями стратегии двойной скользящей средней являются быстрая EMA и медленная EMA. Быстрая EMA имеет параметр по умолчанию 12 дней, в то время как медленная EMA имеет параметр по умолчанию 26 дней.
EMA (t) = (C (t) - EMA (t-1)) x SF + EMA (t-1)
В отличие от простой скользящей средней, EMA придает большее значение последним данным и, таким образом, быстрее реагирует на изменения цен.
Правила торговли:
Введите длинные позиции на золотом кресте быстрого EMA, пересекающего медленный EMA снизу.
Введите короткие позиции на перекрестке смерти быстрого EMA, переходящего ниже медленного EMA сверху.
Выходные позиции по дивергенции СРМ.
Захватывая кросс-модели EMA, он может отражать рыночные тенденции и повышать рентабельность.
В качестве зрелой стратегии технических показателей стратегия двойной скользящей средней имеет следующие преимущества:
Его логика ясна и легко понять и применить.
Он дает очень точное суждение о спросе и предложении на рынке и, следовательно, имеет относительно высокий показатель выигрыша.
Он эффективно отфильтровывает шум рынка и отслеживает основные тенденции.
Он может применяться в различных инструментах и временных рамках.
Она может быть объединена с другими показателями обогащения стратегии.
Он имеет высокую эффективность использования капитала для торговли большим капиталом.
Стратегия также имеет определенные ограничения:
Он не реагирует на интенсивные рыночные движения, такие как резкие распродажи на медвежьем рынке.
Он имеет тенденцию генерировать частые ложные сигналы и срывы на рынках с боковым диапазоном.
Его параметры нуждаются в оптимизации на разных рынках и временных рамках.
Она не может определить соответствующие уровни обратного движения.
Риски могут быть смягчены путем корректировки периодов EMA, добавления дополнительных фильтров и т.д., чтобы сделать стратегию более надежной.
Стратегия двойной скользящей средней может быть улучшена в следующих аспектах:
Включить индикатор MACD для оценки силы тренда и избежать неправильных сделок.
Добавьте торговые объемы, чтобы подтвердить истинные сигналы прорыва.
Комбинируйте с полосами Боллинджера, моделями свечей для более точных правил входа и выхода.
Используйте подходы машинного обучения, такие как LSTM, для автоматической оптимизации параметров для лучшей адаптивности.
Стратегия двойной скользящей средней торговой стратегии использует торговые возможности от золотых крестов EMA и крестов смерти для определения точек обратного движения тренда для стабильной прибыли. Благодаря преимуществам простоты, эффективности капитала и простоты реализации, она является предпочтительным выбором для новичков в алгоритмической торговле.
/*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") // }