A estratégia produz resultados irrealistamente bons, espreitando o futuro

Um de nossos principais objetivos no desenvolvimento da linguagem Pine é fornecer aos usuários o maior número possível de ferramentas úteis. Estas ferramentas podem ter uma variedade de usos diferentes, e com certas manipulações, alguns indicadores e tipos de gráficos permitem extrair dados das futuras barras ou negociações (em relação à barra atualmente processada). Como um trader não pode receber estes dados em negociações reais, estratégias construídas em torno deles podem produzir resultados irrealisticamente rentáveis ao fazer um backtesting, enquanto que em negociações em tempo real estas negociações seriam perdas. O erro de usar informações do futuro nas estratégias é também chamado de look-ahead bias.

Alguns usuários do TradingView, por ignorância ou com intenção maliciosa, tendem a criar idéias e publicações de scripts explorando este recurso. TradingView não pode remover o recurso em si porque pode ser útil em alguns casos, mas, ao mesmo tempo, estamos comprometidos em alertar os usuários sobre este comportamento.

Estratégias que utilizam velas estilo japonês

Uma razão muito comum para este comportamento é o backtesting da Estratégia nos gráficos estilo japonês (Renko, Kagi, etc.). O problema surge do fato de que o Mecanismo de Backtesting de Estratégia considera cada barra como 4 transações, com os preços de abertura, máximo, mínimo e máximo (como é o caso de um gráfico de velas). Por causa disso, em um gráfico da Renko o Mecanismo de Backtesting de Estratégia pode entrar/sair de uma posição a um preço que não existia na realidade. Além disso, se você definir um valor de tamanho de caixa para ser menor que o mintick, é possível verificar se o próximo preço será maior ou menor que o atual e entrar/sair da posição com antecedência, antes que o Mecanismo de Backtesting processe o preço real.

//@version=4
strategy("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])

Como você pode ver na imagem da tela, esta estratégia simples pode fazer negócios a preços muito próximos aos máximos/mínimos.

Estratégias usando o parâmetro calc_on_order_fills = true

Quando o parâmetro calc_on_order_fills = true é especificado na função de estratégia, o Mecanismo de Backtesting realiza um cálculo adicional dentro da barra após a execução da ordem (em contraste com a situação usual quando a estratégia é calculada apenas no fechamento da barra). Ao mesmo tempo, durante o cálculo, a estratégia tem acesso a muitos parâmetros adicionais da barra, por exemplo, valores máximos e mínimos. Isto permite que você escreva uma estratégia que mostrará um excelente desempenho durante o backtesting:

//@version=4
strategy("CalcOnOrderFillsStrategy", overlay=true, calc_on_order_fills=true)// a variable is used to prevent double entry on the same bar
var lastTimeEntry = 0
 longCondition = close > sma(close, 14)  and lastTimeEntry != time
if longCondition    strategy.entry("LongEntryId", strategy.long)
 strategy.exit("exitId", "LongEntryId", limit=high)
lastTimeEntry := time

Na captura de tela, você pode ver que a entrada está ao preço aberto de uma barra, e a saída acontece na parte alta da mesma barra. Isto é, durante o cálculo, após a execução da ordem, definimos a strategy.exit limit price igual ao alto nível da barra atual, o que não podemos fazer em negociações reais.

A lookahead = barmerge.lookahead_on parâmetro de segurança e qualquer segurança antes do Pine v3

A função de segurança em Pine permite que você solicite dados de outros símbolos e/ou intervalos de tempo. Dependendo da implementação, isto pode permitir que a estratégia receba dados do futuro: se alguém, por exemplo, solicitar o fechamento ou o máximo de uma barra diária, enquanto o backtesting da estratégia poderia conhecer estes valores logo na abertura do dia.

Antes da versão 3, a função de segurança devolveria o valor do prazo superior mesmo antes de ter sido acessível. Na versão 3, este comportamento foi fixado, mas para compatibilidade, o parâmetro lookahead foi adicionado à função de segurança. É falso por padrão (ou seja, a visão futura é desligada), mas você pode habilitá-lo definindo o valor do parâmetro lookahead para barmerge.lookahead_on).

Um exemplo de uma estratégia lucrativa construída com este recurso:

//@version=4
strategy("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 day
if time == dayStart    // distance to daily high is further, so we can earn moreif 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)



Na primeira barra, analisamos se o preço subirá ou descerá mais em relação ao preço de abertura e, com base nisso, entramos em uma posição comprada ou vendida, e depois saímos pelo preço máximo ou mínimo do dia, respectivamente.

Note que nem todos os casos em que a security() tem o argumento barmerge.lookahead_on olha para o futuro: por exemplo, se mudássemos o código acima substituindo time/high/low inside security() por time[1]/high[1]/low[1] respectivamente, receberíamos valores para as barras que já fecharam. Isto é frequentemente usado por codificadores experientes para obter dados de security() sem qualquer risco de lookahead.

No momento, todas estas são formas conhecidas para uma estratégia de olhar para o futuro. Esperamos que esta descrição permita criar estratégias que não tenham estas deficiências, bem como evitar estratégias publicadas cujos autores explorem estas características em suas idéias.