Chín loại chiến lược chéo trung bình động

Tác giả:ChaoZhang, Ngày: 2024-01-02 10:37:21
Tags:

img

Tổng quan

Chiến lược này sử dụng hai đường trung bình động với các thiết lập tham số khác nhau cho các hoạt động chéo để xác định hướng xu hướng và các vị trí mở / đóng. Chiến lược cho phép lựa chọn từ 9 loại đường trung bình động khác nhau, bao gồm đường trung bình động đơn giản (SMA), đường trung bình động nhân tố (EMA), đường trung bình động cân (WMA), đường trung bình động Arnaud Legoux (ALMA), đường trung bình động cân khối lượng (VWMA), v.v. Chiến lược cũng thiết lập mức dừng lỗ và lấy lợi nhuận.

Chiến lược logic

Lý thuyết cốt lõi của chiến lược này là so sánh các giá trị của hai đường trung bình động và xác định hướng xu hướng thị trường dựa trên sự chéo chéo của chúng. Cụ thể, chúng tôi thiết lập một đường nhanh và một đường chậm bằng cách sử dụng hai đường trung bình động. Khi đường nhanh vượt qua trên đường chậm, chúng tôi tin rằng thị trường đang có xu hướng tăng và đi dài. Khi đường nhanh vượt qua dưới đường chậm, chúng tôi tin rằng thị trường đang có xu hướng giảm và đi ngắn.

Sau khi nhập vào một vị trí, nếu giá chạm vào đường dừng lỗ, chúng tôi thoát khỏi vị trí để cắt giảm lỗ. Nếu giá chạm vào đường lấy lợi nhuận, chúng tôi thoát khỏi vị trí để khóa lợi nhuận như mong đợi. Điều này cho phép chúng tôi khóa lợi nhuận và ngăn chặn lỗ mở rộng hơn nữa.

Từ logic mã, chiến lược có thể được chia thành bốn phần:

  1. Tính toán các đường trung bình động. Dựa trên lựa chọn của người dùng về loại đường trung bình động, tính toán đường trung bình động nhanh và đường chậm.

  2. Tạo tín hiệu giao dịch. Tạo tín hiệu dài và ngắn dựa trên tình huống chéo của đường nhanh và đường chậm.

  3. Đặt mức dừng lỗ và lấy lợi nhuận. Dựa trên giá nhập cảnh và tỷ lệ phần trăm dừng lỗ / lấy lợi nhuận, tính toán mức dừng lỗ và lấy lợi nhuận trong thời gian thực.

  4. Nhập và thoát. Nhập dựa trên tín hiệu dài / ngắn, thoát dựa trên tín hiệu dừng lỗ / lấy lợi nhuận.

Phân tích lợi thế

Lợi thế lớn nhất của chiến lược này là nó cho phép tự do lựa chọn từ nhiều loại đường trung bình động. Các loại đường trung bình động khác nhau có độ nhạy khác nhau với giá cả. Người dùng có thể chọn đường trung bình động phù hợp dựa trên nhu cầu của riêng họ. Ngoài ra, chiều dài của đường trung bình động có thể được tùy chỉnh để tối ưu hóa chiều dài thời gian.

Một lợi thế khác là các cơ chế dừng lỗ và lấy lợi nhuận được thiết lập. Điều này có thể ngăn chặn hiệu quả các lỗ tiếp theo và khóa lợi nhuận. Nhìn chung, chiến lược này khá linh hoạt với khả năng tùy biến cao, phù hợp với người dùng có nhu cầu khác nhau.

Phân tích rủi ro

Rủi ro chính của chiến lược này là các đường trung bình động bị tụt hậu. Khi giá đột nhiên biến động mạnh mẽ, đường trung bình động không thể phản ứng kịp thời, có thể dẫn đến việc bỏ lỡ thời gian vào hoặc ra tốt nhất. Điều này có thể dẫn đến tổn thất lớn.

Một rủi ro khác là việc thiết lập mức dừng lỗ và lấy lợi nhuận. Nếu phạm vi quá nhỏ, nó có thể dễ bị tổn thương đối với các nhà đầu tư. Nếu quá lớn, rất dễ thất bại trong việc khóa lợi nhuận kịp thời. Do đó, các thông số dừng lỗ / lấy lợi nhuận cần được tối ưu hóa theo điều kiện thị trường trong giao dịch trực tiếp.

