다단계 동적 추세 추종 시스템

ATR MA RSI
생성 날짜: 2024-07-29 17:19:43 마지막으로 수정됨: 2024-07-29 17:19:43
복사: 0 클릭수: 507
avatar of ChaoZhang ChaoZhang
1
집중하다
1617
수행원

다단계 동적 추세 추종 시스템

개요

다단계 동적 트렌드 추적 시스템은 해수욕 거래 법칙에 기반한 개선 전략이다. 이 전략은 동적 정지 및 피라미드 가설을 결합한 여러 시간 주기의 트렌드 신호를 사용하여 중·장기 트렌드를 파악한다. 시스템은 두 가지 트렌드 추적 주기 (L1 및 L2) 를 설정하여 서로 다른 속도의 트렌드를 포착하고, 적응된 ATR 지표를 사용하여 진입, 가설 및 정지 위치를 동적으로 조정한다. 이러한 다단계 설계 전략은 다양한 시장 환경에서 안정성을 유지하면서 피라미드 가설을 통해 수익 잠재력을 극대화 할 수 있습니다.

전략 원칙

  1. 트렌드 식별: 두 개의 이동 평균 주기 ((L1 및 L2) 를 사용하여 서로 다른 속도의 트렌드를 식별합니다. L1은 더 빠른 트렌드를 포착하고 L2는 느리지만 더 신뢰할 수있는 트렌드를 포착합니다.

  2. 입시 신호: 가격이 L1 또는 L2의 고점을 돌파할 때 여러 신호를 생성한다. 만약 지난 L1 거래가 수익성이 있다면, 다음 L1 신호를 건너뛰어 L2 신호가 나타날 때까지 한다.

  3. 동적 스톱: ATR의 배수를 사용하여 (기본 3배) 초기 스톱 거리로서, 지분 시간이 증가함에 따라 스톱 지점은 점진적으로 올라간다.

  4. 피라미드 포지션: 추세가 지속되는 동안, 가격이 0.5 ATR 상승할 때마다 포지션을 추가합니다. 최대 5 번 포지션을 추가합니다.

  5. 리스크 제어: 거래 당의 위험은 계좌의 당기순 가치의 2%를 초과하지 않으며, 지분량을 동적으로 계산하여 달성한다.

  6. 탈퇴 메커니즘: 가격이 10일 하락 (L1) 또는 20일 하락 (L2) 을 넘어가는 경우 또는 이동식 스톱 라인을 유발할 때 평점.

전략적 이점

  1. 다단계 트렌드 캡처: L1과 L2 두 개의 주기, 빠른 트렌드를 캡처 할 수 있고, 장기적인 트렌드를 파악 할 수 있습니다. 전략의 적응성과 안정성을 향상시킵니다.

  2. 동적 위험 관리: ATR을 변동성 지표로 사용하여 시장 변화에 더 잘 적응하기 위해 진입, 중단 및 포지션의 동적 조정을 구현합니다.

  3. 피라미드 포지션: 트렌드가 지속될 때 단계적으로 포지션을 높여서 위험을 통제하고 수익 잠재력을 극대화합니다.

  4. 유연한 변수 설정: 여러 개의 조정 가능한 변수들은 전략이 다른 시장과 거래 스타일에 적응할 수 있게 해준다.

  5. 자동화 실행: 전략은 인간의 개입과 감정적 영향을 줄여 완전히 자동화 될 수 있습니다.

전략적 위험

  1. 트렌드 반전 위험: 강한 트렌드 시장에서 우수한 성능을 보이지만, 흔들리는 시장에서는 손실로 이어질 수 있다.

  2. 슬라이드 포인트 및 거래 비용: 자주 가금 및 이동 중지로 인해 거래 비용이 더 높을 수 있습니다.

  3. 과도한 최적화 위험: 변수가 많기 때문에 과도한 역사 데이터 적합성을 초래할 수 있습니다.

  4. 자금 관리 위험: 초기 자금이 적다면, 수차례의 부가가치를 효율적으로 실행할 수 없습니다.

  5. 시장 유동성 위험: 유동성이 낮은 시장에서, 이상적인 가격에 따라 거래를 수행하는 것이 어려울 수 있습니다.

전략 최적화 방향

  1. 시장 환경 필터를 도입한다: 시장 환경을 판단하기 위해 트렌드 강도 지표 (ADX와 같은) 를 추가할 수 있으며, 흔들리는 시장에서 거래 빈도를 줄일 수 있다.

  2. 최적화된 위지 전략: 고정된 0.5ATR과 5배보다는 동적으로 트렌드 강도에 따라 위지 간격과 수를 조정하는 것을 고려할 수 있다.

  3. 정지 메커니즘을 도입: 장기 트렌드에서, ATR 이윤의 3배를 달성했을 때 절반의 포지션을 청산하는 것과 같이, 이익을 잠금하기 위해 부분 정지를 설정할 수 있습니다.

  4. 다종 연관성 분석: 조합 적용 시 종간 연관성 분석을 추가하여 전반적인 위험/수익 비율을 최적화할 수 있다.

  5. 변동율 필터를 추가: 매우 높은 변동율 기간 동안 거래를 중지하거나 비정상적인 시장에 대응하기 위해 위험 매개 변수를 조정할 수 있습니다.

  6. 탈퇴 메커니즘을 최적화하십시오. parabolic SAR 또는 Chandelier Exit 같은 더 유연한 탈퇴 지표를 사용하는 것이 고려 될 수 있습니다.

요약하다

다단계 동적 트렌드 추적 시스템은 고전적인 해수 무역 법칙과 현대적인 정량화 기술을 결합한 포괄적 전략이다. 다단계 트렌드 식별, 동적 위험 관리 및 피라미드 가장 방법과 같은 방법을 통해, 이 전략은 안정성을 유지하면서, 트렌드에 대한 포착 능력과 수익 잠재력을 향상시킨다. 불안정한 시장에서 도전을 받고 있지만, 합리적인 파라미터 최적화 및 위험 통제를 통해, 이 전략은 다양한 시장 환경에서 안정적인 성능을 유지 할 전망이다.

전략 소스 코드
/*backtest
start: 2024-06-28 00:00:00
end: 2024-07-28 00:00:00
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=5
// This is a strategy based on the famous turtle system.
// https://www.tradingblox.com/originalturtles/originalturtlerules.htm
//
// In a nutshell, it a trend trading system where you are buying on strength, selling on weakness.
// positions should be entered when the price crosses over the 20-day high (L1 high) or 55-day high (L2 high).
// positions should be exited when the prices crosses below the 10-day low (L1 low) or 20-day low (L2 low)
// you can add positions at every unit (measured by multiple of n, where n=1 ATR)
// stops should be placed at 2*n below every position entered, when the stop is hit exit your entire position.
// positions should be entered everytime price crosses over L1 or L2, with one exception:
// if the last trade was an L1 trade and it was a winning trade, skip the next trade unless the price crosses
// over L2, if that is the case, you should take it.
// L1 and L2 levels are also configurable for high and lows.
// N multiple for stops and pyramid are also configurable

// To change this from a strategy to a study:
// 1) uncomment the next line and comment out the strategy line.
// 2) at the end of the file comment out the last 2 lines


// study(title="Turtle Study", overlay=true)
strategy(title='kTF-VNI', overlay=true, initial_capital=100000000, commission_type=strategy.commission.percent, commission_value=0.0, pyramiding=100, process_orders_on_close=true, calc_on_every_tick=true)

stopInput = input.float(3, 'Stop N', step=.05)
riskPercent = input.float(.01, 'Risk % of capital', step=.005)
pyramidInput = input.float(0.5, 'Pyramid N', step=.05)
maxUnits = input.int(5, 'Max Pyramid Units', step=1)
atrPeriod = input(20, 'ATR period')

l1LongInput = 10
l2LongInput = 20
l1LongExitInput = 20
l2LongExitInput = 40

l1LongInput := input.int(20, 'L1 Long', minval=2)
l2LongInput := input.int(60, 'L2 Long', minval=2)
l1LongExitInput := input.int(10, 'L1 Long Exit', minval=2)
l2LongExitInput := input.int(20, 'L2 Long Exit', minval=2)

FromYear = input.int(1970, 'From Year', minval=1900)
FromMonth = input.int(1, 'From Month', minval=1, maxval=12)
FromDay = input.int(1, 'From Day', minval=1, maxval=31)
ToYear = input.int(9999, 'To Year', minval=1900)
ToMonth = input.int(1, 'To Month', minval=1, maxval=12)
ToDay = input.int(1, 'To Day', minval=1, maxval=31)
FromDate = timestamp(FromYear, FromMonth, FromDay, 00, 00)
ToDate = timestamp(ToYear, ToMonth, ToDay, 23, 59)
TradeDateIsAllowed() =>
    time >= FromDate and time <= ToDate

l1Long = ta.highest(l1LongInput)
l1LongExit = ta.lowest(l1LongExitInput)
l2Long = ta.highest(l2LongInput)
l2LongExit = ta.lowest(l2LongExitInput)

bool win = false  // tracks if last trade was winning trade of losing trade.
float buyPrice = 0.0  // tracks the buy price of the last long position.
float nextBuyPrice = 0.0  // tracks the next buy price
float stopPrice = na  // tracks the stop price
int totalBuys = 0  // tracks the total # of pyramid buys
bool inBuy = false  // tracks if we are in a long position or not.
float l1LongPlot = ta.highest(l1LongInput)  // tracks the L1 price to display
float l2LongPlot = ta.highest(l2LongInput)  // tracks the L2 price to display
float n = ta.atr(atrPeriod)  // tracks the n used to calculate stops and pyramid buys
string mode = 'L1'  // tracks whether we are in a L1 position or L2 position.
bool fake = na  // tracks if this is a fake trade, see comments below.
string longLevel = na  // tracks where long positions, stops, pyramid buys occur.
float capitalLeft = strategy.initial_capital
var shares = 0
float fakeBuyPrice = 0.0

// by default use the last value from the previous bar.
buyPrice := buyPrice[1]
totalBuys := totalBuys[1]
nextBuyPrice := nextBuyPrice[1]
stopPrice := stopPrice[1]
win := win[1]
capitalLeft := capitalLeft[1]
inBuy := inBuy[1]
n := ta.atr(atrPeriod)
fakeBuyPrice := fakeBuyPrice[1]

// State to track if we are in a long positon or not.

if not inBuy[1] and (high > l1Long[1] or high > l2Long[1])
    inBuy := true
    inBuy
else
    inBuy := inBuy[1] and low < stopPrice[1] ? false : inBuy
    inBuy := inBuy[1] and mode[1] == 'L1' and low < l1LongExit[1] ? false : inBuy
    inBuy := inBuy[1] and mode[1] == 'L2' and low < l2LongExit[1] ? false : inBuy
    inBuy

// State to track if we are ia a fake trade.  If the last trade was a winning, we need to skip the next trade.
// We still track it though as a fake trade (not counted against us). as the outcome determines if we can
// can take the next trade.

if not inBuy[1] and high > l1Long[1] and win[1]
    fake := true
    fakeBuyPrice := close
    fakeBuyPrice
else
    fake := fake[1]
    fake

if fake[1] and inBuy[1] and not inBuy
    fake := false
    win := close >= fakeBuyPrice
    win

fake := high > l2Long[1] ? false : fake

// Series representing the l1 and l2 levels.   If we break out above the l1 or l2 level, we want the
// line to stay at the breakout level, not follow it up.
l1LongPlot := not inBuy[1] or inBuy[1] and mode == 'L1' and fake[1] ? l1Long[1] : l1LongPlot[1]
l2LongPlot := not inBuy[1] or inBuy[1] and mode == 'L1' and fake[1] ? l2Long[1] : l2LongPlot[1]

// Variable in the series is only set when it happens.   Possible values is L1, L2, SR 
// (stopped out with a loss), SG (exited with a gain), and 'P' for pyramid buy.
longLevel := not inBuy[1] and high > l1Long[1] ? 'L1' : na
longLevel := (not inBuy[1] or inBuy[1] and fake[1]) and high > l2Long[1] ? 'L2' : longLevel

// Either 'L1' or 'L2' depending on what breakout level we are in.
mode := longLevel == na ? mode[1] : longLevel

// Variables to track calculating nextBuyPrice for pyramiding.
if longLevel == 'L1' or longLevel == 'L2'
    buyPrice := close
    totalBuys := 1
    stopPrice := close - stopInput * n
    nextBuyPrice := close + pyramidInput * n
    nextBuyPrice

// Marks if we hit our next buy price, if so mark it with a 'P'
longLevel := longLevel == na and inBuy[1] and high > nextBuyPrice and TradeDateIsAllowed() and totalBuys < maxUnits ? 'P' : longLevel

if longLevel == 'P'
    buyPrice := close
    totalBuys := totalBuys[1] + 1
    stopPrice := close - stopInput * n
    nextBuyPrice := close + pyramidInput * n
    nextBuyPrice

// Tracks stops and exits, marking them with SG or SR
longLevel := longLevel == na and inBuy[1] and low < stopPrice and close >= strategy.position_avg_price ? 'SG' : longLevel
longLevel := longLevel == na and inBuy[1] and low < stopPrice and close < strategy.position_avg_price ? 'SR' : longLevel
longLevel := longLevel == na and mode[1] == 'L1' and inBuy[1] and low < l1LongExit[1] and close >= strategy.position_avg_price ? 'SG' : longLevel
longLevel := longLevel == na and mode[1] == 'L2' and inBuy[1] and low < l2LongExit[1] and close >= strategy.position_avg_price ? 'SG' : longLevel
longLevel := longLevel == na and mode[1] == 'L1' and inBuy[1] and low < l1LongExit[1] and close < strategy.position_avg_price ? 'SR' : longLevel
longLevel := longLevel == na and mode[1] == 'L2' and inBuy[1] and low < l2LongExit[1] and close < strategy.position_avg_price ? 'SR' : longLevel

// Tracks if the trade was a win or loss.
win := longLevel == 'SG' ? true : win
win := longLevel == 'SR' ? false : win

// Variables used to tell strategy when to enter/exit trade.
//plotarrow(fake ? 1 : 0, colordown=color.red, colorup=color.purple, transp=40) // down arrow for winning trade
enterLong = (longLevel == 'L1' or longLevel == 'L2' or longLevel == 'P') and not fake and TradeDateIsAllowed()
exitLong = (longLevel == 'SG' or longLevel == 'SR') and not fake and TradeDateIsAllowed()

p1 = plot(l1LongPlot, title='l1 long', linewidth=3, style=plot.style_stepline, color=color.new(color.green, 0))
p2 = plot(l1LongExit[1], title='l1 exit', linewidth=3, style=plot.style_stepline, color=color.new(color.red, 0))
p3 = plot(l2LongPlot, title='l2 long', linewidth=2, style=plot.style_stepline, color=color.new(color.green, 0))
p4 = plot(l2LongExit[1], title='l2 exit', linewidth=2, style=plot.style_stepline, color=color.new(color.red, 0))
color1 = color.new(color.black, 0)
color2 = color.new(color.black, 100)
col = inBuy ? color1 : color2
p5 = plot(stopPrice, title='stop', linewidth=2, style=plot.style_circles, join=true, color=color.new(color.black, 0))
p6 = plot(nextBuyPrice, title='next buy', linewidth=2, style=plot.style_circles, join=true, color=color.new(color.blue, 0))

fill(p1, p3, color=color.new(color.green, 90))
fill(p2, p4, color=color.new(color.red, 90))

risk = (strategy.initial_capital + strategy.netprofit) * riskPercent
shares := math.floor(risk / (stopInput * n))
capitalLeft := strategy.initial_capital + strategy.netprofit - strategy.position_size * strategy.position_avg_price

if shares * close > capitalLeft
    shares := math.max(0, math.floor(capitalLeft / close))
    shares

shares := math.max(0, shares)

plotshape(longLevel == 'L1' and not fake and strategy.position_size == 0 ? true : false, color=color.new(color.green, 40), style=shape.triangleup, text='L1 ')  // up arrow for entering L1 trade
plotshape(not fake[1] and fake and longLevel == 'L1' and strategy.position_size == 0 ? true : false, color=color.new(color.gray, 40), style=shape.triangleup, text='L1')  // up arrow for entering L1 trade
plotshape(longLevel == 'L2' and strategy.position_size == 0 ? true : false, color=color.new(color.green, 40), style=shape.triangleup, text='L2')  // up arrow for entering L2 trade
plotshape((mode == 'L1' or mode == 'L2') and shares > 0 and enterLong and strategy.position_size > 0 ? true : false, color=color.new(color.green, 40), style=shape.triangleup, text='P')

plotarrow(strategy.position_size == 0 and longLevel == 'L1' and enterLong ? 1 : 0, colordown=color.new(color.black, 40), colorup=color.new(color.green, 40))  // up arrow for entering L1 trade
plotarrow(strategy.position_size == 0 and longLevel == 'L2' and enterLong ? 1 : 0, colordown=color.new(color.black, 40), colorup=color.new(color.green, 40))  // up arrow for entering L2 trade
plotarrow(strategy.position_size > 0 and longLevel == 'SR' and exitLong ? -1 : 0, colordown=color.new(color.red, 40), colorup=color.new(color.purple, 40))  // down arrow for losing trade
plotarrow(strategy.position_size > 0 and longLevel == 'SG' and exitLong ? -1 : 0, colordown=color.new(color.green, 40), colorup=color.new(color.purple, 40))  // down arrow for winning trade
plotshape(longLevel == na and inBuy[1] and not inBuy, color=color.new(color.gray, 40), style=shape.triangleup, text='Exit')  // up arrow for entering L1 trade

plot(ta.atr(atrPeriod), title='ATR', color=color.new(#991515, 0))
plot(strategy.position_avg_price, title='Average Price', color=color.new(#991515, 0))

alertcondition(low < stopPrice, title='crosses under stop price', message='price crossed under stop price')
alertcondition(high > l1Long, title='crosses over L1 price', message='price crossed over L1 price')
alertcondition(high > l2Long, title='crosses over L2 price', message='price crossed over L2 price')
alertcondition(low < l1LongExit, title='crosses under L1 exit price', message='price crossed under L1 exit price')
alertcondition(low < l2LongExit, title='crosses under L2 exit price', message='price crossed under L2 exit price')

strategy.entry('long', strategy.long, qty=shares, comment='long', when=enterLong)
strategy.close('long', when=exitLong)

// simulate_amount = 100000
// simulate_risk = simulate_amount*0.005
// simulate_shares = floor(simulate_risk/(n*stopInput))
// plot(simulate_shares, "Shares", color=#991515, transp=0)
// if (enterLong)
//     label.new(bar_index, high, text=tostring(simulate), style=label.style_none)