Seguidor de tendência de ruptura V2

Autora:ChaoZhang, Data: 2023-11-01 17:24:08
Tags:

img

Resumo

Esta estratégia é uma variação da minha outra estratégia Breakout Trend Follower. Na outra estratégia, você pode usar uma média móvel para atuar como um filtro para seus negócios (ou seja, se o preço estiver abaixo da média móvel, ele não vai durar muito tempo).

Então, este script permite que você olhe para tendências de prazos mais altos (ou seja, há máximos mais altos e mínimos mais altos? Se assim for, esta é uma tendência de alta). Você só toma negociações quando você está com a tendência. Você tem a capacidade de selecionar até duas tendências para atuar como um filtro. Cada direção de tendência é mostrada em uma tabela no gráfico para fácil referência. Os máximos e mínimos de pivô atuais são traçados no gráfico para que você possa ver quando você pode estar quebrando tanto a tendência do prazo atual quanto as tendências de nível mais alto.

O que eu descobri foi que, em geral, esta estratégia não funciona tão bem como a outra, mas parece ser muito mais exigente com as negociações. mostrando taxas de ganho mais altas e um melhor fator de lucro.

Estratégia lógica

A lógica central desta estratégia consiste em identificar tendências utilizando rupturas dos níveis de suporte e resistência em prazos mais longos e realizar operações na direção da tendência.

Em especial, aplica as seguintes medidas:

  1. Calcule os níveis de suporte e resistência do pivô no quadro de tempo atual (por exemplo, 1 hora).

  2. Calcular os níveis de suporte e resistência do pivô em um ou mais prazos mais altos (por exemplo, 4 horas e diariamente).

  3. Traçar esses níveis de suporte e resistência como linhas horizontais no gráfico.

  4. Determine a direção da tendência com base em se o preço quebra pontos altos ou baixos anteriores.

  5. Permitir que o usuário selecione uma ou mais tendências de um período mais longo como condição de filtro. Ou seja, considere apenas a tomada de negociações quando a tendência do período atual estiver alinhada com a tendência do período mais longo.

  6. Quando a condição do filtro de tendência é atendida e o preço atual quebra o nível chave, entre longo ou curto.

  7. À medida que o preço se move, ajuste o stop loss para novos mínimos para garantir lucros e seguir a tendência.

  8. Sair quando for acionado o stop loss ou quando for quebrado o nível chave de suporte/resistência.

Ao analisar tendências em vários prazos, a estratégia tenta negociar apenas na direção de tendências mais fortes para melhorar a taxa de ganho.

Vantagens da estratégia

  • Usar vários prazos para julgar tendências pode identificar com mais precisão a direção da tendência mais forte, evitando ruído.

  • Somente a negociação com as principais tendências melhora significativamente a taxa de ganho.

  • Os níveis de suporte e resistência fornecem níveis claros de entrada e stop loss.

  • Ajustar paradas ao longo da tendência para maximizar o bloqueio de lucro.

  • Lógica estratégica simples e clara, fácil de entender e otimizar.

Riscos da Estratégia

  • Depende de tendências de longo prazo, propensas a ficarem presas a inversões de tendência.

  • Não considera impactos fundamentais, pode desviar-se do preço em eventos importantes.

  • Nenhum controle de dimensionamento de posição definido. Deve otimizar o tamanho por tamanho da conta, volatilidade etc.

  • Período de backtest limitado, deverá alargar os testes em diferentes ambientes de mercado.

  • Não se deve considerar os custos comerciais, devendo ajustar os parâmetros com base nos custos reais.

  • Pode desenvolver sinais para negociações de curto prazo para implementar estratégias de vários prazos.

Orientações de otimização

  • Adicionar condições de filtragem:

    • Fundamentos como ganhos, notícias

    • Indicadores como volume, ATR pára

  • Otimizar parâmetros:

    • Períodos para o cálculo de suporte/resistência

    • Prazos para a determinação da tendência

  • Ampliar o âmbito da estratégia:

    • Desenvolver estratégias comerciais de curto prazo

    • Considerar oportunidades de curto prazo

    • Diferenças entre os mercados

  • Melhorar a gestão dos riscos:

    • Otimizar o dimensionamento das posições em função da volatilidade e do tamanho

    • Melhorar as estratégias de stop loss, como movimentos/paras de parâmetros

    • Introduzir métricas ajustadas ao risco

  • Melhorar a lógica de execução:

    • Seleção do horário de entrada

    • Inscrições de tamanho parcial

    • Optimização do movimento de stop loss

Conclusão

Esta estratégia projetou um sistema de breakout relativamente robusto, analisando tendências em vários prazos. Em comparação com filtros simples como médias móveis, ele demonstrou taxas de ganho e rácios risco-recompensa mais elevados. Mas há algumas áreas que podem ser melhoradas, como a falta de mecanismos sólidos de gerenciamento de risco e consideração dos fundamentos. Com otimização adicional, pode se tornar uma estratégia de tendência muito prática.