Nói chung, chiến lược này chủ yếu dựa trên đường trung bình động để xác định hướng xu hướng. Vì vậy, hiệu quả của nó có thể bị ảnh hưởng khi các sự kiện đột ngột gây ra biến động giá lớn. Ngoài ra, cài đặt tham số cũng có thể có tác động lớn đến lợi nhuận chiến lược.

Hướng dẫn 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. Tối ưu hóa loại đường trung bình động. Chọn đường trung bình động phù hợp hơn dựa trên môi trường thị trường và các sản phẩm giao dịch khác nhau.

  2. Tối ưu hóa các thông số trung bình động. Điều chỉnh chiều dài trung bình động để phù hợp hơn với các đặc điểm của thị trường.

  3. Thêm các chỉ số khác để lọc. MACD, RSI và các chỉ số khác có thể được thêm để tránh giao dịch thường xuyên khi không có xu hướng rõ ràng.

  4. Tối ưu hóa tỷ lệ dừng lỗ / lấy lợi nhuận. Tính toán các thông số dừng lỗ / lấy lợi nhuận tối ưu dựa trên dữ liệu lịch sử.

  5. Thêm các mô hình học máy. Sử dụng LSTM, thuật toán rừng ngẫu nhiên để dự đoán chuyển động giá và hỗ trợ trong việc tạo ra tín hiệu giao dịch.

  6. Sử dụng các thuật toán dừng lỗ sau. Cho phép đường dừng lỗ di chuyển cùng với các biến động giá dần dần để giảm khả năng bị đánh.

Kết luận

Nhìn chung, chiến lược này tương đối đơn giản và thẳng thắn. Nó xác định hướng xu hướng thông qua giao thoa và thuộc về một chiến lược theo xu hướng điển hình. Những lợi thế là dễ hiểu và linh hoạt cao với các loại và tham số trung bình động có thể tùy chỉnh. Những nhược điểm là phản ứng chậm hơn đối với các sự kiện đột ngột và một mức độ chậm trễ. Nói chung, chiến lược này phù hợp với các nhà đầu tư tìm kiếm lợi nhuận ổn định dài hạn.


