Chiến lược đảo ngược Hulk

Tác giả:ChaoZhang, Ngày: 2023-10-17 15:23:49
Tags:

img

Tổng quan

Hulk Pullback Reversal là một chiến lược sử dụng đường trung bình động, MACD, RSI và ADX để xác định sự đảo ngược xu hướng trong giai đoạn rút lui.

Chiến lược logic

Chiến lược sử dụng EMA để xác định hướng xu hướng tổng thể, cũng như xây dựng các vùng mạnh / yếu. Khi giá rút lui từ điểm mạnh sang điểm yếu, chiến lược xác định các cơ hội đảo ngược tiềm năng.

Để lọc các mục nhập sai, MACD được kết hợp để xác nhận các tín hiệu đảo ngược ngắn hạn. Khi giá trị tuyệt đối của MACD vượt quá ngưỡng nhất định, xác suất đảo ngược tăng lên. ADX cũng được yêu cầu ở trên một mức, đảm bảo thị trường đang có xu hướng chứ không phải là dao động.

Cuối cùng, chỉ số RSI hoạt động để tránh các vùng mua quá mức / bán quá mức.

Số lượng giao dịch được thiết lập lại trên mỗi giao dịch giao dịch EMA. Một giới hạn giao dịch tối đa cho mỗi giao dịch giao dịch cũng có thể được đặt, tránh giao dịch quá mức.

Khi các điều kiện được đáp ứng, các lệnh được đặt dựa trên tỷ lệ dừng lỗ và lấy lợi nhuận, để thực hiện giao dịch đảo ngược.

Phân tích lợi thế

Ưu điểm lớn nhất của chiến lược này là sử dụng EMA để xây dựng các vùng mạnh / yếu, tận dụng các mô hình rút lui.

So với các chỉ số dao động đơn, việc thêm xác định xu hướng giúp tránh sự đảo ngược không cần thiết. Kiểm soát các giao dịch tối đa trên đường chéo EMA cũng ngăn ngừa giao dịch quá mức.

Phân tích rủi ro

Rủi ro lớn nhất là khi người theo xu hướng không rút lui, phá vỡ EMA trực tiếp. Điều này sẽ tạo ra các tín hiệu sai và gây ra lỗ.

Các thông số chỉ số không chính xác cũng có thể làm suy giảm chất lượng tín hiệu. Các thông số cần phải được thử nghiệm nhiều lần và tối ưu hóa cho các điều kiện thị trường khác nhau.

Cuối cùng, việc dừng lỗ quá lớn và tiếp tục gây hấn sau khi đảo ngược có thể làm tăng lỗ giao dịch duy nhất.

Hướng dẫn tối ưu hóa

Chiến lược có thể được tối ưu hóa trong các khía cạnh sau:

  1. Kiểm tra các thị trường và tham số khác nhau để EMAs có thể đánh giá tốt hơn xu hướng.

  2. Tối ưu hóa các thông số MACD để có các tín hiệu đảo ngược chính xác và đáng tin cậy hơn.

  3. Điều chỉnh phạm vi chỉ số RSI để tránh mức mua/bán quá mạnh.

  4. Tối ưu hóa tỷ lệ dừng lỗ và lợi nhuận để giảm rủi ro giao dịch duy nhất.

Kết luận

Chiến lược đảo ngược pullback của Hulk đặc biệt nhắm mục tiêu vào các mô hình đảo ngược của những người theo xu hướng tích cực, nắm bắt hiệu quả các cơ hội đảo ngược ngắn hạn. Nó sử dụng EMA để lọc hướng xu hướng và sức mạnh nhiều lớp, với MACD, RSI để xác nhận nhập độ đáng tin cậy cao. Kiểm tra và tối ưu hóa tham số thích hợp cho phép thích nghi với môi trường thị trường khác nhau, làm cho nó trở thành một chiến lược đảo ngược xu hướng rất thực tế.