/*backtest
start: 2023-10-24 00:00:00
end: 2023-10-26 00:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4

// Revision:        1
// Author:          @millerrh
// Strategy:  Enter long when recent swing high breaks out, using recent swing low as stop level.  Move stops up as higher lows print to act
// as trailing stops.  Ride trend as long as it is there and the higher lows aren't breached.  
// The difference between this one and the previous Breakout Trend Follower is that this one uses higher timeframe higher highs/higher lows as a filter instead 
// of an arbitrary Moving Average.  I wanted to test out whether waiting for longer term actual trend changes produced better stats than just the moving average.
// Conditions/Variables 
//    1. Manually configure which dates to back test
//    2. Can add a filter to only take setups that are above (or below for shorts) user-defined larger timeframe trends (helps avoid trading counter trend) 

// === CALL STRATEGY/STUDY, PROGRAMATICALLY ENTER STRATEGY PARAMETERS HERE SO YOU DON'T HAVE TO CHANGE THEM EVERY TIME YOU RUN A TEST ===
// (STRATEGY ONLY) - Comment out srategy() when in a study() 
strategy("Breakout Trend Follower V2", overlay=true, initial_capital=10000, currency='USD', 
   default_qty_type=strategy.percent_of_equity, default_qty_value=100, commission_type=strategy.commission.percent, commission_value=0.1)
// (STUDY ONLY) - Comment out study() when in a strategy() 
//study("Breakout Trend Follower V2", overlay=true)

// === BACKTEST RANGE ===
Start = input(defval = timestamp("01 Jan 2019 06:00 +0000"), title = "Backtest Start Date", type = input.time, group = "Backtest Range")
Finish = input(defval = timestamp("01 Jan 2100 00:00 +0000"), title = "Backtest End Date", type = input.time, group = "Backtest Range")

// == USER INPUTS ==
tableLocation = input(defval="Top", options=["Top", "Bottom"], title = "Info Table Location", group = "Display",
  tooltip = "Place information table on the top of the pane or the bottom of the pane.")
lookback = input(defval = 3, title = "Pivot Lookback Period", group = "Pivot Points",
  tooltip = "Looks for pivot points within this number of bars both left and right.")
showPivotPoints = input(title = "Show Historical Pivot Points?", type = input.bool, defval = false, group = "Pivot Points",
  tooltip = "Toggle this on to see the historical pivot points that were used.  Change the Lookback Period to adjust the frequency of these points.
  The pivot points are only shown for the current chart timeframe - to see the Daily pivot pionts, use the Daily timeframe, etc.")
trendFilter = input(defval="1st Timeframe", options=["1st Timeframe", "Both Timeframes", "None"], title = "Use HTF Trend for Filtering?", group = "Higher Timeframe Levels",
  tooltip = "Signals will be ignored when price is not aligned with the higher timeframe trend(s).  The intent is to keep you out of bear periods and only buying when 
  price is showing strength and you are trading with the trend.")
twoSet = input(defval="D", title="1st High Timeframe", type=input.resolution, group = "Higher Timeframe Levels",
  tooltip = "Allows you to set two different time frames for looking at the trend.")
threeSet = input(defval="W", title="2nd High Timeframe", type=input.resolution, group = "Higher Timeframe Levels")
showMTFLevels = input(title = "Show Multiple Timeframe S/R Levels?", type = input.bool, defval = true, group = "Higher Timeframe Levels",
  tooltip = "Displays the pivot highs and lows of higher timeframes to use as support/resistance levels. When these levels break, the trend
  will change on these higher timeframes.")
currentColorS = input(color.new(color.orange,50), title = "Current Timeframe    Support", type = input.color, group = "Higher Timeframe Levels", inline = "MTF1")
currentColorR = input(color.new(color.blue,50), title = " Resistance", type = input.color, group = "Higher Timeframe Levels", inline = "MTF1")
oneColorS = input(color.new(color.yellow,50), title = "1st High Timeframe   Support", type = input.color, group = "Higher Timeframe Levels", inline = "MTF2")
oneColorR = input(color.new(color.yellow,50), title = " Resistance", type = input.color, group = "Higher Timeframe Levels", inline = "MTF2")
twoColorS = input(color.new(color.white,50), title = "2nd High Timeframe    Support", type = input.color, group = "Higher Timeframe Levels", inline = "MTF3")
twoColorR = input(color.new(color.white,50), title = " Resistance", type = input.color, group = "Higher Timeframe Levels", inline = "MTF3")

//  == DEFINE FUNCTIONS FOR USE IN MULTIPLE TIMEFRAMES (USING A TUPLE TO AVOID SO MANY SECURITY CALLS) ==  
f_getHTF() =>
    ph = pivothigh(high, lookback, lookback)
    pl = pivotlow(low, lookback, lookback)
    highLevel = valuewhen(ph, high[lookback], 0)
    lowLevel = valuewhen(pl, low[lookback], 0)
    barsSinceHigh = barssince(ph) + lookback
    barsSinceLow = barssince(pl) + lookback
    timeSinceHigh = time[barsSinceHigh]
    timeSinceLow = time[barsSinceLow]
    [ph, pl, highLevel, lowLevel, barsSinceHigh, barsSinceLow, timeSinceHigh, timeSinceLow]
    
[ph_01, pl_01, hL_01, lL_01, bsSH_01, bsSL_01, tSH_01, tSL_01] = security(syminfo.tickerid, "", f_getHTF())
[ph_02, pl_02, hL_02, lL_02, bsSH_02, bsSL_02, tSH_02, tSL_02] = security(syminfo.tickerid, twoSet, f_getHTF())
[ph_03, pl_03, hL_03, lL_03, bsSH_03, bsSL_03, tSH_03, tSL_03] = security(syminfo.tickerid, threeSet, f_getHTF())

// Plot historical pivot points for debugging and configuring the lookback period.
plot(showPivotPoints ? ph_01 : na, style=plot.style_cross, linewidth=3, color=color.new(color.yellow,50), offset=-lookback)
plot(showPivotPoints ? pl_01 : na, style=plot.style_cross, linewidth=3, color=color.new(color.yellow,50), offset=-lookback)

// == PLOT SUPPORT/RESISTANCE LINES ON THE HIGHER TIMEFRAMES ==
// Use a function to define the lines
f_line(x1, y1, y2, _color) =>
    var line id = na
    // line.delete(id)
    // id := line.new(x1, y1, time, y2, xloc.bar_time, extend.right, _color)

// 1st Timeframe
highLine1 = showMTFLevels ? f_line(tSH_01, hL_01, hL_01, currentColorR) : na
lowLine1 = showMTFLevels ? f_line(tSL_01, lL_01, lL_01, currentColorS) : na 
// 2nd Timeframe
highLine2 = showMTFLevels ? f_line(tSH_02, hL_02, hL_02, oneColorR) : na
lowLine2 = showMTFLevels ? f_line(tSL_02, lL_02, lL_02, oneColorS) : na
// 3rd Timeframe
highLine3 = showMTFLevels ? f_line(tSH_03, hL_03, hL_03, twoColorR) : na
lowLine3 = showMTFLevels ? f_line(tSL_03, lL_03, lL_03, twoColorS) : na

// == TREND CALCULATIONS (USING A TUPLE TO CONSOLIDATE REPETATIVE CODE AND GENERATE MULTIPE VARIABLES WITH ONE FUNCTION ==
f_signal(highLevel, lowLevel) =>
    uptrendSignal    = high > highLevel
    downtrendSignal  = low < lowLevel
    inUptrend        = bool(na)
    inDowntrend      = bool(na) 
    inUptrend       := uptrendSignal[1] ? true : downtrendSignal[1] ? false : inUptrend[1]
    inDowntrend     := not inUptrend
    [uptrendSignal, downtrendSignal, inUptrend, inDowntrend]

[uptrendSignal1, downtrendSignal1, inUptrend1, inDowntrend1] = f_signal(hL_01, lL_01)  // 1st Timeframe
[uptrendSignal2, downtrendSignal2, inUptrend2, inDowntrend2] = f_signal(hL_02, lL_02)  // 2nd Timeframe
[uptrendSignal3, downtrendSignal3, inUptrend3, inDowntrend3] = f_signal(hL_03, lL_03)  // 3rd Timeframe

// == TREND TABLE PLOTTING ==
tablePos = tableLocation == "Top" ? position.top_right : position.bottom_right
var table trendTable = table.new(tablePos, 3, 1, border_width = 3)
upColor = color.rgb(38, 166, 154)
downColor = color.rgb(240, 83, 80)

f_fillCell(_column, _row, _cellText, _c_color) =>
    table.cell(trendTable, _column, _row, _cellText, bgcolor = color.new(_c_color, 70), text_color = _c_color, width = 6)

if barstate.islast or barstate.islastconfirmedhistory
    f_fillCell(0, 0, inUptrend1 ? "▲" : "▼", inUptrend1 ? upColor : downColor)
    f_fillCell(1, 0, inUptrend2 ? "▲ " + twoSet : "▼ " + twoSet, inUptrend2 ? upColor : downColor)
    f_fillCell(2, 0, inUptrend3 ? "▲ " + threeSet : "▼ " + threeSet, inUptrend3 ? upColor : downColor)

// Conditions for entry and exit
buyConditions =  true
buySignal = high > hL_01 and buyConditions // Code to act like a stop-buy for the Study
sellSignal = low < lL_01 // Code to act like a stop-loss for the Study

// (STRATEGY ONLY) Comment out for Study
strategy.entry("Long", strategy.long, stop = hL_01, when = buyConditions)
// strategy.entry("Long", strategy.long, stop = buyLevel2, when = time > Start and time < Finish and high > maFilterCheck)
strategy.exit("Exit Long", from_entry = "Long", stop=lL_01)



Mais.