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

Chiến lược giao thoa EMA hai năng động với kiểm soát lợi nhuận/mất mát thích nghi

Tác giả:ChaoZhang, Ngày: 2024-12-11 11:23:54
Tags:EMASMA

img

Tổng quan

Đây là một chiến lược giao dịch định lượng dựa trên các tín hiệu chéo EMA kép, sử dụng giao điểm của Trung bình Di chuyển Triệu suất nhanh và chậm (EMA) để xác định xu hướng thị trường, kết hợp với kiểm soát lấy lợi nhuận và dừng lỗ năng động để quản lý rủi ro. Chiến lược sử dụng quản lý vị trí dựa trên tỷ lệ phần trăm, mặc định 10% vốn cho mỗi giao dịch, và thực hiện mục tiêu lợi nhuận năng động và mức dừng lỗ để bảo vệ.

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

Hệ thống EMA được thiết kế để kiểm soát các biến đổi trong thị trường. Các biến đổi trong thị trường được xác định từ thời điểm EMA bắt đầu hoạt động.

Ưu điểm chiến lược

  1. Tính ổn định tín hiệu - Sử dụng EMA thay vì SMA, cung cấp phản ứng nhanh hơn đối với sự thay đổi giá trong khi lọc tiếng ồn thị trường.
  2. Quản lý rủi ro toàn diện - Thực hiện các cơ chế lấy lợi nhuận và dừng lỗ năng động điều chỉnh theo giá nhập cảnh.
  3. Quản lý vốn hợp lý - Sử dụng kích thước vị trí theo tỷ lệ cố định, tránh giao dịch toàn vị trí có rủi ro cao.
  4. Tự động hóa cao - Tự động hóa mọi thứ từ việc tạo tín hiệu đến quản lý vị trí, giảm can thiệp của con người.
  5. Khả năng thích nghi mạnh mẽ - Chiến lược có thể thích nghi với các điều kiện thị trường khác nhau với các tham số có thể điều chỉnh.

Rủi ro chiến lược

  1. EMA Lag - Mặc dù nhanh hơn SMA, EMA vẫn có một số sự chậm trễ vốn có, có khả năng gây ra sự chậm trễ.
  2. Hiệu suất kém trong các thị trường dao động - Có thể tạo ra các tín hiệu đột phá sai thường xuyên trong điều kiện thị trường bên cạnh.
  3. Số nhân cố định cho Lợi nhuận / Loss - Sử dụng số nhân cố định cho Lợi nhuận và dừng lỗ có thể không phù hợp với tất cả các điều kiện thị trường.
  4. Rủi ro rút vốn - 5% dừng lỗ có thể không đủ trong các thị trường biến động cao.

Hướng dẫn tối ưu hóa

  1. Tích hợp các chỉ số biến động - đề xuất thêm ATR để điều chỉnh động các nhân lợi nhuận / lỗ để thích nghi thị trường tốt hơn.
  2. Thêm xác nhận xu hướng - Xem xét kết hợp RSI, MACD để lọc tín hiệu để cải thiện tỷ lệ thắng.
  3. Tối ưu hóa kích thước vị trí - Thực hiện kích thước vị trí năng động dựa trên biến động thị trường để kiểm soát rủi ro tốt hơn.
  4. Thêm bộ lọc thời gian - Xem xét thêm cửa sổ thời gian giao dịch để tránh các giai đoạn biến động cao.
  5. Nâng cao lợi nhuận - Thực hiện dừng lại để nắm bắt nhiều lợi nhuận hơn trong xu hướng mạnh.

Kết luận

Đây là một chiến lược theo xu hướng được thiết kế tốt với logic rõ ràng, sử dụng hai đường chéo EMA để nắm bắt xu hướng và kiểm soát lợi nhuận / lỗ năng động để quản lý rủi ro. Sức mạnh của chiến lược nằm trong các quy tắc rõ ràng và rủi ro được kiểm soát, làm cho nó phù hợp như một nền tảng cho các hệ thống giao dịch trung hạn đến dài hạn. Có một khoảng trống đáng kể để tối ưu hóa thông qua các bộ lọc bổ sung và cơ chế lợi nhuận / lỗ được nâng cao. Các nhà giao dịch nên xác nhận chiến lược thông qua kiểm tra lại trên các điều kiện thị trường khác nhau và điều chỉnh các tham số theo khả năng chịu rủi ro của họ trước khi thực hiện trực tiếp.


