Tendência do RSI Seguindo estratégia com stop loss de trail

Autora:ChaoZhang, Data: 2023-12-08 11:41:31
Tags:

img

Resumo

Esta estratégia é uma estratégia de negociação automatizada que identifica a tendência usando o indicador RSI e confirma a tendência com médias móveis, com configurações de stop loss e take profit.

Estratégia lógica

A estratégia usa principalmente o indicador RSI para identificar condições de sobrecompra e sobrevenda para determinar a tendência. Valores acima de 70 para o RSI indicam uma condição de sobrecompra e valores abaixo de 30 indicam uma condição de sobrevenda. A tendência é confirmada usando os sinais de cruz de ouro e cruz de morte das médias móveis. Os sinais comerciais específicos são:

sinal longo: o RSI vai acima de 68 e a média móvel atual cruza acima da média móvel anterior, vá longo.
Sinais curtos: RSI desce abaixo de 28 e a média móvel atual cruza abaixo da média móvel anterior, vá curto.

As configurações de stop loss e take profit são escalonadas, de mais soltas a mais rigorosas:

Long take profit: tirar lucro 50% da posição a 1,4% acima do máximo, tirar lucro 100% a 0,8% acima do máximo.
O preço de entrada é o preço de saída.

Tome lucro curto: Tome lucro 50% da posição a 0,4% abaixo do mínimo, tire lucro 100% a 0,8% abaixo do mínimo. Previsão de prejuízo curto: fixar prejuízo curto a 2% acima do preço de entrada.

Além disso, quando a tendência se inverte, como RSI quebrando abaixo de 30 quando longo, feche toda a posição longa no mercado; quando RSI quebra acima de 60 quando curto, feche toda a posição curta no mercado.

Vantagens

  1. Usar o RSI para determinar sobrecompra/supervenda para evitar comprar alto e vender baixo.
  2. Filtros com médias móveis para reduzir as negociações contra a tendência principal.
  3. Os "staggered" tomam metas de lucro para maximizar os lucros.
  4. Um stop loss mais amplo permite um certo retrocesso.
  5. O fechamento de posições baseado na inversão de tendência reage rapidamente a eventos repentinos.

Riscos

  1. Mal ajuste dos parâmetros do RSI levando a sinais imprecisos.
  2. Mal ajuste dos parâmetros da média móvel, levando a uma fraca filtragem.
  3. Parar perdas muito largas levando a grandes perdas.
  4. Tirar lucro demasiado apertado, deixando lucros na mesa.
  5. Sinal de reversão impreciso fechando posições desnecessariamente.

Para abordar os riscos acima, deve ser feito um amplo ajuste de parâmetros. Stop loss e take profit também devem ser definidos adequadamente com base na volatilidade do mercado. Os sinais de reversão devem ser usados com cuidado para evitar perdas desnecessárias.

Oportunidades de melhoria

A estratégia pode ser melhorada:

  1. Adicionar mais filtros como volume para melhorar a precisão do sinal.
  2. Implementar stop loss para bloquear os lucros.
  3. Usar o trailing take profit para algumas saídas para maximizar os lucros.
  4. Adicionar comutação de instrumentos para utilizar parâmetros ótimos.
  5. Incorporar o custo de carregamento para futuros para ajustar dinamicamente as paradas.

Conclusão

No geral, esta é uma estratégia madura e confiável de seguir tendências. Identifica a tendência bem usando o RSI e filtros adicionais com médias móveis. Também implementa configurações de stop loss e take profit escalonadas sensíveis. Pode ter um desempenho muito bom nos mercados de tendências se ajustado adequadamente.


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


Mais.