Русский
preview
Métodos de discretização dos movimentos de preço em Python

Métodos de discretização dos movimentos de preço em Python

MetaTrader 5Sistemas de negociação |
121 0
Yevgeniy Koshtenko
Yevgeniy Koshtenko

Introdução

Todo desenvolvedor de sistemas de trading, mais cedo ou mais tarde, se depara com uma questão fundamental: como "fatiar" corretamente os dados de mercado para análise? A abordagem tradicional com intervalos de tempo fixos lembra tentar medir o pulso de um atleta a cada 5 minutos, sem importar se ele está em uma arrancada ou descansando. Durante momentos de alta atividade, informações cruciais se perdem dentro de uma única barra, e em horas calmas, temos dezenas de barras vazias que geram ruído informacional.

Trabalhando com estratégias algorítmicas, observei repetidamente como movimentos fortes de preço "se dissolviam" dentro dos timeframes padrão. Imagine a divulgação de uma notícia importante: em um único minuto o mercado pode se mover mais do que nas horas anteriores. E nosso sistema, fiel ao seu timeframe de um minuto, perde toda a riqueza dessa microestrutura.

Esse problema me levou a mergulhar fundo em métodos alternativos de discretização dos dados de preço. Neste artigo, compartilho minha experiência prática no desenvolvimento de uma biblioteca em Python que implementa diversas abordagens para formação de barras, desde as clássicas Volume e Range bars até métodos mais exóticos como Renko e Kagi.

Vamos abordar não apenas os aspectos técnicos da implementação, mas também o embasamento matemático de cada método. Daremos atenção especial à integração com o MetaTrader 5, já que isso torna nossa solução aplicável na prática para o trading real. O código é aberto, testado com dados reais e, o mais importante, otimizado para funcionar em tempo real.

Para os desenvolvedores, será interessante mergulhar nos detalhes da implementação de atualização contínua das barras e otimização de desempenho. Os traders encontrarão insights valiosos sobre como diferentes tipos de barras podem melhorar suas estratégias. E para aqueles profundamente envolvidos em análise de dados, reservamos uma seção sobre a comparação estatística da eficácia de diferentes abordagens.


Formulação do problema de discretização

Quando comecei a me dedicar seriamente ao algotrading, uma pergunta não saía da minha cabeça: por que estamos tão obcecados com intervalos de tempo? Você olha o gráfico de 5 minutos do EURUSD durante uma divulgação do BCE, e o que vê? Uma única barra enorme que esconde um movimento de 80 pontos com cinco reversões. E uma hora depois, uma sequência de barras pequenas onde o preço apenas oscila no mesmo lugar.

Engraçado, mas encontrei um problema semelhante no meu trabalho anterior, onde eu analisava tráfego de rede. Lá também abandonamos os intervalos fixos em favor de uma discretização adaptativa, coletando pacotes não pelo tempo, mas pelo volume de dados ou por eventos. E então tive um estalo: por que não aplicar essa mesma lógica aos dados de mercado?

Vamos refletir: o que realmente determina o movimento do preço? O tempo? Não. O volume negociado? Mais próximo. A atividade dos grandes players? Ainda mais perto. Na verdade, todos esses fatores são importantes, mas em momentos diferentes, um ou outro assume o papel principal.

Imagine um dia típico de negociação. Pela manhã, baixa atividade, poucos negócios. Aqui podemos usar barras horárias tranquilamente. Na abertura de Londres — explosão de volume, precisamos de discretização por volume. Em eventos de notícias com movimentos bruscos, funcionam melhor as Range bars. E em períodos calmos ou de tendência, Renko ou Kagi mostram resultados excelentes.

Por isso decidi criar uma ferramenta universal, uma espécie de canivete suíço para lidar com dados de mercado. Um script é um módulo em Python, que é capaz de:

  • conectar-se ao MetaTrader 5 e obter dados em tempo real,
  • construir diferentes tipos de barras em tempo real,
  • selecionar automaticamente o método ideal de discretização,
  • entregar tudo isso em um formato prático para análise.

Complicado? À primeira vista, sim. Mas quando você divide a tarefa em partes, tudo fica mais simples. Nas próximas seções, vou mostrar como realizamos isso e algumas descobertas interessantes que fizemos pelo caminho.


Preparação do ambiente