/*backtest
start: 2019-12-23 08:00:00
end: 2024-12-09 08:00:00
period: 1d
basePeriod: 1d
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/
// © Pineify

//======================================================================//
//                    ____  _            _  __                          //
//                   |  _ \(_)_ __   ___(_)/ _|_   _                    //
//                   | |_) | | '_ \ / _ \ | |_| | | |                   //
//                   |  __/| | | | |  __/ |  _| |_| |                   //
//                   |_|   |_|_| |_|\___|_|_|  \__, |                   //
//                                             |___/                    //
//======================================================================//

//@version=5
strategy(title="TQQQ EMA Strategy", overlay=true)

//#region —————————————————————————————————————————————————— Common Dependence

p_comm_time_range_to_unix_time(string time_range, int date_time = time, string timezone = syminfo.timezone) =>
    int start_unix_time = na
    int end_unix_time = na
    int start_time_hour = na
    int start_time_minute = na
    int end_time_hour = na
    int end_time_minute = na
    if str.length(time_range) == 11
        // Format: hh:mm-hh:mm
        start_time_hour := math.floor(str.tonumber(str.substring(time_range, 0, 2)))
        start_time_minute := math.floor(str.tonumber(str.substring(time_range, 3, 5)))
        end_time_hour := math.floor(str.tonumber(str.substring(time_range, 6, 8)))
        end_time_minute := math.floor(str.tonumber(str.substring(time_range, 9, 11)))
    else if str.length(time_range) == 9
        // Format: hhmm-hhmm
        start_time_hour := math.floor(str.tonumber(str.substring(time_range, 0, 2)))
        start_time_minute := math.floor(str.tonumber(str.substring(time_range, 2, 4)))
        end_time_hour := math.floor(str.tonumber(str.substring(time_range, 5, 7)))
        end_time_minute := math.floor(str.tonumber(str.substring(time_range, 7, 9)))
    start_unix_time := timestamp(timezone, year(date_time, timezone), month(date_time, timezone), dayofmonth(date_time, timezone), start_time_hour, start_time_minute, 0)
    end_unix_time := timestamp(timezone, year(date_time, timezone), month(date_time, timezone), dayofmonth(date_time, timezone), end_time_hour, end_time_minute, 0)
    [start_unix_time, end_unix_time]

p_comm_time_range_to_start_unix_time(string time_range, int date_time = time, string timezone = syminfo.timezone) =>
    int start_time_hour = na
    int start_time_minute = na
    if str.length(time_range) == 11
        // Format: hh:mm-hh:mm
        start_time_hour := math.floor(str.tonumber(str.substring(time_range, 0, 2)))
        start_time_minute := math.floor(str.tonumber(str.substring(time_range, 3, 5)))
    else if str.length(time_range) == 9
        // Format: hhmm-hhmm
        start_time_hour := math.floor(str.tonumber(str.substring(time_range, 0, 2)))
        start_time_minute := math.floor(str.tonumber(str.substring(time_range, 2, 4)))
    timestamp(timezone, year(date_time, timezone), month(date_time, timezone), dayofmonth(date_time, timezone), start_time_hour, start_time_minute, 0)

p_comm_time_range_to_end_unix_time(string time_range, int date_time = time, string timezone = syminfo.timezone) =>
    int end_time_hour = na
    int end_time_minute = na
    if str.length(time_range) == 11
        end_time_hour := math.floor(str.tonumber(str.substring(time_range, 6, 8)))
        end_time_minute := math.floor(str.tonumber(str.substring(time_range, 9, 11)))
    else if str.length(time_range) == 9
        end_time_hour := math.floor(str.tonumber(str.substring(time_range, 5, 7)))
        end_time_minute := math.floor(str.tonumber(str.substring(time_range, 7, 9)))
    timestamp(timezone, year(date_time, timezone), month(date_time, timezone), dayofmonth(date_time, timezone), end_time_hour, end_time_minute, 0)

p_comm_timeframe_to_seconds(simple string tf) =>
    float seconds = 0
    tf_lower = str.lower(tf)
    value = str.tonumber(str.substring(tf_lower, 0, str.length(tf_lower) - 1))
    if str.endswith(tf_lower, 's')
        seconds := value
    else if str.endswith(tf_lower, 'd')
        seconds := value * 86400
    else if str.endswith(tf_lower, 'w')
        seconds := value * 604800
    else if str.endswith(tf_lower, 'm')
        seconds := value * 2592000
    else
        seconds := str.tonumber(tf_lower) * 60
    seconds

p_custom_sources() =>
    [open, high, low, close, volume]

//#endregion —————————————————————————————————————————————————————————————————


//#region —————————————————————————————————————————————————— Ta Dependence


//#endregion —————————————————————————————————————————————————————————————


//#region —————————————————————————————————————————————————— Constants

// Input Groups
string P_GP_1      =      ""

//#endregion —————————————————————————————————————————————————————————


//#region —————————————————————————————————————————————————— Inputs

// Default
int p_inp_1        =      input.int(defval=20, title="Fast EMA Length", group=P_GP_1)
int p_inp_2        =      input.int(defval=50, title="Slow EMA Length", group=P_GP_1)
float p_inp_3      =      input.float(defval=1.3, title="Take Profit Price Multiplier", group=P_GP_1, step=0.01)
float p_inp_4      =      input.float(defval=0.95, title="Stop Loss Price Multiplier", group=P_GP_1, step=0.01)


//#endregion ———————————————————————————————————————————————————————


//#region —————————————————————————————————————————————————— Price Data



//#endregion ———————————————————————————————————————————————————————————


//#region —————————————————————————————————————————————————— Indicators

p_ind_1      =      ta.ema(close, p_inp_1) // Fast EMA
p_ind_2      =      ta.ema(close, p_inp_2) // Slow EMA


//#endregion ———————————————————————————————————————————————————————————


//#region —————————————————————————————————————————————————— Conditions

p_cond_1      =      (ta.crossover(p_ind_1, p_ind_2))


//#endregion ———————————————————————————————————————————————————————————


//#region —————————————————————————————————————————————————— Strategy

// Strategy Order Variables
string p_st_name_1                       =      "Entry"
string p_st_name_2                       =      "Exit"
var float p_st_name_2_tp                 =      na
var bool p_st_name_2_tp_can_drawing      =      true
var float p_st_name_2_sl                 =      na
var bool p_st_name_2_sl_can_drawing      =      true

// Strategy Global
open_trades_number = strategy.opentrades
pre_bar_open_trades_number = na(open_trades_number[1]) ? 0 : open_trades_number[1]
var p_entry_order_id = 1
p_can_place_entry_order() =>
    strategy.equity > 0
get_entry_id_name(int current_order_id, string name) =>
    "[" + str.tostring(current_order_id) + "] " + name
is_entry_order(string order_id, string name) =>
    str.startswith(order_id, "[") and str.endswith(order_id, "] " + name)
get_open_trades_entry_ids() =>
    int p_open_trades_count = strategy.opentrades
    string[] p_entry_ids = array.new_string(0, "")
    if p_open_trades_count > 0
        for i = 0 to p_open_trades_count - 1
            array.push(p_entry_ids, strategy.opentrades.entry_id(i))
    p_entry_ids

// Entry (Entry)
if p_cond_1 and p_can_place_entry_order()
    p_st_name_1_id = get_entry_id_name(p_entry_order_id, p_st_name_1)
    p_entry_order_id := p_entry_order_id + 1
    string entry_message = ""
    strategy.entry(id=p_st_name_1_id, direction=strategy.long, alert_message=entry_message, comment=p_st_name_1_id)
    
    // TP/SL Exit (Exit)
    float p_st_name_2_limit = close * p_inp_3
    if p_st_name_2_tp_can_drawing
        p_st_name_2_tp_can_drawing := false
        p_st_name_2_tp := p_st_name_2_limit
    float p_st_name_2_stop = close * p_inp_4
    if p_st_name_2_sl_can_drawing
        p_st_name_2_sl_can_drawing := false
        p_st_name_2_sl := p_st_name_2_stop
    string p_st_name_2_alert_message = ""
    strategy.exit(id=p_st_name_1_id + "_0", from_entry=p_st_name_1_id, qty_percent=100, limit=p_st_name_2_limit, stop=p_st_name_2_stop, comment_profit=p_st_name_2 + " - TP", comment_loss=p_st_name_2 + " - SL", alert_message=p_st_name_2_alert_message)
    

if high >= p_st_name_2_tp or (pre_bar_open_trades_number > 0 and open_trades_number == 0)
    p_st_name_2_tp_can_drawing := true
    p_st_name_2_sl_can_drawing := true
    p_st_name_2_tp := na
    p_st_name_2_sl := na
plot(p_st_name_2_tp, title="Exit - TP", color=color.rgb(0, 150, 136, 0), linewidth=1, style = plot.style_circles)
if low <= p_st_name_2_sl or (pre_bar_open_trades_number > 0 and open_trades_number == 0)
    p_st_name_2_sl_can_drawing := true
    p_st_name_2_tp_can_drawing := true
    p_st_name_2_sl := na
    p_st_name_2_tp := na
plot(p_st_name_2_sl, title="Exit - SL", color=color.rgb(244, 67, 54, 0), linewidth=1, style = plot.style_circles)
//#endregion —————————————————————————————————————————————————————————


//#region —————————————————————————————————————————————————— Indicator Plots

// Fast EMA
plot(p_ind_1, "Fast EMA", color.rgb(33, 150, 243, 0), 1)

// Slow EMA
plot(p_ind_2, "Slow EMA", color.rgb(255, 82, 82, 0), 1)

//#endregion ————————————————————————————————————————————————————————————————


//#region —————————————————————————————————————————————————— Custom Plots

//#endregion —————————————————————————————————————————————————————————————


//#region —————————————————————————————————————————————————— Alert

//#endregion ——————————————————————————————————————————————————————



Có liên quan

Thêm nữa