/*backtest
start: 2022-12-26 00:00:00
end: 2024-01-01 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

//@version=3
strategy("Kozlod - Yet Another Moving Average Cross Strategy", shorttitle="kozlod_yamacs", overlay = true)

// 
// author: Kozlod
// date: 2018-03-06
// 

////////////
// INPUTS //
////////////

ma_type      = input(title = "MA Type",          defval = "SMA", options = ['SMA', 'EMA', 'WMA', 'ALMA', 'VWMA', 'HMA', 'LSMA', 'SMMA', 'DEMA'])
short_ma_len = input(title = "Short MA Length",  defval = 5,     minval = 1)
short_ma_src = input(title = "Short MA Source",   defval = close)
long_ma_len  = input(title = "Long MA Length",   defval = 15,    minval = 2)
long_ma_src  = input(title = "Long MA Source",    defval = close)
alma_offset  = input(title = "ALMA Offset",     type = float,   defval = 0.85,  step = 0.01, minval = 0, maxval = 1)
alma_sigma   = input(title = "ALMA Sigma",      type = float,   defval = 6,     step = 0.01)
lsma_offset  = input(title = "LSMA Offset",      defval = 0,     step = 1)

sl_lev_perc  = input(title = "SL Level % (0 - Off)", type = float,   defval = 0,  minval = 0, step = 0.01)
pt_lev_perc  = input(title = "PT Level % (0 - Off)", type = float,   defval = 0,  minval = 0, step = 0.01)

// Set initial values to 0
short_ma = 0.0
long_ma  = 0.0

// Simple Moving Average (SMA)
if ma_type == 'SMA' 
    short_ma := sma(short_ma_src, short_ma_len)
    long_ma  := sma(long_ma_src,  long_ma_len)

// Exponential Moving Average (EMA)
if ma_type == 'EMA'
    short_ma := ema(short_ma_src, short_ma_len)
    long_ma  := ema(long_ma_src,  long_ma_len)

// Weighted Moving Average (WMA)
if ma_type == 'WMA'
    short_ma := wma(short_ma_src, short_ma_len)
    long_ma  := wma(long_ma_src,  long_ma_len)

// Arnaud Legoux Moving Average (ALMA)
if ma_type == 'ALMA'
    short_ma := alma(short_ma_src, short_ma_len,  alma_offset, alma_sigma)
    long_ma  := alma(long_ma_src,  long_ma_len,   alma_offset, alma_sigma)

// Hull Moving Average (HMA)
if ma_type == 'HMA'
    short_ma := wma(2*wma(short_ma_src, short_ma_len/2)-wma(short_ma_src, short_ma_len), round(sqrt(short_ma_len)))
    long_ma  := wma(2*wma(long_ma_src,  long_ma_len /2)-wma(long_ma_src,  long_ma_len),  round(sqrt(long_ma_len)))

// Volume-weighted Moving Average (VWMA)
if ma_type == 'VWMA'
    short_ma := vwma(short_ma_src, short_ma_len)
    long_ma  := vwma(long_ma_src,  long_ma_len)

// Least Square Moving Average (LSMA)
if ma_type == 'LSMA'
    short_ma := linreg(short_ma_src, short_ma_len, lsma_offset)
    long_ma  := linreg(long_ma_src,  long_ma_len,  lsma_offset)

// Smoothed Moving Average (SMMA)    
if ma_type == 'SMMA'
    short_ma := na(short_ma[1]) ? sma(short_ma_src, short_ma_len) : (short_ma[1] * (short_ma_len - 1) + short_ma_src) / short_ma_len
    long_ma  := na(long_ma[1])  ? sma(long_ma_src,  long_ma_len)  : (long_ma[1]  * (long_ma_len  - 1) + long_ma_src)  / long_ma_len

// Double Exponential Moving Average (DEMA)
if ma_type == 'DEMA'
    e1_short = ema(short_ma_src, short_ma_len)
    e1_long  = ema(long_ma_src,  long_ma_len)
    
    short_ma := 2 * e1_short - ema(e1_short, short_ma_len)
    long_ma  := 2 * e1_long  - ema(e1_long,  long_ma_len)

/////////////
// SIGNALS //
/////////////

long_signal  = crossover( short_ma, long_ma)
short_signal = crossunder(short_ma, long_ma)

// Calculate PT/SL levels 
// Initial values 
last_signal    = 0
prev_tr_price  = 0.0
pt_level       = 0.0
sl_level       = 0.0

// Calculate previous trade price
prev_tr_price := long_signal[1] or short_signal[1] ? open : nz(last_signal[1]) != 0 ? prev_tr_price[1] : na

// Calculate SL/PT levels 
pt_level := nz(last_signal[1]) == 1 ? prev_tr_price * (1 + pt_lev_perc / 100) : nz(last_signal[1]) == -1 ? prev_tr_price * (1 - pt_lev_perc / 100)  : na
sl_level := nz(last_signal[1]) == 1 ? prev_tr_price * (1 - sl_lev_perc / 100) : nz(last_signal[1]) == -1 ? prev_tr_price * (1 + sl_lev_perc / 100)  : na

// Calculate if price hit sl/pt 
long_hit_pt = pt_lev_perc > 0 and nz(last_signal[1]) ==  1 and close >= pt_level
long_hit_sl = sl_lev_perc > 0 and nz(last_signal[1]) ==  1 and close <= sl_level

short_hit_pt = pt_lev_perc > 0 and nz(last_signal[1]) ==  -1 and close <= pt_level
short_hit_sl = sl_lev_perc > 0 and nz(last_signal[1]) ==  -1 and close >= sl_level

// What is last active trade? 
last_signal := long_signal ? 1 : short_signal ? -1 : long_hit_pt or long_hit_sl or short_hit_pt or short_hit_sl ? 0 : nz(last_signal[1])

//////////////
// PLOTTING //
//////////////

// Plot MAs
plot(short_ma, color = red,   linewidth = 2)
plot(long_ma,  color = green, linewidth = 2)


// Plot Levels 
plotshape(prev_tr_price, style = shape.cross, color = gray, location  = location.absolute, size = size.small)


plotshape(sl_lev_perc > 0 ? sl_level : na, style = shape.cross, color = red,   location  = location.absolute, size = size.small)
plotshape(pt_lev_perc > 0 ? pt_level : na, style = shape.cross, color = green, location  = location.absolute, size = size.small)

//////////////
// STRATEGY //
//////////////

strategy.entry("long",  true,  when = long_signal)
strategy.entry("short", false, when = short_signal)

strategy.close("long",  when = long_hit_pt  or long_hit_sl)
strategy.close("short", when = short_hit_pt or short_hit_sl)

Thêm nữa