Chiến lược giao dịch Rùa bơi


Ngày tạo: 2024-02-29 15:15:54 sửa đổi lần cuối: 2024-02-29 15:15:54
sao chép: 4 Số nhấp chuột: 974
1
tập trung vào
1617
Người theo dõi

Chiến lược giao dịch Rùa bơi

Tổng quan

Chiến lược giao dịch rùa là một chiến lược theo dõi xu hướng được cải tiến và tối ưu hóa dựa trên chiến lược giao dịch rùa nổi tiếng. Chiến lược này sử dụng tín hiệu giao dịch hình thành từ đường trung bình di chuyển kép để thực hiện giao dịch theo dõi xu hướng có rủi ro thấp. Quy tắc nhập và thoát tiêu chuẩn của nó có thể kiểm soát rủi ro giao dịch một cách hiệu quả và tăng trưởng vốn ổn định.

Nguyên tắc chiến lược

Chiến lược giao dịch buông xuôi đặt mục tiêu dừng lỗ và lợi nhuận bằng cách tính toán mức cao 20, mức thấp 20, mức cao 55 và mức thấp 55 ngày kết hợp với chỉ số ATR. Tạo tín hiệu dài khi giá vượt quá mức cao 20 ngày; tạo tín hiệu trống khi giá giảm xuống mức thấp 20 ngày. Ngoài ra, chiến lược này cũng thiết lập một cơ chế nhảy nếu giá hiện tại phá vỡ mức cao 20 ngày nhưng không phá vỡ mức cao 55 ngày.

Sau khi tham gia thị trường, chiến lược sẽ sử dụng giá trị của chỉ số ATR để thiết lập điểm dừng lỗ và mục tiêu bồi thường. Hạn chế chủ động khi lỗ đạt đến điểm dừng lỗ; tăng vị trí khi lợi nhuận đạt đến mục tiêu bồi thường. Như vậy, bạn có thể kiểm soát rủi ro của một giao dịch đồng thời tối đa hóa tiềm năng lợi nhuận trong tình huống xu hướng.

Phân tích lợi thế

Lợi thế lớn nhất của chiến lược giao dịch tự do là khả năng kiểm soát rủi ro tuyệt vời. Các quy tắc nhập và thoát tiêu chuẩn hóa có thể kiểm soát hiệu quả tổn thất của một giao dịch, và cơ chế bỏ qua tránh bị mắc kẹt trong tình huống bất lợi qua đêm. Chiến lược dừng lỗ ổn định cũng hạn chế sự xuất hiện của tổn thất liên tục.

Ngoài ra, chiến lược giao dịch tự động sử dụng chỉ số ATR để thiết lập mức dừng lỗ động, điều này cho phép đường dừng lỗ tự động thích ứng với sự thay đổi của biến động thị trường. Điều này đảm bảo đường dừng lỗ không bị quá nới lỏng để gây ra tổn thất lớn và không bị kích hoạt quá chặt chẽ bởi biến động bình thường của thị trường.

Cuối cùng, cơ chế đặt cược của chiến lược cho phép nó nắm bắt đầy đủ lợi nhuận trong tình huống xu hướng. Điều này tạo nền tảng cho sự tăng trưởng ổn định của quỹ.

Phân tích rủi ro

Rủi ro chính của chiến lược buôn bán tự do là không thể tận dụng hiệu quả tình trạng biến động để kiếm lợi nhuận. Khi thị trường biến động lâu dài, đường dừng lỗ có thể thường xuyên bị kích hoạt gây ra tổn thất. Và việc bỏ qua cơ chế cũng có thể dẫn đến tín hiệu kém và bỏ lỡ cơ hội giao dịch tiềm năng.

Ngoài ra, chiến lược này quá phụ thuộc vào các chỉ số kỹ thuật và bỏ qua phân tích cơ bản. Điều này có thể khiến nó không nhận ra được những thay đổi chính sách quan trọng, dẫn đến tổn thất không cần thiết.

Hướng tối ưu hóa

Các chiến lược giao dịch trượt có thể được tối ưu hóa từ các khía cạnh sau:

  1. Kết hợp với chỉ số biến động, điều chỉnh độ nhạy của cơ chế nhảy, tăng tần suất giao dịch trong tình huống biến động

  2. Tăng tín hiệu cơ bản làm bộ lọc, tránh bị ngắt quãng do sự cố đột ngột

  3. Tối ưu hóa các thiết lập tham số ATR để làm cho đường dừng phù hợp hơn với biến động thực tế

  4. Kết hợp các chỉ số năng lượng lượng để tránh thua lỗ và đảo ngược vô hiệu

Tóm tắt

Nhìn chung, chiến lược giao dịch lữ hành cải thiện khả năng kiểm soát lợi nhuận và rủi ro của chiến lược giao dịch lữ hành lữ hành nguyên thủy, một chiến lược thuật toán rủi ro thấp phù hợp để theo dõi xu hướng. Với tối ưu hóa hơn nữa, chiến lược này có thể trở thành một phần quan trọng trong việc xây dựng danh mục lợi nhuận ổn định lâu dài.

Mã nguồn chiến lược
/*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)