Một chiến lược giao dịch định lượng sử dụng hệ thống EMA để xác định hướng xu hướng, chỉ số ADX để xác định sức mạnh xu hướng và kết hợp lọc khối lượng giao dịch cho nhập cảnh
Chiến lược này đầu tiên sử dụng 5 EMA của các giai đoạn khác nhau để đánh giá hướng xu hướng giá. Khi tất cả 5 EMA tăng, nó được đánh giá là hình thành xu hướng tăng. Khi tất cả 5 EMA giảm, nó được đánh giá là hình thành xu hướng giảm.
Sau đó, nó sử dụng chỉ số ADX để đánh giá sức mạnh của xu hướng. Khi đường DI + cao hơn đường DI và giá trị ADX vượt quá ngưỡng đặt, nó được đánh giá là xu hướng tăng mạnh. Khi đường DI cao hơn đường DI + và giá trị ADX vượt quá ngưỡng đặt, nó được đánh giá là xu hướng giảm.
Đồng thời, các bước đột phá trong khối lượng giao dịch được sử dụng để xác nhận bổ sung, yêu cầu khối lượng giao dịch của dòng K hiện tại lớn hơn một số lần số trung bình trong một khoảng thời gian, do đó tránh các mục nhập sai trong các vị trí khối lượng thấp.
Kết hợp với đánh giá toàn diện về hướng xu hướng, sức mạnh xu hướng và khối lượng giao dịch, logic mở dài và ngắn của chiến lược này được hình thành.
Sử dụng một hệ thống EMA để đánh giá hướng xu hướng là đáng tin cậy hơn một EMA duy nhất.
Sử dụng chỉ số ADX để đánh giá sức mạnh của xu hướng tránh các mục sai khi không có xu hướng rõ ràng.
Cơ chế lọc khối lượng giao dịch đảm bảo hỗ trợ khối lượng giao dịch đầy đủ và tăng độ tin cậy của chiến lược.
Thẩm phán toàn diện nhiều điều kiện làm cho tín hiệu mở chính xác và đáng tin cậy hơn.
Số lượng các tham số chiến lược tương đối lớn cho phép cải thiện hiệu suất thông qua tối ưu hóa tham số liên tục.
Trong thị trường giới hạn phạm vi, EMA, ADX và các phán quyết khác có thể đưa ra tín hiệu sai, dẫn đến tổn thất không cần thiết. Các tham số có thể được điều chỉnh thích hợp hoặc các chỉ số khác có thể được thêm để phán quyết phụ.
Các điều kiện lọc khối lượng giao dịch có thể quá nghiêm ngặt, bỏ lỡ cơ hội thị trường.
Tần suất giao dịch được tạo ra bởi chiến lược có thể tương đối cao.
Kiểm tra các kết hợp tham số khác nhau để tìm các tham số tối ưu để cải thiện hiệu suất chiến lược.
Thêm các chỉ số khác như MACD, KDJ để kết hợp với EMA và ADX để tạo ra một đánh giá vị trí mở toàn diện mạnh mẽ hơn.
Thêm các chiến lược dừng lỗ để kiểm soát rủi ro hơn nữa.
Tối ưu hóa các chiến lược quản lý vị trí để đạt được quản lý vốn khoa học hơn.
Bằng cách xem xét toàn diện hướng xu hướng giá, sức mạnh xu hướng và thông tin khối lượng giao dịch, chiến lược này hình thành các quy tắc mở để tránh một số cái bẫy phổ biến ở một mức độ nào đó và có độ tin cậy tương đối mạnh.
/*backtest start: 2022-11-28 00:00:00 end: 2023-12-04 00:00:00 period: 1d basePeriod: 1h 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/ // © BabehDyo //@version=4 strategy("EMA/ADX/VOL-CRYPTO KILLER [15M]", overlay = true, pyramiding=1,initial_capital = 10000, 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.03) //SOURCE ============================================================================================================================================================================================================================================================================================================= src = input(open, title=" Source") // Inputs ======================================================================================================================================================================================================================================================================================================== //ADX -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ADX_options = input("MASANAKAMURA", title=" Adx Type", options = ["CLASSIC", "MASANAKAMURA"], group="ADX") ADX_len = input(21, title=" Adx Length", type=input.integer, minval = 1, group="ADX") th = input(20, title=" Adx Treshold", type=input.float, minval = 0, step = 0.5, group="ADX") //EMA-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Length_ema1 = input(8, title=" 1-EMA Length", minval=1) Length_ema2 = input(13, title=" 2-EMA Length", minval=1) Length_ema3 = input(21, title=" 3-EMA Length", minval=1) Length_ema4 = input(34, title=" 4-EMA Length", minval=1) Length_ema5 = input(55, title=" 5-EMA Length", minval=1) // Range Filter --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- per_ = input(15, title=" Period", minval=1, group = "Range Filter") mult = input(2.6, title=" mult.", minval=0.1, step = 0.1, group = "Range Filter") // Volume ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ volume_f = input(3.2, title=" Volume mult.", minval = 0, step = 0.1, group="Volume") sma_length = input(20, title=" Volume lenght", minval = 1, group="Volume") volume_f1 = input(1.9, title=" Volume mult. 1", minval = 0, step = 0.1, group="Volume") sma_length1 = input(22, title=" Volume lenght 1", minval = 1, group="Volume") //TP PLOTSHAPE ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- tp_long0 = input(0.9, title=" % TP Long", type = input.float, minval = 0, step = 0.1, group="Target Point") tp_short0 = input(0.9, title=" % TP Short", type = input.float, minval = 0, step = 0.1, group="Target Point") // SL PLOTSHAPE --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- sl0 = input(4.2, title=" % Stop loss", type = input.float, minval = 0, step = 0.1, group="Stop Loss") //INDICATORS ======================================================================================================================================================================================================================================================================================================= //ADX------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- calcADX(_len) => up = change(high) down = -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 = rma(tr, _len) _plus = fixnan(100 * rma(plusDM, _len) / truerange) _minus = fixnan(100 * rma(minusDM, _len) / truerange) sum = _plus + _minus _adx = 100 * rma(abs(_plus - _minus) / (sum == 0 ? 1 : sum), _len) [_plus,_minus,_adx] calcADX_Masanakamura(_len) => SmoothedTrueRange = 0.0 SmoothedDirectionalMovementPlus = 0.0 SmoothedDirectionalMovementMinus = 0.0 TrueRange = max(max(high - low, abs(high - nz(close[1]))), abs(low - nz(close[1]))) DirectionalMovementPlus = high - nz(high[1]) > nz(low[1]) - low ? max(high - nz(high[1]), 0) : 0 DirectionalMovementMinus = nz(low[1]) - low > high - nz(high[1]) ? max(nz(low[1]) - low, 0) : 0 SmoothedTrueRange := nz(SmoothedTrueRange[1]) - (nz(SmoothedTrueRange[1]) /_len) + TrueRange SmoothedDirectionalMovementPlus := nz(SmoothedDirectionalMovementPlus[1]) - (nz(SmoothedDirectionalMovementPlus[1]) / _len) + DirectionalMovementPlus SmoothedDirectionalMovementMinus := nz(SmoothedDirectionalMovementMinus[1]) - (nz(SmoothedDirectionalMovementMinus[1]) / _len) + DirectionalMovementMinus DIP = SmoothedDirectionalMovementPlus / SmoothedTrueRange * 100 DIM = SmoothedDirectionalMovementMinus / SmoothedTrueRange * 100 DX = abs(DIP-DIM) / (DIP+DIM)*100 adx = sma(DX, _len) [DIP,DIM,adx] [DIPlusC,DIMinusC,ADXC] = calcADX(ADX_len) [DIPlusM,DIMinusM,ADXM] = calcADX_Masanakamura(ADX_len) DIPlus = ADX_options == "CLASSIC" ? DIPlusC : DIPlusM DIMinus = ADX_options == "CLASSIC" ? DIMinusC : DIMinusM ADX = ADX_options == "CLASSIC" ? ADXC : ADXM L_adx = DIPlus > DIMinus and ADX > th S_adx = DIPlus < DIMinus and ADX > th //EMA----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- xPrice = close EMA1 = ema(xPrice, Length_ema1) EMA2 = ema(xPrice, Length_ema2) EMA3 = ema(xPrice, Length_ema3) EMA4 = ema(xPrice, Length_ema4) EMA5 = ema(xPrice, Length_ema5) L_ema = EMA1 < close and EMA2 < close and EMA3 < close and EMA4 < close and EMA5 < close S_ema = EMA1 > close and EMA2 > close and EMA3 > close and EMA4 > close and EMA5 > close // Range Filter ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- var bool L_RF = na, var bool S_RF = na Range_filter(_src, _per_, _mult)=> var float _upward = 0.0 var float _downward = 0.0 wper = (_per_*2) - 1 avrng = ema(abs(_src - _src[1]), _per_) _smoothrng = ema(avrng, wper)*_mult _filt = _src _filt := _src > nz(_filt[1]) ? ((_src-_smoothrng) < nz(_filt[1]) ? nz(_filt[1]) : (_src-_smoothrng)) : ((_src+_smoothrng) > nz(_filt[1]) ? nz(_filt[1]) : (_src+_smoothrng)) _upward := _filt > _filt[1] ? nz(_upward[1]) + 1 : _filt < _filt[1] ? 0 : nz(_upward[1]) _downward := _filt < _filt[1] ? nz(_downward[1]) + 1 : _filt > _filt[1] ? 0 : nz(_downward[1]) [_smoothrng,_filt,_upward,_downward] [smoothrng, filt, upward, downward] = Range_filter(src, per_, mult) hband = filt + smoothrng lband = filt - smoothrng L_RF := high > hband and upward > 0 S_RF := low < lband and downward > 0 // Volume ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Volume_condt = volume > sma(volume,sma_length)*volume_f Volume_condt1 = volume > sma(volume,sma_length1)*volume_f1 //STRATEGY ========================================================================================================================================================================================================================================================================================================== var bool longCond = na, var bool shortCond = na var int CondIni_long = 0, var int CondIni_short = 0 var bool _Final_longCondition = na, var bool _Final_shortCondition = na var float last_open_longCondition = na, var float last_open_shortCondition = na var int last_longCondition = na, var int last_shortCondition = na var int last_Final_longCondition = na, var int last_Final_shortCondition = na var int nLongs = na, var int nShorts = na L_1 = L_adx and Volume_condt and L_RF and L_ema S_1 = S_adx and Volume_condt and S_RF and S_ema L_2 = L_adx and L_RF and L_ema and Volume_condt1 S_2 = S_adx and S_RF and S_ema and Volume_condt1 L_basic_condt = L_1 or L_2 S_basic_condt = S_1 or S_2 longCond := L_basic_condt shortCond := S_basic_condt CondIni_long := longCond[1] ? 1 : shortCond[1] ? -1 : nz(CondIni_long[1] ) CondIni_short := longCond[1] ? 1 : shortCond[1] ? -1 : nz(CondIni_short[1] ) longCondition = (longCond[1] and nz(CondIni_long[1]) == -1 ) shortCondition = (shortCond[1] and nz(CondIni_short[1]) == 1 ) //POSITION PRICE----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- var float sum_long = 0.0, var float sum_short = 0.0 var float Position_Price = 0.0 last_open_longCondition := longCondition ? close[1] : nz(last_open_longCondition[1] ) last_open_shortCondition := shortCondition ? close[1] : nz(last_open_shortCondition[1] ) last_longCondition := longCondition ? time : nz(last_longCondition[1] ) last_shortCondition := shortCondition ? time : nz(last_shortCondition[1] ) in_longCondition = last_longCondition > last_shortCondition in_shortCondition = last_shortCondition > last_longCondition last_Final_longCondition := longCondition ? time : nz(last_Final_longCondition[1] ) last_Final_shortCondition := shortCondition ? time : nz(last_Final_shortCondition[1] ) nLongs := nz(nLongs[1] ) nShorts := nz(nShorts[1] ) if longCondition nLongs := nLongs + 1 nShorts := 0 sum_long := nz(last_open_longCondition) + nz(sum_long[1]) sum_short := 0.0 if shortCondition nLongs := 0 nShorts := nShorts + 1 sum_short := nz(last_open_shortCondition)+ nz(sum_short[1]) sum_long := 0.0 Position_Price := nz(Position_Price[1]) Position_Price := longCondition ? sum_long/nLongs : shortCondition ? sum_short/nShorts : na //TP--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- var bool long_tp = na, var bool short_tp = na var int last_long_tp = na, var int last_short_tp = na var bool Final_Long_tp = na, var bool Final_Short_tp = na var bool Final_Long_sl0 = na, var bool Final_Short_sl0 = na var bool Final_Long_sl = na, var bool Final_Short_sl = na var int last_long_sl = na, var int last_short_sl = na tp_long = ((nLongs > 1) ? tp_long0 / nLongs : tp_long0) / 100 tp_short = ((nShorts > 1) ? tp_short0 / nShorts : tp_short0) / 100 long_tp := high > (fixnan(Position_Price) * (1 + tp_long)) and in_longCondition short_tp := low < (fixnan(Position_Price) * (1 - tp_short)) and in_shortCondition last_long_tp := long_tp ? time : nz(last_long_tp[1]) last_short_tp := short_tp ? time : nz(last_short_tp[1]) Final_Long_tp := (long_tp and last_longCondition > nz(last_long_tp[1]) and last_longCondition > nz(last_long_sl[1])) Final_Short_tp := (short_tp and last_shortCondition > nz(last_short_tp[1]) and last_shortCondition > nz(last_short_sl[1])) L_tp = iff(Final_Long_tp, fixnan(Position_Price) * (1 + tp_long) , na) S_tp = iff(Final_Short_tp, fixnan(Position_Price) * (1 - tp_short) , na) //TP SIGNALS-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- tplLevel = (in_longCondition and (last_longCondition > nz(last_long_tp[1])) and (last_longCondition > nz(last_long_sl[1])) and not Final_Long_sl[1]) ? (nLongs > 1) ? (fixnan(Position_Price) * (1 + tp_long)) : (last_open_longCondition * (1 + tp_long)) : na tpsLevel = (in_shortCondition and (last_shortCondition > nz(last_short_tp[1])) and (last_shortCondition > nz(last_short_sl[1])) and not Final_Short_sl[1]) ? (nShorts > 1) ? (fixnan(Position_Price) * (1 - tp_short)) : (last_open_shortCondition * (1 - tp_short)) : na //SL --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Risk = sl0 Percent_Capital = 99 sl = in_longCondition ? min(sl0,(((Risk) * 100) / (Percent_Capital * max(1, nLongs)))) : in_shortCondition ? min(sl0,(((Risk) * 100) / (Percent_Capital * max(1, nShorts)))) : sl0 Normal_long_sl = ((in_longCondition and low <= ((1 - (sl / 100)) * (fixnan(Position_Price))))) Normal_short_sl = ((in_shortCondition and high >= ((1 + (sl / 100)) * (fixnan(Position_Price))))) last_long_sl := Normal_long_sl ? time : nz(last_long_sl[1]) last_short_sl := Normal_short_sl ? time : nz(last_short_sl[1]) Final_Long_sl := Normal_long_sl and last_longCondition > nz(last_long_sl[1]) and last_longCondition > nz(last_long_tp[1]) and not Final_Long_tp Final_Short_sl := Normal_short_sl and last_shortCondition > nz(last_short_sl[1]) and last_shortCondition > nz(last_short_tp[1]) and not Final_Short_tp //RE-ENTRY ON TP-HIT----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- if Final_Long_tp or Final_Long_sl CondIni_long := -1 sum_long := 0.0 nLongs := na if Final_Short_tp or Final_Short_sl CondIni_short := 1 sum_short := 0.0 nShorts := na // Colors ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Bar_color = in_longCondition ? #009688 : in_shortCondition ? #f06292 : color.orange barcolor (color = Bar_color) //PLOTS============================================================================================================================================================================================================================================================================================================== plot(L_tp, title = "TP_L", style = plot.style_cross, color = color.fuchsia, linewidth = 7 ) plot(S_tp, title = "TP_S", style = plot.style_cross, color = color.fuchsia, linewidth = 7 ) //Price plots ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ plot((nLongs > 1) or (nShorts > 1) ? Position_Price : na, title = "Price", color = in_longCondition ? color.aqua : color.orange, linewidth = 2, style = plot.style_cross) plot(tplLevel, title="Long TP ", style = plot.style_cross, color=color.fuchsia, linewidth = 1 ) plot(tpsLevel, title="Short TP ", style = plot.style_cross, color=color.fuchsia, linewidth = 1 ) //PLOTSHAPES---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- plotshape(Final_Long_tp, title="TP Long Signal", style = shape.triangledown, location=location.abovebar, color=color.red, size=size.tiny , text="TP", textcolor=color.red, transp = 0 ) plotshape(Final_Short_tp, title="TP Short Signal", style = shape.triangleup, location=location.belowbar, color=color.green, size=size.tiny , text="TP", textcolor=color.green, transp = 0 ) plotshape(longCondition, title="Long", style=shape.triangleup, location=location.belowbar, color=color.blue, size=size.tiny , transp = 0 ) plotshape(shortCondition, title="Short", style=shape.triangledown, location=location.abovebar, color=color.red, size=size.tiny , transp = 0 ) // Backtest ================================================================================================================================================================================================================================================================================================================================== if L_basic_condt strategy.entry ("LONG", strategy.long ) if S_basic_condt strategy.entry ("SHORT", strategy.short ) strategy.exit("TP_L", "LONG", profit = (abs((last_open_longCondition * (1 + tp_long)) - last_open_longCondition) / syminfo.mintick), limit = nLongs >= 1 ? strategy.position_avg_price * (1 + tp_long) : na, loss = (abs((last_open_longCondition*(1-(sl/100)))-last_open_longCondition)/syminfo.mintick)) strategy.exit("TP_S", "SHORT", profit = (abs((last_open_shortCondition * (1 - tp_short)) - last_open_shortCondition) / syminfo.mintick), limit = nShorts >= 1 ? strategy.position_avg_price*(1-(tp_short)) : na, loss = (abs((last_open_shortCondition*(1+(sl/100)))-last_open_shortCondition)/syminfo.mintick)) //By BabehDyo