브레이크업 트렌드 추종자 V2

저자:차오장, 날짜: 2023-11-01 17:24:08
태그:

img

전반적인 설명

이 전략은 다른 브레이크아웃 트렌드 팔로워 전략의 변형입니다. 다른 전략에서는 이동 평균을 사용하여 트레이드를 필터로 사용할 수 있습니다. (즉, 가격이 이동 평균보다 낮으면 오래 가지 않습니다.) 더 높은 시간 프레임에서 트렌드를 감지하는 도구를 만든 후 이동 평균보다 더 나은 필터가 될 수 있는지보고 싶었습니다.

따라서 이 스크립트는 더 높은 시간 프레임 트렌드를 볼 수 있습니다. (즉, 더 높은 최고와 더 높은 하락이 있습니까? 그렇다면 이것은 상승 추세입니다.) 트렌드에있을 때만 거래를합니다. 필터로 작용하기 위해 최대 두 가지 트렌드를 선택할 수 있습니다. 각 트렌드 방향은 쉬운 참조를 위해 차트에 있는 테이블에 표시됩니다. 현재 피보트 최고와 하락은 차트에 그래프로 표시되어 있으므로 현재 시간 프레임 트렌드와 더 높은 수준의 트렌드를 둘 다 깨는 것을 볼 수 있습니다.

제가 발견한 것은 일반적으로 이 전략은 다른 전략만큼 좋은 성과를 거두지 못하지만 거래에 대해 훨씬 더 까다로운 것으로 보입니다. 더 높은 승률과 더 나은 이윤 인수를 보여줍니다. 단지 훨씬 적은 거래가 필요하고 순이익은 좋지 않습니다.

전략 논리

이 전략의 핵심 논리는 더 높은 시간 프레임에서 지원 및 저항 레벨의 파장을 사용하여 트렌드를 식별하고 트렌드 방향으로 거래를하는 것입니다.

구체적으로 다음 단계를 실행합니다.

  1. 현재 시간 프레임 (예: 1 시간) 에서 피오트 지원 및 저항 수준을 계산합니다. 이것은 특정 기간 동안 가장 높은 최고와 가장 낮은 최저를 살펴봄으로써 수행됩니다.

  2. 한 개 이상의 높은 시간 프레임 (예: 4 시간 및 매일) 에서 피오트 지원 및 저항 수준을 계산합니다. 이것은 현재 시간 프레임과 동일한 논리를 사용합니다.

  3. 이 지지 및 저항 수준을 차트에 수평선으로 그려라. 이 수준을 깨는 것은 더 높은 시간 프레임에서의 트렌드 변화를 나타낸다.

  4. 가격이 이전 최고 또는 낮은 지점을 깨는지 여부에 따라 트렌드 방향을 결정합니다. 이전 최고를 넘어서는 것은 상승 추세를 나타냅니다. 이전 최저를 넘어서는 것은 하락 추세를 나타냅니다.

  5. 사용자가 필터 조건으로 하나 이상의 높은 시간 프레임 트렌드를 선택하도록 허용합니다. 즉, 현재 시간 프레임 트렌드가 더 높은 시간 프레임 트렌드와 일치 할 때 거래를 고려하십시오.

  6. 트렌드 필터 조건이 충족되고 현재 가격이 핵심 수준을 깨면, 긴 또는 짧은 항목을 입력합니다. 중지 손실은 이전 주요 지원 또는 저항 수준에 설정됩니다.

  7. 가격 변동에 따라 수익을 확보하고 트렌드를 따라가기 위해 Stop Loss를 새로운 낮은 지점으로 조정합니다.

  8. 정지 손실이 발생하거나 주요 지원/저항 수준이 깨지면 출구.

여러 시간 프레임에서 트렌드를 분석함으로써 전략은 승률을 향상시키기 위해 더 강한 트렌드 방향으로만 거래하려고 시도합니다. 한편, 주요 레벨은 명확한 엔트리 및 스톱 손실 신호를 제공합니다.

전략 의 장점

  • 트렌드를 판단하기 위해 여러 시간 프레임을 사용하면 더 강한 트렌드 방향을 더 정확하게 식별 할 수 있으며 소음을 피합니다.

  • 주요 트렌드에 대한 거래만 크게 승률을 향상시킵니다. 간단한 이동 평균 필터와 비교하면이 전략은 높은 승률과 위험 보상 비율을 보여주었습니다.

  • 지원 및 저항 수준은 명확한 진입 및 중지 손실 수준을 제공합니다. 특정 진입 지점을 추측 할 필요가 없습니다.

  • 트렌드를 따라 스톱을 조정하여 수익을 최대화합니다.

  • 간단하고 명확한 전략 논리, 이해하기 쉽고 최적화하기 쉽습니다.

전략 의 위험

  • 장기적인 추세에 의존하고, 추세 반전에 갇히기 쉽다. 추세를 판단하는 시간 프레임을 단축하거나 다른 지표를 사용하여 도움을 주어야 한다.

  • 근본적인 영향을 고려하지 않습니다. 주요 이벤트에서 가격에서 벗어날 수 있습니다. 수익 날짜와 같은 필터를 추가 할 수 있습니다.

  • 위치 사이즈 컨트롤 설정되지 않습니다. 계정 크기, 변동성 등에 따라 크기를 최적화해야합니다.

  • 제한된 백테스트 기간. 다른 시장 환경에서 테스트를 확장해야합니다.

  • 거래 비용을 고려하지 않고 실제 비용을 기준으로 매개 변수를 조정해야 합니다.

  • 단기 거래에 대한 신호를 개발하여 다중 시간 프레임 전략을 구현할 수 있습니다.

최적화 방향

  • 필터 조건을 추가합니다:

    • 수익, 뉴스 이벤트 같은 기본

    • 부피, ATR 중지와 같은 지표

  • 매개 변수를 최적화:

    • 지원/저항 계산 기간

    • 동향 결정에 대한 기간

  • 전략의 범위를 넓혀라

    • 단기적 거래 전략 개발

    • 단축 기회를 고려하십시오.

    • 시장 간 스프레드

  • 리스크 관리 강화:

    • 변동성 및 크기에 따라 포지션 크기를 최적화

    • 이동 / 브래킷 중지와 같은 중지 손실 전략을 개선

    • 리스크 조정 메트릭

  • 실행 논리를 개선합니다.

    • 입력 시간 선택

    • 부분 크기의 항목

    • 스톱 손실 움직임 최적화

결론

이 전략은 여러 시간 프레임에 걸쳐 트렌드를 분석하여 비교적 견고한 브레이크아웃 시스템을 설계했다. 이동 평균과 같은 간단한 필터와 비교했을 때 더 높은 승률과 위험 보상 비율을 보여주었다. 그러나 탄탄한 위험 관리 메커니즘의 부족과 기본 요소의 고려와 같은 개선 될 수있는 몇 가지 영역이 있습니다. 추가 최적화로 매우 실용적인 트렌드 다음 전략이 될 수 있습니다. 전반적으로 전략 디자인은 건전하며, 멀티 타임 프레임 분석을 통해 정확성을 향상시키고 추가 연구와 응용을 가치가 있습니다.


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



더 많은