쿨라마기 탈출 추적 전략

저자:차오장, 날짜: 2024-01-31 17:06:36
태그:

img

전반적인 설명

이 전략의 주요 아이디어는 더 큰 시간 프레임에서 트렌드 방향을 파악하고 더 작은 시간 프레임에 입력 할 브레이크아웃 포인트를 찾는 것입니다. 스톱 로스 출구는 더 큰 시간 프레임에서 이동 평균을 추적합니다.

전략 원칙

이 전략은 주로 판단을 위한 세 가지 지표에 의존합니다.

먼저, 더 긴 사이클 (일일일적) X일 간단한 이동 평균을 계산합니다. 가격이 이 이동 평균보다 높을 때만 구매할 수 있습니다. 이는 전체 트렌드 방향을 결정하고 오스실레이션 기간을 피하기 위해 사용할 수 있습니다.

두 번째로, 짧은 사이클 (예를 들어 5 일) 에서 가장 높은 가격 Swing High를 계산합니다. 가격이 이 가장 높은 가격을 깨면 구매 신호가 트리거됩니다. lb 룩백 기간 매개 변수는 여기에 적합한 브레이크아웃 포인트를 찾기 위해 사용됩니다.

세 번째로, 스톱 로스 라인을 설정한다. 포지션에 진입한 후, 스톱 로스 라인은 가장 낮은 가격에서 특정 기간 lbStop에서 가장 최근의 낮은 지점에서 멀리 잠겨있다. 동시에, 출구 메커니즘으로 이동 평균 라인 (일일 10 일 EMA와 같이) 을 설정한다. 가격이이 이동 평균 라인 아래에있을 때 포지션을 종료한다.

이 전략은 또한 과장된 포인트를 구매하지 않도록 ATR 값을 설정합니다. 또한 백테스트 시간 범위와 같은 다른 보조 조건이 있습니다.

위의 세 가지 지표의 상호 작용 판단이 이 전략의 핵심 논리를 형성합니다.

이점 분석

탈출 추적 전략으로서 다음과 같은 장점을 가지고 있습니다.

  1. 오스실레이션 시장에서 가짜 브레이크업에 걸리지 않도록 두 가지 시간 프레임을 사용하십시오. 더 긴 시간 프레임은 전체 트렌드를 결정하고 짧은 시간 프레임은 특정 입구점을 찾습니다.

  2. 스윙 높이로 형성된 브레이크아웃 포인트를 사용하십시오. 이 유형의 브레이크아웃은 특정 관성을 가지고 있으며 추적을 형성하기가 쉽습니다. lb 룩백 기간 매개 변수 또한 진정으로 효과적인 브레이크아웃을 찾기 위해 조정 할 수 있습니다.

  3. 스톱 손실 방법은 비교적 엄격합니다. 가장 최근의 최저점을 특정 버퍼 거리로 추적하여 스크래프되지 않도록합니다.

  4. 이동 평균을 출구 메커니즘으로 사용해서 시장 조건에 따라 유연하게 수익을 취합니다.

  5. ATR 지표는 과잉 지렛대 위험을 피합니다.

  6. 다양한 매개 변수 조합이 테스트를 위해 설정될 수 있으며, 최적화 공간이 넓다.

위험 분석

이 전략은 또한 몇 가지 위험을 안고 있습니다.

  1. 가격이 이동 평균선 주위에서 위아래로 변동할 때, 진입 및 출입 포지션 사이에 앞뒤로 전환하는 것이 쉽습니다. 높은 수수료 위험이 있습니다.

  2. 파업점이 이동 평균선에 가까워지면 상대적으로 큰 인회 위험이 있습니다. 이것은 전략의 본질적인 특징입니다.

  3. 시장에서 명백한 추세가 없을 때, 보유 시간은 너무 길어 시간 위험에 직면 할 수 있습니다.

  4. ATR 매개 변수는 합리적으로 설정해야합니다. ATR이 너무 작으면 필터링 효과가 약합니다. 너무 크면 진입 기회가 감소합니다.

  5. 다른 lb 매개 변수들의 결과에 대한 영향을 테스트해야 합니다. 너무 큰 매개 변수는 어떤 기회를 놓칠 수 있고, 너무 작은 매개 변수는 잘못된 파장을 식별할 수 있습니다.

위험 완화:

  1. 필터링 능력을 높이기 위해 이동 평균 매개 변수를 적절히 조정합니다.
  2. ATR 매개 변수를 최적화하고 시각적 판단으로 보완합니다.
  3. 최적의 매개 변수를 찾기 위해 lb 뷰백 기간을 조정합니다.
  4. 오스실레이션 시장에서 거래를 중단하십시오.

최적화 방향

