Mô hình đảo ngược đột phá dựa trên chiến lược giao dịch rùa

Tác giả:ChaoZhang, Ngày: 2024-01-29 16:48:00
Tags:

img

Tổng quan

Chiến lược này dựa trên chiến lược giao dịch rùa nổi tiếng, được xác nhận qua nhiều năm. Nó gửi tín hiệu dài và ngắn với các lệnh kim tự tháp lên đến 5, có nghĩa là chiến lược có thể kích hoạt đến 5 lệnh theo cùng một hướng. Với quản lý rủi ro và tiền tốt.

Cần lưu ý rằng chiến lược kết hợp 2 hệ thống làm việc cùng nhau (S1 và S2).

Chiến lược logic

Định kích thước vị trí rất quan trọng đối với các nhà giao dịch rùa để quản lý rủi ro một cách đúng đắn. Chiến lược định kích thước vị trí này thích nghi với biến động thị trường và tài khoản (lợi nhuận và lỗ). Nó dựa trên ATR (Mức True Range), cũng có thể được gọi là N. Độ dài mặc định của nó là 20.

Số lượng đơn vị mua là:

unit = (percentage_to_risk/100)*account/atr*syminfo.pointvalue 

Tùy thuộc vào sự tham vọng rủi ro của bạn, bạn có thể tăng tỷ lệ phần trăm tài khoản của bạn, nhưng các nhà giao dịch rùa mặc định là 1%.

Ngoài ra còn có một quy tắc bổ sung để giảm rủi ro nếu giá trị tài khoản giảm xuống dưới vốn ban đầu: trong trường hợp này và chỉ trong trường hợp này, trong công thức đơn vị phải được thay thế bằng:

account := (strategy.equity-strategy.openprofit)*(strategy.equity-strategy.openprofit)/strategy.initial_capital

2 hệ thống làm việc cùng nhau:
Nếu nó là một mức cao mới, chúng ta mở một vị trí dài và ngược lại nếu nó là một mức thấp mới, chúng ta vào một vị trí ngắn.

Chúng ta thêm một quy tắc nữa:
Quy tắc bổ sung này cho phép nhà giao dịch có xu hướng lớn nếu tín hiệu hệ thống 1 đã bị bỏ qua. Nếu tín hiệu cho hệ thống 1 đã bị bỏ qua, và nến tiếp theo cũng là một đột phá 20 ngày mới, S1 không đưa ra tín hiệu. Chúng ta phải chờ tín hiệu S2 hoặc chờ một nến không tạo ra một đột phá mới để kích hoạt lại S1.

Phân tích lợi thế

Chiến lược Rùa cho phép chúng ta thêm các đơn vị vào vị trí nếu giá di chuyển theo lợi thế của chúng ta. Tôi đã cấu hình chiến lược để cho phép tối đa 5 lệnh được thêm theo cùng một hướng. Vì vậy, nếu giá thay đổi từ, chúng tôi thêm các đơn vị với công thức kích thước vị trí.

Chúng tôi đã đặt SL tối đa là 10% cho lệnh đầu tiên, có nghĩa là bạn sẽ không mất hơn 10% giá trị của lệnh đầu tiên của bạn. Tuy nhiên, có thể mất nhiều hơn trên lệnh kim tự tháp của bạn, vì SL được tăng / giảm 0,5 * ATR ((20), không đảm bảo mất hơn 10% trên lệnh kim tự tháp của bạn.

Phân tích rủi ro

Rủi ro lớn nhất của chiến lược này là các vị trí quá lớn. Vì lệnh thị trường được sử dụng để đặt lệnh, việc đặt nhiều lệnh thị trường lớn cùng một lúc sẽ có tác động rất lớn đến báo giá, gây ra sự trượt lớn. Điều này sẽ dẫn đến tổn thất vốn rất lớn.

Một rủi ro khác là cấu hình quản lý vốn không phù hợp. Ví dụ, cấu hình dừng lỗ không chính xác hoặc tỷ lệ quá lớn có thể dẫn đến tổn thất lớn. Điều này cần phải được cấu hình cẩn thận theo sự thèm rủi ro của chính mình.

Tối ưu hóa

Chiến lược có thể được tối ưu hóa trong các khía cạnh sau:

  1. Kiểm tra tác động của các tham số khác nhau như thời gian ATR, nhân ATR để dừng lỗ, v.v. về tỷ lệ trở lại và sắc nét. Tìm kết hợp tham số tối ưu.

  2. Kiểm tra các quy tắc vào và ra khác nhau. Ví dụ, sử dụng các mẫu nến làm bộ lọc bổ sung.

  3. Hãy thử các loại dừng lỗ khác, chẳng hạn như dừng lỗ di chuyển, dừng lỗ động. Điều này có thể làm giảm xác suất dừng lỗ bị trúng.

  4. Kiểm tra số lượng khác nhau của các lệnh kim tự tháp. càng nhiều lệnh, đòn bẩy và rủi ro càng lớn. tìm điểm cân bằng tốt nhất.

  5. Cố gắng ngừng giao dịch trong khoảng thời gian cụ thể (chẳng hạn như trước khi phát hành dữ liệu lương không nông nghiệp của Hoa Kỳ) để tránh tác động của các sự kiện lớn.

Tóm lại

Nhìn chung, chiến lược này đạt được sự cân bằng tốt giữa rủi ro và lợi nhuận, phù hợp với giao dịch xu hướng trung và dài hạn. Nó có những lợi thế của việc hệ thống hóa giao dịch, rủi ro có thể kiểm soát được. Chiến lược có thể được cải thiện hơn nữa bằng cách tối ưu hóa để tăng sự ổn định và lợi nhuận.


/*backtest
start: 2023-12-01 00:00:00
end: 2023-12-31 23:59:59
period: 1h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This Pine Script™ code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © gsanson66


//This strategy is based on the famous "Turtle Strategy"
//A well-known strategy which proved its performance during past years 
//@version=5
strategy("TURTLE STRATEGY", overlay=true)


//------------------------------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) => true


//---------------------------------------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-------------------------------//
strategy.initial_capital = 50000
//Checking if the date belong to the range
inRange := inBacktestPeriod(startDate, endDate)

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



Thêm nữa