Stratégie de trading quantifiée pour l’entrée en bourse combinée à un filtrage du volume des transactions
La stratégie commence par déterminer la direction de la tendance des prix à l’aide de cinq moyennes EMA de différentes périodes. Elle est considérée comme une tendance à plusieurs têtes lorsque les cinq moyennes EMA sont toutes à la hausse et comme une tendance à la baisse lorsque les cinq moyennes EMA sont toutes à la baisse.
L’indicateur ADX est ensuite utilisé pour déterminer la force et la faiblesse de la tendance. Il est considéré comme une tendance forte lorsque la ligne DI+ est supérieure à la ligne DI- et que la valeur ADX dépasse le seuil fixé.
Dans le même temps, l’utilisation de la rupture de volume de transactions pour la confirmation supplémentaire, exigeant le volume de transactions de la ligne K actuelle est supérieure à un certain nombre de multiples de la moyenne des cycles, afin d’éviter une entrée en bourse erronée dans les positions de faible volume.
La logique des positions à plusieurs têtes et à vide de la stratégie est formée par une analyse globale de la direction de la tendance, de l’intensité de la tendance et du volume des transactions.
L’utilisation d’un système de moyenne EMA pour déterminer la direction d’une tendance est plus fiable que l’utilisation d’une seule moyenne EMA.
Les indicateurs ADX permettent de déterminer la force ou la faiblesse de la tendance et d’éviter les erreurs d’entrée en jeu en l’absence de tendance claire.
Un mécanisme de filtrage des volumes de transactions, assurant un soutien adéquat des volumes de transactions et renforçant la fiabilité de la stratégie.
Les signaux d’ouverture de position sont plus précis et plus fiables.
Les paramètres de stratégie sont plus nombreux et peuvent être optimisés pour améliorer l’efficacité de la stratégie.
En cas de choc, les jugements tels que l’EMA, l’ADX et l’ADX peuvent émettre des signaux erronés, ce qui entraîne des pertes inutiles. Les paramètres peuvent être ajustés de manière appropriée ou d’autres indicateurs peuvent être ajoutés pour aider à juger.
Les conditions de filtrage du volume des transactions sont trop strictes et risquent de manquer des opportunités de marché, il est possible de réduire les paramètres de filtrage du volume des transactions de manière appropriée.
La fréquence des transactions générées par la stratégie peut être élevée, il est nécessaire de faire attention à la gestion des fonds et de contrôler correctement la taille des positions individuelles.
Tester différentes combinaisons de paramètres pour trouver les meilleurs et améliorer l’efficacité de la stratégie.
L’ajout d’autres indicateurs, tels que le MACD, le KDJ et d’autres, en combinaison avec l’EMA et l’ADX, forme un jugement plus solide sur l’ouverture de position globale.
Ajout d’une stratégie de stop-loss pour contrôler davantage le risque.
Optimiser les stratégies de gestion des positions pour une gestion plus scientifique des fonds.
La stratégie prend en compte la direction de la tendance des prix, la force de la tendance et les informations sur le volume des transactions, forme des règles d’ouverture de position, évite dans une certaine mesure les pièges courants et présente une grande fiabilité. Cependant, il est nécessaire de perfectionner davantage le système de stratégie en optimisant les paramètres, en choisissant les indicateurs et en contrôlant le risque.
/*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