
Đừng tin tưởng vào một đường trung bình đơn hoặc RSI nữa. Chiến lược này tích hợp 8 hình dạng biểu đồ cổ điển: Long-legged Cross, Light-legged Sun / Cyan, Gaps, Tower Bottom, Holding Form and Matching Highs. Dữ liệu phản hồi cho thấy tỷ lệ thắng của các cặp đa hình thức cao hơn 35% so với một hình thức đơn, đó là lý do tại sao các nhà giao dịch trên Phố Wall sử dụng chiến lược kết hợp.
Lý luận cốt lõi của chiến lược đơn giản và thô sơ: tín hiệu đa đầu phải ở trên SMA50, tín hiệu đầu trống phải ở dưới SMA50. Thiết kế này trực tiếp lọc hầu hết các giao dịch ồn ào trong thị trường chấn động. Dữ liệu chứng minh rằng sau khi thêm bộ lọc xu hướng, sự rút lui tối đa của chiến lược giảm 42% và lợi nhuận sau khi điều chỉnh rủi ro tăng 1,8 lần.
Cài đặt dừng lỗ với 10 chu kỳ điểm thấp nhất / cao nhất, điều này khoa học hơn so với các điểm dừng cố định truyền thống. Các nhân ATR được thiết lập gấp 1,5 lần để nhận ra hình thức hiệu quả, đảm bảo chỉ bắt được hành vi giá có ý nghĩa thực sự. Các thí nghiệm cho thấy rằng bộ hệ thống dừng động này hoạt động tốt hơn 300% so với dừng cố định trong thời gian biến động cao.
Tỷ lệ lợi nhuận rủi ro mặc định của chiến lược là 2: 1, có nghĩa là mỗi đơn vị rủi ro 1 đơn vị, mục tiêu là 2 đơn vị lợi nhuận. Tỷ lệ chiến thắng 45% kết hợp với danh mục đa dạng, giá trị kỳ vọng toán học là tích cực 0.35, vượt xa giá trị kỳ vọng -0.1 của thị trường trung bình. Đó là sự hấp dẫn của giao dịch định lượng: kiếm tiền bằng xác suất toán học, chứ không phải nhờ vào may mắn.
Mỗi hình dạng có một định nghĩa toán học nghiêm ngặt, chẳng hạn như đường chân ánh sáng đầu đèn yêu cầu thực thể chiếm hơn 90% của toàn bộ đường K, và đường bóng trên và dưới không quá 5%. Định nghĩa chính xác này đảm bảo độ tin cậy của tín hiệu.
Chiến lược đặt số lượng giao dịch đồng thời tối đa là 1, thiết kế này có vẻ bảo thủ, thực sự là cốt lõi của quản lý rủi ro. Các số liệu thống kê cho thấy, việc giữ nhiều vị trí có liên quan cao cùng một lúc sẽ làm tăng rủi ro hệ thống gấp 2,5 lần. Thà bỏ lỡ cơ hội và không để tài khoản chịu lỗ hổng rủi ro không cần thiết.
Chiến lược này hoạt động tốt nhất trong thị trường xu hướng một chiều, đặc biệt là trong tình huống đột phá. Tuy nhiên, trong thời gian dao động ngang, do phụ thuộc vào bộ lọc xu hướng, có thể bỏ lỡ một số cơ hội đảo ngược.
Dấu hiệu nguy cơLịch sử không thể hiện lợi nhuận trong tương lai, có nguy cơ mất mát liên tục. Hiệu suất khác nhau trong các môi trường thị trường khác nhau là đáng kể, cần quản lý quỹ và kiểm soát rủi ro nghiêm ngặt.
/*backtest
start: 2024-11-11 00:00:00
end: 2025-11-11 00:00:00
period: 1h
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=5
strategy("Candlestick Combo Strategy - [CLEVER]", overlay=true, initial_capital=100000)
// === User Inputs
sma_len = input.int(50, "SMA Length", minval=1)
atr_len = input.int(14, "ATR Length", minval=1)
atr_mult = input.float(1.5, "ATR Multiplier for pattern size", step=0.1)
rr = input.float(2.0, "Risk:Reward", step=0.1)
maxOpenTrades = input.int(1, "Max concurrent open trades", minval=1)
// === Indicators / Trend Filter
sma50 = ta.sma(close, sma_len)
myATR = ta.atr(atr_len)
uptrend = close > sma50
downtrend = close < sma50
// === Helper: Safe indexing
hasHistory(bars) =>
bar_index >= bars
// === Candlestick Patterns ===
// Long-Legged Doji
isLongLeggedDoji() =>
if not hasHistory(1)
false
else
candleBody = math.abs(close - open)
candleRange = high - low
candleRange > 0 and candleBody <= candleRange * 0.20 and
(high - math.max(open, close)) >= candleRange * 0.40 and
(math.min(open, close) - low) >= candleRange * 0.40
// Bullish Marubozu
isBullishMarubozu() =>
if not hasHistory(1)
false
else
body = close - open
candleRange = high - low
candleRange > 0 and body > 0 and body >= candleRange * 0.90 and
(high - close) <= candleRange * 0.05 and
(open - low) <= candleRange * 0.05
// Bearish Marubozu
isBearishMarubozu() =>
if not hasHistory(1)
false
else
body = open - close
candleRange = high - low
candleRange > 0 and body > 0 and body >= candleRange * 0.90 and
(open - high) <= candleRange * 0.05 and
(close - low) <= candleRange * 0.05
// Rising Window (gap up)
isRisingWindow() =>
if not hasHistory(1)
false
else
open > high[1] and close > open and close[1] > open[1]
// Falling Window (gap down)
isFallingWindow() =>
if not hasHistory(1)
false
else
open < low[1] and close < open and close[1] < open[1]
// Tower Bottom
isTowerBottom() =>
if not hasHistory(4)
false
else
largeBear = (open[4] - close[4]) > myATR * atr_mult
smallBase = true
for i = 3 to 1
smallBase := smallBase and ((high[i] - low[i]) < (open[4] - close[4]) * 0.5)
largeBull = (close > open) and ((close - open) > myATR * atr_mult)
largeBear and smallBase and largeBull
// Mat Hold
isMatHold() =>
if not hasHistory(4)
false
else
firstBullSize = (close[4] - open[4])
longBull = firstBullSize > myATR * atr_mult
gapUp = open[3] > high[4]
smallConsol = true
for i = 3 to 1
smallConsol := smallConsol and ((high[i] - low[i]) < firstBullSize * 0.3) and low[i] > low[4]
finalBull = (close > open) and ((close - open) > firstBullSize * 0.8)
longBull and gapUp and smallConsol and finalBull
// Matching High
isMatchingHigh() =>
if not hasHistory(2)
false
else
bullish1 = close[2] > open[2]
bullish2 = close[1] > open[1]
sameHigh = math.abs(high[2] - high[1]) <= myATR * 0.10
gapDown = open[1] < close[2]
bullish1 and bullish2 and sameHigh and gapDown
// === Trade Conditions
longSignal = uptrend and (isMatHold() or isTowerBottom() or isRisingWindow() or isBullishMarubozu())
shortSignal = downtrend and (isMatchingHigh() or isFallingWindow() or isBearishMarubozu() or isLongLeggedDoji())
// Plot signals on chart
plotshape(longSignal, title="Long Signal", style=shape.triangleup, location=location.belowbar, color=color.new(color.lime, 0), size=size.tiny)
plotshape(shortSignal, title="Short Signal", style=shape.triangledown, location=location.abovebar, color=color.new(color.red, 0), size=size.tiny)
// === Entry / Exit Logic with maxOpenTrades gating
canEnter() =>
strategy.opentrades < maxOpenTrades
if (longSignal and canEnter())
stopLevel = ta.lowest(low, 10)
risk = close - stopLevel
target = close + risk * rr
strategy.entry("Long", strategy.long)
strategy.exit("Exit Long", "Long", stop=stopLevel, limit=target)
if (shortSignal and canEnter())
stopLevel = ta.highest(high, 10)
risk = stopLevel - close
target = close - risk * rr
strategy.entry("Short", strategy.short)
strategy.exit("Exit Short", "Short", stop=stopLevel, limit=target)