
Chiến lược này sử dụng chỉ số Hall để xác định hướng xu hướng, sau đó kết hợp với chỉ số ngẫu nhiên để nhập vào. Khi Hall đi qua đường ray trung tâm, hãy nhìn vào và khi đi qua, hãy nhìn vào. Trong khi đó, khi chỉ số ngẫu nhiên K đường đi qua D đường từ khu vực mua quá mức, đi qua khu vực bán quá mức.
Chiến lược giao dịch này chủ yếu sử dụng chỉ số Hall để xác định xu hướng của thị trường, sau đó sử dụng chỉ số ngẫu nhiên để nhập vào cụ thể.
Đầu tiên, chiến lược xác định phương pháp tính toán cho chỉ số Hall, bao gồm công thức tính toán cho đường trung đạo, đường trên và đường dưới. Đường trung đạo được tính bằng phương tiện di chuyển có trọng lượng WMA, đường trên và đường dưới là độ lệch của đường trung đạo.
Sau đó, dựa trên mối quan hệ giữa đường trục trung tâm và đường trục trên và dưới, đánh giá hướng xu hướng. Khi đường trục trung tâm đi qua đường trục dưới, đại diện cho giá mua mạnh hơn, thuộc xu hướng đi chệch; khi đường trục trung tâm đi qua đường trục dưới, giá bán mạnh hơn, thuộc xu hướng đi chệch.
Ngoài ra, chiến lược cũng xác định các phương pháp tính toán cho các chỉ số ngẫu nhiên, bao gồm các công thức tính toán cho các giá trị K và D. Các giá trị K được sử dụng để làm mỏng SMA của RSI, và giá trị D là một lần nữa làm mỏng SMA của giá trị K.
Sau khi đánh giá hướng của xu hướng, nếu đốm, khi đường K của chỉ số ngẫu nhiên đi qua đường D từ dưới vùng bán tháo; nếu đốm, khi đường K đi qua đường D từ vùng mua tháo.
Bằng cách này, kết hợp các phán đoán xu hướng của chỉ số Hall và phán đoán mua quá mức của chỉ số ngẫu nhiên, có thể đưa ra các bước vào ổn định và chính xác hơn.
Ưu điểm lớn nhất của chiến lược này là kết hợp phán đoán xu hướng và phán đoán mua quá mức, có thể phân tích nhiều chiều về thị trường, có độ chính xác cao hơn.
Trong đó, có một số ưu điểm:
Chỉ số Hall có thể xác định hiệu quả xu hướng thị trường và định vị ở cấp độ lớn;
Các chỉ số ngẫu nhiên đánh giá quá mua quá bán, giúp nắm bắt được sự thay đổi của lực lượng mua và bán, nắm bắt thời điểm tốt nhất để vào thị trường;
Các tín hiệu được xác thực bởi nhau và giảm tín hiệu giả.
Khả năng thích ứng linh hoạt với các giống và chu kỳ thời gian khác nhau thông qua điều chỉnh tham số;
Sử dụng lệch đường giữa để tạo ra các kênh giao dịch trên và dưới đường ray, có thể tìm thấy hỗ trợ và kháng cự tiềm năng.
STOP LOSS, EXIT ON TARGETS percent used to scale positions Điều chỉnh lệnh lớn
Use of hull data Dictionary gives multiple asset class flexibility
Các hướng tối ưu hóa được chọn có thể giúp tăng sự ổn định và lợi nhuận của chiến lược
Chiến lược này cũng có một số rủi ro cần lưu ý, chủ yếu là:
Chỉ số Hall có thể bị tụt hậu, có thể bỏ lỡ điểm chuyển hướng, dẫn đến tổn thất không cần thiết.
Cài đặt tham số chỉ số ngẫu nhiên không đúng có thể tạo ra tín hiệu dư thừa, nên lọc đúng tín hiệu chéo của đường K và đường D.
Chỉ số Hall được sử dụng cùng với chỉ số ngẫu nhiên, và nếu tham số không phù hợp, có thể có tín hiệu sai.
Kích thước đường ray quá lớn hoặc quá nhỏ có thể ảnh hưởng đến chất lượng tín hiệu giao dịch và cần được kiểm tra kỹ lưỡng để tìm các tham số tối ưu.
Các chỉ số đường trung và đường dài có thể không hiệu quả.
Data mismatches between hull and stoch causing false signals
Sharp trend changes not caught by hull can cause losses
Testing on more timeframes/symbols needed to verify robustness
Những rủi ro này có thể được tối ưu hóa bằng cách:
Giảm chiều dài của chỉ số Hall một cách thích hợp để tăng độ nhạy cảm với sự thay đổi xu hướng.
Tối ưu hóa các tham số của chỉ số ngẫu nhiên, giảm tín hiệu giả.
Điều chỉnh các tham số trên và dưới đường ray để tìm ra đường thông rộng tối ưu.
Thêm các tín hiệu xác nhận chỉ số khác, chẳng hạn như MACD.
Thêm chiến lược dừng lỗ để kiểm soát rủi ro.
Chiến lược này cũng có thể được tối ưu hóa theo các khía cạnh sau:
Thử nghiệm nhiều giống hơn và nhiều tham số chu kỳ thời gian hơn để xác minh sự ổn định của chiến lược.
Tăng các cơ chế dừng lỗ. Các cơ chế này có thể kiểm soát rủi ro tốt hơn, chẳng hạn như dừng lỗ theo dõi, dừng di chuyển.
Tối ưu hóa logic điều kiện nhập cảnh, thiết lập các điều kiện lọc nghiêm ngặt hơn, giảm tín hiệu giả.
Nghiên cứu cách sử dụng kênh chỉ số Hall để xác định tốt hơn các điểm hỗ trợ và kháng cự.
Khám phá các tín hiệu xác thực có thể được thêm vào các chỉ số khác.
Tối ưu hóa tham số. Tối ưu hóa các tham số như chiều dài chỉ số Hall, chỉ số ngẫu nhiên K, D, v.v.
Thêm chức năng quản lý vị trí. Điều chỉnh kích thước vị trí dựa trên số lần rút và chiến thắng liên tiếp.
Thêm luật dừng lỗ, dừng chân.
Optimize hull length parameter for better trend sensitivity
Add additional filters or confirming indicators to improve signal quality
Explore using hull bands to identify dynamic support/resistance levels
Parameter optimization for stoch RSI lengths, overbought/oversold levels
Introduce better position sizing and risk management rules
Nhìn chung, chiến lược này kết hợp phán đoán xu hướng và phán đoán mua bán quá mức để nhập vào thị trường là một ý tưởng hiệu quả. Tuy nhiên, do các chỉ số tự có vấn đề, tín hiệu giao dịch của nó cũng không hoàn toàn đáng tin cậy và cần được tối ưu hóa hơn nữa.
/*backtest
start: 2023-10-16 00:00:00
end: 2023-10-17 00:00:00
period: 5m
basePeriod: 1m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=4
//Basic Hull Ma Pack tinkered by InSilico
//Converted to Strategy by DashTrader
strategy("Hull Suite + Stoch RSI Strategy v1.1", overlay=true, pyramiding=1, initial_capital=100, default_qty_type= strategy.percent_of_equity, default_qty_value = 100, calc_on_order_fills=false, slippage=0,commission_type=strategy.commission.percent,commission_value=0.023)
strat_dir_input = input(title="Strategy Direction", defval="all", options=["long", "short", "all"])
strat_dir_value = strat_dir_input == "long" ? strategy.direction.long : strat_dir_input == "short" ? strategy.direction.short : strategy.direction.all
strategy.risk.allow_entry_in(strat_dir_value)
//////////////////////////////////////////////////////////////////////
// Testing Start dates
testStartYear = input(2016, "Backtest Start Year")
testStartMonth = input(1, "Backtest Start Month")
testStartDay = input(1, "Backtest Start Day")
testPeriodStart = timestamp(testStartYear,testStartMonth,testStartDay,0,0)
//Stop date if you want to use a specific range of dates
testStopYear = input(2030, "Backtest Stop Year")
testStopMonth = input(12, "Backtest Stop Month")
testStopDay = input(30, "Backtest Stop Day")
testPeriodStop = timestamp(testStopYear,testStopMonth,testStopDay,0,0)
stoch_upper_input = input(88, "Stoch Upper Threshold", type=input.float)
stoch_lower_input = input(5, "Stoch Lower Threshold", type=input.float)
sl = input(0.7, "SL %", type=input.float, step=0.1)
tp = input(2.1, "TP %", type=input.float, step=0.1)
// slowEMA = ema(close, slowEMA_input)
// vwap = vwap(close)
// rsi = rsi(close, rsi_input)
// stoch rsi
smoothK = 3
smoothD = 3
lengthRSI = 14
lengthStoch = 14
rsi1 = rsi(close, 14)
k = sma(stoch(rsi1, rsi1, rsi1, lengthStoch), smoothK)
d = sma(k, smoothD)
testPeriod() =>
time >= testPeriodStart and time <= testPeriodStop ? true : false
// Component Code Stop
//////////////////////////////////////////////////////////////////////
//INPUT
src = input(close, title="Source")
modeSwitch = input("Hma", title="Hull Variation", options=["Hma", "Thma", "Ehma"])
length = input(180, title="Length(180-200 for floating S/R , 55 for swing entry)")
switchColor = input(true, "Color Hull according to trend?")
candleCol = input(false,title="Color candles based on Hull's Trend?")
visualSwitch = input(true, title="Show as a Band?")
thicknesSwitch = input(1, title="Line Thickness")
transpSwitch = input(40, title="Band Transparency",step=5)
//FUNCTIONS
//HMA
HMA(_src, _length) => wma(2 * wma(_src, _length / 2) - wma(_src, _length), round(sqrt(_length)))
//EHMA
EHMA(_src, _length) => ema(2 * ema(_src, _length / 2) - ema(_src, _length), round(sqrt(_length)))
//THMA
THMA(_src, _length) => wma(wma(_src,_length / 3) * 3 - wma(_src, _length / 2) - wma(_src, _length), _length)
//SWITCH
Mode(modeSwitch, src, len) =>
modeSwitch == "Hma" ? HMA(src, len) :
modeSwitch == "Ehma" ? EHMA(src, len) :
modeSwitch == "Thma" ? THMA(src, len/2) : na
//OUT
HULL = Mode(modeSwitch, src, length)
MHULL = HULL[0]
SHULL = HULL[2]
//COLOR
hullColor = switchColor ? (HULL > HULL[2] ? #00ff00 : #ff0000) : #ff9800
//PLOT
///< Frame
Fi1 = plot(MHULL, title="MHULL", color=hullColor, linewidth=thicknesSwitch, transp=50)
Fi2 = plot(visualSwitch ? SHULL : na, title="SHULL", color=hullColor, linewidth=thicknesSwitch, transp=50)
///< Ending Filler
fill(Fi1, Fi2, title="Band Filler", color=hullColor, transp=transpSwitch)
///BARCOLOR
barcolor(color = candleCol ? (switchColor ? hullColor : na) : na)
bgcolor(color = k < stoch_lower_input and crossover(k, d) ? color.green : na)
bgcolor(color = d > stoch_upper_input and crossover(d, k) ? color.red : na)
notInTrade = strategy.position_size == 0
if notInTrade and HULL[0] > HULL[2] and testPeriod() and k < stoch_lower_input and crossover(k, d)
// if HULL[0] > HULL[2] and testPeriod()
stopLoss = close * (1 - sl / 100)
profit25 = close * (1 + (tp / 100) * 0.25)
profit50 = close * (1 + (tp / 100) * 0.5)
takeProfit = close * (1 + tp / 100)
strategy.entry("long", strategy.long, alert_message="buy")
strategy.exit("exit long 25%", "long", stop=stopLoss, limit=profit25, qty_percent=25, alert_message="profit_25")
strategy.exit("exit long 50%", "long", stop=stopLoss, limit=profit50, qty_percent=25, alert_message="profit_50")
strategy.exit("exit long", "long", stop=stopLoss, limit=takeProfit)
// line.new(bar_index, profit25, bar_index + 4, profit25, color=color.green)
// line.new(bar_index, profit50, bar_index + 4, profit50, color=color.green)
// box.new(bar_index, stopLoss, bar_index + 4, close, border_color=color.red, bgcolor=color.new(color.red, 80))
// box.new(bar_index, close, bar_index + 4, takeProfit, border_color=color.green, bgcolor=color.new(color.green, 80))
if notInTrade and HULL[0] < HULL[2] and testPeriod() and d > stoch_upper_input and crossover(d, k)
// if HULL[0] < HULL[2] and testPeriod()
stopLoss = close * (1 + sl / 100)
profit25 = close * (1 - (tp / 100) * 0.25)
profit50 = close * (1 - (tp / 100) * 0.5)
takeProfit = close * (1 - tp / 100)
strategy.entry("short", strategy.short, alert_message="sell")
strategy.exit("exit short 25%", "short", stop=stopLoss, limit=profit25, qty_percent=25, alert_message="profit_25")
strategy.exit("exit short 50%", "short", stop=stopLoss, limit=profit50, qty_percent=25, alert_message="profit_50")
strategy.exit("exit short", "short", stop=stopLoss, limit=takeProfit)
// line.new(bar_index, profit25, bar_index + 4, profit25, color=color.green)
// line.new(bar_index, profit50, bar_index + 4, profit50, color=color.green)
// box.new(bar_index, stopLoss, bar_index + 4, close, border_color=color.red, bgcolor=color.new(color.red, 80))
// box.new(bar_index, close, bar_index + 4, takeProfit, border_color=color.green, bgcolor=color.new(color.green, 80))
// var table winrateDisplay = table.new(position.bottom_right, 1, 1)
// table.cell(winrateDisplay, 0, 0, "Winrate: " + tostring(strategy.wintrades / strategy.closedtrades * 100, '#.##')+" %", text_color=color.white)