Em qualquer projeto sério, preparar o ambiente é um verdadeiro desafio. Principalmente quando se trabalha com MetaTrader 5 e Python ao mesmo tempo. Após alguns meses de experimentos, cheguei ao stack ideal:

  • Python 3.9 ,
  • MetaTrader 5 para acesso aos dados de mercado,
  • pandas e numpy para processamento de dados (essenciais),
  • scipy e statsmodels para análise estatística,
  • mplfinance para construção de gráficos,

Curiosidade: é possível usar o plotly para visualização, mas o bom e velho matplotlib é mais rápido. E no algotrading, cada milissegundo conta.


Métodos de discretização de séries temporais

Sabe o que análise de dados do mercado e a mecânica quântica têm em comum? Em ambos os casos, a forma de observar altera o próprio objeto da observação. A maneira como "fatiamos" os dados de mercado determina em grande parte o que veremos neles.

Tradicionais OHLC

Vamos começar pelo básico, as Volume bars. Aqui tudo gira em torno do volume negociado. Atingiu 100 contratos, fecha-se a barra. Simples? Sim. Eficaz? Muito. Especialmente quando se quer captar a atividade dos grandes players. Lembro de um caso no ouro, o timeframe padrão mostrava marasmo, mas as volume bars desenhavam claramente a acumulação de posição por um participante de peso.

Range bars — o próximo nível. Aqui analisamos a variação de preço. Atingiu 10 pontos de movimento, nova barra. Não importa se isso ocorreu em um segundo ou em uma hora. Em movimentos de tendência é uma maravilha: nada de ruído, apenas a estrutura pura da tendência.

Agora, Momentum bars — meu xodó pessoal. Elas acompanham o impulso do movimento. Imagine que você não mede a distância, mas sim a velocidade da mudança de preço. Em movimentos fortes, oferecem um detalhamento incrível, e em consolidações, não geram ruído.

Volatility Regime bars — aqui já entramos na pilotagem avançada. Elas se adaptam à volatilidade atual do mercado. Em períodos calmos, as barras se alargam; em momentos turbulentos, se contraem. São especialmente boas em mercados de criptomoedas, onde a volatilidade pode multiplicar em minutos.

Swing-point bars capturam os extremos locais. É como desenhar um gráfico de máximo em máximo ou de mínimo em mínimo. Lembra um pouco o Price Action clássico, mas com base matemática precisa.

Acceleration bars — um método relativamente novo. Monitoram a aceleração do preço. Sabe aqueles momentos em que o movimento acelera de repente? São exatamente esses que as acceleration bars detectam. Muito úteis no scalping, onde é crucial identificar o início de um impulso.


Implementação das Volume e Range bars

Volume e Range bars são como dois microscópios distintos para analisar o mercado. Volume bars focam na atividade dos traders, Range bars na volatilidade. Durante o desenvolvimento delas, cheguei a algumas descobertas interessantes.

Volume Bars

Primeiro sobre as Volume bars. Veja só o paradoxo: em períodos de alta atividade, elas se contraem como uma mola, de modo que vinte barras podem caber em um único minuto padrão. Já nas horas calmas, uma única Volume bar pode se estender por meio dia. E isso é o ideal, pois queremos ver o mercado no seu ritmo natural.

def create_volume_bars(self, volume_threshold: float) -> pd.DataFrame:
    df = self.get_raw_data()
    bars = []
    current_volume = 0
    bar_open = df.iloc[0]['open']
    bar_high = df.iloc[0]['high']
    bar_low = df.iloc[0]['low']
    bar_time = df.iloc[0]['time']
    
    for _, row in df.iterrows():
        current_volume += row['tick_volume']
        bar_high = max(bar_high, row['high'])
        bar_low = min(bar_low, row['low'])
        
        if current_volume >= volume_threshold:
            bars.append({
                'time': bar_time,
                'open': bar_open,
                'high': bar_high,
                'low': bar_low,
                'close': row['close'],
                'volume': current_volume
            })
            current_volume = 0
            bar_open = row['close']
            bar_high = row['high']
            bar_low = row['low']
            bar_time = row['time']

Com as Range bars foi ainda mais interessante. Descobri que elas destacam muito bem os níveis de suporte e resistência. Por quê? Porque cada barra tem um tamanho fixo. Quando o preço encontra um nível, as barras começam a se "compressar"; esse é um sinal claro de que o nível é relevante.

Range Bars

