Skip to content

Latest commit

 

History

History
411 lines (302 loc) · 19.1 KB

游龟交易策略Turtle-Trend-Strategy.md

File metadata and controls

411 lines (302 loc) · 19.1 KB

Name

游龟交易策略Turtle-Trend-Strategy

Author

ChaoZhang

Strategy Description

IMG [trans]

概述

游龟交易策略是基于著名的乌龟交易策略进行改进和优化的趋势跟踪策略。该策略利用双移动平均线形成的交易信号,实现低风险的趋势跟踪交易。其标准化的进入和退出规则,可以有效控制交易风险,实现稳定的资金增长。

策略原理

游龟交易策略通过计算20日高点、20日低点、55日高点和55日低点,结合ATR指标设定止损位和盈利目标。当价格超过20日高点时生成长信号;当价格跌破20日低点时生成空信号。此外,该策略还设置了一个跳过机制,如果当前价格突破20日高低点但没有突破55日高低点,则跳过本次交易信号。

在进入市场后,策略会利用ATR指标的值来设置止损位和加仓目标。当亏损达到止损位时主动止损;当盈利达到加仓目标时加大仓位。这样可以在趋势行情中获利潜力最大化的同时控制单笔交易的风险。

优势分析

游龟交易策略最大的优势在于风险控制能力出色。标准化的进入退出规则可以有效控制单笔交易的损失,跳过机制避免了被隔夜跳空困在不利行情中的可能。稳定的止损策略也限制了连续亏损的出现。

另外,游龟交易策略采用ATR指标来动态设定止损位,这使得止损线可以自动适应市场波动率的变化。这保证了止损线既不会过于宽松造成大额损失,也不会过于紧凑被市场正常波动触发。

最后,策略的加仓机制使其可以充分捕捉趋势行情中的利润。这为资金的稳步增长奠定了基础。

风险分析

游龟交易策略主要的风险在于无法有效利用震荡行情获得利润。当市场长期震荡时,止损线可能会频繁被触发造成损失。而跳过机制也会导致信号不足,错过潜在的交易机会。

另外,该策略过于依赖技术指标,忽略了基本面分析。这使得它可能无法识别重大的政策面变化,从而导致不必要的损失。

优化方向

游龟交易策略可以从以下几个方面进行优化:

  1. 结合波动率指标,调整跳过机制的灵敏度,在震荡行情中提高交易频率

  2. 增加基本面信号作为过滤器,避免被突发事件击中止损

  3. 优化ATR参数的设置,使止损线更贴合真实的波动情况

  4. 结合量能指标,避免亏损后进入无效反转

总结

总的来说,游龟交易策略改进了原始乌龟交易策略的盈利和风险控制能力,是一种适合追踪趋势行情的低风险算法策略。通过进一步优化,该策略可以成为构建长期稳定盈利组合的重要部分。

||

Overview

The Turtle Trend strategy is an enhanced version of the famous Turtle Trading strategy. It utilizes the trading signals generated by double moving averages to implement low-risk trend following trading. Its standardized entry and exit rules can effectively control trading risks and achieve stable capital growth.

Strategy Logic

The Turtle Trend strategy calculates the 20-day high, 20-day low, 55-day high and 55-day low, combined with the ATR indicator to set stop loss and profit target. It generates long signals when price exceeds 20-day high and short signals when price breaks 20-day low. In addition, a skip mechanism is set to skip trading signals if prices break through 20-day high/low but fail to break through 55-day high/low.

After entering the market, the strategy utilizes the ATR values to set stop loss and pyramiding target. It stops out when losses reach stop loss level and increases position size when profits reach pyramiding target. This maximizes profit potential in trending markets while controlling risks of individual trades.

Advantage Analysis

The biggest advantage of Turtle Trend strategy lies in its excellent risk control capabilities. Standardized entry and exit rules can effectively control losses of individual trades. The skip mechanism avoids being stuck in adverse market conditions. The stable stop loss strategy also limits consecutive losses.

In addition, Turtle Trend strategy uses ATR indicator to dynamically set stop loss, enabling stop loss line to automatically adapt to changes in market volatility. This ensures that stop loss is neither too loose to cause huge losses nor too tight to be triggered by normal market fluctuations.

Finally, the pyramiding mechanism enables the strategy to fully capture profits in trending markets, laying the foundation for steady capital growth.

Risk Analysis

The main risk of Turtle Trend strategy is that it fails to profit from range-bound markets. When the market fluctuates in a range for long periods, stop loss may be frequently triggered resulting losses. Also, the skip mechanism may lead to insufficient signals and thus miss potential trading opportunities.

In addition, over reliance on technical indicators ignores fundamentals analysis. It may fail to detect major policy changes and cause unnecessary losses.

Optimization

Turtle Trend strategy can be optimized in the following aspects:

  1. Adjust skip mechanism’s sensitivity by combining volatility indicators to increase trading frequency in ranging markets.

  2. Add fundamental signals as filter to avoid being hit by stop loss due to sporadic events.

  3. Optimize ATR parameter settings to make stop loss line adhere more closely to actual fluctuation.

  4. Combine volume indicators to avoid entering ineffective pullback after a loss.

Summary

In summary, Turtle Trend Strategy improves the profitability and risk control capabilities of the original Turtle Trading Strategy. It is a low-risk algorithm strategy suitable for tracking trending markets. With further optimization, it can become an important part of building long-term steady profitable portfolio.

[/trans]

Strategy Arguments

Argument Default Description
v_input_float_1 true (?Turtle Parameters)Risk % of capital
v_input_int_1 20 ATR period
v_input_float_2 1.5 Stop ATR
v_input_float_3 0.5 Pyramid Profit
v_input_int_2 20 S1 Long
v_input_int_3 55 S2 Long
v_input_int_4 10 S1 Long Exit
v_input_int_5 20 S2 Long Exit
v_input_int_6 15 S1 Short
v_input_int_7 55 S2 Short
v_input_int_8 7 S1 Short Exit
v_input_int_9 20 S2 Short Exit
v_input_1 timestamp(1 Jan 2020 00:00:00) (?Backtesting Period)Start Date
v_input_2 timestamp(1 July 2034 00:00:00) End Date

Source (PineScript)

/*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)


Detail

https://www.fmz.com/strategy/443140

Last Modified

2024-02-29 15:15:54