이 전략은 또한 다음 차원에서 최적화 될 수 있습니다.

  1. 최적의 매개 변수를 찾기 위해 이동 평균 매개 변수의 다양한 조합을 테스트합니다.

  2. 다른 ATR 매개 변수 설정을 시도하여 진입 기회와 위험 통제를 균형 잡습니다.

  3. lb 뷰백 기간 매개 변수를 최적화하여 보다 효율적인 브레이크아웃을 식별합니다.

  4. 역동적인 스톱 로스를 구축해 보세요. 변동성과 드라우다운을 기반으로요. 위험을 통제하기 위해서요.

  5. 브레이크아웃의 효과를 결정하기 위해 거래량과 같은 다른 요소를 포함합니다.

  6. /,< 및 다른 방법을 개발하여 극한점을 참조로 찾습니다.

  7. 최적의 매개 변수를 위한 매개 변수를 훈련하는 기계 학습을 시도

요약

전체적으로, 이것은 전형적인 브레이크아웃 추적 전략이다. 이중 시간 프레임을 판단하면, 진입 시기를 식별하기 위해 스윙 하이를 사용하며, 스톱 로스 라인과 이동 평균 이중 보험 출구 메커니즘을 사용하여 완전한 논리적 시스템을 형성한다. 이 전략의 위험 및 수익 특성은 명확하며, 중장기 추적 투자자에게 적합하다. 특정 위험이 있지만 매개 변수 및 규칙을 최적화함으로써 감소 할 수 있다. 전략은 개선할 여지가 많다. 더 많은 지표를 통합하면 전략 효과를 더욱 향상시킬 수 있다.


