트레일링 브레이크아웃 전략


생성 날짜: 2023-10-17 16:36:49 마지막으로 수정됨: 2023-10-17 16:36:49
복사: 0 클릭수: 690
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

트레일링 브레이크아웃 전략

개요

이 전략은 주로 唐通道指標를 통해 추적형의 돌파 거래 전략을 구현한다. 이 전략은 추세와 돌파 두 가지 거래 사고방식을 결합하고, 긴 선의 추세 판단에 기초하여, 짧은 주기의 돌파점을 찾아 엔트리를 수행하고, 트렌드 상황에서의 순진 거래를 실현한다. 또한, 전략은 각 거래의 위험 수익률을 제어하기 위해 중지 손실 및 중지 수준을 설정한다.

전략 원칙

  1. 唐通道 지표의 매개 변수, 기본 주기 20;

  2. EMA 평평한 이동 평균선, 기본 주기 200;

  3. 리스크/수익비율이 1.5로 설정됩니다.

  4. 돌파 후퇴 파라미터를 다중 헤드 및 빈 헤드로 설정합니다.

  5. 그 기록은 어떤 지점으로 기록되었는지,

  6. 멀티 헤드 신호: 이전 돌파구가 낮은 지점이고 가격이 둥지안 상반도와 EMA 평균선보다 높으면 멀티 헤드 신호를 생성합니다.

  7. 허공 신호: 이전 돌파구가 높은 지점이고 가격이 둥지안 하단 궤도와 EMA 평균선 이하인 경우 허공 신호를 생성한다.

  8. 다중 상점 포지션에 들어가면, 정지 손실을 둥지안 하계 철회 5점으로 설정하고, 정지 손실을 위험-수익 비율 곱하기 정지 거리로 설정합니다.

  9. 공허 포지션에 들어간 후, 정지 손실은 둥천 상철 철회 5점으로 설정하고, 정지는 위험 수익 비율 곱하기 정지 손실 거리를 다.

이 방법으로, 전략은 추세 판단과 돌파구 조작을 결합하여, 순차적으로, 긴 선의 추세에서 더 짧은 기간의 기회를 잡을 수 있습니다. 동시에, 손실을 막는 설치는 단일 거래의 위험 수익 상황을 제어 할 수 있습니다.

우위 분석

  1. 긴 트렌드를 추적하고, 역동적인 거래를 피하기 위해 계속 노력하십시오.

  2. 동치안 통로가 긴 선의 지표로서, EMA 평선 필터와 결합하여 트렌드 방향을 더 잘 판단할 수 있다.

  3. 손해 막기 장치는 각 위험을 제어하여 가능한 손실을 제한합니다.

  4. 위험과 이익의 비율을 최적화하여 손실과 손실의 비율을 높여 초과 수익을 추구하십시오.

  5. 리포트 파라미터를 유연하게 설정하여 다른 시장에 맞는 최적의 파라미터 조합을 조정할 수 있다.

위험 분석

  1. 둥치안 통로와 EMA 평행선이 필터링 지표로 사용되어 잘못된 신호가 발생할 수 있습니다.

  2. 브레이크 트레이드는 쉽게 잡힐 수 있고, 트렌드 배경을 명확하게 파악하는 것이 필요합니다.

  3. 스톱 로즈 스톱 거리는 고정되어 있으며, 시장의 변동에 따라 조정할 수 없습니다.

  4. Parameters 최적화 공간은 제한되어 있고, 실디 디스크 효과는 보장되지 않는다.

  5. 거래 시스템은 너무 많은 무작위적 사건들을 견딜 수 없고, 블랙 스완 사건은 큰 손실을 초래할 수 있다.

