
Chiến lược này là một hệ thống giao dịch định lượng dựa trên phân tích nhiều khung thời gian, sử dụng các chỉ số MACD, chỉ số RSI, đường trung bình VWAP và bộ lọc tỷ lệ biến động ATR để thực hiện giao dịch trên các khung thời gian 30 phút và 1 giờ. Chiến lược này hỗ trợ cả giao dịch mua bán và mua bán bằng cách xác nhận các tín hiệu giao dịch của các chỉ số kỹ thuật trong các khung thời gian khác nhau và kết hợp với các điều kiện biến động để lọc để cải thiện chất lượng giao dịch.
Nguyên tắc cốt lõi của chiến lược này là lọc các tín hiệu chất lượng thấp thông qua xác nhận đa điều kiện, bao gồm một số thành phần chính như sau:
Tín hiệu chéo MACD đa khung thời gian:
RSI mua quá bán quá:
Xác định vị trí giá VWAP kép:
Bộ lọc tỷ lệ dao động:
Cơ chế rút lui đa cấp:
Thông qua việc lọc và xác nhận các điều kiện đa tầng này, chiến lược nhằm mục đích bắt biến động trung hạn có định hướng rõ ràng, đồng thời lọc các tín hiệu chất lượng thấp, tăng tỷ lệ thắng và tỷ lệ thua lỗ.
Xác nhận khung thời gian đa dạngBằng cách kết hợp các tín hiệu trong khung thời gian 30 phút và 1 giờ, chiến lược có thể nhận biết tốt hơn các xu hướng thực và giảm tác động của các tín hiệu giả. Đặc biệt, tính năng xác nhận xu hướng MACD 1 giờ giúp tránh giao dịch ngược xu hướng.
Tính thích ứng biến độngBộ lọc tỷ lệ biến động ATR đảm bảo rằng chiến lược chỉ tham gia khi thị trường có đủ động lực và tránh giao dịch trong khu vực biến động thấp, điều này làm giảm nguy cơ biến động vùng chết.
Cơ chế rút lui linh hoạtChiến lược này bao gồm không chỉ dừng lỗ cố định mà còn có cơ chế thoát động dựa trên chỉ số đảo ngược, cho phép xuất hiện kịp thời và bảo vệ lợi nhuận khi giá chưa đạt đến mức dừng nhưng thị trường đã bắt đầu đảo ngược.
Xác định vị trí giá képYêu cầu giá nằm trên () hoặc dưới () hai khung thời gian VWAP, điều này xác nhận thêm động lực và hướng của giá, giảm bớt sự phá vỡ giả.
Kiểm soát rủi roChiến lược này có cơ chế dừng lỗ và quản lý vị trí (đặc biệt là 5% lợi nhuận tài khoản cho mỗi giao dịch), giúp kiểm soát lỗ hổng rủi ro cho mỗi giao dịch và bảo vệ vốn.
Thách thức tỷ lệ thắng thấpĐiều này là do việc lọc đa điều kiện, mặc dù cải thiện chất lượng tín hiệu, nhưng cũng làm giảm đáng kể tần suất giao dịch, dẫn đến số lượng mẫu nhỏ, có ý nghĩa thống kê hạn chế.
Độ nhạy tham sốChiến lược sử dụng nhiều tham số có thể điều chỉnh, bao gồm độ dài MACD, giá trị RSI, tham số bộ lọc ATR. Những thay đổi nhỏ trong các tham số này có thể có ảnh hưởng đáng kể đến hiệu suất của chiến lược và có nguy cơ tối ưu hóa quá mức.
Giới hạn của Stop Loss% cố định: Sử dụng cùng một tỷ lệ dừng ((1.5%) và dừng ((0.5%) cho tất cả các môi trường thị trường, có thể không phù hợp với các môi trường biến động khác nhau. Trong thị trường biến động cao, dừng có thể quá chặt chẽ; trong thị trường biến động thấp, dừng có thể quá xa.
Sự chậm trễ của nhiều khung thời gian: Sử dụng một khung thời gian dài hơn (ví dụ: 1 giờ) để xác nhận tín hiệu có thể gây ra sự chậm trễ, dẫn đến cơ hội nhập cảnh bị bỏ lỡ hoặc rút lui chậm.
Thiếu khả năng thích ứng với môi trường thị trườngChiến lược không bao gồm các cơ chế phân biệt các môi trường thị trường khác nhau (trend/shake) có thể không hoạt động tốt trong một số điều kiện thị trường.
Giải pháp:
Tối ưu hóa dừng động: Thay đổi tỷ lệ dừng cố định thành giá trị động dựa trên ATR, ví dụ sử dụng 1.5×ATR làm dừng và 3×ATR làm dừng. Điều này có thể làm cho chiến lược thích ứng tốt hơn với các môi trường thị trường khác nhau, cung cấp dừng thoải mái hơn trong thời gian biến động cao và thắt chặt mục tiêu dừng trong thời gian biến động thấp.
Phân loại môi trường thị trường: giới thiệu cơ chế nhận diện môi trường thị trường, phân biệt thị trường xu hướng và thị trường chấn động. Bạn có thể sử dụng ADX, băng thông Brin hoặc mối quan hệ của giá với trung bình di chuyển dài hạn để nhận biết trạng thái thị trường và điều chỉnh các tham số chiến lược theo đó hoặc thậm chí chuyển đổi logic giao dịch hoàn toàn.
Tối ưu hóa thời gian nhập cảnhChiến lược hiện tại: Việc nhập vào K-line hiện tại xảy ra ở MACD crossover, có thể phải đối mặt với điểm trượt hoặc trì hoãn thực hiện. Hãy xem xét nhập vào khi K-line tiếp theo mở sau khi xác nhận crossover, hoặc đặt giá giới hạn vào trong một khu vực giá cụ thể để có được giá thực hiện tốt hơn.
Bộ lọc thời gianTăng bộ lọc thời gian giao dịch, tránh các thời điểm giao dịch kém hiệu quả nhất định. Ví dụ, bạn có thể tránh giao dịch vào những thời điểm có thể có tính thanh khoản thấp hoặc biến động không đều, chẳng hạn như cuối giờ châu Á hoặc giờ giao dịch châu Âu - Mỹ.
Các tham số chỉ số tự điều chỉnhThiết kế các tham số của MACD, RSI và ATR để tự điều chỉnh dựa trên biến động thị trường gần đây hoặc tự điều chỉnh theo chu kỳ. Ví dụ: tham số MACD ngắn hơn có thể được sử dụng trong thị trường biến động cao và tham số dài hơn được sử dụng trong thị trường biến động thấp.
Tăng cường tín hiệuTạo hệ thống đánh giá cường độ cho tín hiệu nhập, đánh giá tín hiệu dựa trên nhiều yếu tố (như kích thước trục MACD, độ lệch RSI, khoảng cách VWAP, v.v.), chỉ thực hiện giao dịch với cường độ vượt quá ngưỡng nhất định, hoặc điều chỉnh kích thước vị trí tùy theo động lực cường độ tín hiệu.
Tăng cường học máyGhi chú: Tiến hành mô hình học máy để dự đoán các tín hiệu nào có khả năng tạo ra giao dịch có lợi nhuận hơn, xác định các kết hợp mô hình có giá trị nhất dựa trên mô hình đào tạo dữ liệu lịch sử. Điều này có thể cải thiện khả năng thích ứng và tỷ lệ chiến thắng của chiến lược.
Những hướng tối ưu hóa này nhằm cải thiện tính ổn định, khả năng thích ứng và hiệu suất lâu dài của chiến lược, trong khi vẫn giữ nguyên logic cốt lõi của nó. Thông qua những cải tiến này, chiến lược có thể đáp ứng tốt hơn với sự thay đổi của môi trường và điều kiện thị trường khác nhau.
Multi-Time Frame (MACD-RSI) - Chiến lược giao dịch qua tỷ lệ biến động chéo MACD-RSI là một hệ thống giao dịch toàn diện được thiết kế để xác định các cơ hội giao dịch chất lượng cao bằng cách kết hợp nhiều chỉ số kỹ thuật và tín hiệu từ nhiều khung thời gian. Điểm mạnh cốt lõi của chiến lược này nằm ở cơ chế xác nhận tín hiệu đa tầng và chức năng quản lý rủi ro được xây dựng, cho phép nó kiểm soát rủi ro trong khi nắm bắt biến động giá.
Mặc dù có những thách thức về tỷ lệ thắng thấp, chiến lược duy trì giá trị kỳ vọng tích cực bằng cách tăng thu nhập của giao dịch lợi nhuận trung bình. Hiệu suất chiến lược có thể được nâng cao hơn nữa bằng cách thực hiện các biện pháp tối ưu hóa được đề xuất, đặc biệt là các biện pháp dừng dừng động, phân loại môi trường thị trường và phân loại cường độ tín hiệu.
Chiến lược này phù hợp với các nhà giao dịch ngắn hạn và trung hạn, đặc biệt là những người tìm kiếm phương pháp giao dịch có hệ thống dựa trên phân tích kỹ thuật và coi trọng quản lý rủi ro. Cơ chế xác nhận đa điều kiện của chiến lược, mặc dù giảm tần suất giao dịch, nhưng nâng cao chất lượng của mỗi giao dịch, phù hợp với triết lý giao dịch “ít hơn là nhiều”, nhấn mạnh chất lượng chứ không phải số lượng.
Trong ứng dụng thực tế, khuyến nghị các nhà giao dịch thử nghiệm chiến lược này trước tiên trong môi trường mô phỏng, đặc biệt là thử nghiệm hiệu quả của các biện pháp tối ưu hóa, sau đó áp dụng một cách thận trọng cho giao dịch thực. Đồng thời, việc liên tục theo dõi các thay đổi trong điều kiện thị trường và điều chỉnh các tham số chiến lược khi thích hợp sẽ giúp duy trì hiệu suất ổn định lâu dài.
/*backtest
start: 2025-01-01 00:00:00
end: 2025-06-08 00:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"ETH_USDT"}]
*/
// This Pine Script® code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © GentlemanOfTrading
//@version=6
strategy(title = "ETH Day Trader", overlay = true, margin_long = 100, margin_short = 100, default_qty_type = strategy.percent_of_equity, default_qty_value = 5)
// ==== 1) USER INPUTS ====
// MACD/RSI lengths
fastLen = input.int(12, title="MACD Fast EMA Length", minval=1)
slowLen = input.int(26, title="MACD Slow EMA Length", minval=1)
signalLen = input.int(9, title="MACD Signal EMA Length", minval=1)
rsiLen = input.int(14, title="RSI Length", minval=1)
// RSI thresholds
rsiThreshLong30 = input.int(55, title="RSI30m > (Long)", minval=1, maxval=100)
rsiThreshShort30= input.int(45, title="RSI30m < (Short)", minval=1, maxval=100)
rsiThresh1h = input.int(50, title="RSI1h Threshold", minval=1, maxval=100)
// ATR filter (30m)
atrLen = input.int(14, title="ATR Length (30m)", minval=1)
atrMaLen = input.int(20, title="ATR MA Length (30m)", minval=1)
// Take Profit / Stop Loss (percent)
tpPerc = input.float(1.5, title="Take Profit (%)", minval=0.1) / 100
slPerc = input.float(0.5, title="Stop Loss (%)", minval=0.1) / 100
// Toggle whether to use 1h trend confirmation
use1hTrend = input.bool(true, title="Use 1h MACD Trend Confirmation?")
// ==== 2) FETCH INDICATORS ON 30m ====
// We assume this script is applied on a chart ≤ 30m (e.g. 15m or 5m),
// but if you apply it on a 30m chart it still works: security() with "30" just returns the same bar.
[macd30m, macdSig30m, _] = ta.macd(close, fastLen, slowLen, signalLen)
rsi30m = ta.rsi(close, rsiLen)
atr30m = ta.atr(atrLen)
// ==== 3) FETCH INDICATORS ON 1h & VWAPs via request.security() ====
// --- 1h MACD & RSI ---
[macd1h, macdSig1h, _] = request.security(syminfo.tickerid, "60", ta.macd(close, fastLen, slowLen, signalLen), lookahead=barmerge.lookahead_off)
rsi1h = request.security(syminfo.tickerid, "60", ta.rsi(close, rsiLen), lookahead=barmerge.lookahead_off)
// --- 30m VWAP & 1h VWAP (session VWAP) ---
vwap30m = request.security(syminfo.tickerid, "30", ta.vwap(close), lookahead=barmerge.lookahead_off)
vwap1h = request.security(syminfo.tickerid, "60", ta.vwap(close), lookahead=barmerge.lookahead_off)
// ==== 4) BUILD VOLATILITY FILTER (30m ATR vs ATR MA) ====
atr30m_ma = ta.sma(atr30m, atrMaLen)
volatilityOK = atr30m >= atr30m_ma
// ==== 5) MULTI-TIMEFRAME CROSS CONDITIONS ====
// 30m MACD cross signals
longCross30m = ta.crossover(macd30m, macdSig30m)
shortCross30m = ta.crossunder(macd30m, macdSig30m)
// 1h MACD trend confirmation
macdTrendUp1h = macd1h > macdSig1h
macdTrendDown1h = macd1h < macdSig1h
// ==== 6) ENTRY & EXIT CONDITIONS ====
// LONG ENTRY:
// • 30m MACD crossover
// • 30m RSI > rsiThreshLong30
// • (optionally) 1h MACD line > 1h MACD signal
// • Price > 30m VWAP AND Price > 1h VWAP
// • 30m ATR ≥ 30m ATR MA (volatility filter)
longEntryCond =
longCross30m
and (rsi30m > rsiThreshLong30)
and (close > vwap30m)
and (close > vwap1h)
and volatilityOK
and (use1hTrend ? macdTrendUp1h : true)
// LONG EXIT:
// • fixed TP/SL
// OR • 30m MACD crossunder
// OR • 1h MACD falls below signal (trend flipped)
var float entryPriceLong = na
longExitCond = false
if (strategy.position_size > 0)
// Price-based TP / SL checks
entryPriceLong := nz(entryPriceLong[1], strategy.position_avg_price)
longTPprice = entryPriceLong * (1 + tpPerc)
longSLprice = entryPriceLong * (1 - slPerc)
// check TP/SL first
longExitTP = high >= longTPprice
longExitSL = low <= longSLprice
// fallback: MACD crossunder on 30m OR 1h trend flips
macdTrendFlip1h = macdTrendUp1h and (macd1h < macdSig1h)
macdCross30m = shortCross30m
longExitCond := longExitTP or longExitSL or macdCross30m or macdTrendFlip1h
else
entryPriceLong := na // reset when no position
// SHORT ENTRY:
// • 30m MACD crossunder
// • 30m RSI < rsiThreshShort30
// • (optionally) 1h MACD line < 1h MACD signal
// • Price < 30m VWAP AND Price < 1h VWAP
// • 30m ATR ≥ 30m ATR MA (volatility filter)
shortEntryCond =
shortCross30m
and (rsi30m < rsiThreshShort30)
and (close < vwap30m)
and (close < vwap1h)
and volatilityOK
and (use1hTrend ? macdTrendDown1h : true)
// SHORT EXIT:
// • fixed TP/SL
// OR • 30m MACD crossover
// OR • 1h MACD flips up
var float entryPriceShort = na
shortExitCond = false
if (strategy.position_size < 0)
entryPriceShort := nz(entryPriceShort[1], strategy.position_avg_price)
shortTPprice = entryPriceShort * (1 - tpPerc)
shortSLprice = entryPriceShort * (1 + slPerc)
// check TP/SL first
shortExitTP = low <= shortTPprice
shortExitSL = high >= shortSLprice
macdTrendFlipUp1h = macdTrendDown1h and (macd1h > macdSig1h)
macdCrossUp30m = longCross30m
shortExitCond := shortExitTP or shortExitSL or macdCrossUp30m or macdTrendFlipUp1h
else
entryPriceShort := na // reset when no position
// ==== 7) EXECUTE STRATEGY ORDERS WITH LABELS & ALERTS ====
// — Long Entry —
if (longEntryCond and strategy.position_size == 0)
strategy.entry("Long", strategy.long)
label.new(bar_index, low, text="Buy (LT)", style=label.style_label_up, color=color.new(color.green, 0), textcolor=color.white, yloc=yloc.belowbar)
alert("Buy (LT)", alert.freq_once_per_bar_close)
// — Long Exit —
if (strategy.position_size > 0 and longExitCond)
strategy.close("Long")
label.new(bar_index, high, text="Sell (LT)", style=label.style_label_down, color=color.new(color.red, 0), textcolor=color.white, yloc=yloc.abovebar)
alert("Sell (LT)", alert.freq_once_per_bar_close)
// — Short Entry —
if (shortEntryCond and strategy.position_size == 0)
strategy.entry("Short", strategy.short)
label.new(bar_index, high, text="Sell (ST)", style=label.style_label_down, color=color.new(color.red, 0), textcolor=color.white, yloc=yloc.abovebar)
alert("Sell (ST)", alert.freq_once_per_bar_close)
// — Short Exit —
if (strategy.position_size < 0 and shortExitCond)
strategy.close("Short")
label.new(bar_index, low, text="Buy (ST)", style=label.style_label_up, color=color.new(color.green, 0), textcolor=color.white, yloc=yloc.belowbar)
alert("Buy (ST)", alert.freq_once_per_bar_close)
// ==== 8) OPTIONAL PLOTTING (for debugging) ====
// We’ve removed any `transp`/`opacity` arguments. Instead, we use `color.new(baseColor, α)`
// for transparency, where α = 0 is fully opaque and α = 255 is fully transparent.
// 30m VWAP
plot(vwap30m, title = "VWAP 30m", color = color.new(color.teal, 80)) // ~31% transparentlinewidth= 1
// 1h VWAP
plot(vwap1h, title = "VWAP 1h", color = color.new(color.fuchsia, 80), linewidth= 1) // ~31% transparent
// 30m ATR vs ATR_MA
plot(atr30m, title = "ATR 30m", color = color.new(color.orange, 80))
plot(atr30m_ma, title = "ATR30m MA", color = color.new(color.yellow, 80))
// 30m MACD Histogram (bars)
plot(macd30m - macdSig30m, title = "MACD Histogram (30m)", style = plot.style_columns, color = (macd30m - macdSig30m >= 0 ? color.new(color.green, 80) : color.new(color.red, 80)))
// 1h MACD Histogram (area)
h1 = request.security(syminfo.tickerid, "60", macd1h - macdSig1h, lookahead=barmerge.lookahead_off)
plot(1, title = "MACD Hist (1h)", style = plot.style_area, color = (h1 >= 0 ? color.new(color.green, 80) : color.new(color.red, 80)))