/*backtest
start: 2023-01-24 00:00:00
end: 2024-01-30 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/
// © millerrh

// The intent of this strategy is to buy breakouts with a tight stop on smaller timeframes in the direction of the longer term trend.
// Then use a trailing stop of a close below either the 10 MA or 20 MA (user choice) on that larger timeframe as the position 
// moves in your favor (i.e. whenever position price rises above the MA).
// Option of using daily ATR as a measure of finding contracting ranges and ensuring a decent risk/reward.
// (If the difference between the breakout point and your stop level is below a certain % of ATR, it could possibly find those consolidating periods.)

//@version=4
strategy("Qullamaggie Breakout", 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)
   
// === BACKTEST RANGE ===
Start = input(defval = timestamp("01 Jan 2019 06:00 +0000"), title = "Backtest Start Date", type = input.time)
Finish = input(defval = timestamp("01 Jan 2100 00:00 +0000"), title = "Backtest End Date", type = input.time)

// Inputs
lb = input(defval = 3, title = "Lookback Period for Swing High", minval = 1,
   tooltip = "Lookback period for defining the breakout level.")
lbStop = input(defval = 3, title = "Lookback Bars for Stop Level", minval = 1,
   tooltip = "Initial stop placement is the lowest low this many bars back. Allows for tighter stop placement than referencing swing lows.")  
htf = input(defval="D", title="Timeframe of Moving Averages", type=input.resolution,
  tooltip = "Allows you to set a different time frame for the moving averages. The default behavior is to identify good tightening setups on a larger timeframe
  (like daily) and enter the trade on a breakout occuring on a smaller timeframe, using the moving averages of the larger timeframe to trail your stop.")
maType = input(defval="SMA", options=["EMA", "SMA"], title = "Moving Average Type")
ma1Length = input(defval = 10, title = "1st Moving Average Length", minval = 1)
ma2Length = input(defval = 20, title = "2nd Moving Average Length", minval = 1)
ma3Length = input(defval = 50, title = "3rd Moving Average Length", minval = 1)
useMaFilter = input(title = "Use 3rd Moving Average for Filtering?", type = input.bool, defval = true,
  tooltip = "Signals will be ignored when price is under this slowest moving average.  The intent is to keep you out of bear periods and only
             buying when price is showing strength or trading with the longer term trend.")
trailMaInput = input(defval="2nd Moving Average", options=["1st Moving Average", "2nd Moving Average"], title = "Trailing Stop")

// MA Calculations
ma(maType, src, length) =>
    maType == "EMA" ? ema(src, length) : sma(src, length) //Ternary Operator (if maType equals EMA, then do ema calc, else do sma calc)
ma1 = security(syminfo.tickerid, htf, ma(maType, close, ma1Length))
ma2 = security(syminfo.tickerid, htf, ma(maType, close, ma2Length))
ma3 = security(syminfo.tickerid, htf, ma(maType, close, ma3Length))

plot(ma1, color=color.purple, style=plot.style_line, title="MA1", linewidth=2, transp = 60)
plot(ma2, color=color.yellow, style=plot.style_line, title="MA2", linewidth=2, transp = 60)
plot(ma3, color=color.white, style=plot.style_line, title="MA3", linewidth=2, transp = 60)

// === USE ATR FOR FILTERING ===
// The idea here is that you want to buy in a consolodating range for best risk/reward. So here you can compare the current distance between 
// support/resistance vs.the ATR and make sure you aren't buying at a point that is too extended from normal.
useAtrFilter = input(title = "Use ATR for Filtering?", type = input.bool, defval = false,
  tooltip = "Signals will be ignored if the distance between support and resistance is larger than a user-defined percentage of Daily ATR. 
             This allows the user to ensure they are not buying something that is too extended and instead focus on names that are consolidating more.")
atrPerc = input(defval = 100, title = "% of Daily ATR Value", minval = 1)
atrValue = security(syminfo.tickerid, "D", atr(14))*atrPerc*.01

// === PLOT SWING HIGH/LOW AND MOST RECENT LOW TO USE AS STOP LOSS EXIT POINT ===
// Change these values to adjust the look back and look forward periods for your swing high/low calculations
pvtLenL = lb
pvtLenR = lb

// Get High and Low Pivot Points
pvthi_ = pivothigh(high, pvtLenL, pvtLenR)
pvtlo_ = pivotlow(low, pvtLenL, pvtLenR)

// Force Pivot completion before plotting.
Shunt = 1 //Wait for close before printing pivot? 1 for true 0 for flase
maxLvlLen = 0 //Maximum Extension Length
pvthi = pvthi_[Shunt]
pvtlo = pvtlo_[Shunt]

// Count How many candles for current Pivot Level, If new reset.
counthi = barssince(not na(pvthi))
countlo = barssince(not na(pvtlo))
 
pvthis = fixnan(pvthi)
pvtlos = fixnan(pvtlo)
hipc = change(pvthis) != 0 ? na : color.maroon
lopc = change(pvtlos) != 0 ? na : color.green

// Display Pivot lines
plot((maxLvlLen == 0 or counthi < maxLvlLen) ? pvthis : na, color=hipc, transp=0, linewidth=1, offset=-pvtLenR-Shunt, title="Top Levels")
// plot((maxLvlLen == 0 or countlo < maxLvlLen) ? pvtlos : na, color=lopc, transp=0, linewidth=1, offset=-pvtLenR-Shunt, title="Bottom Levels")
plot((maxLvlLen == 0 or counthi < maxLvlLen) ? pvthis : na, color=hipc, transp=0, linewidth=1, offset=0, title="Top Levels 2")
// plot((maxLvlLen == 0 or countlo < maxLvlLen) ? pvtlos : na, color=lopc, transp=0, linewidth=1, offset=0, title="Bottom Levels 2")

// BUY CONDITIONS
stopLevelCalc = valuewhen(pvtlo_, low[pvtLenR], 0) //Stop Level at Swing Low
buyLevel = valuewhen(pvthi_, high[pvtLenR], 0) //Buy level at Swing High
plot(buyLevel, style=plot.style_line, color=color.blue, title = "Current Breakout Level", show_last=1, linewidth=1, transp=50, trackprice=true)

// Conditions for entry and exit
stopLevel = float(na) // Define stop level here as "na" so that I can reference it in the inPosition 
  // variable and the ATR calculation before the stopLevel is actually defined.
buyConditions = (useMaFilter ? buyLevel > ma3 : true) and
  (useAtrFilter ? (buyLevel - stopLevel[1]) < atrValue : true)
// buySignal = high > buyLevel and buyConditions
buySignal = crossover(high, buyLevel) and buyConditions
trailMa = trailMaInput == "1st Moving Average" ? ma1 : ma2
sellSignal = crossunder(close, trailMa)
// sellSignal = security(syminfo.tickerid, htf, close < trailMa) and security(syminfo.tickerid, htf, close[1] < trailMa)


// STOP AND PRICE LEVELS
inPosition = bool(na)
inPosition := buySignal[1] ? true : sellSignal[1] ? false : low <= stopLevel[1] ? false : inPosition[1]

lowDefine = lowest(low, lbStop)
stopLevel := inPosition ? stopLevel[1] : lowDefine
// plot(stopLevel)

buyPrice = buyLevel
buyPrice := inPosition ? buyPrice[1] : buyLevel
plot(stopLevel, style=plot.style_line, color=color.orange, title = "Current Stop Level", show_last=1, linewidth=1, transp=50, trackprice=true)
plot(inPosition ? stopLevel : na, style=plot.style_circles, color=color.orange, title = "Historical Stop Levels", transp=50, trackprice=false)
// plot(buyPrice, style=plot.style_line, color=color.blue, linewidth=1, transp=50, trackprice=true)

// (STRATEGY ONLY) Comment out for Study
strategy.entry("Long", strategy.long, stop = buyLevel, when = buyConditions)
strategy.exit("Exit Long", from_entry = "Long", stop=stopLevel[1])
if (low[1] > trailMa)
    strategy.close("Long", when = sellSignal)
// if (low[1] > trailMa)
//     strategy.exit("Exit Long", from_entry = "Long", stop=trailMa) //to get this to work right, I need to reference highest highs instead of swing highs
    //because it can have me buy right back in after selling if the stop level is above the last registered swing high point.

더 많은