탈출 전략 추적

저자:차오장, 날짜: 2023-10-17 16:36:49
태그:

img

전반적인 설명

이 전략은 주로 트레이킹 브레이크아웃 거래 전략을 구현하기 위해 돈치안 채널 지표를 사용합니다. 이 전략은 트렌드를 추적하고 브레이크아웃 거래 아이디어를 결합하여 주요 트렌드를 식별하여 트렌드를 따라 거래하기 위해 짧은 주기에 브레이크아웃 포인트를 찾습니다. 또한 전략은 각 거래의 위험 / 보상을 제어하기 위해 스톱 로스를 설정하고 수익 수준을 취합니다. 전반적으로 전략은 트렌드를 추적하고 주요 트렌드의 방향으로 거래하는 장점이 있습니다.

전략 논리

  1. 돈치안 채널 지표의 설정 매개 변수, 기본 기간은 20입니다.

  2. EMA 이동평균을 설정하고, 기본 기간은 200입니다.

  3. 위험/이익 비율을 설정합니다.

  4. 롤백 매개 변수를 설정합니다.

  5. 이전 브레이크오웃이 높은 지점이나 낮은 지점인지 기록합니다.

  6. 긴 신호: 이전 파업이 낮은 경우, 가격은 치안 상단 및 EMA 라인 이상으로 떨어집니다.

  7. 짧은 신호: 이전 파업이 높은 경우, 가격은 돈치안 하위 대역 아래와 EMA 라인 아래로 떨어집니다.

  8. 긴 진입 후, 도의 하위 띠에서 5 포인트를 빼고 스톱 로스를 설정하고, 리스크/어워드 비율로 스톱 로스 거리를 곱한 수익을 취합니다.

  9. 짧은 진입 후, 5점을 더한 도 상단에서 스톱 로스를 설정하고, 리스크/어워드 비율로 스톱 로스 거리를 곱한 수익을 취합니다.

이러한 방식으로, 전략은 트렌드 추종 및 브레이크아웃 거래를 결합하여 주요 트렌드와 함께 거래합니다. 한편, 스톱 로스 및 취득은 각 거래의 위험 / 보상을 제어합니다.

이점 분석

  1. 주요 트렌드를 따르고, 트렌드에 반대하는 거래를 피하세요.

  2. 장기 지표로서의 돈치안 채널은 EMA 필터와 결합하여 트렌드를 효과적으로 식별 할 수 있습니다.

  3. 손해를 멈추고 수익을 취하면 거래당 위험을 통제하고 잠재적 손실을 제한합니다.

  4. 리스크/이익 비율을 최적화하면 수익률을 높일 수 있고, 더 많은 수익을 추구할 수 있습니다.

  5. 유연한 백테스트 매개 변수, 다른 시장에 대한 매개 변수를 최적화 할 수 있습니다.

위험 분석

  1. 돈치안 채널과 EMA는 때때로 잘못된 신호를 줄 수 있습니다.

  2. 브레이크아웃 거래는 쉽게 함정에 빠질 수 있습니다. 트렌드 배경을 명확하게 파악해야 합니다.

  3. 고정 스톱 로즈와 영업이익은 시장 변동에 따라 조정할 수 없습니다.

  4. 매개 변수 최적화 공간이 제한되어 있고 실시간 성능은 보장되지 않습니다.

  5. 블랙 스완 사건에 취약한 거래 시스템은 심각한 손실로 이어질 수 있습니다.

최적화 방향

  1. 신호 품질을 향상시키기 위해 오시레이터 같은 더 많은 필터를 추가하는 것을 고려하십시오.

  2. 시장 변동성과 ATR에 따라 적응 스톱 로스를 설정하고 수익을 취합니다.

  3. 실제 시장에 맞게 매개 변수를 테스트하고 최적화하기 위해 기계 학습을 사용합니다.

  4. 함정을 피하기 위한 조건으로 볼륨이나 변동성을 가지고 입력 논리를 최적화합니다.

  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)

더 많은