
Chiến lược này sử dụng hai thiết lập tham số khác nhau để hoạt động chéo giữa các trung bình di chuyển, mở và đóng vị trí tùy thuộc vào hướng xu hướng của tín hiệu chéo. Chiến lược cho phép lựa chọn 9 loại trung bình di chuyển khác nhau, bao gồm trung bình di chuyển đơn giản (SMA), trung bình di chuyển chỉ số (EMA), trung bình di chuyển trọng số (WMA), trung bình di chuyển Almo (ALMA), trung bình di chuyển giá trị số (VWMA) và nhiều hơn nữa. Chiến lược đồng thời thiết lập điểm dừng lỗ và điểm dừng.
Lập luận cốt lõi của chiến lược này là so sánh giá trị của hai đường trung bình di chuyển để đánh giá xu hướng thị trường dựa trên sự giao nhau của hai đường trung bình di chuyển. Cụ thể, chúng tôi đặt hai đường trung bình di chuyển, đường nhanh và đường chậm. Khi đường nhanh đi qua đường chậm, cho rằng thị trường đi vào xu hướng tăng, làm nhiều hơn; khi đường nhanh đi qua đường chậm, cho rằng thị trường đi vào xu hướng giảm, làm trống.
Sau khi vào vị trí, nếu giá chạm đến đường dừng lỗ thì thua lỗ và thoát khỏi vị trí; nếu giá chạm đến đường dừng lỗ thì lợi nhuận đạt được mong đợi và thoát khỏi vị trí. Như vậy, bạn có thể khóa lợi nhuận và ngăn chặn tổn thất mở rộng.
Theo logic của mã, chiến lược này bao gồm bốn phần:
Tính trung bình di chuyển. Tính trung bình di chuyển của đường nhanh và đường chậm được tính theo loại trung bình di chuyển mà người dùng chọn.
Tạo tín hiệu giao dịch. Dựa trên sự giao thoa của đường nhanh và đường chậm, tạo ra tín hiệu giao dịch nhiều và ngắn.
Thiết lập điểm dừng lỗ. Tính toán giá của đường dừng lỗ và đường dừng lỗ trong thời gian thực dựa trên giá khởi điểm và tỷ lệ phần trăm dừng lỗ.
Bước vào và bước ra. Bước vào theo tín hiệu làm nhiều và làm trống, bước ra theo tín hiệu dừng lỗ.
Ưu điểm lớn nhất của chiến lược này là có thể tự do lựa chọn nhiều loại moving average khác nhau. Các loại moving average khác nhau có độ nhạy với giá khác nhau, người dùng có thể chọn moving average phù hợp với nhu cầu của mình. Ngoài ra, có thể tùy chỉnh độ dài của moving average, để tối ưu hóa chiều thời gian.
Một lợi thế khác là thiết lập một cơ chế dừng lỗ. Điều này có thể ngăn chặn hiệu quả các tổn thất mở rộng hơn nữa, đồng thời khóa lợi nhuận. Nhìn chung, chiến lược này là linh hoạt, có thể tùy chỉnh cao, phù hợp với người dùng có nhu cầu khác nhau.
Rủi ro chính của chiến lược này là các trung bình di chuyển có độ trễ. Khi giá đột ngột biến động mạnh, trung bình di chuyển không thể phản ứng kịp thời, có thể dẫn đến việc bỏ lỡ thời điểm vào hoặc ra sân tốt nhất.
Một rủi ro khác là thiết lập vị trí dừng lỗ. Nếu thiết lập quá nhỏ, có thể sẽ bị mạo hiểm; Nếu quá lớn, có thể dẫn đến lợi nhuận bị khóa không kịp thời. Vì vậy, trong thực tế, hãy tối ưu hóa tham số dừng lỗ theo tình hình thị trường.
Nói chung, chiến lược này dựa chủ yếu vào đường trung bình di chuyển để xác định xu hướng, vì vậy hiệu quả sẽ bị giảm giá khi sự kiện bất ngờ dẫn đến biến động giá lớn. Ngoài ra, cài đặt tham số cũng có ảnh hưởng lớn đến lợi nhuận của chiến lược.
Chiến lược này có thể được tối ưu hóa theo các khía cạnh sau:
Loại trung bình di chuyển được tối ưu hóa. Chọn trung bình di chuyển phù hợp hơn cho các môi trường thị trường khác nhau và các loại giao dịch.
Các tham số để tối ưu hóa các trung bình di chuyển. Điều chỉnh độ dài của trung bình di chuyển để phù hợp hơn với các đặc điểm của thị trường.
Thêm bộ lọc các chỉ số khác. Bạn có thể tham gia các chỉ số khác như MACD, RSI để tránh giao dịch thường xuyên trong thị trường không có xu hướng.
Tối ưu hóa tỷ lệ dừng lỗ. Tính toán tham số dừng lỗ tối ưu dựa trên dữ liệu lịch sử.
Thêm mô hình học máy. Sử dụng các thuật toán như LSTM, rừng ngẫu nhiên để dự đoán biến động giá, hỗ trợ tạo tín hiệu giao dịch.
Sử dụng thuật toán theo dõi dừng. Cho phép đường dừng di chuyển theo xu hướng giá, giảm khả năng dừng được kích hoạt.
Chiến lược này nói chung là đơn giản, trực tiếp, theo hướng xu hướng thông qua đánh giá chéo, thuộc chiến lược theo xu hướng điển hình. Ưu điểm là đơn giản, dễ hiểu, linh hoạt cao, có thể tự chọn loại trung bình di chuyển và tham số. Ưu điểm là phản ứng chậm đối với sự kiện bất ngờ, tồn tại một mức độ trì trệ.
/*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)