Chiến lược giao dịch ETF dựa trên ATR và Breakout


Ngày tạo: 2023-12-26 16:05:55 sửa đổi lần cuối: 2023-12-26 16:05:55
sao chép: 2 Số nhấp chuột: 822
1
tập trung vào
1623
Người theo dõi

Chiến lược giao dịch ETF dựa trên ATR và Breakout

Tổng quan

Chiến lược này là một chiến lược giao dịch tự động của ETF dựa trên mức sóng thực trung bình (ATR) và mức giá phá vỡ. Nó sử dụng ATR để tính toán điểm dừng lỗ và điểm dừng và mở nhiều hoặc ngắn khi giá phá vỡ mức cao nhất hoặc thấp nhất trong một chu kỳ.

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

Chiến lược này dựa trên các nguyên tắc sau:

  1. Sử dụng giá cao nhất và giá thấp nhất của một chu kỳ (ví dụ như 20 đường K) để xác định xu hướng và hướng của giá. Khi giá phá vỡ giá cao nhất của chu kỳ, làm nhiều; Khi giá phá vỡ giá thấp nhất của chu kỳ, làm trống.

  2. Sử dụng ATR để tính toán động mức dừng chân. Khoảng cách giữa mức dừng chân với giá vào là ATR của một chu kỳ ATR nhân với hệ số ((như 2)

  3. Sử dụng ATR để tính toán điểm dừng. Khoảng cách dừng từ giá vào là giá trị ATR của một chu kỳ ATR nhân với hệ số ((như 1)

  4. Sử dụng ATRtrailer đa yếu tố để theo dõi dừng. Khi giá phá vỡ điểm dừng trailer theo hướng không thuận lợi, dừng lỗ.

Chiến lược này đơn giản và đáng tin cậy, nó xem xét xu hướng của xu hướng giá, có lợi cho việc nắm bắt xu hướng giá kịp thời; và thiết lập điểm dừng và dừng để nắm bắt cơ hội kiếm lợi nhuận và kiểm soát rủi ro.

Phân tích lợi thế

Chiến lược này có những ưu điểm sau:

  1. Ý tưởng chiến lược đơn giản, rõ ràng, dễ hiểu và dễ thực hiện.

  2. Sử dụng ATR để tính toán Stop Loss, bạn có thể điều chỉnh kích thước vị trí động, kiểm soát rủi ro linh hoạt.

  3. Chiến lược phán đoán phá vỡ chu kỳ dễ dàng nắm bắt xu hướng giá, lợi nhuận tốt hơn.

  4. Trailer Stop có thể dừng lại kịp thời, tránh chịu rủi ro quá lớn.

  5. Nó được sử dụng cho các loại có xu hướng rõ ràng như ETF, cổ phiếu, v.v.

Phân tích rủi ro

Chiến lược này cũng có những rủi ro sau:

  1. Trong khi đó, các nhà đầu tư khác cũng có thể có những dấu hiệu sai lầm và đảo ngược khi giao dịch.

  2. Cài đặt tham số chu kỳ không đúng có thể bỏ lỡ xu hướng giá hoặc giao dịch quá nhiều lần.

  3. Các tham số hệ số được đặt không đúng, có thể dẫn đến dừng hoặc dừng quá cấp tiến hoặc bảo thủ, ảnh hưởng đến lợi nhuận.

  4. Rủi ro của ETF, chẳng hạn như rủi ro chính sách, rủi ro phí bảo hiểm, cũng có thể ảnh hưởng đến chiến lược.

Giải pháp tương ứng:

  1. Tối ưu hóa các tham số, giảm tỷ lệ giao dịch ảo.
  2. Kết hợp nhiều yếu tố và bộ lọc để xác định tín hiệu giao dịch.
  3. Điều chỉnh tham số theo thị trường khác nhau.
  4. Đầu tư phân tán, kiểm soát vị trí của một ETF.

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

Chiến lược này có thể được tối ưu hóa hơn nữa ở những khía cạnh sau:

  1. Các chỉ số như đường trung bình di chuyển được sử dụng để lọc các tín hiệu giả.

  2. Thêm mô-đun tối ưu hóa tham số thích ứng, tự động tối ưu hóa tham số theo chu kỳ và giống khác nhau.

  3. Thêm mô hình học máy dự đoán điểm cao và điểm thấp của đường K tiếp theo để đánh giá tín hiệu đột phá.

  4. Cân nhắc các chỉ số như khối lượng giao dịch tràn ngập, phòng chống phá vỡ giả.

  5. Tối ưu hóa kích thước và tỷ lệ của các vị trí mở kho, thích ứng với các loại khác nhau và môi trường thị trường mở kho.

Tóm tắt

Chiến lược tổng thể của chiến lược là rõ ràng và đơn giản, phá vỡ cơ chế cốt lõi và ATR động dừng lỗ có thể kiểm soát rủi ro và khóa lợi nhuận hiệu quả. Bằng cách tối ưu hóa tham số và kết hợp với nhiều chỉ số lọc hơn, chiến lược có thể được tăng cường hơn nữa yếu tố lợi nhuận và khả năng kiểm soát rủi ro, một chiến lược định lượng đáng để bắt đầu và tối ưu hóa liên tục.

Mã nguồn chiến lược
/*backtest
start: 2023-12-18 00:00:00
end: 2023-12-21 03:00:00
period: 1m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © FX_minds

//@version=4
strategy("ETF tradedr", overlay=true, pyramiding=100, default_qty_type=strategy.percent_of_equity, default_qty_value=100)

//------------------------------ get user input
lookback                   = input(title="HH LL lookback", type=input.integer, defval=20)
ATR_periode                = input(title="ATR period", type=input.integer, defval=14)
ATR_SL_multiplier          = input(title="ATR SL multiplier", type=input.float, defval=2)
ATR_TP_multiplier          = input(title="ATR TP multiplier", type=input.float, defval=1)
trailing_SL_ATR_multiplier = input(title="ATR trailing SL multiplier", type=input.float, defval=3.5)
lookback_trailing_SL       = input(title="trailing SL lookback", type=input.integer, defval=4)
max_sequel_trades          = input(title="max sequel trades", type=input.float, defval=1)
trade_long                 = input(title= "trade long ?", type=input.bool, defval=true)
trade_short                = input(title= "trade short ?", type=input.bool, defval=false)

//------------------------------ determine entry conditions
long_condition   = barstate.isconfirmed and crossover(high, highest(high, lookback)[1])
short_condition  = barstate.isconfirmed and crossunder(low, lowest(low, lookback)[1])


//------------------------------ count open long trades
count_open_longs = 0
count_open_longs := nz(count_open_longs[1])

if (long_condition) 
    count_open_longs := count_open_longs +1
    //label.new(bar_index, low, tostring(count_open_longs, "#"), xloc.bar_index, yloc.belowbar, color.green, label.style_none, color.green, size.large)

if (short_condition)
    count_open_longs := 0


//------------------------------ count open short trades
count_open_shorts = 0
count_open_shorts := nz(count_open_shorts[1])

if (short_condition)
    count_open_shorts := count_open_shorts +1
    //label.new(bar_index, low, tostring(count_open_shorts, "#"), xloc.bar_index, yloc.belowbar, color.red, label.style_none, color.red, size.large)

if (long_condition)
    count_open_shorts := 0


//------------------------------ calculate entryprice
entryprice_long = long_condition ? close : na
entryprice_short = short_condition ? close : na


//------------------------------ calculate SL & TP
SL_distance = atr(ATR_periode) * ATR_SL_multiplier
TP_distance  = atr(ATR_periode) * ATR_TP_multiplier
trailing_SL_distance = atr(ATR_periode) * trailing_SL_ATR_multiplier

SL_long = entryprice_long - SL_distance
SL_short = entryprice_short + SL_distance

trailing_SL_short = lowest(close, lookback_trailing_SL) + trailing_SL_distance
trailing_SL_long  = highest(close, lookback_trailing_SL) - trailing_SL_distance

trailing_SL_short_signal = crossover(high, trailing_SL_short[1])
trailing_SL_long_signal = crossunder(low, trailing_SL_long[1])


//------------------------------ plot entry price & SL  
plot(entryprice_long, style=plot.style_linebr, color=color.white)
plot(SL_long, style=plot.style_linebr, color=color.red)
plot(SL_short, style=plot.style_linebr, color=color.green)
plot(trailing_SL_short, style=plot.style_linebr, color=color.red)
plot(trailing_SL_long, style=plot.style_linebr, color=color.green)


//------------------------------ submit entry orders
if (long_condition) and (count_open_longs <= max_sequel_trades) and (trade_long == true)
    strategy.entry("Long" + tostring(count_open_longs, "#"), strategy.long)
    strategy.exit("SL Long"+ tostring(count_open_longs, "#"), 
     from_entry="Long" + tostring(count_open_longs, "#"), stop=SL_long)

if (short_condition) and (count_open_shorts <= max_sequel_trades) and (trade_short == true)
    strategy.entry("Short" + tostring(count_open_shorts, "#"), strategy.short)
    strategy.exit("SL Short" + tostring(count_open_shorts, "#"), 
     from_entry="Short" + tostring(count_open_shorts, "#"), stop=SL_short)
    

//------------------------------ submit exit conditions
if (trailing_SL_long_signal)
    strategy.close("Long" + tostring(count_open_longs, "#"))
    strategy.close("Long" + tostring(count_open_longs-1, "#"))
    strategy.close("Long" + tostring(count_open_longs-2, "#"))
    strategy.close("Long" + tostring(count_open_longs-4, "#"))
    strategy.close("Long" + tostring(count_open_longs-5, "#"))
    strategy.close("Long" + tostring(count_open_longs-6, "#"))
    strategy.close("Long" + tostring(count_open_longs-7, "#"))
    strategy.close("Long" + tostring(count_open_longs-8, "#"))
    strategy.close("Long" + tostring(count_open_longs-9, "#"))
    
if (trailing_SL_short_signal)
    strategy.close("Short" + tostring(count_open_shorts, "#"))
    strategy.close("Short" + tostring(count_open_shorts-1, "#"))
    strategy.close("Short" + tostring(count_open_shorts-2, "#"))
    strategy.close("Short" + tostring(count_open_shorts-3, "#"))
    strategy.close("Short" + tostring(count_open_shorts-4, "#"))
    strategy.close("Short" + tostring(count_open_shorts-5, "#"))
    strategy.close("Short" + tostring(count_open_shorts-6, "#"))
    strategy.close("Short" + tostring(count_open_shorts-7, "#"))
    strategy.close("Short" + tostring(count_open_shorts-8, "#"))
    strategy.close("Short" + tostring(count_open_shorts-9, "#"))