Стратегия следования за трендом RSI Trailing Stop


Дата создания: 2023-12-08 11:41:31 Последнее изменение: 2023-12-08 11:41:31
Копировать: 3 Количество просмотров: 722
1
Подписаться
1621
Подписчики

Стратегия следования за трендом RSI Trailing Stop

Обзор

Эта стратегия - это автоматическая торговая стратегия, которая использует RSI для идентификации тенденции и установления стоп-лосса для подтверждения тенденции в сочетании с движущейся средней. Когда RSI выше 68 и движущаяся средняя превышает текущую движущуюся среднюю, делайте больше; когда RSI меньше 28 и движущаяся средняя превышает текущую движущуюся среднюю, делайте пусто.

Стратегический принцип

Стратегия использует RSI, чтобы определить тенденцию, когда RSI выше 70 - это зона сверхпокупок, а меньше 30 - это зона сверхпродаж. Для подтверждения тенденции используется золотой крест и крест смерти в сочетании с движущейся средней. Конкретные торговые сигналы:

Многоголовый сигнал: RSI больше 68 и пересекает текущую скользящую среднюю перед тем, как пересечь скользящую среднюю. Пустой сигнал: RSI меньше 28 и пересекает текущую подвижную среднюю, прежде чем двигаться вниз.

Настройка стоп-стоп для каждого пункта устанавливает различные пропорции стоп-стоп, от более мягких до более строгих, а именно:

Многоглавная фиксация: в высоких точках 1,4% фиксируют половину позиции, в высоких точках 0,8% фиксируют полную позицию. Многоочередная стоп-камера: 2% от стоимости билета.

Пустой Stop: 0,4% на низком уровне, чтобы остановить половину позиции, 0,8% на низком уровне, чтобы остановить полную позицию.
Стоп-стоп: 2% от стоимости билета.

В то же время, когда тенденция меняется, например, когда RSI превышает 30, рыночная цена полностью сглаживается; когда RSI превышает 60, рыночная цена полностью сглаживается.

Стратегические преимущества

  1. Используйте RSI, чтобы оценить перекуп и перепродажу, чтобы избежать перестрелки.
  2. Подвижная средняя фильтрует тенденции, уменьшая нетрадиционные операции.
  3. Настройка прогрессивного фиксатора, чтобы максимизировать прибыль
  4. Высокая точка остановки, чтобы дать тренду соответствующее пространство.
  5. Стратегия обратного ликвидации в сочетании с индикатором перехода на тренд, быстрое реагирование на внезапные события.

Стратегический риск

  1. Проблемы с настройкой параметров RSI, которые приводят к неэффективной идентификации.
  2. Проблемы с параметрами скользящих средних, которые приводят к плохому эффекту фильтрации.
  3. Стоп-стоп слишком мягкий, риск увеличения убытков.
  4. “Однако, я не думаю, что это будет иметь большое значение.
  5. По мнению экспертов, это приведет к нежелательным убыткам.

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

Направление оптимизации

В частности, можно сделать следующее:

  1. Добавление большего количества фильтров для повышения точности сигналов. Например, добавление фильтров объема транзакций.
  2. Настройка стратегии остановки убытков, отслеживание наивысшей цены и наименьшей цены, реализация мобильного остановки убытков.
  3. Например, если вы хотите, чтобы ваш кошелек оставался на одном месте, вы можете использовать его для отслеживания остановки.
  4. Добавление комбинации параметров, таких как переключение источников данных, использование различных циклов для разных сортов.
  5. Повышение учета стоимости свободных фьючерсных позиций, динамическая корректировка стоп-стоп.

Подвести итог

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

Исходный код стратегии
// © CRabbit
//@version=5

// Starting with $100 and using 10% of the account per trade
strategy("RSI Template", shorttitle="RSI", overlay=false, initial_capital=100, default_qty_value=10, default_qty_type=strategy.percent_of_equity)

// RSI Indicator
ma(source, length, type) =>
    switch type
        "SMA" => ta.sma(source, length)
        "Bollinger Bands" => ta.sma(source, length)
        "EMA" => ta.ema(source, length)
        "SMMA (RMA)" => ta.rma(source, length)
        "WMA" => ta.wma(source, length)
        "VWMA" => ta.vwma(source, length)

rsiLengthInput = input.int(4, minval=1, title="RSI Length", group="RSI Settings")
rsiSourceInput = input.source(close, "Source", group="RSI Settings")
maTypeInput = input.string("SMA", title="MA Type", options=["SMA", "Bollinger Bands", "EMA", "SMMA (RMA)", "WMA", "VWMA"], group="MA Settings")
maLengthInput = input.int(23, title="MA Length", group="MA Settings")
bbMultInput = input.float(2.0, minval=0.001, maxval=50, title="BB StdDev", group="MA Settings")

up = ta.rma(math.max(ta.change(rsiSourceInput), 0), rsiLengthInput)
down = ta.rma(-math.min(ta.change(rsiSourceInput), 0), rsiLengthInput)
rsi = down == 0 ? 100 : up == 0 ? 0 : 100 - (100 / (1 + up / down))
rsiMA = ma(rsi, maLengthInput, maTypeInput)
isBB = maTypeInput == "Bollinger Bands"

