Chiến lược giao dịch đảo ngược trung bình EMA


Ngày tạo: 2023-10-26 15:33:50 sửa đổi lần cuối: 2023-10-26 15:33:50
sao chép: 2 Số nhấp chuột: 1006
1
tập trung vào
1617
Người theo dõi

Chiến lược giao dịch đảo ngược trung bình EMA

Tổng quan

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

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

Chiến lược này sử dụng EMA như một chỉ số đường trung bình và tính toán khoảng cách phần trăm của giá hiện tại với EMA. Khi giá đủ xa EMA (bằng mặc định là 9%), sẽ mở nhiều vị trí; Khi giá đủ gần EMA (bằng mặc định là 1%), sẽ tháo dỡ. Sau khi mở vị trí, nó sẽ sử dụng lệnh dừng hoạt động để khóa lợi nhuận và tăng dần mức dừng khi lợi nhuận tăng lên.

Cụ thể, chiến lược bao gồm các thành phần sau:

  1. Tính toán đường trung bình của EMA. Có thể cấu hình chu kỳ (bằng 200 mặc định), nguồn dữ liệu (giá đóng cửa), cách tính toán (EMA, SMA, RMA, WMA).

  2. Tính phần trăm chênh lệch giữa giá hiện tại và EMA.

  3. Theo tỷ lệ chênh lệch mở vị trí. Mức giới hạn mở vị trí là 9% (có thể cấu hình) và mức giới hạn mở vị trí là 9% (có thể cấu hình).

  4. Hỗ trợ mở thang. Bạn có thể cấu hình số bậc thang và mỗi bậc thang.

  5. Theo dõi dừng lỗ sau khi mở vị trí. Bạn có thể cấu hình ngưỡng bắt đầu dừng lỗ (mức lợi nhuận mặc định là 1%) và mức độ theo dõi (mức lợi nhuận mặc định là 1%)

  6. Theo tỷ lệ chênh lệch, giá trị lỗ hổng của các vị trí bằng phẳng là 1% (có thể cấu hình), vị trí trống cũng tương tự.

  7. Hủy bỏ đơn đặt hàng chưa hoàn thành. Khi giá lại gần với EMA, sẽ hủy bỏ đơn đặt hàng chưa hoàn thành.

  8. Tỷ lệ dừng lỗ có thể cấu hình.

  9. Hỗ trợ phản hồi và giao dịch trực tiếp.

Phân tích lợi thế

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

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

  2. Các tham số mở, dừng và xóa 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 hàng dốc có thể được xây dựng theo từng đợt, giảm chi phí đơn lẻ.

  4. Hạn chế hoạt động có thể khóa lợi nhuận, quản lý rủi ro.

  5. Không gian tối ưu hóa rộng rãi, có thể điều chỉnh tham số đường trung bình hoặc chênh lệch vị trí đóng cửa để thích ứng với các tình huống khác nhau.

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

  7. Hình ảnh trực quan giúp bạn dễ dàng quan sát và phân tích.

Phân tích rủi ro

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

  1. Rủi ro phù hợp với dữ liệu phản hồi. Tối ưu hóa tham số có thể phù hợp quá mức với dữ liệu phản hồi, hiệu quả của ổ đĩa thực bị nghi ngờ.

  2. Rủi ro thất bại của đường trung bình. Giá có thể rời xa đường trung bình một cách lớn trong thời gian dài và không thể quay trở lại.

  3. Hạn chế thiệt hại bị theo đuổi qua rủi ro.

  4. Giao dịch thường xuyên, chi phí giao dịch nặng.

  5. Các trường hợp đột biến có thể gây ra nguy cơ cao.

Quản lý rủi ro:

  1. Nhiều điều chỉnh tham số để đảm bảo tham số ổn định. Nhiều thị trường chứng minh hiệu quả.

  2. Chu kỳ trung bình được cấu hình hợp lý, không thể quá ngắn hoặc quá dài.

  3. Giảm mức độ tổn thất thích hợp để tránh bị mắc kẹt.

  4. Các điều kiện mở cửa và giảm tần suất giao dịch.

  5. Kết hợp với nhiều chỉ số khác, cải thiện khả năng thích ứng với các sự kiện bất ngờ.

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

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

  1. Thêm các điều kiện lọc, chẳng hạn như khối lượng giao dịch, băng tần Brin, RSI và các chỉ số khác, để giảm tín hiệu giả.

  2. Thêm đường trung bình tổng hợp, như hệ thống EMA kép, để tăng xác suất giao dịch theo chiều hướng.

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

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

  5. Tăng khả năng dự đoán học máy, hỗ trợ xác định xác suất giá rời khỏi đường trung bình.

  6. Cân nhắc giao dịch xuyên thời gian, sử dụng giao dịch ban đêm hoặc giao dịch trước khi giao dịch.

  7. Tích hợp các nhóm cổ phiếu, tự động chọn và giao dịch cổ phiếu, mở rộng khả năng chiến lược.

Tóm tắt

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 đường trung bình giá. Nó sử dụng các tính năng thống kê của đường trung bình để đánh giá xu hướng biến đổi và kiểm soát rủi ro bằng cách dừng lỗ.

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