Aliás, sobre a escolha do threshold para os dois tipos de barras. Testei vários métodos, mas o que funciona melhor é uma regra simples: para Volume bars uso 0.1% do volume médio diário, para Range bars, 0.5 do ATR. Às vezes, soluções simples realmente são melhores que as complexas.


Momentum-based bars (formação de barra com base no acúmulo de impulso do movimento)

As Momentum bars foram uma verdadeira descoberta. Trabalhando nelas, percebi como o mercado se move em surtos: primeiro acumula energia, depois vem uma liberação abrupta. Eis como implementei isso:

def create_momentum_bars(self, momentum_threshold: float) -> pd.DataFrame:
    df = self.get_raw_data()
    bars = []
    bar_open = df.iloc[0]['open']
    bar_high = df.iloc[0]['high']
    bar_low = df.iloc[0]['low']
    bar_time = df.iloc[0]['time']
    current_volume = 0
    
    for _, row in df.iterrows():
        momentum = abs(row['close'] - bar_open)  # Ключевой момент - считаем импульс
        bar_high = max(bar_high, row['high'])
        bar_low = min(bar_low, row['low'])
        current_volume += row['tick_volume']
        
        if momentum >= momentum_threshold:  # Порог преодолен - формируем новый бар
            bars.append({
                'time': bar_time,
                'open': bar_open,
                'high': bar_high,
                'low': bar_low,
                'close': row['close'],
                'volume': current_volume,
                'momentum': momentum  # Добавил для анализа
            })
            
            # Сброс параметров для нового бара
            bar_open = row['close']
            bar_high = row['high']
            bar_low = row['low']
            bar_time = row['time']
            current_volume = 0

Nos testes com EUR/USD, essa implementação apresentou resultados excelentes, especialmente durante eventos de notícias. Cada impulso significativo gera uma barra separada, oferecendo uma visão muito mais clara do movimento. O threshold dinâmico momentum_threshold = 0.8 ATR para mercados calmos e 1.2 ATR para mercados voláteis revelou-se o equilíbrio ideal entre sensibilidade e filtragem de ruído.

Momentum Bars


Volatility Regime bars (ajuste adaptativo do tamanho da barra com base no regime de volatilidade)

Operando criptomoedas, notei algo curioso: os timeframes padrão viram uma bagunça durante explosões de volatilidade. E então veio a ideia de: e se o tamanho da barra se ajustasse ao regime atual do mercado?

def create_volatility_bars(self, base_threshold: float, lookback: int = 20) -> pd.DataFrame:
    df = self.get_raw_data()
    bars = []
    current_volume = 0
    
    # Динамический расчет ATR для определения режима волатильности
    df['tr'] = df.apply(lambda x: max(
        x['high'] - x['low'],
        abs(x['high'] - x['close'].shift(1)),
        abs(x['low'] - x['close'].shift(1))
    ), axis=1)
    df['atr'] = df['tr'].rolling(lookback).mean()
    
    bar_open = df.iloc[0]['open']
    bar_high = df.iloc[0]['high']
    bar_low = df.iloc[0]['low']
    bar_time = df.iloc[0]['time']
    
    for i, row in df.iterrows():
        # Адаптивный порог на основе текущей волатильности
        volatility_ratio = row['atr'] / df['atr'].mean()
        current_threshold = base_threshold * volatility_ratio
        
        bar_high = max(bar_high, row['high'])
        bar_low = min(bar_low, row['low'])
        price_range = bar_high - bar_low
        current_volume += row['tick_volume']
        
        if price_range >= current_threshold:
            bars.append({
                'time': bar_time,
                'open': bar_open,
                'high': bar_high,
                'low': bar_low,
                'close': row['close'],
                'volume': current_volume,
                'threshold': current_threshold  # Для анализа
            })
            
            bar_open = row['close']
            bar_high = row['high']
            bar_low = row['low']
            bar_time = row['time']
            current_volume = 0
            
    return pd.DataFrame(bars)

A sacada está no fato de que o threshold para formação da barra não é fixo, mas muda conforme o mercado. Em períodos calmos, as barras se estendem, dando uma visão mais limpa. Em momentos agitados elas encolhem, para que não percamos movimentos importantes.

Barras de volatilidade

A descoberta mais interessante surgiu no BTC/USD: antes de grandes movimentos, a frequência de formação de barras começa a crescer exponencialmente. Isso virou um excelente preditor de movimentos explosivos futuros.


Swing-point bars (formação de barras com base em máximas e mínimas locais)

