La stratégie utilise des signaux combinés de plusieurs indicateurs techniques pour réaliser des transactions dynamiques sur des actifs tels que des actions, des monnaies numériques. La stratégie peut identifier automatiquement les tendances du marché et suivre les tendances. La stratégie intègre également un mécanisme de stop-loss pour contrôler les risques.
Cette stratégie utilise principalement plusieurs indicateurs tels que la moyenne mobile, l’indicateur de force relative (RSI), l’amplitude réelle moyenne (ATR) et l’indicateur de mouvement directionnel (ADX) pour générer des signaux de négociation via une combinaison d’indicateurs.
Plus précisément, la stratégie utilise d’abord les doubles moyennes mobiles pour former un signal de fourche dorée. La longueur de la ligne rapide est de 10 jours, la longueur de la ligne lente est de 50 jours.
Sur la base de la moyenne mobile double, la stratégie introduit également l’indicateur RSI pour confirmer les signaux de tendance et éviter les fausses ruptures. Le RSI juge la force du marché par la différence entre la ligne rapide et la ligne lente, la longueur étant de 14. Le RSI génère un signal d’achat lorsqu’il est porté à 30 et un signal de vente lorsqu’il est porté à 70.
En outre, la stratégie utilise l’indicateur ATR pour ajuster automatiquement le seuil de rupture. L’indicateur ATR peut refléter efficacement la volatilité du marché. Lorsque la volatilité du marché augmente, la stratégie définit le seuil de rupture plus largement, ce qui réduit le risque de rupture.
Enfin, la stratégie utilise l’indicateur ADX pour juger de la force de la tendance. L’ADX juge la force de la tendance par la différence entre l’indicateur DI + et l’indicateur DI - positif.
La combinaison de plusieurs indicateurs permet à la stratégie d’être plus prudente dans l’émission de signaux de trading et d’éviter d’être trompée par de faux signaux sur le marché, ce qui permet d’obtenir un taux de victoire plus élevé.
Cette stratégie présente les avantages suivants:
L’utilisation combinée de plusieurs indicateurs tels que la moyenne, le RSI, l’ATR et l’ADX peut améliorer l’exactitude des décisions de négociation et éviter les erreurs de jugement causées par un seul indicateur.
L’ajustement automatique du seuil de stop en fonction de la volatilité du marché réduit la probabilité que le stop soit déclenché et permet de contrôler efficacement le risque de transaction.
En évaluant la force de la tendance à l’aide de l’indicateur ADX, il est possible de réduire les pertes causées par les opérations inversées.
Les paramètres de la stratégie tels que la longueur de la ligne moyenne, la longueur du RSI, le cycle ATR et le cycle ADX peuvent être ajustés et optimisés en fonction des différents marchés.
En utilisant un système de courbe rapide et moyenne pour juger de la tendance de la ligne longue, et en combinant des indicateurs tels que le RSI pour réduire l’impact du bruit de la ligne courte, il est possible de tenir la ligne longue dans la tendance et d’obtenir un rendement plus élevé.
Cette stratégie comporte également des risques, principalement:
Les combinaisons de paramètres multiples augmentent la difficulté d’optimisation, et des combinaisons de paramètres inappropriées peuvent entraîner une altération de l’efficacité de la stratégie. Ce risque peut être atténué par un retour d’expérience plus adéquat et un ajustement des paramètres.
Les indicateurs techniques ont leurs propres conditions de marché applicables. Lorsque le marché entre dans un état particulier, les indicateurs impliqués dans la stratégie peuvent être invalidés simultanément. Le risque présenté par cet événement BLACK SWAN doit être pris en compte.
La stratégie autorise les transactions à la baisse. Les transactions à la baisse comportent un risque de perte illimité. Ce risque peut être réduit en définissant un stop-loss.
En cas de revers de tendance, les signaux indicatifs ne peuvent pas réagir rapidement, ce qui peut entraîner des pertes inverses. Certains paramètres de l’indicateur peuvent être raccourcis de manière appropriée pour améliorer la sensibilité.
Il y a encore de la place pour d’autres améliorations à la stratégie. Les principales idées d’optimisation sont:
En analysant la corrélation entre les différents indicateurs et l’état du marché, des mécanismes peuvent être conçus pour ajuster dynamiquement le poids des indicateurs afin d’améliorer l’efficacité des décisions dans différents environnements de marché.
L’utilisation de modèles tels que l’apprentissage en profondeur pour prédire la direction des variations de prix, l’aide à la conception manuelle des règles de décision et l’amélioration de l’exactitude des décisions stratégiques.
Le module d’optimisation automatique des paramètres a été conçu pour les données historiques des fenêtres coulissantes, permettant un ajustement dynamique des paramètres de l’indicateur afin de mieux adapter les stratégies aux changements du marché.
L’ajout d’une méthode d’analyse des cycles de variation, telle que la théorie des vagues, aide à déterminer le mouvement de la ligne longue dans la tendance et améliore la probabilité de rentabilité des positions.
Cette stratégie utilise une combinaison de plusieurs indicateurs tels que la moyenne mobile, le RSI, l’ATR et l’ADX pour concevoir un ensemble de règles de décision plus complet, permettant de déterminer les tendances des lignes plus longues à l’aide d’un système de moyenne et de réduire les interférences sonores à l’aide d’indicateurs à courte période tels que le RSI. En outre, la stratégie a une plus grande marge d’optimisation et devrait obtenir de meilleurs résultats.
/*backtest
start: 2023-01-28 00:00:00
end: 2024-02-03 00:00:00
period: 1d
basePeriod: 1h
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
// This source code to my testing
// © sgb
//@version=5
strategy(title='Soren test 2', overlay=true, initial_capital=100, pyramiding=1, calc_on_order_fills=true, calc_on_every_tick=true, default_qty_type=strategy.percent_of_equity, default_qty_value=50, commission_value=0.04)
//SOURCE =============================================================================================================================================================================================================================================================================================================
src = input(open)
// INPUTS ============================================================================================================================================================================================================================================================================================================
//ADX --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ADX_options = input.string('MASANAKAMURA', title='Adx Type', options=['CLASSIC', 'MASANAKAMURA'], group='ADX')
ADX_len = input.int(38, title='Adx lenght', minval=1, group='ADX')
th = input.float(23, title='Adx Treshold', minval=0, step=0.5, group='ADX')
// Volume ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
volume_f = input.float(1.2, title='Volume mult.', minval=0, step=0.1, group='Volume')
sma_length = input.int(35, title='Volume lenght', minval=1, group='Volume')
//RSI----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
len_3 = input.int(25, title='RSI lenght', group='Relative Strenght Indeks')
src_3 = input.source(low, title='RSI Source', group='Relative Strenght Indeks')
RSI_VWAP_length = input(25, title='Rsi vwap lenght')
// Range Filter ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
per_ = input.int(26, title='SAMPLING PERIOD', minval=1, group='Range Filter')
mult = input.float(2.3, title='RANGE MULTIPLIER', minval=0.1, step=0.1, group='Range Filter')
// Cloud --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
len = input.int(1, title='Cloud Length', group='Cloud')
//RMI ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
RMI_len = input.int(26, title='Rmi Lenght', minval=1, group='Relative Momentum Index')
mom = input.int(17, title='Rmi Momentum', minval=1, group='Relative Momentum Index')
RMI_os = input.int(33, title='Rmi oversold', minval=0, group='Relative Momentum Index')
RMI_ob = input.int(68, title='Rmi overbought', minval=0, group='Relative Momentum Index')
// Indicators Calculations ========================================================================================================================================================================================================================================================================================================
// 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 = ta.ema(math.abs(_src - _src[1]), _per_)
_smoothrng = ta.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
//ADX-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
calcADX(_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)
sum = _plus + _minus
_adx = 100 * ta.rma(math.abs(_plus - _minus) / (sum == 0 ? 1 : sum), _len)
[_plus, _minus, _adx]
calcADX_Masanakamura(_len) =>
SmoothedTrueRange = 0.0
SmoothedDirectionalMovementPlus = 0.0
SmoothedDirectionalMovementMinus = 0.0
TrueRange = math.max(math.max(high - low, math.abs(high - nz(close[1]))), math.abs(low - nz(close[1])))
DirectionalMovementPlus = high - nz(high[1]) > nz(low[1]) - low ? math.max(high - nz(high[1]), 0) : 0
DirectionalMovementMinus = nz(low[1]) - low > high - nz(high[1]) ? math.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 = math.abs(DIP - DIM) / (DIP + DIM) * 100
adx = ta.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
// Volume -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Volume_condt = volume > ta.sma(volume, sma_length) * volume_f
//RSI------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
up_3 = ta.rma(math.max(ta.change(src_3), 0), len_3)
down_3 = ta.rma(-math.min(ta.change(src_3), 0), len_3)
rsi_3 = down_3 == 0 ? 100 : up_3 == 0 ? 0 : 100 - 100 / (1 + up_3 / down_3)
L_rsi = rsi_3 < 70
S_rsi = rsi_3 > 30
RSI_VWAP = ta.rsi(ta.vwap(close), RSI_VWAP_length)
RSI_VWAP_overSold = 13
RSI_VWAP_overBought = 68
L_VAP = ta.crossover(RSI_VWAP, RSI_VWAP_overSold)
S_VAP = ta.crossunder(RSI_VWAP, RSI_VWAP_overBought)
//Cloud --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
PI = 2 * math.asin(1)
hilbertTransform(src) =>
0.0962 * src + 0.5769 * nz(src[2]) - 0.5769 * nz(src[4]) - 0.0962 * nz(src[6])
computeComponent(src, mesaPeriodMult) =>
hilbertTransform(src) * mesaPeriodMult
computeAlpha(src, fastLimit, slowLimit) =>
mesaPeriod = 0.0
mesaPeriodMult = 0.075 * nz(mesaPeriod[1]) + 0.54
smooth = 0.0
smooth := (4 * src + 3 * nz(src[1]) + 2 * nz(src[2]) + nz(src[3])) / 10
detrender = 0.0
detrender := computeComponent(smooth, mesaPeriodMult)
I1 = nz(detrender[3])
Q1 = computeComponent(detrender, mesaPeriodMult)
jI = computeComponent(I1, mesaPeriodMult)
jQ = computeComponent(Q1, mesaPeriodMult)
I2 = 0.0
Q2 = 0.0
I2 := I1 - jQ
Q2 := Q1 + jI
I2 := 0.2 * I2 + 0.8 * nz(I2[1])
Q2 := 0.2 * Q2 + 0.8 * nz(Q2[1])
Re = I2 * nz(I2[1]) + Q2 * nz(Q2[1])
Im = I2 * nz(Q2[1]) - Q2 * nz(I2[1])
Re := 0.2 * Re + 0.8 * nz(Re[1])
Im := 0.2 * Im + 0.8 * nz(Im[1])
if Re != 0 and Im != 0
mesaPeriod := 2 * PI / math.atan(Im / Re)
mesaPeriod
if mesaPeriod > 1.5 * nz(mesaPeriod[1])
mesaPeriod := 1.5 * nz(mesaPeriod[1])
mesaPeriod
if mesaPeriod < 0.67 * nz(mesaPeriod[1])
mesaPeriod := 0.67 * nz(mesaPeriod[1])
mesaPeriod
if mesaPeriod < 6
mesaPeriod := 6
mesaPeriod
if mesaPeriod > 50
mesaPeriod := 50
mesaPeriod
mesaPeriod := 0.2 * mesaPeriod + 0.8 * nz(mesaPeriod[1])
phase = 0.0
if I1 != 0
phase := 180 / PI * math.atan(Q1 / I1)
phase
deltaPhase = nz(phase[1]) - phase
if deltaPhase < 1
deltaPhase := 1
deltaPhase
alpha = fastLimit / deltaPhase
if alpha < slowLimit
alpha := slowLimit
alpha
[alpha, alpha / 2.0]
er = math.abs(ta.change(src, len)) / math.sum(math.abs(ta.change(src)), len)
[a, b] = computeAlpha(src, er, er * 0.1)
mama = 0.0
mama := a * src + (1 - a) * nz(mama[1])
fama = 0.0
fama := b * mama + (1 - b) * nz(fama[1])
alpha = math.pow(er * (b - a) + a, 2)
kama = 0.0
kama := alpha * src + (1 - alpha) * nz(kama[1])
L_cloud = kama > kama[1]
S_cloud = kama < kama[1]
// RMI -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
RMI(len, m) =>
up = ta.ema(math.max(close - close[m], 0), len)
dn = ta.ema(math.max(close[m] - close, 0), len)
RMI = dn == 0 ? 0 : 100 - 100 / (1 + up / dn)
RMI
L_rmi = ta.crossover(RMI(RMI_len, mom), RMI_os)
S_rmi = ta.crossunder(RMI(RMI_len, mom), RMI_ob)
//STRATEGY ==========================================================================================================================================================================================================================================================================================================
L_1 = L_VAP and L_RF and not S_adx
S_1 = S_VAP and S_RF and not L_adx
L_2 = L_adx and Volume_condt and L_rsi and L_cloud
S_2 = S_adx and Volume_condt and S_rsi and S_cloud
L_3 = L_rmi and L_RF and not S_adx
S_3 = S_rmi and S_RF and not L_adx
L_basic_condt = L_1 or L_2 or L_3
S_basic_condt = S_1 or S_2 or S_3
var bool longCondition = na
var bool shortCondition = na
var float last_open_longCondition = na
var float last_open_shortCondition = na
var int last_longCondition = 0
var int last_shortCondition = 0
longCondition := L_basic_condt
shortCondition := S_basic_condt
last_open_longCondition := longCondition ? close : nz(last_open_longCondition[1])
last_open_shortCondition := shortCondition ? close : 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
// SWAP-SL ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
var int last_long_sl = na
var int last_short_sl = na
sl = input.float(2, 'Swap % period', minval=0, step=0.1, group='strategy settings')
long_sl = ta.crossunder(low, (1 - sl / 100) * last_open_longCondition) and in_longCondition and not longCondition
short_sl = ta.crossover(high, (1 + sl / 100) * last_open_shortCondition) and in_shortCondition and not shortCondition
last_long_sl := long_sl ? time : nz(last_long_sl[1])
last_short_sl := short_sl ? time : nz(last_short_sl[1])
var bool CondIni_long_sl = 0
CondIni_long_sl := long_sl ? 1 : longCondition ? -1 : nz(CondIni_long_sl[1])
var bool CondIni_short_sl = 0
CondIni_short_sl := short_sl ? 1 : shortCondition ? -1 : nz(CondIni_short_sl[1])
Final_Long_sl = long_sl and nz(CondIni_long_sl[1]) == -1 and in_longCondition and not longCondition
Final_Short_sl = short_sl and nz(CondIni_short_sl[1]) == -1 and in_shortCondition and not shortCondition
var int sectionLongs = 0
sectionLongs := nz(sectionLongs[1])
var int sectionShorts = 0
sectionShorts := nz(sectionShorts[1])
// RE-ENTRY ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
if longCondition or Final_Long_sl
sectionLongs += 1
sectionShorts := 0
sectionShorts
if shortCondition or Final_Short_sl
sectionLongs := 0
sectionShorts += 1
sectionShorts
var float sum_long = 0.0
var float sum_short = 0.0
if longCondition
sum_long := nz(last_open_longCondition) + nz(sum_long[1])
sum_short := 0.0
sum_short
if Final_Long_sl
sum_long := (1 - sl / 100) * last_open_longCondition + nz(sum_long[1])
sum_short := 0.0
sum_short
if shortCondition
sum_short := nz(last_open_shortCondition) + nz(sum_short[1])
sum_long := 0.0
sum_long
if Final_Short_sl
sum_long := 0.0
sum_short := (1 + sl / 100) * last_open_shortCondition + nz(sum_short[1])
sum_short
var float Position_Price = 0.0
Position_Price := nz(Position_Price[1])
Position_Price := longCondition or Final_Long_sl ? sum_long / sectionLongs : shortCondition or Final_Short_sl ? sum_short / sectionShorts : na
//TP_1 -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
tp = input.float(1.2, 'Tp-1 ', minval=0, step=0.1, group='strategy settings')
long_tp = ta.crossover(high, (1 + tp / 100) * fixnan(Position_Price)) and in_longCondition and not longCondition
short_tp = ta.crossunder(low, (1 - tp / 100) * fixnan(Position_Price)) and in_shortCondition and not shortCondition
var int last_long_tp = na
var int last_short_tp = na
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])
Final_Short_tp = short_tp and last_shortCondition > nz(last_short_tp[1])
fixnan_1 = fixnan(Position_Price)
ltp = Final_Long_tp ? fixnan_1 * (1 + tp / 100) : na
fixnan_2 = fixnan(Position_Price)
stp = Final_Short_tp ? fixnan_2 * (1 - tp / 100) : na
if Final_Short_tp or Final_Long_tp
sum_long := 0.0
sum_short := 0.0
sectionLongs := 0
sectionShorts := 0
sectionShorts
if Final_Long_tp
CondIni_long_sl == 1
if Final_Short_tp
CondIni_short_sl == 1
// COLORS & PLOTS --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
ADX_COLOR = L_adx ? color.lime : S_adx ? color.red : color.orange
barcolor(color=ADX_COLOR)
hbandplot = plot(hband, title='RF HT', color=ADX_COLOR, transp=50)
lbandplot = plot(lband, title='RF LT', color=ADX_COLOR, transp=50)
fill(hbandplot, lbandplot, title='RF TR', color=ADX_COLOR, transp=90)
plotshape(longCondition, title='Long', style=shape.triangleup, location=location.belowbar, color=color.new(color.blue, 0), size=size.tiny)
plotshape(shortCondition, title='Short', style=shape.triangledown, location=location.abovebar, color=color.new(color.red, 0), size=size.tiny)
plot(ltp, style=plot.style_circles, linewidth=5, color=color.new(color.fuchsia, 0), editable=false)
plot(stp, style=plot.style_circles, linewidth=5, color=color.new(color.fuchsia, 0), editable=false)
//BACKTESTING--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Q = 50
SL = input.float(0.4, 'StopLoss ', minval=0, step=0.1)
strategy.entry('long', strategy.long, when=longCondition)
strategy.entry('short', strategy.short, when=shortCondition)
strategy.exit('TP', 'long', qty_percent=Q, limit=fixnan(Position_Price) * (1 + tp / 100))
strategy.exit('TP', 'short', qty_percent=Q, limit=fixnan(Position_Price) * (1 - tp / 100))
strategy.exit('SL', 'long', stop=fixnan(Position_Price) * (1 - SL / 100))
strategy.exit('SL', 'short', stop=fixnan(Position_Price) * (1 + SL / 100))
//
//
//
//
//
//
// By SGB