Chiến lược này kết hợp ba đường trung bình di chuyển phẳng, chỉ số tương đối mạnh (RSI) và chỉ số William để xác định xu hướng của giá cổ phiếu và tìm kiếm cơ hội vào khi xu hướng đảo ngược. Khi ba đường trung bình di chuyển chậm và nhanh lên (thấp) và RSI cao hơn (thấp hơn) 50 và có tín hiệu William đi xuống (lên), hãy làm nhiều hơn (không) đầu.
Chiến lược này sử dụng trung bình di chuyển trơn trong ba chu kỳ khác nhau, bao gồm đường nhanh, đường trung và đường chậm. Khi đường nhanh vượt qua đường trung, nó cho thấy giá cổ phiếu đang trong xu hướng tăng; khi đường nhanh vượt qua đường trung, nó cho thấy giá cổ phiếu đang trong xu hướng giảm.
Cụ thể, khi giá cổ phiếu đi vào xu hướng tăng, chiến lược này sẽ chờ đợi 5 điều kiện sau cùng được đáp ứng trước khi mở thêm vị thế:
Sau khi giá cổ phiếu đi vào xu hướng giảm, chiến lược sẽ chờ đợi 5 điều kiện sau cùng được đáp ứng trước khi mở lệnh shorting:
Sau khi thực hiện nhiều thời gian ngắn, chiến lược sẽ thiết lập điểm dừng lỗ và điểm dừng để kiểm soát rủi ro. Cụ thể, điểm dừng là một phần trăm nhất định của giá nhập cảnh và điểm dừng là giá sau khi giá nhập cảnh di chuyển theo hướng có lợi.
Kết hợp với nhiều chỉ số xác nhận nhập cảnh, có thể ngăn chặn hiệu quả phá vỡ giả. Ba đường thẳng xác định hướng xu hướng, chỉ số William nắm bắt tín hiệu đảo ngược, RSI lọc các biến động, cùng nhau nâng cao độ chính xác của nhập cảnh.
Thiết lập điểm dừng lỗ, bạn có thể kiểm soát tốt tỷ lệ lợi nhuận rủi ro cho mỗi đơn vị, do đó đảm bảo giao dịch có lợi nhuận lớn hơn giao dịch thua lỗ.
Chiến lược logic rõ ràng và dễ hiểu, thiết lập tham số hợp lý, phù hợp cho các nhà giao dịch ở mọi cấp độ.
Trong trường hợp dao động, chỉ số có thể phát ra tín hiệu sai, dẫn đến việc nhập không cần thiết. Bạn có thể lọc một số trường hợp dao động bằng cách tối ưu hóa các tham số của RSI.
Đường nhanh giữa các đường giao nhau có thể bị phá vỡ giả, nên được sử dụng cùng với các chỉ số khác. Có thể xem xét thêm chỉ số giao dịch.
Điểm dừng lỗ quá gần với giá vào có thể bị dừng và thiết lập điểm dừng lỗ cần được điều chỉnh ở vị trí thích hợp.
Các điểm dừng quá xa giá vé có thể không thể dừng vé ra khỏi vé và cần phải điều chỉnh điểm dừng ở vị trí phù hợp.
Có thể thử nghiệm các tổ hợp tham số của các chu kỳ khác nhau, tối ưu hóa các tham số của ba đường trung bình và RSI.
Các chỉ số khác có thể được thêm vào, chẳng hạn như chỉ số giao dịch, để đánh giá liệu giao dịch có nổi bật hay không trước khi đột phá.
Các thiết lập tham số của chiến lược này có thể được thử nghiệm theo các giống khác nhau.
Có thể vẽ đường cong lợi nhuận dựa trên kết quả kiểm tra lại và kiểm tra các thiết lập tham số dừng lỗ.
Bạn có thể thử mô phỏng giao dịch trước khi khởi động và tối ưu hóa các tham số.
Chiến lược này có logic rõ ràng, sử dụng các chỉ số kết hợp để vào và ra, có thể kiểm soát rủi ro hiệu quả. Có rất nhiều không gian để tối ưu hóa các tham số của chiến lược, bằng cách thử nghiệm các thiết lập tham số khác nhau, chiến lược này có thể trở thành một chiến lược giao dịch định lượng có lợi nhuận ổn định. Tuy nhiên, không có chiến lược nào có thể hoàn toàn tránh được tổn thất và yêu cầu các nhà giao dịch duy trì kỷ luật giao dịch.
/*backtest
start: 2023-08-28 00:00:00
end: 2023-09-27 00:00:00
period: 3h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//This script is a combination of 3 smoothed moving averages, and RSI. When moving averages are aligned upward (downward) and RSI is above (below) 50 and a down (up) William fractal appears, it enters long (short) position. Exiting from long and short entries are defined by StopLoss and TargetProfit.
//@version=5
strategy(title="3SmmaCrossUp + Fractal + RSI", overlay=true, default_qty_type=strategy.percent_of_equity, default_qty_value=100, currency=currency.USD, commission_type=strategy.commission.percent, commission_value=0.03)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////// inputs
// Global
src = input(close, title="Source")
stopLoss = input.float(defval = 0.1, title = "Stop Loss %", minval = 0, maxval=100, step = 0.1)
targetProfit = input.float(defval = 0.4, title = "Target Profit %", minval = 0, maxval=100, step = 0.1)
// Smooth Moving Average
fastSmmaLen = input.int(21, minval=1, title="Fast Length", group = "Smooth Moving Average")
midSmmaLen = input.int(50, minval=1, title="Mid Length",group = "Smooth Moving Average")
slowSmmaLen = input.int(200, minval=1, title="Slow Length",group = "Smooth Moving Average")
// RSI
rsiLen = input.int(defval=14, title="length", minval=1, maxval=1000, step=1, group="RSI")
// Fractals
n = input.int(title="Periods", defval=2, minval=2, group = "Fractals")
///////////////////////////////////////////////////////////////////////////////////////////////////////////////// initialization
var waitingFirstTradeInUpwardTrend = false
var waitingFirstTradeInDownwardTrend = false
///////////////////////////////////////////////////////////////////////////////////////////////////////////////// functions
smma(ma, src, len) =>
smma = 0.0
smma := na(smma[1]) ? ma : (smma[1] * (len - 1) + src) / len
smma
fractals(n, highs, lows) =>
// UpFractal
bool upflagDownFrontier = true
bool upflagUpFrontier0 = true
bool upflagUpFrontier1 = true
bool upflagUpFrontier2 = true
bool upflagUpFrontier3 = true
bool upflagUpFrontier4 = true
for i = 1 to n
upflagDownFrontier := upflagDownFrontier and (highs[n-i] < highs[n])
upflagUpFrontier0 := upflagUpFrontier0 and (highs[n+i] < highs[n])
upflagUpFrontier1 := upflagUpFrontier1 and (highs[n+1] <= highs[n] and highs[n+i + 1] < highs[n])
upflagUpFrontier2 := upflagUpFrontier2 and (highs[n+1] <= highs[n] and highs[n+2] <= highs[n] and highs[n+i + 2] < highs[n])
upflagUpFrontier3 := upflagUpFrontier3 and (highs[n+1] <= highs[n] and highs[n+2] <= highs[n] and highs[n+3] <= highs[n] and highs[n+i + 3] < highs[n])
upflagUpFrontier4 := upflagUpFrontier4 and (highs[n+1] <= highs[n] and highs[n+2] <= highs[n] and highs[n+3] <= highs[n] and highs[n+4] <= highs[n] and highs[n+i + 4] < highs[n])
flagUpFrontier = upflagUpFrontier0 or upflagUpFrontier1 or upflagUpFrontier2 or upflagUpFrontier3 or upflagUpFrontier4
upFractal = (upflagDownFrontier and flagUpFrontier)
// downFractal
bool downflagDownFrontier = true
bool downflagUpFrontier0 = true
bool downflagUpFrontier1 = true
bool downflagUpFrontier2 = true
bool downflagUpFrontier3 = true
bool downflagUpFrontier4 = true
for i = 1 to n
downflagDownFrontier := downflagDownFrontier and (lows[n-i] > lows[n])
downflagUpFrontier0 := downflagUpFrontier0 and (lows[n+i] > lows[n])
downflagUpFrontier1 := downflagUpFrontier1 and (lows[n+1] >= lows[n] and lows[n+i + 1] > lows[n])
downflagUpFrontier2 := downflagUpFrontier2 and (lows[n+1] >= lows[n] and lows[n+2] >= lows[n] and lows[n+i + 2] > lows[n])
downflagUpFrontier3 := downflagUpFrontier3 and (lows[n+1] >= lows[n] and lows[n+2] >= lows[n] and lows[n+3] >= lows[n] and lows[n+i + 3] > lows[n])
downflagUpFrontier4 := downflagUpFrontier4 and (lows[n+1] >= lows[n] and lows[n+2] >= lows[n] and lows[n+3] >= lows[n] and lows[n+4] >= lows[n] and lows[n+i + 4] > lows[n])
flagDownFrontier = downflagUpFrontier0 or downflagUpFrontier1 or downflagUpFrontier2 or downflagUpFrontier3 or downflagUpFrontier4
downFractal = (downflagDownFrontier and flagDownFrontier)
[upFractal, downFractal]
///////////////////////////////////////////////////////////////////////////////////////////////////////////////// calcs
[upFractal, downFractal] = fractals(n, high, low)
rsiIsHigh = ta.rsi(src, rsiLen) >= 50
slowMa = ta.sma(src, slowSmmaLen)
midMa = ta.sma(src, midSmmaLen)
fastMa = ta.sma(src, fastSmmaLen)
slowSmma = smma(slowMa ,src, slowSmmaLen)
midSmma = smma(midMa, src, midSmmaLen)
fastSmma = smma(fastMa, src, fastSmmaLen)
isFastSmmaUpward = ta.rising(fastSmma, 1)
isMidSmmaUpward = ta.rising(midSmma, 1)
isSlowSmmaUpward = ta.rising(slowSmma, 1)
isFastSmmaDownward = ta.falling(fastSmma, 1)
isMidSmmaDownward = ta.falling(midSmma, 1)
isSlowSmmaDownward = ta.falling(slowSmma, 1)
slowMovingAveragesAreUpward = isMidSmmaUpward and isSlowSmmaUpward
slowMovingAveragesAreDownward = isMidSmmaDownward and isSlowSmmaDownward
justEnteredUpwardTrend = ta.crossover(fastSmma, midSmma) ? true : false
justEnteredDownwardTrend = ta.crossunder(fastSmma, midSmma) ? true : false
waitingFirstTradeInUpwardTrend := justEnteredUpwardTrend == true ? true : (isFastSmmaDownward or isMidSmmaDownward or isSlowSmmaDownward ? false : waitingFirstTradeInUpwardTrend)
waitingFirstTradeInDownwardTrend := justEnteredDownwardTrend == true ? true : (isFastSmmaUpward or isMidSmmaUpward or isSlowSmmaUpward ? false : waitingFirstTradeInDownwardTrend)
priceCrossedOverSlowMa = ta.crossover(close, slowSmma)
priceCrossedUnderSlowMa = ta.crossunder(close, slowSmma)
enterLongCondition = barstate.isconfirmed and low > fastSmma and rsiIsHigh and (downFractal or priceCrossedOverSlowMa) and waitingFirstTradeInUpwardTrend and strategy.position_size == 0
enterShortCondition = barstate.isconfirmed and high < fastSmma and (not rsiIsHigh) and (upFractal or priceCrossedUnderSlowMa) and waitingFirstTradeInDownwardTrend and strategy.position_size == 0
///////////////////////////////////////////////////////////////////////////////////////////////////////////////// strategy
if(enterLongCondition)
strategy.entry(id="L", direction=strategy.long)
waitingFirstTradeInUpwardTrend := false
if(enterShortCondition)
strategy.entry(id="S", direction=strategy.short)
waitingFirstTradeInDownwardTrend := false
if(strategy.position_size > 0)
strategy.exit(id="EL", stop=strategy.position_avg_price * (1 - stopLoss/100), limit=strategy.position_avg_price * (1+targetProfit/100))
if(strategy.position_size < 0)
strategy.exit(id="ES", stop=strategy.position_avg_price * (1 + stopLoss/100), limit=strategy.position_avg_price * (1-targetProfit/100))
///////////////////////////////////////////////////////////////////////////////////////////////////////////////// plots
plot(series = slowSmma, title="Slow SMMA", linewidth=3)
plot(series = midSmma, title="Mid SMMA", linewidth=2)
plot(series = fastSmma, title="Fast SMMA", linewidth=1)
plotchar(series=rsiIsHigh, title='rsiIsHigh', char='')
plotchar(series=justEnteredUpwardTrend, title='justEnteredUpwardTrend', char='')
plotchar(series=justEnteredDownwardTrend, title='justEnteredDownwardTrend', char='')
plotchar(series=waitingFirstTradeInUpwardTrend, title='waitingFirstTradeInUpwardTrend', char='')
plotchar(series=waitingFirstTradeInDownwardTrend, title='waitingFirstTradeInDownwardTrend', char='')
plotchar(series=enterLongCondition, title='enterLongCondition' , char='')
plotchar(series=enterShortCondition, title='enterShortCondition' , char='')
plotshape(series=upFractal, title='upFractal', style=shape.triangleup, location=location.abovebar, color=#009688, size = size.tiny)
plotshape(series=downFractal, title='downFractal', style=shape.triangledown, location=location.belowbar, color=color.red, size = size.tiny)