거북이 트렌드 전략 (Turtle Trend strategy) 은 유명한 거북이 트레이딩 전략의 향상된 버전이다. 이중 이동 평균에 의해 생성된 거래 신호를 활용하여 거래를 따라 낮은 위험 트렌드를 구현합니다. 표준화 된 입출구 규칙은 거래 위험을 효과적으로 제어하고 안정적인 자본 성장을 달성 할 수 있습니다.
거북이 트렌드 전략은 20일 최고, 20일 최저, 55일 최고 및 55일 최저를 계산하고, ATR 지표와 결합하여 스톱 로스 및 수익 목표를 설정합니다. 가격이 20일 최고를 초과할 때 긴 신호를 생성하고 가격이 20일 최저를 돌파할 때 짧은 신호를 생성합니다. 또한, 가격이 20일 최고 / 최저를 돌파하지만 55일 최고 / 최저를 돌파하지 않으면 점프 메커니즘이 설정되어 거래 신호를 건너뛰습니다.
시장에 진출한 후 전략은 ATR 값을 사용하여 스톱 로스 및 피라미드 타겟을 설정합니다. 손실이 스톱 로스 수준에 도달하면 중단하고 수익이 피라미드 타겟에 도달하면 포지션 크기를 증가시킵니다. 이것은 개별 거래의 위험을 제어하면서 트렌딩 시장에서 수익 잠재력을 극대화합니다.
거북이 트렌드 전략의 가장 큰 장점은 탁월한 리스크 제어 기능에 있다. 표준화된 입출입 규칙은 개별 거래의 손실을 효과적으로 제어할 수 있다. 점프 메커니즘은 불리한 시장 조건에 갇히지 않도록 한다. 안정적인 스톱 로스 전략은 연속 손실을 제한하기도 한다.
또한 거북이 트렌드 전략은 ATR 지표를 사용하여 동적으로 스톱 로스를 설정하여 스톱 로스 라인이 자동으로 시장 변동성의 변화에 적응 할 수 있습니다. 이것은 스톱 로스가 너무 느슨하지 않고 큰 손실을 유발하거나 정상적인 시장 변동에 의해 유발되지 않도록합니다.
마지막으로, 피라미드 메커니즘은 전략이 트렌드 시장에서 이익을 완전히 포착 할 수 있도록 해 주며, 안정적인 자본 성장의 기초를 마련합니다.
거북이 트렌드 전략의 주요 위험은 범위 제한 시장에서 이익을 얻지 못한다는 것입니다. 시장이 장기간 범위 내에서 변동할 때, 스톱 로스는 종종 손실을 유발할 수 있습니다. 또한, 점프 메커니즘은 불충분한 신호로 이어질 수 있으며 잠재적인 거래 기회를 놓칠 수 있습니다.
또한 기술 지표에 지나치게 의존하는 것은 근본 분석을 무시합니다. 주요 정책 변화를 감지하지 못하고 불필요한 손실을 초래할 수 있습니다.
거북이 트렌드 전략은 다음과 같은 측면에서 최적화 될 수 있습니다:
오차 메커니즘의 감수성을 조정하여 변동성 지표를 결합하여 다양한 시장에서 거래 빈도를 증가시킵니다.
기본 신호를 필터로 추가하여 산발적인 이벤트로 인해 스톱 로스로 인해 타격을 받지 않도록 합니다.
부진 후 비효율적 인 회귀를 피하기 위해 부피 지표를 결합하십시오.
요약하자면, 거북이 트렌드 전략은 원래의 거북이 거래 전략의 수익성과 위험 통제 기능을 향상시킵니다. 트렌딩 시장을 추적하는 데 적합한 저 위험 알고리즘 전략입니다. 추가 최적화로 장기적으로 안정적인 수익성있는 포트폴리오를 구축하는 중요한 부분이 될 수 있습니다.
/*backtest start: 2024-01-29 00:00:00 end: 2024-02-28 00:00:00 period: 3h basePeriod: 15m exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}] */ //@version=5 strategy("TURTLE STRATEGY", precision=2, overlay=true, initial_capital=1000, commission_type=strategy.commission.percent, commission_value=0.18, slippage=3, pyramiding=5, close_entries_rule="ANY", margin_long=100, margin_short=100) //------------------------------TOOL TIPS--------------------------------// t1 = "Percentage of the account the trader is willing to lose. This percentage is used to define the position size based on previous gains or losses. Turtle traders default to 1%." t2 = "ATR Length" t3 = "ATR Multiplier to fix the Stop Loss" t4 = "Pyramiding : ATR Multiplier to set a profit target to increase position size" t5 = "System 1 enter long if there is a new high after this selected period of time" t6 = "System 2 enter long if there is a new high after this selected period of time" t7 = "Exit Long from system 1 if there is a new low after this selected period of time" t8 = "Exit Long from system 2 if there is a new low after this selected period of time" t9 = "System 1 enter short if there is a new low after this selected period of time" t10 = "System 2 enter short if there is a new low after this selected period of time" t11 = "Exit short from system 1 if there is a new high after this selected period of time" t12 = "Exit short from system 2 if there is a new high after this selected period of time" //----------------------------------------FUNCTIONS---------------------------------------// //@function Displays text passed to `txt` when called. debugLabel(txt, color) => label.new(bar_index, high, text=txt, color=color, style=label.style_label_lower_right, textcolor=color.black, size=size.small) //@function which looks if the close date of the current bar falls inside the date range inBacktestPeriod(start, end) => (time >= start) and (time <= end) //---------------------------------------USER INPUTS--------------------------------------// //Risk Management and turtle system input percentage_to_risk = input.float(1, "Risk % of capital", maxval=100, minval=0, group="Turtle Parameters", tooltip=t1) atr_period = input.int(20, "ATR period", minval=1, group="Turtle Parameters", tooltip=t2) stop_N_multiplier = input.float(1.5, "Stop ATR", minval=0.1, group="Turtle Parameters", tooltip=t3) pyramid_profit = input.float(0.5, "Pyramid Profit", minval=0.01, group="Turtle Parameters", tooltip=t4) S1_long = input.int(20, "S1 Long", minval=1, group="Turtle Parameters", tooltip=t5) S2_long = input.int(55, "S2 Long", minval=1, group="Turtle Parameters", tooltip=t6) S1_long_exit = input.int(10, "S1 Long Exit", minval=1, group="Turtle Parameters", tooltip=t7) S2_long_exit = input.int(20, "S2 Long Exit", minval=1, group="Turtle Parameters", tooltip=t8) S1_short = input.int(15, "S1 Short", minval=1, group="Turtle Parameters", tooltip=t9) S2_short = input.int(55, "S2 Short", minval=1, group="Turtle Parameters", tooltip=t10) S1_short_exit = input.int(7, "S1 Short Exit", minval=1, group="Turtle Parameters", tooltip=t11) S2_short_exit = input.int(20, "S2 Short Exit", minval=1, group="Turtle Parameters", tooltip=t12) //Backtesting period startDate = input(title="Start Date", defval=timestamp("1 Jan 2020 00:00:00"), group="Backtesting Period") endDate = input(title="End Date", defval=timestamp("1 July 2034 00:00:00"), group="Backtesting Period") //----------------------------------VARIABLES INITIALISATION-----------------------------// //Turtle variables atr = ta.atr(atr_period) var float buy_price_long = na var float buy_price_short = na var float stop_loss_long = na var float stop_loss_short = na float account = na //Entry variables day_high_syst1 = ta.highest(high, S1_long) day_low_syst1 = ta.lowest(low, S1_short) day_high_syst2 = ta.highest(high, S2_long) day_low_syst2 = ta.lowest(low, S2_short) var bool skip = false var bool unskip_buffer_long = false var bool unskip_buffer_short = false //Exit variables exit_long_syst1 = ta.lowest(low, S1_long_exit) exit_short_syst1 = ta.highest(high, S1_short_exit) exit_long_syst2 = ta.lowest(low, S2_long_exit) exit_short_syst2 = ta.highest(high, S2_short_exit) float exit_signal = na //Backtesting period bool inRange = na //------------------------------CHECKING SOME CONDITIONS ON EACH SCRIPT EXECUTION-------------------------------// //Checking if the date belong to the range inRange := true strategy.initial_capital = 50000 //Checking if the current equity is higher or lower than the initial capital to adjusted position size if strategy.equity - strategy.openprofit < strategy.initial_capital account := (strategy.equity-strategy.openprofit)*(strategy.equity-strategy.openprofit)/strategy.initial_capital else account := strategy.equity - strategy.openprofit //Checking if we close all trades in case where we exit the backtesting period if strategy.position_size!=0 and not inRange strategy.close_all() debugLabel("END OF BACKTESTING PERIOD : we close the trade", color=color.rgb(116, 116, 116)) //--------------------------------------SKIP MANAGEMENT------------------------------------// //Checking if a long signal has been skiped and system2 is not triggered if skip and high>day_high_syst1[1] and high<day_high_syst2[1] unskip_buffer_long := true //Checking if a short signal has been skiped and system2 is not triggered if skip and low<day_low_syst1[1] and low>day_low_syst2[1] unskip_buffer_short := true //Checking if current high is lower than previous 20_day_high after a skiped long signal to set skip to false if unskip_buffer_long if high<day_high_syst1[1] skip := false unskip_buffer_long := false //Checking if current low is higher than previous 20_day_low after a skiped short signal to set skip to false if unskip_buffer_short if low>day_low_syst1[1] skip := false unskip_buffer_short := false //Checking if we have an open position to reset skip and unskip buffers if strategy.position_size!=0 and skip skip := false unskip_buffer_long := false unskip_buffer_short := false //--------------------------------------------ENTRY CONDITIONS--------------------------------------------------// //We calculate the position size based on turtle calculation unit = (percentage_to_risk/100)*account/atr*syminfo.pointvalue //Long order for system 1 if not skip and not (strategy.position_size>0) and inRange and unit>0 strategy.cancel("Long Syst 2") //We check that position size doesn't exceed available equity if unit*day_high_syst1>account unit := account/day_high_syst1 stop_loss_long := day_high_syst1 - stop_N_multiplier*atr //We adjust SL if it's greater than 10% of trade value and fix it to 10% if stop_loss_long < day_high_syst1*0.9 stop_loss_long := day_high_syst1*0.9 strategy.order("Long Syst 1", strategy.long, unit, stop=day_high_syst1) buy_price_long := day_high_syst1 //Long order for system 2 if skip and not (strategy.position_size>0) and inRange and unit>0 //We check that position size doesn't exceed available equity if unit*day_high_syst2>account unit := account/day_high_syst2 stop_loss_long := day_high_syst2 - stop_N_multiplier*atr //We adjust SL if it's greater than 10% of trade value and fix it to 10% if stop_loss_long < day_high_syst2*0.9 stop_loss_long := day_high_syst2*0.9 strategy.order("Long Syst 2", strategy.long, unit, stop=day_high_syst2) buy_price_long := day_high_syst2 //Short order for system 1 if not skip and not (strategy.position_size<0) and inRange and unit>0 strategy.cancel("Short Syst 2") //We check that position size doesn't exceed available equity if unit*day_low_syst1>account unit := account/day_low_syst1 stop_loss_short := day_low_syst1 + stop_N_multiplier*atr //We adjust SL if it's greater than 10% of trade value and fix it to 10% if stop_loss_short > day_low_syst1*1.1 stop_loss_short := day_low_syst1*1.1 strategy.order("Short Syst 1", strategy.short, unit, stop=day_low_syst1) buy_price_short := day_low_syst1 //Short order for system 2 if skip and not (strategy.position_size<0) and inRange and unit>0 //We check that position size doesn't exceed available equity if unit*day_low_syst2>account unit := account/day_low_syst2 stop_loss_short := day_low_syst2 + stop_N_multiplier*atr //We adjust SL if it's greater than 10% of trade value and fix it to 10% if stop_loss_short > day_low_syst2*1.1 stop_loss_short := day_low_syst2*1.1 strategy.order("Short Syst 2", strategy.short, unit, stop=day_low_syst2) buy_price_short := day_low_syst2 //-------------------------------PYRAMIDAL------------------------------------// //Pyramid for long orders if close > buy_price_long + (pyramid_profit*atr) and strategy.position_size>0 //We calculate the remaining capital remaining_capital = account - strategy.position_size*strategy.position_avg_price*(1-0.0018) //We calculate units to add to the long position units_to_add = (percentage_to_risk/100)*remaining_capital/atr*syminfo.pointvalue if remaining_capital > units_to_add and units_to_add>0 //We set the new Stop loss stop_loss_long := stop_loss_long + pyramid_profit*atr strategy.entry("Pyramid Long", strategy.long, units_to_add) buy_price_long := close //Pyramid for short orders if close < buy_price_short - (pyramid_profit*atr) and strategy.position_size<0 //We calculate the remaining capital remaining_capital = account + strategy.position_size*strategy.position_avg_price*(1-0.0018) //We calculate units to add to the short position units_to_add = (percentage_to_risk/100)*remaining_capital/atr*syminfo.pointvalue if remaining_capital > units_to_add and units_to_add>0 //We set the new Stop loss stop_loss_short := stop_loss_short - pyramid_profit*atr strategy.entry("Pyramid Short", strategy.short, units_to_add) buy_price_short := close //----------------------------EXIT ORDERS-------------------------------// //Checking if exit_long_syst1 is higher than stop_loss_long if strategy.opentrades.entry_id(0)=="Long Syst 1" if exit_long_syst1[1] > stop_loss_long exit_signal := exit_long_syst1[1] else exit_signal := stop_loss_long //Checking if exit_long_syst2 is higher than stop_loss_long if strategy.opentrades.entry_id(0)=="Long Syst 2" if exit_long_syst2[1] > stop_loss_long exit_signal := exit_long_syst2[1] else exit_signal := stop_loss_long //Checking if exit_short_syst1 is lower than stop_loss_short if strategy.opentrades.entry_id(0)=="Short Syst 1" if exit_short_syst1[1] < stop_loss_short exit_signal := exit_short_syst1[1] else exit_signal := stop_loss_short //Checking if exit_short_syst2 is lower than stop_loss_short if strategy.opentrades.entry_id(0)=="Short Syst 2" if exit_short_syst2[1] < stop_loss_short exit_signal := exit_short_syst2[1] else exit_signal := stop_loss_short //If the exit order is configured to close the position at a profit, we set 'skip' to true (we substract commission) if strategy.position_size*exit_signal>strategy.position_size*strategy.position_avg_price*(1-0.0018) strategy.cancel("Long Syst 1") strategy.cancel("Short Syst 1") skip := true if strategy.position_size*exit_signal<=strategy.position_size*strategy.position_avg_price*(1-0.0018) skip := false //We place stop exit orders if strategy.position_size > 0 strategy.exit("Exit Long", stop=exit_signal) if strategy.position_size < 0 strategy.exit("Exit Short", stop=exit_signal) //------------------------------PLOTTING ELEMENTS-------------------------------// plotchar(atr, "ATR", "", location.top, color.rgb(131, 5, 83)) //Plotting enter threshold plot(day_high_syst1[1], "20 day high", color.rgb(118, 217, 159)) plot(day_high_syst2[1], "55 day high", color.rgb(4, 92, 53)) plot(day_low_syst1[1], "20 day low", color.rgb(234, 108, 108)) plot(day_low_syst2[1], "55 day low", color.rgb(149, 17, 17)) //Plotting Exit Signal plot(exit_signal, "Exit Signal", color.blue, style=plot.style_circles) //Plotting our position exit_long_syst2_plot = plot(exit_long_syst2[1], color=na) day_high_syst2_plot = plot(day_high_syst2[1], color=na) exit_short_syst2_plot = plot(exit_short_syst2[1], color=na) day_low_syst2_plot = plot(day_low_syst2[1], color=na) fill(exit_long_syst2_plot, day_high_syst2_plot, color=strategy.position_size>0 ? color.new(color.lime, 90) : na) fill(exit_short_syst2_plot, day_low_syst2_plot, color=strategy.position_size<0 ? color.new(color.red, 90) : na)