Tài nguyên đang được tải lên... tải...

Chiến lược giao dịch EMA

Tác giả:ChaoZhang, Ngày: 2023-10-26 15:33:50
Tags:

EMA均值回归交易策略

Thông tin chi tiết

Chiến lược giao dịch EMA là một chiến lược giao dịch để mở và dừng giao dịch dựa trên mức độ giá rời khỏi đường trung bình. Nó sử dụng tỷ lệ phần trăm chênh lệch giữa đường trung bình EMA và giá hiện tại như một tín hiệu mở và sử dụng theo dõi dừng lỗ để quản lý vị trí.

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

Chiến lược này sử dụng EMA như là một chỉ số đường thẳng và tính toán tỷ lệ phần trăm chênh lệch giữa giá hiện tại và EMA. Khi giá đủ xa EMA (định hướng 9%), nó sẽ mở nhiều giao dịch; khi giá đủ gần EMA (định hướng 1%), nó sẽ đóng cửa. Sau khi mở giao dịch, nó sẽ sử dụng lệnh dừng lỗ để khóa lợi nhuận, dần dần điều chỉnh đường mất mát cao khi lợi nhuận tăng lên.

Đặc biệt, chiến lược bao gồm các thành phần sau:

  1. Tính toán EMA trung tuyến. Có thể cấu hình chu kỳ (thông mặc 200), nguồn dữ liệu (giá đóng cửa), phương thức tính toán (EMA, SMA, RMA, WMA).

  2. Tính toán tỷ lệ phần trăm chênh lệch của giá hiện tại với EMA.

  3. Tùy theo tỷ lệ chênh lệch, giá thềm mở thêm là 9% (có thể cấu hình) và giá thềm mở trống là 9% (có thể cấu hình).

  4. Hỗ trợ mở thang. Bạn có thể tùy chỉnh số thang và độ cao của mỗi thang.

  5. Theo dõi dừng lỗ sau khi bắt đầu giao dịch. Có thể cấu hình ngưỡng bắt đầu dừng lỗ ((thích mục lợi nhuận 1%) và phạm vi theo dõi ((thích mục 1%)).

  6. Theo tỷ lệ chênh lệch, ngang hàng. Mức threshold ngang hàng đa hàng là 1% (có thể được cấu hình), ngang hàng trống tương tự.

  7. Việc hủy bỏ giao dịch chưa hoàn thành. Khi giá lại gần EMA, lệnh chưa hoàn thành sẽ bị hủy bỏ.

  8. Có thể cấu hình tỷ lệ dừng mất mát.

  9. Hỗ trợ kiểm tra lại và giao dịch trong thời gian thực.

Phân tích ưu thế

Chiến lược này có những lợi thế sau:

  1. Sử dụng khái niệm quay trở về đường trung tuyến, mở giao dịch khi giá rời khỏi đường trung tuyến và đứng yên khi quay trở lại, phù hợp với lý thuyết giao dịch xu hướng.

  2. Các thông số mở, dừng, tròn có thể được cấu hình chi tiết để phù hợp với các môi trường thị trường khác nhau.

  3. Việc mở kho thang có thể xây dựng hàng loạt, giảm chi phí đơn lẻ.

  4. Việc dừng lỗ hoạt động có thể khóa lợi nhuận và quản lý rủi ro.

  5. Tối ưu hóa không gian lớn, có thể điều chỉnh các tham số đường trung tuyến hoặc chênh lệch giao dịch mở để phù hợp với các thị trường khác nhau.

  6. Hỗ trợ ngôn ngữ lập trình chính thống Pine Script, có thể sử dụng trực tiếp trong TradingView.

  7. Các biểu đồ trực quan được hiển thị để dễ dàng quan sát và phân tích.

Phân tích rủi ro

Một số người cho rằng chiến lược này cũng có những rủi ro:

  1. Rủi ro khớp dữ liệu tái kiểm tra. Tối ưu hóa tham số có thể quá khớp dữ liệu tái kiểm tra, hiệu quả thực tế không chắc chắn.

  2. Rủi ro thất bại đường trung tuyến. Giá có thể rời đường trung tuyến đáng kể trong thời gian dài và không thể quay trở lại.

  3. Trong khi đó, các nhà đầu tư khác cũng cho rằng các khoản đầu tư của họ có thể bị phá vỡ.

  4. Các giao dịch thường xuyên và chi phí giao dịch nặng nề.

  5. Các nhà nghiên cứu cho biết, các trường hợp đột ngột có thể ảnh hưởng rất lớn đến sự phát triển của con người.

Quản lý rủi ro:

  1. Nhiều tham số được điều chỉnh để đảm bảo các tham số vững chắc. Nhiều thị trường xác minh hiệu quả.

  2. Các chu kỳ đều đường được cấu hình hợp lý, không quá ngắn hoặc quá dài.

  3. Giới thiệu về việc sử dụng các thiết bị này.

  4. Việc nới lỏng các điều kiện mở giao dịch và giảm tần suất giao dịch là điều thích hợp.

  5. Các nhà nghiên cứu cho biết, việc kết hợp nhiều chỉ số hơn sẽ giúp tăng khả năng thích ứng với các sự kiện khẩn cấp.

Định hướng tối ưu

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

  1. Tăng các điều kiện lọc như khối lượng giao dịch, đường viền, RSI và các chỉ số khác để giảm tín hiệu giả.

  2. Tăng đường trung bình phức tạp, chẳng hạn như hệ thống EMA kép, làm tăng xác suất giao dịch thuận lợi.

  3. Tối ưu hóa chiến lược dừng lỗ, chẳng hạn như dừng lỗ tự điều chỉnh, Chandelier Exit, để hạn chế rủi ro hơn nữa.

  4. Tăng chức năng tối ưu hóa tham số tự động, tự động tìm kiếm các sự kết hợp tham số tối ưu hơn.

  5. Tăng dự đoán học máy, giúp xác định khả năng giá rời đường trung bình.

  6. Hãy xem xét giao dịch qua thời gian, sử dụng thông tin giao dịch đêm hoặc giao dịch trước.

  7. Tích hợp hồ bơi cổ phiếu, tự động chọn và giao dịch cổ phiếu, mở rộng năng lực chiến lược.

Tóm lại

Chiến lược EMA là một chiến lược theo dõi xu hướng dựa trên các đặc điểm của xu hướng xu hướng giá; nó sử dụng các tính năng thống kê của xu hướng để xác định sự đảo ngược xu hướng và kiểm soát rủi ro bằng việc dừng lỗ; nó tập trung nhiều hơn vào chiến lược giao dịch xu hướng xu hướng thay vì giao dịch đóng cửa. Chiến lược này có thể làm phong phú thêm sự kết hợp của các chiến lược theo dõi xu hướng, nhưng cần chú ý đến các vấn đề tối ưu hóa và kiểm soát tần suất giao dịch. Nếu tiếp tục tối ưu hóa các cơ chế dừng lỗ, cải thiện chất lượng giao dịch, hiệu quả chiến đấu có thể tốt hơn.


/*backtest
start: 2022-10-19 00:00:00
end: 2023-10-25 00:00:00
period: 1d
basePeriod: 1h
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/
// © jordanfray

//@version=5
strategy(title="EMA Mean Reversion Strategy", overlay=true, max_bars_back=5000, default_qty_type=strategy.percent_of_equity, default_qty_value=100,initial_capital=100000, commission_type=strategy.commission.percent, commission_value=0.05, backtest_fill_limits_assumption=2)


// Indenting Classs
indent_1 = " "
indent_2 = "  "
indent_3 = "   "
indent_4 = "    "


// Tooltips
longEntryToolTip = "When the percentage that the price is away from the selected EMA reaches this point, a long postion will open."
shortEntryToolTip = "When the percentage that the price is away from the selected EMA reaches this point, a short postion will open."
closeEntryToolTip = "When the percentage that the price is away from the selected EMA reaches this point, open postion will close."
ladderInToolTip = "Enable this to use the laddering settings below."
cancelEntryToolTip = "When the percentage that the price is away from the selected EMA reaches this point, any unfilled entries will be canceled."

// Group Titles
group_one_title = "EMA Settings"
group_two_title = "Entry Settings"


// Colors
blue = color.new(#00A5FF,0)
lightBlue = color.new(#00A5FF,90)
green = color.new(#2DBD85,0)
gray_80 =  color.new(#7F7F7F,80)
gray_60 =  color.new(#7F7F7F,60)
gray_40 =  color.new(#7F7F7F,40)
white = color.new(#ffffff,0)
red = color.new(#E02A4A,0)
transparent = color.new(#000000,100)


// Strategy Settings
EMAtimeframe = input.timeframe(defval="", title="Timeframe", group=group_one_title)
EMAlength = input.int(defval=200, minval=1, title="Length", group=group_one_title)
EMAtype = input.string(defval="EMA", options = ["EMA", "SMA", "RMA", "WMA"], title="Type", group=group_one_title)
EMAsource = input.source(defval=close, title="Source", group=group_one_title)

openLongEntryAbove = input.float(defval=9, title="Long Position Entry Trigger", tooltip=longEntryToolTip, group=group_two_title)
openEntryEntryAbove = input.float(defval=9, title="Short Position Entry Trigger", tooltip=shortEntryToolTip, group=group_two_title)
closeEntryBelow = input.float(defval=1.0, title="Close Position Trigger", tooltip=closeEntryToolTip, group=group_two_title)
cancelEntryBelow = input.float(defval=4, title="Cancel Unfilled Entries Trigger", tooltip=cancelEntryToolTip, group=group_two_title)

enableLaddering = input.bool(defval=true, title="Ladder Into Positions", tooltip=ladderInToolTip, group=group_two_title)
ladderRungs = input.int(defval=4, minval=2, maxval=4, step=1, title=indent_4+"Ladder Rungs", group=group_two_title)
ladderStep = input.float(defval=.5, title=indent_4+"Ladder Step (%)", step=.1, group=group_two_title)/100
stop_loss_val = input.float(defval=4.0, title="Stop Loss (%)", step=0.1, group=group_two_title)/100
start_trailing_after = input.float(defval=1, title="Start Trailing After (%)", step=0.1, group=group_two_title)/100
trail_behind = input.float(defval=1, title="Trail Behind (%)", step=0.1, group=group_two_title)/100

// Calculate trailing stop values
long_start_trailing_val = strategy.position_avg_price + (strategy.position_avg_price * start_trailing_after)
long_trail_behind_val = close - (strategy.position_avg_price * trail_behind)
long_stop_loss = strategy.position_avg_price * (1.0 - stop_loss_val)
short_start_trailing_val = strategy.position_avg_price - (strategy.position_avg_price * start_trailing_after)
short_trail_behind_val = close + (strategy.position_avg_price * trail_behind)
short_stop_loss = strategy.position_avg_price * (1 + stop_loss_val)


// Calulate EMA
EMA = switch EMAtype
    "EMA" => ta.ema(EMAsource, EMAlength)
    "SMA" => ta.sma(EMAsource, EMAlength)
    "RMA" => ta.rma(EMAsource, EMAlength)
    "WMA" => ta.wma(EMAsource, EMAlength)
    => na
EMA_ = EMAtimeframe == timeframe.period ? EMA : request.security(syminfo.ticker, EMAtimeframe, EMA[1], lookahead = barmerge.lookahead_on)
plot(EMA_, title="EMA", linewidth=2, color=blue, editable=true)

EMA_cloud_upper_band_val = EMA_ + (EMA_ * openLongEntryAbove/100)
EMA_cloud_lower_band_val = EMA_ - (EMA_ * openLongEntryAbove/100)
EMA_cloud_upper_band = plot(EMA_cloud_upper_band_val, title="EMA Cloud Upper Band", color=blue)
EMA_cloud_lower_band = plot(EMA_cloud_lower_band_val, title="EMA Cloud Upper Band", color=blue)
fill(EMA_cloud_upper_band, EMA_cloud_lower_band, editable=false, color=lightBlue)

distance_from_EMA = ((close - EMA_)/close)*100
if distance_from_EMA < 0
    distance_from_EMA := distance_from_EMA * -1

// Calulate Ladder Entries
long_ladder_1_limit_price = close - (close * 1 * ladderStep)
long_ladder_2_limit_price = close - (close * 2 * ladderStep)
long_ladder_3_limit_price = close - (close * 3 * ladderStep)
long_ladder_4_limit_price = close - (close * 4 * ladderStep)

short_ladder_1_limit_price = close + (close * 1 * ladderStep)
short_ladder_2_limit_price = close + (close * 2 * ladderStep)
short_ladder_3_limit_price = close + (close * 3 * ladderStep)
short_ladder_4_limit_price = close + (close * 4 * ladderStep)

var position_qty = strategy.equity/close
if enableLaddering
    position_qty := (strategy.equity/close) / ladderRungs
else
    position_qty := strategy.equity/close
    
plot(position_qty, color=white)
//plot(strategy.equity, color=green)

// Entry Conditions
currently_in_a_postion = strategy.position_size != 0
currently_in_a_long_postion = strategy.position_size > 0
currently_in_a_short_postion = strategy.position_size < 0
average_price = strategy.position_avg_price

bars_since_entry = currently_in_a_postion ? bar_index - strategy.opentrades.entry_bar_index(strategy.opentrades - 1) + 1 : 5
long_run_up = ta.highest(high, bar_index == 0 ? 5000: bars_since_entry)
long_run_up_line = plot(long_run_up, style=plot.style_stepline, editable=false, color=currently_in_a_long_postion ? green : transparent)
start_trailing_long_entry = currently_in_a_long_postion and long_run_up > long_start_trailing_val
long_trailing_stop = start_trailing_long_entry ? long_run_up - (long_run_up * trail_behind) : long_stop_loss
long_trailing_stop_line = plot(long_trailing_stop, style=plot.style_stepline, editable=false, color=currently_in_a_long_postion ? long_trailing_stop > strategy.position_avg_price ? green : red : transparent)

short_run_up = ta.lowest(low, bar_index == 0 ? 5000: bars_since_entry)
short_run_up_line = plot(short_run_up, style=plot.style_stepline, editable=false, color=currently_in_a_short_postion ? green : transparent)
start_trailing_short_entry = currently_in_a_short_postion and short_run_up < short_start_trailing_val
short_trailing_stop = start_trailing_short_entry ? short_run_up + (short_run_up * trail_behind) : short_stop_loss
short_trailing_stop_line = plot(short_trailing_stop, style=plot.style_stepline, editable=false, color=currently_in_a_short_postion ? short_trailing_stop < strategy.position_avg_price ? green : red : transparent)

long_conditions_met = distance_from_EMA > openLongEntryAbove and close < EMA_ and not currently_in_a_postion
short_conditions_met = distance_from_EMA > openEntryEntryAbove and close > EMA_ and not currently_in_a_postion
close_long_entries = distance_from_EMA <= closeEntryBelow or close <= long_trailing_stop
close_short_entries = distance_from_EMA <= closeEntryBelow or close >= short_trailing_stop
cancel_entries = distance_from_EMA <= cancelEntryBelow

plotshape(long_conditions_met ? close : na, style=shape.diamond, title="Long Conditions Met" )
plotshape(short_conditions_met ? close : na, style=shape.diamond, title="Short Conditions Met" )
plot(average_price,style=plot.style_stepline, editable=false, color=currently_in_a_postion ? blue : transparent)

// Long Entry
if enableLaddering
    if ladderRungs == 2
        strategy.entry(id="Long Ladder 1", direction=strategy.long, qty=position_qty, limit=long_ladder_1_limit_price, when=long_conditions_met)
        strategy.entry(id="Long Ladder 2", direction=strategy.long, qty=position_qty, limit=long_ladder_2_limit_price, when=long_conditions_met)
    else if ladderRungs == 3
        strategy.entry(id="Long Ladder 1", direction=strategy.long, qty=position_qty, limit=long_ladder_1_limit_price, when=long_conditions_met)
        strategy.entry(id="Long Ladder 2", direction=strategy.long, qty=position_qty, limit=long_ladder_2_limit_price, when=long_conditions_met)
        strategy.entry(id="Long Ladder 3", direction=strategy.long, qty=position_qty, limit=long_ladder_3_limit_price, when=long_conditions_met)
    else if ladderRungs == 4
        strategy.entry(id="Long Ladder 1", direction=strategy.long, qty=position_qty, limit=long_ladder_1_limit_price, when=long_conditions_met)
        strategy.entry(id="Long Ladder 2", direction=strategy.long, qty=position_qty, limit=long_ladder_2_limit_price, when=long_conditions_met)
        strategy.entry(id="Long Ladder 3", direction=strategy.long, qty=position_qty, limit=long_ladder_3_limit_price, when=long_conditions_met)
        strategy.entry(id="Long Ladder 4", direction=strategy.long, qty=position_qty, limit=long_ladder_4_limit_price, when=long_conditions_met)
    
    strategy.exit(id="Close Long Ladder 1", from_entry="Long Ladder 1", stop=long_trailing_stop, limit=long_trailing_stop, when=close_long_entries)
    strategy.exit(id="Close Long Ladder 2", from_entry="Long Ladder 2", stop=long_trailing_stop, limit=long_trailing_stop, when=close_long_entries)
    strategy.exit(id="Close Long Ladder 3", from_entry="Long Ladder 3", stop=long_trailing_stop, limit=long_trailing_stop, when=close_long_entries)
    strategy.exit(id="Close Long Ladder 4", from_entry="Long Ladder 4", stop=long_trailing_stop, limit=long_trailing_stop, when=close_long_entries)
    
    strategy.cancel(id="Long Ladder 1", when=cancel_entries)
    strategy.cancel(id="Long Ladder 2", when=cancel_entries)
    strategy.cancel(id="Long Ladder 3", when=cancel_entries)
    strategy.cancel(id="Long Ladder 4", when=cancel_entries)
else
    strategy.entry(id="Long", direction=strategy.long, qty=100, when=long_conditions_met)
    strategy.exit(id="Close Long", from_entry="Long", stop=long_stop_loss, limit=EMA_, when=close_long_entries)
    strategy.cancel(id="Long", when=cancel_entries)

// Short Entry
if enableLaddering
    if ladderRungs == 2
        strategy.entry(id="Short Ladder 1", direction=strategy.short, qty=position_qty, limit=short_ladder_1_limit_price, when=short_conditions_met)
        strategy.entry(id="Short Ladder 2", direction=strategy.short, qty=position_qty, limit=short_ladder_2_limit_price, when=short_conditions_met)
    else if ladderRungs == 3
        strategy.entry(id="Short Ladder 1", direction=strategy.short, qty=position_qty, limit=short_ladder_1_limit_price, when=short_conditions_met)
        strategy.entry(id="Short Ladder 2", direction=strategy.short, qty=position_qty, limit=short_ladder_2_limit_price, when=short_conditions_met)
        strategy.entry(id="Short Ladder 3", direction=strategy.short, qty=position_qty, limit=short_ladder_3_limit_price, when=short_conditions_met)
    else if ladderRungs == 4
        strategy.entry(id="Short Ladder 1", direction=strategy.short, qty=position_qty, limit=short_ladder_1_limit_price, when=short_conditions_met)
        strategy.entry(id="Short Ladder 2", direction=strategy.short, qty=position_qty, limit=short_ladder_2_limit_price, when=short_conditions_met)
        strategy.entry(id="Short Ladder 3", direction=strategy.short, qty=position_qty, limit=short_ladder_3_limit_price, when=short_conditions_met)
        strategy.entry(id="Short Ladder 4", direction=strategy.short, qty=position_qty, limit=short_ladder_4_limit_price, when=short_conditions_met)
    
    strategy.exit(id="Close Short Ladder 1", from_entry="Short Ladder 1", stop=short_trailing_stop, limit=EMA_, when=close_short_entries)
    strategy.exit(id="Close Short Ladder 2", from_entry="Short Ladder 2", stop=short_trailing_stop, limit=EMA_, when=close_short_entries)
    strategy.exit(id="Close Short Ladder 3", from_entry="Short Ladder 3", stop=short_trailing_stop, limit=EMA_, when=close_short_entries)
    strategy.exit(id="Close Short Ladder 4", from_entry="Short Ladder 4", stop=short_trailing_stop, limit=EMA_, when=close_short_entries)
    
    strategy.cancel(id="Short Ladder 1", when=cancel_entries)
    strategy.cancel(id="Short Ladder 2", when=cancel_entries)
    strategy.cancel(id="Short Ladder 3", when=cancel_entries)
    strategy.cancel(id="Short Ladder 4", when=cancel_entries)
else
    strategy.entry(id="Short", direction=strategy.short, when=short_conditions_met)
    strategy.exit(id="Close Short", from_entry="Short", limit=EMA_, when=close_short_entries)
    strategy.cancel(id="Short", when=cancel_entries)



Nhiều hơn nữa