Desenvolvendo as Swing-point bars, tentei resolver o problema de perder pontos importantes de reversão. Sabe aqueles momentos em que o preço vira bruscamente e, no gráfico comum, isso vira uma barra confusa e sem forma?

def create_swing_bars(self, swing_threshold: float = 0.001) -> pd.DataFrame:
    df = self.get_raw_data()
    bars = []
    
    current_swing = 'none'  # Текущее направление свинга
    potential_swing_price = df.iloc[0]['close']
    bar_start_price = df.iloc[0]['close']
    bar_time = df.iloc[0]['time']
    volume_sum = 0
    
    for i, row in df.iterrows():
        volume_sum += row['tick_volume']
        price = row['close']
        
        if current_swing == 'none':
            if abs(price - bar_start_price) >= swing_threshold:
                current_swing = 'up' if price > bar_start_price else 'down'
                potential_swing_price = price
        
        elif current_swing == 'up':
            if price > potential_swing_price:
                potential_swing_price = price
            elif (potential_swing_price - price) >= swing_threshold:
                bars.append({
                    'time': bar_time,
                    'open': bar_start_price,
                    'high': potential_swing_price,
                    'low': min(bar_start_price, price),
                    'close': price,
                    'volume': volume_sum,
                    'swing_type': 'up_to_down'
                })
                bar_start_price = price
                bar_time = row['time']
                volume_sum = 0
                current_swing = 'down'
                potential_swing_price = price
        
        elif current_swing == 'down':
            if price < potential_swing_price:
                potential_swing_price = price
            elif (price - potential_swing_price) >= swing_threshold:
                bars.append({
                    'time': bar_time,
                    'open': bar_start_price,
                    'high': max(bar_start_price, price),
                    'low': potential_swing_price,
                    'close': price,
                    'volume': volume_sum,
                    'swing_type': 'down_to_up'
                })
                bar_start_price = price
                bar_time = row['time']
                volume_sum = 0
                current_swing = 'up'
                potential_swing_price = price
                
    return pd.DataFrame(bars)

O diferencial desse código é que ele não apenas identifica extremos locais, mas rastreia reversões "significativas". O threshold aqui atua como um filtro de ruído. No GBP/USD, o valor 0.0012 funciona muito bem: elimina pequenas oscilações, mas capta com precisão os pontos-chave de reversão.

Swing-point bars

E sabe de uma coisa? Em mercados de tendência essas barras fornecem sinais incrivelmente claros. Principalmente quando você observa a sequência de reversões, que frequentemente forma belos padrões harmônicos. E em consolidações, mostram bem a acumulação antes de um grande movimento.


Acceleration bars (barras com base na variação da aceleração do preço)

Observando o movimento do preço nos futuros do S&P500, notei um padrão interessante: antes de movimentos fortes, o preço não apenas acelera, mas faz isso de uma forma específica. Isso inspirou a criação de dois tipos de barras: Speed bars (monitoram a velocidade) e Acceleration bars (acompanham a aceleração).

def create_acceleration_bars(self, acc_threshold: float = 0.0001) -> pd.DataFrame:
    df = self.get_raw_data()
    bars = []
    
    # Считаем скорость изменения цены
    df['speed'] = df['close'].diff() / df.index.to_series().diff().dt.total_seconds()
    # Считаем ускорение
    df['acceleration'] = df['speed'].diff() / df.index.to_series().diff().dt.total_seconds()
    
    bar_open = df.iloc[0]['open']
    bar_high = df.iloc[0]['high']
    bar_low = df.iloc[0]['low']
    bar_time = df.iloc[0]['time']
    
    acc_sum = 0
    volume_sum = 0
    
    for i, row in df.iterrows():
        volume_sum += row['tick_volume']
        acc_sum += abs(row['acceleration'])
        bar_high = max(bar_high, row['high'])
        bar_low = min(bar_low, row['low'])
        
        # Новый бар формируется при накоплении заданного ускорения
        if acc_sum >= acc_threshold:
            bars.append({
                'time': bar_time,
                'open': bar_open,
                'high': bar_high,
                'low': bar_low,
                'close': row['close'],
                'volume': volume_sum,
                'acceleration': acc_sum
            })
            
            bar_open = row['close']
            bar_high = row['high']
            bar_low = row['low']
            bar_time = row['time']
            acc_sum = 0
            volume_sum = 0
            
    return pd.DataFrame(bars)