/*backtest
start: 2023-09-16 00:00:00
end: 2023-10-16 00:00:00
period: 3h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/

// This source code is subject to the terms of the Mozilla Public License 2.0 at https://mozilla.org/MPL/2.0/
// © npietronuto1

//@version=5
strategy("Hulk Scalper x35 Leverage", shorttitle = "Smash Pullback Strat", overlay=true, initial_capital=100, default_qty_type=strategy.percent_of_equity, default_qty_value=100)


//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//RSI
rsiLength = input.int(20)
RsiTopInput = input.int(2)
RsiBotInput = input.int(-2)

// toprsiLine = hline(RsiTopInput, title = "Rsi Top Line", linestyle = hline.style_solid)
// botrsiLine = hline(RsiBotInput, title = "Rsi Bottom Line", linestyle = hline.style_solid)

rsi = ta.rsi(close, rsiLength)
rsiWeighted = rsi - 50 //Zeros Rsi to look nicer


//------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
adxlen = input(14, title="ADX Smoothing")
dilen = input(14, title="DI Length")
dirmov(len) =>
	up = ta.change(high)
	down = -ta.change(low)
	plusDM = na(up) ? na : (up > down and up > 0 ? up : 0)
	minusDM = na(down) ? na : (down > up and down > 0 ? down : 0)
	truerange = ta.rma(ta.tr, len)
	plus = fixnan(100 * ta.rma(plusDM, len) / truerange)
	minus = fixnan(100 * ta.rma(minusDM, len) / truerange)
	[plus, minus]
adx(dilen, adxlen) =>
	[plus, minus] = dirmov(dilen)
	sum = plus + minus
	adx = 100 * ta.rma(math.abs(plus - minus) / (sum == 0 ? 1 : sum), adxlen)
sig = adx(dilen, adxlen)

ADXfilterlevel = input.int(33, title = "ADX filter amount")

// plot(sig, color=color.red, title="ADX")
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//MACD
FastMacdLength = input.int(12, group = "MACD") 
SlowMacdLength = input.int(26, group = "MACD")
SignalLength = input.int(11, group = "MACD")
MacdTickAmountNeeded = input.float(5.45, title = "Tick Amount for entry", group = "MACD")

res = input.timeframe("1", group = "MACD")


// bullishgrow_col = input.color(defval = #3179f5)
// bullishweaken_col = input.color(defval = #00e1ff)
// bearishweaken_col = input.color(defval = #ff01f1)
// bearishgrow_col = input.color(defval = #9d00e5)


[FastMacd, SlowMacd, Macdhist] = ta.macd(close, FastMacdLength, SlowMacdLength, SignalLength)

//Pull MACD from Lower timeframe
MACD = request.security(syminfo.tickerid, res, Macdhist, gaps = barmerge.gaps_on)


//Grow and Fall Color
// getgrow_fall_col(Value) =>
//     if Value >= 0
    
//         if Value >= Value[1]
//             color.new(bullishgrow_col, transp = 10)
            
//         else if Value <= Value[1]
//             color.new(bullishweaken_col, transp = 10)
            
//     else if Value <= 0
    
//         if Value <= Value[1]
//             color.new(bearishgrow_col, transp = 10)
            
//         else if Value >= Value[1]
//             color.new(bearishweaken_col, transp = 10)
            
    
    
//CONDITIONS that check if MACD is overbought or oversold
MACDisAboveBand = MACD > MacdTickAmountNeeded
MACDisBelowBand = MACD < MacdTickAmountNeeded*-1
    
    
    
//Plot
// plot(MACD, style = plot.style_columns, color = getgrow_fall_col(MACD))
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------






//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//EMAs
//Inputs
EmaFastLength = input.int(50, title = "Ema Fast Length")
EmaSlowLength = input.int(200, title = "Ema Slow Length")

StrongUpTrendCol = input.color(color.rgb(74, 255, 163))
//WeakUptrend = input.color(color.rgb(74, 255, 163, 50))
StrongDownTrendCol = input.color(color.rgb(255, 71, 84))
//WeakDownTrend = input.color(color.rgb(255, 71, 84, 50))

//Calculations


emaFast= ta.ema(close, EmaFastLength)

emaSlow= ta.ema(close, EmaSlowLength)

emaDist=emaFast-emaSlow
EmaLengthFraction = emaDist/4

emafrac5 = emaSlow + EmaLengthFraction
emafrac4 = emaSlow + EmaLengthFraction*2
emafrac3 = emaSlow + EmaLengthFraction*3
emafrac2 = emaSlow + EmaLengthFraction*4


UptrendCol_DowntrendCol= emaFast>=emaSlow ? StrongUpTrendCol:StrongDownTrendCol
//Plot
ema1p = plot(emaFast, color = color.new(#000000, transp = 100))
ema2p = plot(emafrac2, color = color.new(#000000, transp = 100))
ema3p = plot(emafrac3, color = color.new(#000000, transp = 100))
ema4p = plot(emafrac4, color = color.new(#000000, transp = 100))
ema5p = plot(emafrac5, color = color.new(#000000, transp = 100))
ema6p = plot(emaSlow, color = color.new(#000000, transp = 100))


fill(ema2p,ema3p, color = color.new(UptrendCol_DowntrendCol, 70))
fill(ema3p,ema4p, color = color.new(UptrendCol_DowntrendCol, 60))
fill(ema4p,ema5p, color = color.new(UptrendCol_DowntrendCol, 50))
fill(ema5p,ema6p, color = color.new(UptrendCol_DowntrendCol, 40))


//Conditons
FastEma_above_SlowEma = emaFast > emaSlow  
FastEma_below_SlowEma = emaFast < emaSlow

emaCrossEvent = ta.crossover(emaFast, emaSlow) or ta.crossover(emaSlow, emaFast)





//------------------------------------------------------------------------------------------------------------------------------------------------------------------------





//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//Trade Cap per EMA X
//Inputs
MaxTrades_PerCross_Checkbox = input.bool(true, "Limit Trades Per Cross", group = "Filters")



TrdCount = 0//Variable that keeps current trade count

if(TrdCount[1] > 0)//Passes variable on to current candle
    TrdCount := TrdCount[1]
    
    
//Reset trade count if EMAs X    
emaXevent = ta.crossover(emaFast, emaSlow) or ta.crossover(emaSlow, emaFast) // Check for EMA cross
if(emaXevent)
    TrdCount := 0
    

//Conditions
MaxTrades = input.int(6)

IsMaxTrades_BelowCap = TrdCount[1] < MaxTrades //Condition that applies max trade count

if(not MaxTrades_PerCross_Checkbox)
    IsMaxTrades_BelowCap := true
//------------------------------------------------------------------------------------------------------------------------------------------------------------------------




//------------------------------------------------------------------------------------------------------------------------------------------------------------------------
//STRATEGY LOGIC

//Parameters
TakeProfitInput = input.float(0.0135, title = "Take Profit %", group = "TP/SL")
StopLossInput = input.float(0.011, title = "Stop Loss %", group = "TP/SL")


//TP/SL calculations
Long_takeProfit = close * (1 + TakeProfitInput)
Long_stopLoss = close * (1 - StopLossInput)

Short_takeProfit = close * (1 - TakeProfitInput)
Short_stopLoss = close * (1 + StopLossInput)


//LONG and Short
LongConditionPt1 = close > emaSlow and MACDisBelowBand and  sig > ADXfilterlevel
LongConditionPt2 = FastEma_above_SlowEma and IsMaxTrades_BelowCap and strategy.position_size == 0
//Checks if Rsi Inbetween Lines
LongConditionPt3 = rsiWeighted < RsiTopInput and rsiWeighted > RsiBotInput



ShortConditionPt1 = close < emaSlow and MACDisAboveBand and sig > ADXfilterlevel
ShortConditionPt2 = FastEma_below_SlowEma and IsMaxTrades_BelowCap and strategy.position_size == 0
//Checks if Rsi Inbetween Lines
ShortConditionPt3 = rsiWeighted < RsiTopInput and rsiWeighted > RsiBotInput





// longCondition = FastEma_above_SlowEma and MACDisBelowBand and IsMaxTrades_BelowCap and rsiWeighted < RsiTopInput and strategy.position_size == 0
longCondition = LongConditionPt1 and LongConditionPt2 and LongConditionPt3
if(longCondition)

    strategy.entry("long", strategy.long)
    strategy.exit("exit", "long", limit = Long_takeProfit, stop = Long_stopLoss)
    
    TrdCount := TrdCount + 1//ADD to Max Trades Count
    
    alert("Go Long with TP at" + str.tostring(Long_takeProfit) + "and SL at" + str.tostring(Long_stopLoss), alert.freq_once_per_bar_close)





shortCondition = ShortConditionPt1 and ShortConditionPt2 and ShortConditionPt3
if(shortCondition )
    
    strategy.entry("short", strategy.short)
    strategy.exit("exit", "short", limit = Short_takeProfit, stop = Short_stopLoss)

    TrdCount := TrdCount + 1 //ADD to Max Trades Count
    
    alert("Go Short with TP at" + str.tostring(Short_takeProfit) + "and SL at" + str.tostring(Short_stopLoss), alert.freq_once_per_bar_close)


    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    
    


Thêm nữa