
Cet article présente une stratégie de trading algorithmique qui utilise un modèle d’absorption pour identifier des opportunités de profit et des prix croisés avec des moyennes mobiles comme signal d’entrée. Cette stratégie combine l’analyse technique des prix et les méthodes de suivi des tendances pour compiler et inverser les points de basculement de la tendance.
La logique de base de cette stratégie est basée sur la fusion de deux indicateurs non liés:
Mode de dévoration: un type de réversion de deux lignes K, où l’entité de la deuxième ligne K dévore complètement l’entité de la première ligne K, pour identifier les opportunités de réversion.
Le prix croise la moyenne mobile: un signal d’achat est généré lorsque le prix croise la moyenne mobile vers le haut depuis le bas de la moyenne mobile; un signal de vente est généré lorsque le prix croise la moyenne mobile vers le bas depuis le haut de la moyenne mobile.
En déduisant le moment où le marché pourrait se retourner en absorbant la forme, le croisement des prix avec les moyennes mobiles peut être utilisé comme un filtre pour déterminer le retour et augmenter la probabilité de profit.
Plus précisément, la stratégie détermine la probabilité d’une convergence et d’une inversion en suivant trois formes d’absorption: l’absorption à plusieurs têtes, l’absorption à tête vide et l’absorption sans fil. Elle filtre ensuite les signaux de fourches dorées et de fourches mortes associés aux prix et aux moyennes mobiles et décide finalement de la direction à prendre.
Le plus grand avantage de cette stratégie est l’utilisation d’une combinaison d’indicateurs non pertinents pour améliorer l’efficacité de la prise de décision. La forme de l’absorption permet de déterminer le moment et la probabilité d’une reprise du marché; et la direction et la force de la reprise sont vérifiées par la vérification croisée des prix et des moyennes mobiles. Les deux se vérifient mutuellement et peuvent réduire efficacement les pertes de transactions causées par de faux signaux.
Un autre avantage est la flexibilité de la configuration des paramètres. L’utilisateur peut définir lui-même des paramètres tels que la périodicité de la moyenne mobile, le stop loss, etc., afin d’optimiser la stratégie.
Malgré l’utilisation d’indicateurs multiples pour améliorer l’efficacité du jugement, la stratégie présente un certain risque de faux signaux. La forme de la consommation n’est pas un signal de revers fiable à 100%, et les croisements de prix avec des moyennes mobiles peuvent être inefficaces.
De plus, comme la plupart des stratégies d’analyse technique, cette stratégie est moins efficace sur les marchés confrontés à des situations conflictuelles telles que les fluctuations de prix. Des fluctuations persistantes peuvent déclencher un stop loss ou réduire la marge de profit.
Pour maîtriser le risque, il est possible d’ajuster les paramètres des moyennes mobiles pour optimiser le stop loss. Il est également possible de considérer l’implication de la stratégie d’ajustement dynamique en combinaison avec d’autres indicateurs pour identifier les tendances et les conditions de choc.
Cette stratégie peut être optimisée par les éléments suivants:
Testez plus de types de moyennes mobiles pour trouver la meilleure combinaison de paramètres. Par exemple, les moyennes mobiles pondérées, les moyennes mobiles de la fluctuation de la fluctuation, etc.
Il est important d’augmenter les indicateurs de tendance et d’éviter de prendre des positions sur des marchés instables, tels que l’ADX, la ceinture de Brin.
Optimiser les méthodes de stop-loss pour améliorer l’efficacité de ce dernier. Des stratégies de stop-loss telles que le suivi des stops et la sortie de Chandelier peuvent être envisagées.
Augmentation de la méthode d’apprentissage automatique pour déterminer la forme de la ligne K et amélioration de l’exactitude de la reconnaissance de l’engorgement.
Ajout d’une fonction d’optimisation automatique des paramètres pour une adaptation automatique des paramètres.
Cette stratégie utilise la méthode de l’absorption de la forme pour déterminer le moment du retournement et la vérification de la direction du retournement en croisant le prix avec la moyenne mobile. Pour améliorer l’efficacité de la prise de décision grâce à la fusion des indicateurs, c’est une stratégie d’analyse technique. L’avantage est que les indicateurs sont complémentaires et que les paramètres sont flexibles; L’inconvénient est qu’il existe toujours un risque de faux signal et qu’il est faible par rapport aux conditions de choc.
/*backtest
start: 2023-12-30 00:00:00
end: 2024-01-29 00:00:00
period: 3h
basePeriod: 15m
exchanges: [{"eid":"Futures_Binance","currency":"BTC_USDT"}]
*/
//@version=4
//@author=Daveatt
StrategyName = "BEST Engulfing + MA"
ShortStrategyName = "BEST Engulfing + MA"
strategy(title=StrategyName, shorttitle=ShortStrategyName, overlay=true)
includeEngulfing = true
includeMA = true
source_ma = input(title="Source Price vs MA", type=input.source, defval=close)
typeofMA = input(title="Type of MA", defval="SMA", options=["RMA", "SMA", "EMA", "WMA", "VWMA", "SMMA", "KMA", "TMA", "HullMA", "DEMA", "TEMA"])
length_ma = input(32, title = "MA Length", type=input.integer)
// ---------- Candle components and states
GreenCandle = close > open
RedCandle = close < open
NoBody = close==open
Body = abs(close-open)
// bullish conditions
isBullishEngulfing1 = max(close[1],open[1]) < max(close,open) and min(close[1],open[1]) > min(close,open) and Body > Body[1] and GreenCandle and RedCandle[1]
isBullishEngulfing2 = max(close[1],open[1]) < max(close,open) and min(close[1],open[1]) <= min(close,open) and Body > Body[1] and GreenCandle and RedCandle[1]
// bearish conditions
isBearishEngulfing1 = max(close[1],open[1]) < max(close,open) and min(close[1],open[1]) > min(close,open) and Body > Body[1] and RedCandle and GreenCandle[1]
isBearishEngulfing2 = max(close[1],open[1]) >= max(close,open) and min(close[1],open[1]) > min(close,open) and Body > Body[1] and RedCandle and GreenCandle[1]
// consolidation of conditions
isBullishEngulfing = isBullishEngulfing1 or isBullishEngulfing2
isBearishEngulfing = isBearishEngulfing1 or isBearishEngulfing2
//isBullishEngulfing = max(close[1],open[1]) < max(close,open) and min(close[1],open[1]) > min(close,open) and Body > Body[1] and GreenCandle and RedCandle[1]
//isBearishEngulfing = max(close[1],open[1]) < max(close,open) and min(close[1],open[1]) > min(close,open) and Body > Body[1] and RedCandle and GreenCandle[1]
Engulf_curr = 0 - barssince(isBearishEngulfing) + barssince(isBullishEngulfing)
Engulf_Buy = Engulf_curr < 0 ? 1 : 0
Engulf_Sell = Engulf_curr > 0 ? 1 : 0
// Price vs MM
smma(src, len) =>
smma = 0.0
smma := na(smma[1]) ? sma(src, len) : (smma[1] * (len - 1) + src) / len
smma
ma(smoothing, src, length) =>
if smoothing == "RMA"
rma(src, length)
else
if smoothing == "SMA"
sma(src, length)
else
if smoothing == "EMA"
ema(src, length)
else
if smoothing == "WMA"
wma(src, length)
else
if smoothing == "VWMA"
vwma(src, length)
else
if smoothing == "SMMA"
smma(src, length)
else
if smoothing == "HullMA"
wma(2 * wma(src, length / 2) - wma(src, length), round(sqrt(length)))
else
if smoothing == "LSMA"
src
else
if smoothing == "KMA"
xPrice = src
xvnoise = abs(xPrice - xPrice[1])
nfastend = 0.666
nslowend = 0.0645
nsignal = abs(xPrice - xPrice[length])
nnoise = sum(xvnoise, length)
nefratio = iff(nnoise != 0, nsignal / nnoise, 0)
nsmooth = pow(nefratio * (nfastend - nslowend) + nslowend, 2)
nAMA = 0.0
nAMA := nz(nAMA[1]) + nsmooth * (xPrice - nz(nAMA[1]))
nAMA
else
if smoothing == "TMA"
sma(sma(close, length), length)
else
if smoothing == "DEMA"
2 * src - ema(src, length)
else
if smoothing == "TEMA"
3 * (src - ema(src, length)) + ema(ema(src, length), length)
else
src
MA = ma(typeofMA, source_ma, length_ma)
plot(MA, color=#006400FF, title="MA breakout", linewidth=3)
macrossover = crossover (source_ma, MA)
macrossunder = crossunder(source_ma, MA)
since_ma_buy = barssince(macrossover)
since_ma_sell = barssince(macrossunder)
macross_curr = 0 - since_ma_sell + since_ma_buy
bullish_MA_cond = macross_curr < 0 ? 1 : 0
bearish_MA_cond = macross_curr > 0 ? 1 : 0
posUp = (Engulf_Buy ? 1 : 0) + (bullish_MA_cond ? 1 : 0)
posDn = (Engulf_Sell ? 1 : 0) + (bearish_MA_cond ? 1 : 0)
conditionUP = posUp == 2 and posUp[1] < 2
conditionDN = posDn == 2 and posDn[1] < 2
sinceUP = barssince(conditionUP)
sinceDN = barssince(conditionDN)
// primary-first signal of the trend
nUP = crossunder(sinceUP,sinceDN)
nDN = crossover(sinceUP,sinceDN)
// and the following secondary signals
// save of the primary signal
sinceNUP = barssince(nUP)
sinceNDN = barssince(nDN)
buy_trend = sinceNDN > sinceNUP
sell_trend = sinceNDN < sinceNUP
// engulfing by
barcolor(nUP ? color.orange : na, title="Bullish condition")
barcolor(nDN ? color.yellow : na, title="Bearish condition")
isLong = nUP
isShort = nDN
long_entry_price = valuewhen(nUP, close, 0)
short_entry_price = valuewhen(nDN, close, 0)
longClose = close[1] < MA
shortClose = close[1] > MA
///////////////////////////////////////////////
//* Backtesting Period Selector | Component *//
///////////////////////////////////////////////
StartYear = input(2017, "Backtest Start Year",minval=1980)
StartMonth = input(1, "Backtest Start Month",minval=1,maxval=12)
StartDay = input(1, "Backtest Start Day",minval=1,maxval=31)
testPeriodStart = timestamp(StartYear,StartMonth,StartDay,0,0)
StopYear = input(2020, "Backtest Stop Year",minval=1980)
StopMonth = input(12, "Backtest Stop Month",minval=1,maxval=12)
StopDay = input(31, "Backtest Stop Day",minval=1,maxval=31)
testPeriodStop = timestamp(StopYear,StopMonth,StopDay,0,0)
testPeriod() => true
//////////////////////////
//* Profit Component *//
//////////////////////////
input_tp_pips = input(600, "Backtest Profit Goal (in USD)",minval=0)
input_sl_pips = input(300, "Backtest STOP Goal (in USD)",minval=0)
tp = buy_trend? long_entry_price + input_tp_pips : short_entry_price - input_tp_pips
sl = buy_trend? long_entry_price - input_sl_pips : short_entry_price + input_sl_pips
long_TP_exit = buy_trend and high >= tp
short_TP_exit = sell_trend and low <= tp
plot(tp, title="TP", style=plot.style_circles, linewidth=3, color=color.blue)
plot(sl, title="SL", style=plot.style_circles, linewidth=3, color=color.red)
if testPeriod()
strategy.entry("Long", 1, when=isLong)
strategy.close("Long", when=longClose )
strategy.exit("XL","Long", limit=tp, when=buy_trend, stop=sl)
if testPeriod()
strategy.entry("Short", 0, when=isShort)
strategy.close("Short", when=shortClose )
strategy.exit("XS","Short", when=sell_trend, limit=tp, stop=sl)