Na prática, descobri que as Acceleration bars funcionam muito bem no pré-mercado de ações americanas. Elas literalmente "enxergam" o acúmulo de pressão antes de um movimento forte. Já nas criptomoedas geram uma quantidade enorme de falsos sinais, já que os dados são barulhentos demais.

Acceleration bars

Curiosamente, os melhores resultados apareceram no par USD/JPY durante a sessão de Tóquio. Provavelmente por causa da natureza específica desse mercado, onde ocorrem frequentemente movimentos bruscos após períodos de calma.


New High/Low Sequence bars (barras com base na velocidade de renovação dos extremos)

Durante a análise de mercado, notei que a força de uma tendência muitas vezes não está no tamanho do movimento, mas na velocidade com que os máximos ou mínimos são atualizados. Isso fica especialmente evidente nos futuros, onde o preço às vezes avança em pequenos passos, mas com grande persistência numa direção só.

def create_sequence_bars(self, sequence_threshold: int = 3, time_threshold: int = 300) -> pd.DataFrame:
    df = self.get_raw_data()
    bars = []
    
    high_sequence = 0  # Счетчик новых максимумов
    low_sequence = 0   # Счетчик новых минимумов
    bar_open = df.iloc[0]['open']
    bar_high = df.iloc[0]['high']
    bar_low = df.iloc[0]['low']
    bar_time = df.iloc[0]['time']
    last_high = bar_high
    last_low = bar_low
    volume_sum = 0
    start_time = bar_time
    
    for i, row in df.iterrows():
        current_time = row['time']
        volume_sum += row['tick_volume']
        time_delta = (current_time - start_time).total_seconds()
        
        # Проверяем обновление максимумов/минимумов
        if row['high'] > last_high:
            high_sequence += 1
            low_sequence = 0
            last_high = row['high']
        elif row['low'] < last_low:
            low_sequence += 1
            high_sequence = 0
            last_low = row['low']
            
        bar_high = max(bar_high, row['high'])
        bar_low = min(bar_low, row['low'])
        
        # Формируем бар если набралась последовательность или вышли за время
        if (high_sequence >= sequence_threshold or 
            low_sequence >= sequence_threshold or 
            time_delta >= time_threshold):
            
            bars.append({
                'time': bar_time,
                'open': bar_open,
                'high': bar_high,
                'low': bar_low,
                'close': row['close'],
                'volume': volume_sum,
                'sequence_type': 'up' if high_sequence > low_sequence else 'down',
                'sequence_count': max(high_sequence, low_sequence)
            })
            
            bar_open = row['close']
            bar_high = row['high']
            bar_low = row['low']
            bar_time = current_time
            start_time = current_time
            high_sequence = 0
            low_sequence = 0
            last_high = bar_high
            last_low = bar_low
            volume_sum = 0
            
    return pd.DataFrame(bars)

No EUR/USD, essa abordagem funcionou especialmente bem durante movimentos de tendência, pois evidencia a persistência do preço em romper níveis. Interessante notar que sequence_threshold = 3 é o que dá melhor resultado; valores maiores fazem perder reversões importantes, valores menores geram muito ruído.

New High/Low Sequence bars

Vamos ver também como ficam as Renko bars:

Renko Bars

E as barras de três linhas de rompimento:

Barras de três linhas de rompimento

E aqui também as Kagi bars:

Kagi bars




Estatísticas básicas (momentos da distribuição, autocorrelação)

Com base nos testes no EURUSD (M15, 01.10.2024 - 15.01.2025):

Quantidade de barras formadas:

  • Tradicional: 825 barras
  • Volume: 793 barras
  • Range: 329 barras
  • Momentum: 48 barras
  • Renko: 98 barras
  • Kagi: 39 barras
  • Three Line Break: 227 barras
  • Volatility Regime: 38 barras
  • Swing Point: 247 barras
  • Acceleration: 393 barras
  • New High/Low: 468 barras

Tamanho médio da barra (em pontos):

  • Tradicional: 6.29
  • Volume: 9.40
  • Range: 15.41
  • Momentum: 32.07
  • Renko: 10.00
  • Kagi: 18.95
  • Three Line Break: 4.85
  • Volatility Regime: 33.62
  • Swing Point: 17.29
  • Acceleration: 12.95
  • New High/Low: 11.08

