La stratégie produit des résultats irréalistement en se projetant dans l'avenir.
L'un de nos principaux objectifs dans le développement du langage Pine est de fournir aux utilisateurs autant d'outils utiles que possible. Ces outils peuvent avoir une variété d'utilisations différentes, et avec certaines manipulations, certains indicateurs et types de graphiques vous permettent d'extraire des données des futures barres ou trades (par rapport à la barre actuellement traitée). Étant donné qu'un trader ne peut pas recevoir ces données dans le cadre d'un trading réel, les stratégies construites autour d'elles peuvent produire des résultats irréalistement rentables lors d'un backtesting, alors que dans un trading en temps réel, ces trades seraient des pertes. L'erreur consistant à utiliser des informations du futur dans les stratégies est également appelée biais de look-ahead.
Certains utilisateurs de TradingView, par ignorance ou avec des intentions malveillantes, ont tendance à créer des idées et des publications de script exploitant cette fonctionnalité. TradingView ne peut pas supprimer la fonctionnalité elle-même car elle peut être utile dans certains cas, mais en même temps, nous nous engageons à avertir les utilisateurs de ce comportement.
Stratégies utilisant des bougies de style japonais
Une raison très courante de ce comportement est le backtesting de stratégies sur des graphiques de style japonais (Renko, Kagi, etc.). Le problème vient du fait que le moteur de backtesting de stratégie considère chaque barre comme 4 transactions, avec les prix d'ouverture, de haut, de bas et de clôture (comme c'est le cas avec un graphique en chandelier ordinaire). De ce fait, sur un graphique Renko, le moteur de backtesting de stratégie peut entrer/sortir d'une position à un prix qui n'existe pas dans la réalité. En outre, si vous définissez une valeur de taille de boîte inférieure au mintick, il est possible de vérifier si le prochain prix sera supérieur ou inférieur au prix actuel et d'entrer/sortir de la position à l'avance, avant que le moteur de backtesting ne traite le prix réel. macos/deepLFree.translatedWithDeepL.text
//@version=4strategy("My Strategy", overlay=true)if close < close[1] strategy.entry("ShortEntryId", strategy.short)strategy.close("ShortEntryId", when = close > close[1])if close > close[1] strategy.entry("LongEntryId", strategy.long)strategy.close("LongEntryId", when = close < close[1])
JavaScriptComme vous pouvez le voir sur la capture d'écran, cette stratégie simple peut réaliser des transactions à des prix très proches des prix maximum/minimum.
Stratégies utilisant le paramètre calc_on_order_fills = true
Lorsque le paramètre calc_on_order_fills = true est spécifié dans la fonction de la stratégie, le Backtesting Engine effectue un calcul supplémentaire dans la barre après l'exécution de l'ordre (contrairement à la situation habituelle où la stratégie est calculée uniquement à la clôture de la barre). En même temps, pendant le calcul, la stratégie a accès à de nombreux paramètres supplémentaires de la barre, par exemple, les valeurs hautes et basses. Cela vous permet d'écrire une stratégie qui affichera d'excellentes performances lors du backtesting :
//@version=4strategy("CalcOnOrderFillsStrategy", overlay=true, calc_on_order_fills=true)// a variable is used to prevent double entry on the same barvar lastTimeEntry = 0longCondition = close > sma(close, 14) and lastTimeEntry != timeif longCondition strategy.entry("LongEntryId", strategy.long)strategy.exit("exitId", "LongEntryId", limit=high)lastTimeEntry := time
JavaScriptSur la capture d'écran, vous pouvez voir que l'entrée se fait au prix d'ouverture d'une barre, et que la sortie se fait au plus haut de la même barre. C'est-à-dire que pendant le calcul, après l'exécution de l'ordre, nous avons fixé le prix limite de sortie de la stratégie au niveau le plus haut de la barre actuelle, ce que nous ne pouvons pas faire dans le trading réel.
Le paramètre lookahead = barmerge.lookahead_on dans security et dans toute security avant Pine v3
La fonction security de Pine vous permet de demander des données à partir d'autres symboles et/ou d'autres horizons temporels. Selon l'implémentation, cela peut permettre à la stratégie de recevoir des données du futur : si l'on demande, par exemple, la clôture ou le haut d'une barre quotidienne, lors du backtesting, la stratégie pourrait connaître ces valeurs dès l'ouverture de la journée.
Avant la version 3, la fonction de sécurité donnait la valeur de l'intervalle de temps supérieur avant même qu'elle ne soit accessible. Dans la version 3, ce comportement a été corrigé, mais par souci de compatibilité, le paramètre lookahead a été ajouté à la fonction de sécurité. Il est faux par défaut (c'est-à-dire que la vision future est désactivée), mais vous pouvez l'activer en fixant la valeur du paramètre lookahead à barmerge.lookahead_on).
Un exemple de stratégie rentable construite à l'aide de cette fonction :
//@version=4strategy("My Strategy", overlay=true)dayStart = security(syminfo.tickerid, "1D", time, lookahead=barmerge.lookahead_on)dayHigh = security(syminfo.tickerid, "1D", high, lookahead=barmerge.lookahead_on)dayLow = security(syminfo.tickerid, "1D", low, lookahead=barmerge.lookahead_on)// entry at first bar of a dayif time == dayStart // distance to daily high is further, so we can earn more if abs(open - dayHigh) > abs(open - dayLow) strategy.entry("LongEntryId", strategy.long) strategy.exit("exitLongId", "LongEntryId", limit=dayHigh) else strategy.entry("ShortEntryId", strategy.short) strategy.exit("exitShortId", "ShortEntryId", limit=dayLow) plot(dayHigh)plot(dayLow)
JavaScriptSur la première barre, nous analysons si le prix va évoluer davantage à la hausse ou à la baisse par rapport au prix d'ouverture et, sur cette base, nous entrons dans une position longue ou courte, puis nous sortons au prix maximum ou minimum du jour, respectivement.
Notez que tous les cas où security() a l'argument barmerge.lookahead_on ne se projettent pas dans le futur : par exemple, si nous devions modifier le code ci-dessus en remplaçant time/high/low dans security() par time[1]/high[1]/low[1] respectivement, nous recevrions des valeurs pour les barres qui ont déjà été fermées. Cette méthode est souvent utilisée par les codeurs expérimentés pour obtenir des données de security() sans risque de lookahead.
Pour l'instant, ce sont toutes des façons connues pour une stratégie de regarder vers l'avenir. Nous espérons que cette description vous permettra de créer des stratégies qui ne présentent pas ces défauts, ainsi que d'éviter les stratégies publiées dont les auteurs exploitent ces caractéristiques dans leurs idées.