plot(rsi, "RSI", color=#7E57C2)
plot(rsiMA, "RSI-based MA", color=color.green)
rsiUpperBand = hline(70, "RSI Upper Band", color=#787B86)
hline(50, "RSI Middle Band", color=color.new(#787B86, 50))
rsiLowerBand = hline(30, "RSI Lower Band", color=#787B86)
fill(rsiUpperBand, rsiLowerBand, color=color.rgb(126, 87, 194, 90), title="RSI Background Fill")


// Configure backtest start date with inputs
startDate = input.int(title="Start Date", defval=1, minval=1, maxval=31)
startMonth = input.int(title="Start Month", defval=6, minval=1, maxval=12)
startYear = input.int(title="Start Year", defval=2022, minval=1800, maxval=2100)

// See if this bar's time happened on/after start date
afterStartDate = (time >= timestamp(syminfo.timezone,
     startYear, startMonth, startDate, 0, 0))


// Long and Short buy strategy
// Submit a market open/ close Long order, but only on/after start date
if (afterStartDate)
    if rsi > 68 and (rsiMA > rsiMA[1])
        strategy.entry("Long Order", strategy.long, comment="ENTER-LONG")
    if rsi < 30
        strategy.close("Long Order", alert_message="L-CL")

strategy.exit("L-TP1", from_entry="Long Order", limit=high * 1.004, qty_percent=50, alert_message="L-TP1" + str.tostring(high * 1.004))
strategy.exit("L-TP2", from_entry="Long Order", limit=high * 1.008, qty_percent=100, alert_message="L-TP2" + str.tostring(high * 1.008))
strategy.exit("Exit Long", from_entry="Long Order", stop=low * 0.98, alert_message="L-SL" + str.tostring(low * 0.98))        


// Submit a market Open/ Close Short order, but only on/after start date
if (afterStartDate)
    if rsi < 28 and (rsiMA < rsiMA[1])
        strategy.entry("Short Order", strategy.short, comment="ENTER-SHORT")
    if rsi > 60
        strategy.close("Short Order", alert_message="S-CL")    

strategy.exit("S-TP1", from_entry="Short Order", limit=low * 0.996, qty_percent=50, alert_message="S-TP1" + str.tostring(low * 0.996))
strategy.exit("S-TP2", from_entry="Short Order", limit=low * 0.992, qty_percent=100, alert_message="S-TP2" + str.tostring(low * 0.992))
strategy.exit("Exit Short", from_entry="Short Order", stop=high * 1.02, alert_message="S-SL" + str.tostring(high * 1.02))

// MONTHLY TABLE //

prec      = input(2, title = "Return Precision")

new_month = month(time) != month(time[1])
new_year  = year(time)  != year(time[1])

eq = strategy.equity

bar_pnl = eq / eq[1] - 1

cur_month_pnl = 0.0
cur_year_pnl  = 0.0

// Current Monthly P&L
cur_month_pnl := new_month ? 0.0 : 
                 (1 + cur_month_pnl[1]) * (1 + bar_pnl) - 1 

// Current Yearly P&L
cur_year_pnl := new_year ? 0.0 : 
                 (1 + cur_year_pnl[1]) * (1 + bar_pnl) - 1  

// Arrays to store Yearly and Monthly P&Ls
var month_pnl  = array.new_float(0)
var month_time = array.new_int(0)

var year_pnl  = array.new_float(0)
var year_time = array.new_int(0)

if (not na(cur_month_pnl[1]) and (new_month or barstate.islast))
    array.push(month_pnl , cur_month_pnl[1])
    array.push(month_time, time[1])

if (not na(cur_year_pnl[1]) and (new_year or barstate.islast))
    array.push(year_pnl , cur_year_pnl[1])
    array.push(year_time, time[1])

// Monthly P&L Table    
var monthly_table = table(na)

if (barstate.islast)
    monthly_table := table.new(position.bottom_right, columns = 14, rows = array.size(year_pnl) + 1, border_width = 1)

    table.cell(monthly_table, 0,  0, "",     bgcolor = #cccccc)
    table.cell(monthly_table, 1,  0, "Jan",  bgcolor = #cccccc)
    table.cell(monthly_table, 2,  0, "Feb",  bgcolor = #cccccc)
    table.cell(monthly_table, 3,  0, "Mar",  bgcolor = #cccccc)
    table.cell(monthly_table, 4,  0, "Apr",  bgcolor = #cccccc)
    table.cell(monthly_table, 5,  0, "May",  bgcolor = #cccccc)
    table.cell(monthly_table, 6,  0, "Jun",  bgcolor = #cccccc)
    table.cell(monthly_table, 7,  0, "Jul",  bgcolor = #cccccc)
    table.cell(monthly_table, 8,  0, "Aug",  bgcolor = #cccccc)
    table.cell(monthly_table, 9,  0, "Sep",  bgcolor = #cccccc)
    table.cell(monthly_table, 10, 0, "Oct",  bgcolor = #cccccc)
    table.cell(monthly_table, 11, 0, "Nov",  bgcolor = #cccccc)
    table.cell(monthly_table, 12, 0, "Dec",  bgcolor = #cccccc)
    table.cell(monthly_table, 13, 0, "Year", bgcolor = #999999)


    for yi = 0 to array.size(year_pnl) - 1
        table.cell(monthly_table, 0,  yi + 1, str.tostring(year(array.get(year_time, yi))), bgcolor = #cccccc)
        
        y_color = array.get(year_pnl, yi) > 0 ? color.new(color.green, transp = 50) : color.new(color.red, transp = 50)
        table.cell(monthly_table, 13, yi + 1, str.tostring(math.round(array.get(year_pnl, yi) * 100, prec)), bgcolor = y_color)
        
    for mi = 0 to array.size(month_time) - 1
        m_row   = year(array.get(month_time, mi))  - year(array.get(year_time, 0)) + 1
        m_col   = month(array.get(month_time, mi)) 
        m_color = array.get(month_pnl, mi) > 0 ? color.new(color.green, transp = 70) : color.new(color.red, transp = 70)
        
        table.cell(monthly_table, m_col, m_row, str.tostring(math.round(array.get(month_pnl, mi) * 100, prec)), bgcolor = m_color)