Normalidade da distribuição (p-valor):

  • Kagi: 0.426 (mais próxima de distribuição normal)
  • Volatility Regime: 0.931 (melhor resultado)
  • Swing Point: 0.025
  • Demais: <0.001 (forte desvio da normalidade)

Autocorrelação (p-valor Ljung-Box):

  • Tradicional: 0.031
  • Volume: 0.042
  • Range: 0.760 (baixa autocorrelação)
  • Momentum: 0.007 (alta autocorrelação)
  • Kagi: 0.109
  • Volatility Regime: 0.126
  • Acceleration: 0.168
  • New High/Low: 0.136

Entropia informacional (indicador relativo de "informatividade"):

  1. Tradicional: -114.770 (máxima)
  2. Volume: -101.388
  3. New High/Low: -67.108
  4. Three Line Break: -55.022
  5. Acceleration: -51.867
  6. Range: -30.120
  7. Swing Point: -22.500
  8. Momentum: -9.033
  9. Volatility Regime: -7.311
  10. Kagi: -5.818 (mínima)

Principais conclusões:

  • Volatility Regime e Kagi bars apresentam a distribuição mais próxima do normal
  • Range bars demonstram a menor autocorrelação
  • Barras Traditional e Volume retêm o máximo de informação, mas com mais ruído
  • Momentum e Volatility Regime bars oferecem o maior detalhamento dos movimentos relevantes


Testes de estacionaridade e normalidade

A análise dos testes de Dickey-Fuller (ADF) revelou resultados interessantes:

Teste de estacionaridade (estatística ADF, p-valor):

  • Traditional: -10.98, p < 0.001
  • Volume: -10.67, p < 0.001
  • Range: -14.35, p < 0.001
  • Momentum: -3.80, p = 0.003
  • Renko: -7.87, p < 0.001
  • Kagi: -3.88, p = 0.002
  • Volatility Regime: -1.81, p = 0.377
  • Swing Point: -12.38, p < 0.001
  • Acceleration: -15.79, p < 0.001
  • New High/Low: -11.15, p < 0.001

Teste de normalidade (estatística, p-valor):

  • Tradicional: 161.76, p < 0.001
  • Volume: 151.28, p < 0.001
  • Range: 21.70, p < 0.001
  • Momentum: 31.57, p < 0.001
  • Renko: 815.37, p < 0.001
  • Kagi: 1.71, p = 0.426
  • Volatility Regime: 0.14, p = 0.931
  • Swing Point: 7.42, p = 0.025
  • Acceleration: 59.09, p < 0.001
  • New High/Low: 79.08, p < 0.001

Principais insights:

  1. 1. Todos os tipos de barras, exceto Volatility Regime, demonstram estacionaridade (p < 0.05)
  2. 2. Somente Kagi e Volatility Regime apresentam distribuição normal
  3. 3. As barras com maior estacionaridade são Acceleration e Range
  4. 4. Renko apresenta o maior desvio da normalidade


Comparação da entropia informacional dos datasets

Ao analisar a entropia de diferentes tipos de barras, notei uma regularidade interessante: quanto maior a entropia, mais "crua" é a informação de mercado contida na barra, mas também se torna mais difícil extrair dela um sinal útil.

Distribuição por nível de entropia:

  • Tradicional: -114.770 (máxima)
  • Volume: -101.388
  • New High/Low: -67.108
  • Three Line Break: -55.022
  • Acceleration: -51.867
  • Range: -30.120
  • Swing Point: -22.500
  • Momentum: -9.033
  • Volatility Regime: -7.311
  • Kagi: -5.818 (mínima)

Por que isso é importante? Imagine que você está tentando encontrar uma agulha no palheiro. As barras Traditional são o palheiro inteiro, enquanto as Kagi são um feixe já selecionado, tornando muito mais fácil encontrar a agulha.

Quanto ao grau de informatividade, as barras se dividem em grupos:

Máxima informatividade (mas com muito ruído):

  • Tradicional e Volume
  • Capturam todos os micromovimentos do mercado
  • Boas para aprendizado de máquina profundo

Equilíbrio ideal:

  • New High/Low
  • Acceleration
  • Three Line Break
  • Funcionam bem em trading algorítmico

Mínima entropia (sinais limpos):

  • Kagi
  • Volatility Regime
  • Momentum
  • Perfeitas para trading manual


Avaliação da capacidade preditiva dos diferentes tipos de barras

