Стратегия торговли трендом на основе скользящей средней

Автор:Чао Чжан, Дата: 2023-10-30 15:53:25
Тэги:

img

Обзор

Эта стратегия использует систему скользящих средних для определения текущего направления тренда и делает длинные или короткие позиции в соответствии с трендом. Когда скользящая средняя растет, уверенность в длинном выше, так что идите длинным. Когда скользящая средняя падает, уверенность в коротком выше, так что идите коротким. Эта стратегия в основном использует систему скользящих средних для определения направления тренда рынка, принадлежащего к следующей стратегии тренда.

Логика стратегии

  1. Вычислить взвешенную скользящую среднюю vwma как показатель скользящей средней за определенный период (по умолчанию 400 периодов).

  2. Определить, если скользящий средний vwma растет, если растет, установить длинный сигнал восходящего тренда; если падает, установить короткий сигнал нисходящего тренда.

  3. Когда рост тренда верен, идете в длинный; когда спад тренда верен, закрывайте длинный и идите в короткий.

  4. Вычислить стратегию return bar_pnl и buy & hold return bar_bh для каждой строки.

  5. В соответствии с квартальными и годовыми временными метками вычислить квартальную стратегическую доходность quarter_pnl, годовую доходность year_pnl и соответствующую доходность buy & hold quarter_bh, year_bh.

  6. Показать квартальную стратегию прибыли против прибыли покупки и хранения в таблице.

Анализ преимуществ

Основными преимуществами этой стратегии являются:

  1. Определяет рыночную тенденцию по скользящей средней, легко понять.

  2. Хорошо контролирую снижение цен, следуя тренду, уменьшаю убытки на рынках без тренда.

  3. Некоторые настраиваемые параметры. В основном регулируют период скользящей средней, легко тестировать и оптимизировать.

  4. Интуитивно понятная таблица возвратов, чтобы показать результаты ясно.

  5. Добавить buy & hold return в таблицу для сравнения, показывает избыточную доходность.

  6. Гибкое положение стола, легко интегрируется с другими стратегиями.

Анализ рисков

Существуют также некоторые риски:

  1. Низкая производительность на долгосрочном бычьем рынке по сравнению с покупкой и удержанием.

  2. Высокий риск на рынке с ограниченным диапазоном. может добавить фильтрующие условия, такие как прерывание предыдущего максимума для уменьшения транзакций.

  3. Движущаяся средняя имеет плохую способность к настройке кривой, может пропустить поворотные моменты тренда.

  4. Нет механизма стоп-лосса, риски огромного снижения, можно установить динамический стоп-лосс или размещение позиции.

  5. Для таблицы, можно добавить показатели риска, такие как коэффициент резкости, максимальное снижение.

Руководство по оптимизации

Стратегия может быть оптимизирована в следующих аспектах:

  1. Оптимизировать параметры скользящей средней, корректировать период на основе рыночных режимов.

  2. Добавьте фильтры вроде прерывания предыдущего максимума, чтобы уменьшить удары.

  3. Попробуйте различные типы скользящих средних, как WMA, DEMA и т.д.

  4. Добавьте механизмы остановки потерь, такие как динамические остановки или размещение позиций.

  5. Обогатите содержимое таблицы, добавьте такие показатели, как соотношение резкости, максимальное использование.

  6. Объедините с другими индикаторами, такими как MACD, Bollinger Bands, чтобы определить тенденции.

  7. Оптимизировать размещение позиций, динамически корректировать позиции на основе рыночных условий.

  8. Испытать на разных продуктах, найти наилучшее применение.

Заключение

Стратегия торговли скользящей средней относительно проста и проста. Она следует за трендом путем определения тренда с использованием скользящей средней, с хорошим контролем за снижением, подходящим для трейдеров, следующих за трендом. Есть еще большое пространство для оптимизации, например, система скользящей средней, механизм остановки потери, размещение позиций и т. д., чтобы сделать ее адаптивной к сложным рыночным условиям.


/*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)

Больше