Эта стратегия использует систему скользящих средних для определения текущего направления тренда и делает длинные или короткие позиции в соответствии с трендом. Когда скользящая средняя растет, уверенность в длинном выше, так что идите длинным. Когда скользящая средняя падает, уверенность в коротком выше, так что идите коротким. Эта стратегия в основном использует систему скользящих средних для определения направления тренда рынка, принадлежащего к следующей стратегии тренда.
Вычислить взвешенную скользящую среднюю vwma как показатель скользящей средней за определенный период (по умолчанию 400 периодов).
Определить, если скользящий средний vwma растет, если растет, установить длинный сигнал восходящего тренда; если падает, установить короткий сигнал нисходящего тренда.
Когда рост тренда верен, идете в длинный; когда спад тренда верен, закрывайте длинный и идите в короткий.
Вычислить стратегию return bar_pnl и buy & hold return bar_bh для каждой строки.
В соответствии с квартальными и годовыми временными метками вычислить квартальную стратегическую доходность quarter_pnl, годовую доходность year_pnl и соответствующую доходность buy & hold quarter_bh, year_bh.
Показать квартальную стратегию прибыли против прибыли покупки и хранения в таблице.
Основными преимуществами этой стратегии являются:
Определяет рыночную тенденцию по скользящей средней, легко понять.
Хорошо контролирую снижение цен, следуя тренду, уменьшаю убытки на рынках без тренда.
Некоторые настраиваемые параметры. В основном регулируют период скользящей средней, легко тестировать и оптимизировать.
Интуитивно понятная таблица возвратов, чтобы показать результаты ясно.
Добавить buy & hold return в таблицу для сравнения, показывает избыточную доходность.
Гибкое положение стола, легко интегрируется с другими стратегиями.
Существуют также некоторые риски:
Низкая производительность на долгосрочном бычьем рынке по сравнению с покупкой и удержанием.
Высокий риск на рынке с ограниченным диапазоном. может добавить фильтрующие условия, такие как прерывание предыдущего максимума для уменьшения транзакций.
Движущаяся средняя имеет плохую способность к настройке кривой, может пропустить поворотные моменты тренда.
Нет механизма стоп-лосса, риски огромного снижения, можно установить динамический стоп-лосс или размещение позиции.
Для таблицы, можно добавить показатели риска, такие как коэффициент резкости, максимальное снижение.
Стратегия может быть оптимизирована в следующих аспектах:
Оптимизировать параметры скользящей средней, корректировать период на основе рыночных режимов.
Добавьте фильтры вроде прерывания предыдущего максимума, чтобы уменьшить удары.
Попробуйте различные типы скользящих средних, как WMA, DEMA и т.д.
Добавьте механизмы остановки потерь, такие как динамические остановки или размещение позиций.
Обогатите содержимое таблицы, добавьте такие показатели, как соотношение резкости, максимальное использование.
Объедините с другими индикаторами, такими как MACD, Bollinger Bands, чтобы определить тенденции.
Оптимизировать размещение позиций, динамически корректировать позиции на основе рыночных условий.
Испытать на разных продуктах, найти наилучшее применение.
Стратегия торговли скользящей средней относительно проста и проста. Она следует за трендом путем определения тренда с использованием скользящей средней, с хорошим контролем за снижением, подходящим для трейдеров, следующих за трендом. Есть еще большое пространство для оптимизации, например, система скользящей средней, механизм остановки потери, размещение позиций и т. д., чтобы сделать ее адаптивной к сложным рыночным условиям.
/*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)