Trabalhando com modelos preditivos, cheguei a uma ideia interessante: e se usássemos diferentes tipos de barras como "especialistas" individuais dentro de um ensemble? Cada tipo de barra "enxerga" o mercado à sua maneira, e essas visões podem ser combinadas.

Força preditiva por tipo de barra:

Alta previsibilidade:

  • Momentum (p=0.007)
    • Melhores resultados em movimentos bruscos
    • Mostra claramente a força da tendência
    • Mínimo de falsos sinais em tendências fortes
  • Renko (p=0.018)
    • Excelente em movimentos de tendência
    • Filtragem de ruído muito eficiente
    • Sofre em mercados laterais

Previsibilidade média:

  • Volatility Regime (p=0.126)
  • Acceleration (p=0.168)
  • New High/Low (p=0.136)
  • Kagi (p=0.109)

Baixa previsibilidade:

  • Range (p=0.760)
  • Three Line Break (p=0.686)
  • Swing Point (p=0.709)

A ideia de um modelo multibarras:

Imagine um sistema que analisa todos os tipos de barras simultaneamente. Por exemplo:

  1. Momentum identifica a força do movimento
  2. Volatility Regime ajusta o tamanho da posição
  3. New High/Low confirma a tendência
  4. Kagi filtra os falsos sinais

Nos testes com EUR/USD, essa abordagem trouxe resultados interessantes:

  • Acurácia aumentou em 12%
  • Falsos positivos caíram 23%
  • Drawdown reduziu em 15%


Considerações finais

Trabalhar com diferentes tipos de barras abriu horizontes inesperados. A principal conclusão: não existe um "tipo de barra ideal". Cada um tem seu ponto forte:

  • Tradicional e Volume — para aprendizado de máquina
  • Momentum e Renko — para trading de tendência
  • Kagi e Volatility Regime — para operar em alta volatilidade
  • New High/Low e Acceleration — para scalping

Acredito que o futuro está nas soluções híbridas, capazes de alternar entre tipos de barras conforme as condições do mercado. Imagine uma plataforma que escolhe automaticamente o tipo de barra mais adequado com base no estado atual do mercado e na estratégia de trading.

Na próxima versão da biblioteca, pretendo adicionar otimização automática dos parâmetros para cada tipo de barra e um sistema de comutação dinâmica entre eles. O mercado nunca para, e nossas ferramentas devem evoluir junto com ele.

Traduzido do russo pela MetaQuotes Ltd.
Artigo original: https://www.mql5.com/ru/articles/16914

Arquivos anexados |
Como Implementar Otimização Automática em Expert Advisors MQL5 Como Implementar Otimização Automática em Expert Advisors MQL5
Guia passo a passo para otimização automática em MQL5 para Expert Advisors. Vamos abordar uma lógica de otimização robusta, boas práticas para seleção de parâmetros e como reconstruir estratégias com backtesting. Além disso, métodos mais avançados como a otimização walk-forward serão discutidos para aprimorar sua abordagem de trading.
Avaliação visual e ajuste da negociação no MetaTrader 5 Avaliação visual e ajuste da negociação no MetaTrader 5
No testador de estratégias, é possível não apenas otimizar os parâmetros do robô de negociação. Vamos mostrar como avaliar, após o fato, o histórico de negociação de sua conta e fazer ajustes na negociação dentro do testador, alterando os tamanhos dos stop orders das posições abertas.
Criando um Painel Administrativo de Negociação em MQL5 (Parte III): Aprimorando a Interface com Estilo Visual (I) Criando um Painel Administrativo de Negociação em MQL5 (Parte III): Aprimorando a Interface com Estilo Visual (I)
Neste artigo, focaremos no estilo visual da interface gráfica do usuário (GUI) do nosso Painel Administrativo de Negociação usando MQL5. Exploraremos várias técnicas e recursos disponíveis no MQL5 que permitem a personalização e otimização da interface, garantindo que ela atenda às necessidades dos traders enquanto mantém uma estética atraente.
Do básico ao intermediário: Eventos em Objetos (I) Do básico ao intermediário: Eventos em Objetos (I)
Neste artigo irei ver três dos seis eventos que podem ser disparado pelo MetaTrader 5, quando algo acontece a um objeto presente no gráfico. Estes evento são muito uteis quando o assunto é interação com o usuário. Isto por que sem entender estes eventos, você irá ter muito mais trabalho para manter uma certa configuração no gráfico. Tentando controlar objetos com finalidades específicas.