최적화 방향

  1. 더 많은 지표를 추가하여 필터링을 고려할 수 있습니다. 예를 들어, 진동 지표, 신호 품질을 향상시킵니다.

  2. 스마트 스톱로스 스톱을 설정하여 시장의 변동과 ATR 지표의 동력에 따라 손실 위치를 조정할 수 있습니다.

  3. 기계 학습과 같은 방법을 사용하여 실제 시장에 더 가깝게 테스트 및 최적화 할 수 있습니다.

  4. 출전 논리를 최적화하여 VOLUME 또는 변동률 지표를 보조 조건으로 설정하여 함정을 피할 수 있습니다.

  5. 트렌드 추적 전략이나 기계 학습과 결합하여 혼합 전략을 형성하여 안정성을 향상시킬 수 있습니다.

요약하다

이 전략은 추적형 돌파 전략으로서, 핵심 아이디어는 긴 선의 추세를 판단한 전제 하에 돌파를 신호로 삼고, 단편 거래 위험을 제어하기 위한 스톱 로즈 스을 설정하는 것이다. 이 전략은 장점이 있지만, 또한 최적화 할 수 있는 공간이 있다.

전략 소스 코드
/*backtest
start: 2023-09-16 00:00:00
end: 2023-10-16 00:00:00
period: 4h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=4
// Welcome to my second script on Tradingview with Pinescript
// First of, I'm sorry for the amount of comments on this script, this script was a challenge for me, fun one for sure, but I wanted to thoroughly go through every step before making the script public
// Glad I did so because I fixed some weird things and I ended up forgetting to add the EMA into the equation so our entry signals were a mess
// This one was a lot tougher to complete compared to my MACD crossover trend strategy but I learned a ton from it, which is always good and fun
// Also I'll explain the strategy and how I got there through some creative coding(I'm saying creative because I had to figure this stuff out by myself as I couldn't find any reference codes)
// First things first. This is a Donchian Channel Breakout strategy which follows the following rules
// If the price hits the upperband of the Donchian Channel + price is above EMA and the price previously hit the lowerband of the Donchian Channel it's a buy signal
// If the price hits the lowerband of the Donchian Channel + price is below EMA and the price prevbiously hit the upper band of the Donchian Channel it's a sell signal
// Stop losses are set at the lower or upper band with a 0.5% deviation because we are acting as if those two bands are the resistance in this case
// Last but not least(yes, this gave BY FAR the most trouble to code), the profit target is set with a 1.5 risk to reward ratio
// If you have any suggestions to make my code more efficient, I'll be happy to hear so from you
// So without further ado, let's walk through the code

// The first line is basically standard because it makes backtesting so much more easy, commission value is based on Binance futures fees when you're using BNB to pay those fees in the futures market
// strategy(title="Donchian Channels", shorttitle="DC", overlay=true, default_qty_type = strategy.cash, default_qty_value = 150, initial_capital = 1000, currency = currency.USD, commission_type = "percent", commission_value = 0.036)
// The built-in Donchian Channels + an added EMA input which I grouped with the historical bars from the Donchian Channels
length          = input(20, minval=1, group = "Indicators")
lower           = lowest(length)
upper           = highest(length)
basis           = avg(upper, lower)
emaInput        = input(title = "EMA Input", type = input.integer, defval = 200, minval = 10, maxval = 400, step = 1, group = "Indicators")
// I've made three new inputs, for risk/reward ratio and for the standard pullback deviation. My advise is to not use the pullback inputs as I'm not 100% sure if they work as intended or not
riskreward      = input(title = "Risk/Reward Ratio", type = input.float, defval = 1.50, minval = 0.01, maxval = 100, step = 0.01, group = "Risk/Reward")
pullbackLong    = input(title = "Distance from Long pullback %", type = input.float, defval = 0.995, minval = 0.001, maxval = 2, step = 0.001, group = "Risk/Reward")
pullbackShort   = input(title = "Distance from Short pullback %", type = input.float, defval = 1.005, minval = 0.001, maxval = 2, step = 0.001, group = "Risk/Reward")

// Input backtest range, you can adjust these in the input options, just standard stuff
fromMonth       = input(defval = 1,    title = "From Month",      type = input.integer, minval = 1, maxval = 12, group = "Backtest Date Range")
fromDay         = input(defval = 1,    title = "From Day",        type = input.integer, minval = 1, maxval = 31, group = "Backtest Date Range")
fromYear        = input(defval = 2000, title = "From Year",       type = input.integer, minval = 1970,           group = "Backtest Date Range")
thruMonth       = input(defval = 1,    title = "Thru Month",      type = input.integer, minval = 1, maxval = 12, group = "Backtest Date Range")
thruDay         = input(defval = 1,    title = "Thru Day",        type = input.integer, minval = 1, maxval = 31, group = "Backtest Date Range")
thruYear        = input(defval = 2099, title = "Thru Year",       type = input.integer, minval = 1970,           group = "Backtest Date Range")
// Date variable also standard stuff
inDataRange     = (time >= timestamp(syminfo.timezone, fromYear, fromMonth, fromDay, 0, 0)) and (time < timestamp(syminfo.timezone, thruYear, thruMonth, thruDay, 0, 0))

// I had to makes these variables because the system has to remember whether the previous 'breakout' was a high or a low
// Also, because I based my stoploss on the upper/lower band of the indicator I had to find a way to change this value just once without losing the value, that was added, on the next bar
var previousishigh = false
var previousislow = false
var longprofit = 0.0
var shortprofit = 0.0
var stoplossLong = 0.0
var stoplossShort = 0.0
// These are used as our entry variables
emaCheck = ema(close, emaInput)
longcond = high >= upper and close > emaCheck
shortcond = low <= lower and close < emaCheck

// With these two if statements I'm changing the boolean variable above to true, we need this to decide out entry position
if high >= upper
    previousishigh := true
if low <= lower
    previousislow := true

// Made a last minute change on this part. To clean up our entry signals we don't want our breakouts, while IN a position, to change. This way we do not instantly open a new position, almost always in the opposite direction, upon exiting one
if strategy.position_size > 0 or strategy.position_size < 0 
    previousishigh := false
    previousislow := false

// Strategy inputs
// Long - previous 'breakout' has to be a low, the current price has to be a new high and above the EMA, we're not allowed to be in a position and ofcourse it has to be within our given data for backtesting purposes
if previousislow == true and longcond and strategy.position_size == 0 and inDataRange
    strategy.entry("Long Entry", strategy.long, comment = "Entry Long")
    stoplossLong := lower * pullbackLong
    longprofit := ((((1 - stoplossLong / close) * riskreward) + 1) * close)
    strategy.exit("Long Exit", "Long Entry", limit = longprofit, stop = stoplossLong, comment = "Long Exit")

// Short - Previous 'breakout' has to be a high, current price has to be a new low and lowe than the 200EMA, we're not allowed to trade when we're in a position and it has to be within our given data for backtesting purposes
if previousishigh == true and shortcond and strategy.position_size == 0 and inDataRange
    strategy.entry("Short Entry", strategy.short, comment = "Entry Short")
    stoplossShort := upper * pullbackShort
    shortprofit := (close - ((((1 - close / stoplossShort) * riskreward) * close)))
    strategy.exit("Short Exit", "Short Entry", limit = shortprofit, stop = stoplossShort, comment = "Short Exit")
    
// This plots the Donchian Channels on the chart which is just using the built-in Donchian Channels
plot(basis, "Basis", color=color.blue)
u = plot(upper, "Upper", color=color.green)
l = plot(lower, "Lower", color=color.red)
fill(u, l, color=#0094FF, transp=95, title="Background")

// These plots are to show if the variables are working as intended, it's a mess I know but I didn't have any better ideas, they work well enough for me
// plot(previousislow ? close * 0.95 : na, color=color.red, linewidth=2, style=plot.style_linebr)
// plot(previousishigh ? close * 1.05 : na, color=color.green, style=plot.style_linebr)
// plot(longprofit, color=color.purple)
// plot(shortprofit, color=color.silver)
// plot(stoplossLong)
// plot(stoplossShort)
// plot(strategy.position_size)