La stratégie est une stratégie dynamique basée sur des indicateurs, utilisant des indicateurs d’oscillateurs tels que le RSI, le Stoch et le MACD pour construire des signaux de négociation stratégiques. L’idée principale de la stratégie est d’utiliser l’indicateur pour identifier la direction de la tendance lorsque les prix sont en état de choc et d’entrer en fonction du signal de l’indicateur.
La stratégie commence par appeler la fonction f_getOscilatorValues pour obtenir les valeurs des différents indicateurs d’oscillation, y compris le RSI, le Stoch, le MACD, etc. Ensuite, la fonction f_getSupertrend pour calculer les valeurs de l’indicateur de tendance décalée est utilisée pour suivre les arrêts.
Après avoir calculé l’indicateur, la stratégie appelle la fonction f_getBuySellStops, qui calcule l’arrêt d’entrée et l’arrêt d’arrêt en fonction de la valeur de l’indicateur. Plus précisément, elle calcule l’indicateur ATR et prend l’arrêt d’entrée par ATR multiplié par un coefficient d’arrêt.
La stratégie détermine ensuite l’orientation physique de la ligne K. Si la ligne K est en hausse, elle est dessinée en vert et si la ligne K est en baisse, elle est dessinée en rouge. Après avoir dessiné la ligne K et l’indicateur, la stratégie détermine si la condition d’entrée est remplie.
Après l’entrée, le stop-loss est suivi, le stop-loss est suivi en haut ou en bas du rail, selon ce qui est le plus proche. Lorsque le stop-loss est déclenché, le marché est libéré.
Cette stratégie présente les avantages suivants:
L’utilisation d’indicateurs d’oscillation pour identifier la direction de la tendance permet de saisir en temps opportun les occasions de revirement de courte ligne du marché.
La stratégie de suspension des pertes en retard peut limiter les pertes individuelles avant que les pertes ne s’élargissent.
La taille de la position peut être ajustée de manière dynamique en fonction de l’arrêt de perte et de l’arrêt de position calculés par l’ATR.
Le filtrage est effectué en combinaison avec une moyenne de haute périodicité, afin d’éviter le bourrage.
La stratégie de blocage partiel permet de maintenir les bénéfices et de bloquer une partie des bénéfices.
La stratégie est simple, claire, facile à comprendre et adaptée aux débutants en trading quantitatif.
Cette stratégie comporte aussi des risques:
Les indicateurs oscillators présentent des problèmes de retard, ce qui peut entraîner un retard dans le signal d’entrée et un retard dans le signal de sortie. Les paramètres de l’indicateur peuvent être optimisés en ajustant les paramètres de l’indicateur ou en ajoutant un indicateur de suivi de tendance.
Le point de stop est proche et peut être atteint par un stop-break. Il est possible d’alléger la portée de stop-loss de manière appropriée ou d’utiliser des stratégies de stop-loss dynamiques telles que le stop Chandelier.
Après un arrêt partiel, la position restante peut être clôturée. Vous pouvez réduire le pourcentage d’arrêt partiel pour laisser de la place.
Risque de ressemblance des données de retracement. Les données doivent être vérifiées plusieurs fois dans différents marchés pour éviter les surcorrélations.
Les moyennes à hautes périodes peuvent également être inefficaces en tant que conditions de filtrage. Des méthodes telles que la classification des tendances devraient être utilisées pour aider à déterminer le mouvement des grandes périodes.
Cette stratégie peut être optimisée dans les domaines suivants:
Tester des combinaisons de paramètres de différents oscillators, en choisissant une combinaison qui fournit un signal de meilleure qualité, comme l’indicateur Sttoch pour les lignes K rapides.
Essayez de modifier une partie de l’arrêt en arrêt mobile, en réglant la position de l’arrêt en fonction de l’ATR ou de la moyenne mobile
L’ajout d’un algorithme d’apprentissage automatique pour la détection des tendances à grande périodicité remplace le filtrage linéaire à haute périodicité et améliore la précision de la détection.
L’augmentation de l’indicateur de quantité d’énergie peut être utilisée comme condition de filtrage d’entrée pour éviter des échanges inversés inutiles.
L’intégration et l’optimisation des poids des indicateurs permettent de sélectionner la combinaison d’indicateurs la plus appropriée pour la variété actuelle.
Ajout d’un module de contrôle de vent par apprentissage automatique, optimisation dynamique des positions de stop loss, stop stop, position, etc.
Ajouter des signaux de négociation en arbitrage triangulaire ou en arbitrage à terme pour profiter de la différence de prix entre les options futures et les options en espèces.
Cette stratégie est une stratégie idéale pour les débutants en trading quantitatif, elle est claire et basée sur l’analyse des indicateurs et le contrôle des risques. Cependant, l’optimisation des paramètres et l’évitement des risques sur le terrain sont nécessaires pour obtenir des rendements stables.
/*backtest
start: 2023-08-26 00:00:00
end: 2023-09-25 00:00:00
period: 1h
basePeriod: 15m
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/
// © HeWhoMustNotBeNamed
//@version=4
strategy("Oscilator candles - strategy", overlay=false, initial_capital = 1000, default_qty_type = strategy.percent_of_equity, default_qty_value = 100, commission_type = strategy.commission.percent, pyramiding = 1, commission_value = 0.01, calc_on_order_fills = true)
oscilatorType = input(title="Oscliator Type", defval="stoch", options=["rsi", "stoch", "cog", "macd", "tsi", "cci", "cmo", "mfi"])
length = input(3)
shortlength = input(3)
longlength = input(9)
showSupertrend = input(true)
AtrMAType = input(title="Moving Average Type", defval="rma", options=["ema", "sma", "hma", "rma", "vwma", "wma"])
AtrLength = input(30, step=10)
stopMultiplier = input(4)
targetMultiplier = input(3)
wicks = input(true)
considerWicksForDelayByStep = input(false)
colorByPreviousClose = input(true)
useHTFPivot = input(false)
resolution = input("12M", type=input.resolution)
HTFMultiplier = input(4, title="Higher Timeframe multiplier (Used when resolution is set to Same as Symbol)", minval=2, step=1)
PivotLength = input(2, step=1)
tradeDirection = input(title="Trade Direction", defval=strategy.direction.long, options=[strategy.direction.all, strategy.direction.long, strategy.direction.short])
i_startTime = input(defval = timestamp("01 Jan 2010 00:00 +0000"), title = "Backtest Start Time", type = input.time)
i_endTime = input(defval = timestamp("01 Jan 2099 00:00 +0000"), title = "Backtest End Time", type = input.time)
inDateRange = true
f_getOscilatorValues(oscilatorType, length, shortlength, longlength)=>
oOpen = rsi(open, length)
oClose = rsi(close, length)
oHigh = rsi(high, length)
oLow = rsi(low, length)
if(oscilatorType == "tsi")
oOpen := tsi(open, shortlength, longlength)
oClose := tsi(close, shortlength, longlength)
oHigh := tsi(high, shortlength, longlength)
oLow := tsi(low, shortlength, longlength)
if(oscilatorType == "stoch")
oOpen := stoch(open, longlength, shortlength, length)
oClose := stoch(close, longlength, shortlength, length)
oHigh := stoch(high, longlength, shortlength, length)
oLow := stoch(low, longlength, shortlength, length)
if(oscilatorType == "cci")
oOpen := cci(open, length)
oClose := cci(close, length)
oHigh := cci(high, length)
oLow := cci(low, length)
if(oscilatorType == "cog")
oOpen := cog(open, length)
oClose := cog(close, length)
oHigh := cog(high, length)
oLow := cog(low, length)
if(oscilatorType == "cmo")
oOpen := cmo(open, length)
oClose := cmo(close, length)
oHigh := cmo(high, length)
oLow := cmo(low, length)
if(oscilatorType == "mfi")
oOpen := mfi(open, length)
oClose := mfi(close, length)
oHigh := mfi(high, length)
oLow := mfi(low, length)
if(oscilatorType == "macd")
[macdLineOpen, signalLineOpen, histLineOpen] = macd(open, shortlength, longlength, length)
[macdLineClose, signalLineClose, histLineClose] = macd(close, shortlength, longlength, length)
[macdLineHigh, signalLineHigh, histLineHigh] = macd(high, shortlength, longlength, length)
[macdLineLow, signalLineLow, histLineLow] = macd(low, shortlength, longlength, length)
oOpen := macdLineOpen
oClose := macdLineClose
oHigh := macdLineHigh
oLow := macdLineLow
[oOpen, oClose, oHigh, oLow]
f_getMovingAverage(source, MAType, length)=>
ma = sma(source, length)
if(MAType == "ema")
ma := ema(source,length)
if(MAType == "hma")
ma := hma(source,length)
if(MAType == "rma")
ma := rma(source,length)
if(MAType == "vwma")
ma := vwma(source,length)
if(MAType == "wma")
ma := wma(source,length)
ma
f_getSupertrend(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, stopMultiplier, wicks)=>
truerange = max(oHigh, oClose[1]) - min(oLow, oClose[1])
averagetruerange = f_getMovingAverage(truerange, AtrMAType, AtrLength)
atr = averagetruerange * stopMultiplier
longStop = oClose - atr
longStopPrev = nz(longStop[1], longStop)
longStop := (wicks ? oLow[1] : oClose[1]) > longStopPrev ? max(longStop, longStopPrev) : longStop
shortStop = oClose + atr
shortStopPrev = nz(shortStop[1], shortStop)
shortStop := (wicks ? oHigh[1] : oClose[1]) < shortStopPrev ? min(shortStop, shortStopPrev) : shortStop
dir = 1
dir := nz(dir[1], dir)
dir := dir == -1 and (wicks ? oHigh : oClose) > shortStopPrev ? 1 : dir == 1 and (wicks ? oLow : oClose) < longStopPrev ? -1 : dir
trailingStop = dir == 1? longStop : shortStop
[dir, trailingStop]
f_getBuySellStops(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, considerWicks, considerWicksForDelayByStep, stopMultiplier, targetMultiplier)=>
barState = 0
source = oClose
truerange = max(oHigh, oClose[1]) - min(oLow, oClose[1])
atr = f_getMovingAverage(truerange, AtrMAType, AtrLength)
buyStop = source - atr * stopMultiplier
sellStop = source + atr * stopMultiplier
buyStopDerived = buyStop
sellStopDerived = sellStop
highTarget = considerWicks ? oHigh : source
lowTarget = considerWicks ? oLow : source
highTargetDelayByStep = considerWicksForDelayByStep ? oHigh : source
lowTargetDelayByStep = considerWicksForDelayByStep ? oLow : source
barState := highTarget > sellStopDerived[1] ? 1 : lowTarget < buyStopDerived[1] ? -1 : nz(barState[1],0)
buyMultiplier = (barState == 1)? stopMultiplier : targetMultiplier
sellMultiplier = (barState == -1)? stopMultiplier : targetMultiplier
buyStop := source - atr * buyMultiplier
sellStop := source + atr * sellMultiplier
buyStop := barState == 1? max(buyStop, buyStop[1]) : barState == -1? min(buyStop, buyStop[1]) : buyStop
sellStop := barState == 1? max(sellStop, sellStop[1]) : barState == -1? min(sellStop, sellStop[1]) : sellStop
buyStopDerived := buyStop
sellStopDerived := sellStop
buyStopDerived := highTargetDelayByStep < sellStopDerived[1] and lowTargetDelayByStep > buyStopDerived[1] ? buyStopDerived[1] : buyStopDerived
sellStopDerived := highTargetDelayByStep < sellStopDerived[1] and lowTargetDelayByStep > buyStopDerived[1] ? sellStopDerived[1] : sellStopDerived
[buyStopDerived, sellStopDerived, barState]
f_secureSecurity(_symbol, _res, _src) => security(_symbol, _res, _src[1], lookahead = barmerge.lookahead_on, gaps=barmerge.gaps_off)
f_multiple_resolution(HTFMultiplier) =>
target_Res_In_Min = timeframe.multiplier * HTFMultiplier * (
timeframe.isseconds ? 1. / 60. :
timeframe.isminutes ? 1. :
timeframe.isdaily ? 1440. :
timeframe.isweekly ? 7. * 24. * 60. :
timeframe.ismonthly ? 30.417 * 24. * 60. : na)
target_Res_In_Min <= 0.0417 ? "1S" :
target_Res_In_Min <= 0.167 ? "5S" :
target_Res_In_Min <= 0.376 ? "15S" :
target_Res_In_Min <= 0.751 ? "30S" :
target_Res_In_Min <= 1440 ? tostring(round(target_Res_In_Min)) :
tostring(round(min(target_Res_In_Min / 1440, 365))) + "D"
f_getPivotHighLow(oOpen, oClose, oHigh, oLow, HTFMultiplier, resolution, PivotLength)=>
derivedResolution = resolution == ""? f_multiple_resolution(HTFMultiplier) : resolution
HTFHigh = f_secureSecurity(syminfo.tickerid, derivedResolution, oHigh)
HTFLow = f_secureSecurity(syminfo.tickerid, derivedResolution, oLow)
CLOSEprev = f_secureSecurity(syminfo.tickerid, derivedResolution, oClose)
pivothi = pivothigh(HTFHigh, PivotLength, PivotLength)
pivotlo = pivotlow(HTFLow, PivotLength, PivotLength)
pivothi := na(pivothi)? nz(pivothi[1]) : pivothi
pivotlo := na(pivotlo)? nz(pivotlo[1]) : pivotlo
[pivothi, pivotlo]
[oOpen, oClose, oHigh, oLow] = f_getOscilatorValues(oscilatorType, length, shortlength, longlength)
[dir, trailingStop] = f_getSupertrend(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, stopMultiplier, wicks)
candleColor = colorByPreviousClose ?
(oClose[1] < oClose ? color.green : oClose[1] > oClose ? color.red : color.silver) :
(oOpen < oClose ? color.green : oOpen > oClose ? color.red : color.silver)
plotcandle(oOpen, oHigh, oLow, oClose, 'Oscilator Candles', color = candleColor)
[buyStopDerived, sellStopDerived, barState] = f_getBuySellStops(oOpen, oClose, oHigh, oLow, AtrMAType, AtrLength, wicks, considerWicksForDelayByStep, stopMultiplier, targetMultiplier)
trailingStopDerived = barState == 1? buyStopDerived : sellStopDerived
plot(showSupertrend?trailingStopDerived:na, title="TrailingStop", style=plot.style_linebr, linewidth=1, color= barState == 1 ? color.green : color.red)
[pivotHigh, pivotLow] = f_getPivotHighLow(open, close, high, low, HTFMultiplier, resolution, PivotLength)
buyCondition = (barState == 1) and (close > pivotHigh or not useHTFPivot)
exitBuyConditin = (barState == -1)
sellCondition = (barState == -1) and (close < pivotLow or not useHTFPivot)
exitSellCondition = (barState == 1)
// strategy.risk.allow_entry_in(tradeDirection)
strategy.entry("Buy", strategy.long, when=buyCondition and inDateRange, oca_name="oca")
strategy.entry("Sell", strategy.short, when=sellCondition and inDateRange, oca_name="oca")
strategy.close("Buy", when = exitBuyConditin)
strategy.close( "Sell", when = exitSellCondition)