Subversion Repositories Integrator Subversion

Rev

Blame | Last modification | View Log | Download | RSS feed

package br.com.kronus.core;

import br.com.ec.core.util.VerificadorUtil;
import br.com.kronus.core.Candle;

import java.util.ArrayList;
import java.util.List;

/**
 * Detector + Monitor de Gatilhos (Referência, G1, G2, G3, G4)
 *
 * REGRAS IMPLEMENTADAS (resumo):
 *
 * Candle Referência:
 *  - Candle que demarca uma região (topo ou fundo) e que posteriormente
 *    será rompido contrariamente à sua tendência pelo Gatilho 1.
 *  - Ex.: candle comprador -> se um candle posterior romper seu FUNDO,
 *        esse posterior é G1 e o rompido é a referência.
 *    Ex.: candle vendedor -> se um candle posterior romper seu TOPO,
 *        esse posterior é G1 e o rompido é a referência.
 *
 * Gatilho 1:
 *  - Primeiro candle que rompe a tendência contrária a algum candle anterior
 *    (sem insiders).
 *  - Se G1 for COMPRADOR: deve romper o TOPO do candle referência.
 *  - Se G1 for VENDEDOR: deve romper o FUNDO do candle referência.
 *
 * Gatilho 2:
 *  - Candle que retorna à região do candle referência buscando liquidez.
 *  - Último candle antes da nova quebra de tendência.
 *  - Fechamento deve estar dentro da região total (incluindo pavio)
 *    do candle referência.
 *  - Se ultrapassar a máxima (ou mínima) do candle referência, deve-se procurar
 *    por um novo candle referência a partir desse candle.
 *  - EXCEÇÃO: se o candle for da mesma tendência de G1 e tiver rompido
 *    sua tendência (novo topo na compra / novo fundo na venda), também é G2.
 *
 * Gatilho 3:
 *  - Candle posterior ao G2.
 *  - Mesma tendência de G1.
 *  - Se referência for COMPRADORA:
 *      * topo de G3 < topo da referência
 *      * G3 rompe o FUNDO do G2
 *      * se romper o topo da referência após o G2 → invalida padrão.
 *  - Se referência for VENDEDORA:
 *      * topo de G3 > topo da referência
 *      * G3 rompe o TOPO do G2
 *      * se romper o fundo da referência após o G2 → invalida padrão.
 *
 * Gatilho 4:
 *  - Desarma a operação.
 *  - Se referência COMPRADORA: seu topo será rompido pelo candle do G4.
 *  - Se referência VENDEDORA: seu fundo será rompido.
 *  - Após G4 a análise recomeça.
 */

//package br.com.kronus.strategy.gatilhos;

import java.util.ArrayList;
import java.util.List;

/**
* Detector de padrões de gatilhos (GR, G1, G2, G3, G4)
* trabalhando tanto em modo backtest quanto em modo tempo real.
*
* Regras resumidas:
*
* GR comprador (A):
*   - Candle comprador.
*   - Último candle da tendência compradora.
*   - Maior topo da pernada compradora.
*   - Após ele, tendência muda para vendedora.
*   - Um vendedor subsequente rompe o fundo de A => G1 vendedor, A vira GR.
*
* GR vendedor (B):
*   - Candle vendedor.
*   - Último candle da tendência vendedora.
*   - Menor fundo da pernada vendedora.
*   - Após ele, tendência muda para compradora.
*   - Um comprador subsequente rompe o topo de B => G1 comprador, B vira GR.
*
* G2 comprador (a partir de GR comprador):
*   - Após G1 (vendedor), surge nova tendência compradora.
*   - O ÚLTIMO candle dessa tendência compradora tem fechamento dentro da região do GR.
*   - Se nessa tendência compradora alguma barra romper o topo do GR, o padrão é descartado.
*   - Se a tendência terminar sem que o último comprador feche dentro da região do GR, descarta.
*
* G3 comprador:
*   - Após G2, o próximo candle deve ser vendedor.
*   - Em uma sequência vendedora, algum vendedor:
*       * rompe o fundo de G2 (mínima < mínima de G2) e
*       * tem topo <= topo do GR
*     => esse candle é G3.
*
* G4 comprador:
*   - Próximo candle após G3.
*   - Se romper o topo do GR (máxima > máxima do GR) => G4.
*   - Desarma a operação, padrão é encerrado, nova análise começa após esse candle.
*
* G2 vendedor (a partir de GR vendedor):
*   - Após G1 (comprador), surge nova tendência vendedora.
*   - O ÚLTIMO candle dessa tendência vendedora tem fechamento dentro da região do GR.
*   - Se nessa tendência vendedora alguma barra romper o fundo do GR, o padrão é descartado.
*
* G3 vendedor:
*   - Após G2, o próximo candle deve ser comprador.
*   - Em uma sequência compradora, algum comprador:
*       * rompe o topo de G2 (máxima > máxima de G2) e
*       * tem fundo >= fundo do GR
*     => esse candle é G3.
*
* G4 vendedor:
*   - Próximo candle após G3.
*   - Se romper o fundo do GR (mínima < mínima do GR) => G4.
*
* Outside em relação ao GR:
*   - Qualquer candle C após o GR que:
*       * C.maxima > GR.maxima E
*       * C.minima < GR.minima
*     => padrão atual é descartado, nova análise começa após C.
*
* Obs.: Quando um ciclo termina (padrão encontrado ou descartado),
* a próxima análise SEMPRE começa após o último candle usado.
*/

public class DetectorGatilhos {

 private final boolean logAtivo;

 // Estado apenas para o modo tempo real
 private int idxProximaAnaliseTempoReal = 0;

 public DetectorGatilhos() {
     this(false);
 }

 public DetectorGatilhos(boolean logAtivo) {
     this.logAtivo = logAtivo;
 }

 private void log(String msg) {
     if (logAtivo) {
         System.out.println(msg);
     }
 }

 private static class ResultadoPadrao {
     PadraoGatilho padrao; // pode ser null (quando não houve padrão válido)
     int lastIndex;        // último índice de candle usado no ciclo

     ResultadoPadrao(PadraoGatilho padrao, int lastIndex) {
         this.padrao = padrao;
         this.lastIndex = lastIndex;
     }
 }

 // =====================================================================
 // API PRINCIPAL – BACKTEST (lista completa de candles)
 // =====================================================================

 public List<PadraoGatilho> identificarPadroes(List<Candle> candles) {
     List<PadraoGatilho> padroes = new ArrayList<>();
     int n = candles.size();
     if (n < 4) {
         return padroes;
     }

     int idxRef = 0;

     while (idxRef < n - 3) {
         ResultadoPadrao resultado = detectarPadraoAPartir(candles, idxRef);

         if (resultado == null) {
             idxRef++;
             continue;
         }

         if (resultado.padrao != null) {
             padroes.add(resultado.padrao);
         }

         // Próxima análise sempre começa após o último candle usado no ciclo
         idxRef = Math.max(resultado.lastIndex + 1, idxRef + 1);
     }

     return padroes;
 }

 private ResultadoPadrao detectarPadraoAPartir(List<Candle> candles, int idxRef) {
     Candle ref = candles.get(idxRef);

     if (ref.isCandleComprador()) {
         return detectarPadraoComprador(candles, idxRef);
     } else if (ref.isCandleVendedor()) {
         return detectarPadraoVendedor(candles, idxRef);
     } else {
         // candle sem tendência não serve como GR
         return new ResultadoPadrao(null, idxRef);
     }
 }

 // =====================================================================
 // CASO 1 – GR COMPRADOR (candle A)
 // =====================================================================

 private ResultadoPadrao detectarPadraoComprador(List<Candle> candles, int idxRef) {
            int n = candles.size();
            Candle ref = candles.get(idxRef); // candidato a GR
            int lastIndex = idxRef;

            // 0) Validar se idxRef pode ser GR comprador (A)
            if (!ref.isCandleComprador()) {
                return new ResultadoPadrao(null, idxRef);
            }

            // 0.1 – início da pernada compradora que termina em A
            int inicioTrendCompra = idxRef;
            for (int i = idxRef - 1; i >= 0; i--) {
                Candle c = candles.get(i);
                if (!c.isCandleComprador()) {
                    break;
                }
                inicioTrendCompra = i;
            }

            // 0.2 – primeiro candle direcional após A
            int idxPrimeiroDirecionalAposRef = -1;
            for (int i = idxRef + 1; i < n; i++) {
                Candle c = candles.get(i);
                if (!c.isCandleComprador() && !c.isCandleVendedor()) {
                    continue;
                }

                // 🔹 OUTSIDE em relação ao GR (APENAS ATÉ G1)
                if (isOutsideReferencia(ref, c)) {
                    lastIndex = i;
                    log(String.format(
                            "RefC[%d]: OUTSIDE em [%d] antes da mudança de tendência. Padrão descartado.",
                            idxRef, i));
                    return new ResultadoPadrao(null, lastIndex);
                }

                idxPrimeiroDirecionalAposRef = i;
                break;
            }

            if (idxPrimeiroDirecionalAposRef == -1) {
                return new ResultadoPadrao(null, lastIndex);
            }

            Candle primeiroDirecional = candles.get(idxPrimeiroDirecionalAposRef);
            if (!primeiroDirecional.isCandleVendedor()) {
                // primeiro direcional após A ainda é comprador → A não é último da pernada
                return new ResultadoPadrao(null, idxRef);
            }

            // 0.3 – A tem o maior topo da pernada compradora
            double topoRef = ref.getMaxima();
            for (int i = inicioTrendCompra; i <= idxRef; i++) {
                Candle c = candles.get(i);
                if (c.getMaxima() > topoRef) {
                    return new ResultadoPadrao(null, idxRef);
                }
            }

            int idxPrimeiroVendedor = idxPrimeiroDirecionalAposRef;

            // 1) Encontrar G1 (vendedor que rompe o fundo do GR)
            int idxG1 = -1;
            Candle g1 = null;

            for (int i = idxPrimeiroVendedor; i < n; i++) {
                Candle c = candles.get(i);

                // 🔹 OUTSIDE em relação ao GR (APENAS ATÉ G1)
                if (isOutsideReferencia(ref, c)) {
                    lastIndex = i;
                    log(String.format(
                            "RefC[%d]: OUTSIDE em [%d] durante busca de G1. Padrão descartado.",
                            idxRef, i));
                    return new ResultadoPadrao(null, lastIndex);
                }

                if (!c.isCandleVendedor()) {
                    // tendência vendedora terminou antes do rompimento
                    lastIndex = i - 1;
                    return new ResultadoPadrao(null, lastIndex);
                }

                lastIndex = i;

                if (c.getMinima() < ref.getMinima()) {
                    idxG1 = i;
                    g1 = c;
                    break;
                }
            }

            if (idxG1 == -1) {
                return new ResultadoPadrao(null, lastIndex);
            }

            log(String.format("RefC[%d] (GR) => G1 (vendedor) em [%d]", idxRef, idxG1));

            // =====================================================
            // A PARTIR DAQUI (G2, G3, G4) NÃO VERIFICAMOS MAIS OUTSIDE
            // =====================================================

            // 2) Encontrar G2 (retorno comprador à região do GR)
            int idxPrimeiroComprador = -1;
            for (int i = idxG1 + 1; i < n; i++) {
                Candle c = candles.get(i);

                if (!c.isCandleComprador() && !c.isCandleVendedor()) {
                    continue;
                }
                if (c.isCandleComprador()) {
                    idxPrimeiroComprador = i;
                    break;
                } else {
                    lastIndex = i;
                }
            }

            if (idxPrimeiroComprador == -1) {
                return new ResultadoPadrao(null, lastIndex);
            }

            boolean rompeuTopoRef = false;
            Candle ultimoCompradorTrend = null;
            int idxUltimoCompradorTrend = -1;

            for (int i = idxPrimeiroComprador; i < n; i++) {
                Candle c = candles.get(i);

                if (!c.isCandleComprador()) {
                    break;
                }

                ultimoCompradorTrend = c;
                idxUltimoCompradorTrend = i;
                lastIndex = i;

                if (c.getMaxima() > ref.getMaxima()) {
                    rompeuTopoRef = true;
                    break;
                }
            }

            if (rompeuTopoRef || idxUltimoCompradorTrend == -1) {
                return new ResultadoPadrao(null, lastIndex);
            }

            boolean fechamentoDentroRegiaoRef =
                    ultimoCompradorTrend.getFechamento() >= ref.getMinima() &&
                    ultimoCompradorTrend.getFechamento() <= ref.getMaxima();

            if (!fechamentoDentroRegiaoRef) {
                return new ResultadoPadrao(null, lastIndex);
            }

            Candle g2 = ultimoCompradorTrend;
            int idxG2 = idxUltimoCompradorTrend;
            log(String.format("RefC[%d], G1[%d] => G2 (comprador) em [%d]", idxRef, idxG1, idxG2));

            // 3) Encontrar G3 (vendedor rompendo fundo de G2, topo <= topo do GR)
            int idxPrimeiroVendedorAposG2 = -1;
            for (int i = idxG2 + 1; i < n; i++) {
                Candle c = candles.get(i);

                if (!c.isCandleComprador() && !c.isCandleVendedor()) {
                    continue;
                }

                if (c.isCandleVendedor()) {
                    idxPrimeiroVendedorAposG2 = i;
                    break;
                } else {
                    lastIndex = i;
                    // pela sua regra, o próximo após G2 deveria ser vendedor
                    return new ResultadoPadrao(null, lastIndex);
                }
            }

            if (idxPrimeiroVendedorAposG2 == -1) {
                return new ResultadoPadrao(null, lastIndex);
            }

            int idxG3 = -1;
            Candle g3 = null;

            for (int i = idxPrimeiroVendedorAposG2; i < n; i++) {
                Candle c = candles.get(i);
                if (!c.isCandleVendedor()) {
                    lastIndex = i - 1;
                    break;
                }

                lastIndex = i;

                boolean rompeFundoG2 = c.getMinima() < g2.getMinima();
                boolean topoMenorOuIgualRef = c.getMaxima() <= ref.getMaxima();

                if (rompeFundoG2 && topoMenorOuIgualRef) {
                    idxG3 = i;
                    g3 = c;
                    break;
                }
            }

            if (idxG3 == -1 || g3 == null) {
                return new ResultadoPadrao(null, lastIndex);
            }

            log(String.format("RefC[%d], G1[%d], G2[%d] => G3 (vendedor) em [%d]",
                    idxRef, idxG1, idxG2, idxG3));

            // 4) G4 – próximo candle rompe topo do GR
            Candle g4 = null;
            int proxIdx = idxG3 + 1;
            if (proxIdx < n) {
                Candle c = candles.get(proxIdx);
                lastIndex = proxIdx;

                if (c.getMaxima() > ref.getMaxima()) {
                    g4 = c;
                    log(String.format("RefC[%d], G1[%d], G2[%d], G3[%d] => G4 em [%d]",
                            idxRef, idxG1, idxG2, idxG3, proxIdx));
                } else {
                    log(String.format("RefC[%d], G1[%d], G2[%d], G3[%d]: próximo candle [%d] não é G4.",
                            idxRef, idxG1, idxG2, idxG3, proxIdx));
                }
            }

            PadraoGatilho padrao = new PadraoGatilho();
            padrao.setReferencia(ref);
            padrao.setGatilho1(g1);
            padrao.setGatilho2(g2);
            padrao.setGatilho3(g3);
            padrao.setGatilho4(g4);

            return new ResultadoPadrao(padrao, lastIndex);
        }


 // =====================================================================
 // CASO 2 – GR VENDEDOR (candle B)
 // =====================================================================

 private ResultadoPadrao detectarPadraoVendedor(List<Candle> candles, int idxRef) {
            int n = candles.size();
            Candle ref = candles.get(idxRef); // candidato a GR vendedor
            int lastIndex = idxRef;

            // 0) Validar se idxRef pode ser GR vendedor (B)
            if (!ref.isCandleVendedor()) {
                return new ResultadoPadrao(null, idxRef);
            }

            // 0.1 – início da pernada vendedora que termina em B
            int inicioTrendVenda = idxRef;
            for (int i = idxRef - 1; i >= 0; i--) {
                Candle c = candles.get(i);
                if (!c.isCandleVendedor()) {
                    break;
                }
                inicioTrendVenda = i;
            }

            // 0.2 – primeiro candle direcional após B
            int idxPrimeiroDirecionalAposRef = -1;
            for (int i = idxRef + 1; i < n; i++) {
                Candle c = candles.get(i);
                if (!c.isCandleComprador() && !c.isCandleVendedor()) {
                    continue;
                }

                // 🔹 OUTSIDE em relação ao GR (APENAS ATÉ G1)
                if (isOutsideReferencia(ref, c)) {
                    lastIndex = i;
                    log(String.format(
                            "RefV[%d]: OUTSIDE em [%d] antes da mudança de tendência. Padrão descartado.",
                            idxRef, i));
                    return new ResultadoPadrao(null, lastIndex);
                }

                idxPrimeiroDirecionalAposRef = i;
                break;
            }

            if (idxPrimeiroDirecionalAposRef == -1) {
                return new ResultadoPadrao(null, lastIndex);
            }

            Candle primeiroDirecional = candles.get(idxPrimeiroDirecionalAposRef);
            if (!primeiroDirecional.isCandleComprador()) {
                // primeiro direcional após B ainda é vendedor
                return new ResultadoPadrao(null, idxRef);
            }

            // 0.3 – B tem o MENOR fundo da pernada vendedora
            double fundoRef = ref.getMinima();
            for (int i = inicioTrendVenda; i <= idxRef; i++) {
                Candle c = candles.get(i);
                if (c.getMinima() < fundoRef) {
                    return new ResultadoPadrao(null, idxRef);
                }
            }

            int idxPrimeiroComprador = idxPrimeiroDirecionalAposRef;

            // 1) Encontrar G1 (comprador que rompe topo do GR)
            int idxG1 = -1;
            Candle g1 = null;

            for (int i = idxPrimeiroComprador; i < n; i++) {
                Candle c = candles.get(i);

                // 🔹 OUTSIDE em relação ao GR (APENAS ATÉ G1)
                if (isOutsideReferencia(ref, c)) {
                    lastIndex = i;
                    log(String.format(
                            "RefV[%d]: OUTSIDE em [%d] durante busca de G1. Padrão descartado.",
                            idxRef, i));
                    return new ResultadoPadrao(null, lastIndex);
                }

                if (!c.isCandleComprador()) {
                    lastIndex = i - 1;
                    return new ResultadoPadrao(null, lastIndex);
                }

                lastIndex = i;

                if (c.getMaxima() > ref.getMaxima()) {
                    idxG1 = i;
                    g1 = c;
                    break;
                }
            }

            if (idxG1 == -1) {
                return new ResultadoPadrao(null, lastIndex);
            }

            log(String.format("RefV[%d] (GR) => G1 (comprador) em [%d]", idxRef, idxG1));

            // =====================================================
            // A PARTIR DAQUI (G2, G3, G4) NÃO VERIFICAMOS MAIS OUTSIDE
            // =====================================================

            // 2) Encontrar G2 (retorno vendedor à região do GR)
            int idxPrimeiroVendedor = -1;
            for (int i = idxG1 + 1; i < n; i++) {
                Candle c = candles.get(i);

                if (!c.isCandleComprador() && !c.isCandleVendedor()) {
                    continue;
                }

                if (c.isCandleVendedor()) {
                    idxPrimeiroVendedor = i;
                    break;
                } else {
                    lastIndex = i;
                }
            }

            if (idxPrimeiroVendedor == -1) {
                return new ResultadoPadrao(null, lastIndex);
            }

            boolean rompeuFundoRef = false;
            Candle ultimoVendedorTrend = null;
            int idxUltimoVendedorTrend = -1;

            for (int i = idxPrimeiroVendedor; i < n; i++) {
                Candle c = candles.get(i);

                if (!c.isCandleVendedor()) {
                    break;
                }

                ultimoVendedorTrend = c;
                idxUltimoVendedorTrend = i;
                lastIndex = i;

                if (c.getMinima() < ref.getMinima()) {
                    rompeuFundoRef = true;
                    break;
                }
            }

            if (rompeuFundoRef || idxUltimoVendedorTrend == -1) {
                return new ResultadoPadrao(null, lastIndex);
            }

            boolean fechamentoDentroRegiaoRef =
                    ultimoVendedorTrend.getFechamento() >= ref.getMinima() &&
                    ultimoVendedorTrend.getFechamento() <= ref.getMaxima();

            if (!fechamentoDentroRegiaoRef) {
                return new ResultadoPadrao(null, lastIndex);
            }

            Candle g2 = ultimoVendedorTrend;
            int idxG2 = idxUltimoVendedorTrend;
            log(String.format("RefV[%d], G1[%d] => G2 (vendedor) em [%d]", idxRef, idxG1, idxG2));

            // 3) Encontrar G3 (comprador rompendo topo de G2, fundo >= fundo do GR)
            int idxPrimeiroCompradorAposG2 = -1;
            for (int i = idxG2 + 1; i < n; i++) {
                Candle c = candles.get(i);

                if (!c.isCandleComprador() && !c.isCandleVendedor()) {
                    continue;
                }

                if (c.isCandleComprador()) {
                    idxPrimeiroCompradorAposG2 = i;
                    break;
                } else {
                    lastIndex = i;
                    return new ResultadoPadrao(null, lastIndex);
                }
            }

            if (idxPrimeiroCompradorAposG2 == -1) {
                return new ResultadoPadrao(null, lastIndex);
            }

            int idxG3 = -1;
            Candle g3 = null;

            for (int i = idxPrimeiroCompradorAposG2; i < n; i++) {
                Candle c = candles.get(i);
                if (!c.isCandleComprador()) {
                    lastIndex = i - 1;
                    break;
                }

                lastIndex = i;

                boolean rompeTopoG2 = c.getMaxima() > g2.getMaxima();
                boolean fundoMaiorOuIgualRef = c.getMinima() >= ref.getMinima();

                if (rompeTopoG2 && fundoMaiorOuIgualRef) {
                    idxG3 = i;
                    g3 = c;
                    break;
                }
            }

            if (idxG3 == -1 || g3 == null) {
                return new ResultadoPadrao(null, lastIndex);
            }

            log(String.format("RefV[%d], G1[%d], G2[%d] => G3 (comprador) em [%d]",
                    idxRef, idxG1, idxG2, idxG3));

            // 4) G4 – próximo candle rompe fundo do GR
            Candle g4 = null;
            int proxIdx = idxG3 + 1;
            if (proxIdx < n) {
                Candle c = candles.get(proxIdx);
                lastIndex = proxIdx;

                if (c.getMinima() < ref.getMinima()) {
                    g4 = c;
                    log(String.format("RefV[%d], G1[%d], G2[%d], G3[%d] => G4 em [%d]",
                            idxRef, idxG1, idxG2, idxG3, proxIdx));
                } else {
                    log(String.format("RefV[%d], G1[%d], G2[%d], G3[%d]: próximo candle [%d] não é G4.",
                            idxRef, idxG1, idxG2, idxG3, proxIdx));
                }
            }

            PadraoGatilho padrao = new PadraoGatilho();
            padrao.setReferencia(ref);
            padrao.setGatilho1(g1);
            padrao.setGatilho2(g2);
            padrao.setGatilho3(g3);
            padrao.setGatilho4(g4);

            return new ResultadoPadrao(padrao, lastIndex);
        }


 // =====================================================================
 // HELPER – Candle outside em relação ao GR
 // =====================================================================

 /**
  * Outside em relação ao GR:
  *  - atual.max > GR.max e atual.min < GR.min
  */

 private boolean isOutsideReferencia(Candle referencia, Candle atual) {
     if (referencia == null || atual == null) return false;
     return atual.getMaxima() > referencia.getMaxima()
             && atual.getMinima() < referencia.getMinima();
 }

 // =====================================================================
 // MODO TEMPO REAL (candle a candle)
 // =====================================================================

 /**
  * Reinicia o estado do modo tempo real.
  */

 public void resetTempoReal() {
     this.idxProximaAnaliseTempoReal = 0;
 }

 /**
  * Deve ser chamado SEMPRE que um novo candle for adicionado à lista.
  *
  * Exemplo:
  *   candles.add(novoCandle);
  *   PadraoGatilho padrao = detector.processarCandleTempoReal(candles);
  *
  *   if (padrao != null) {
  *       // padrão completo encontrado
  *   }
  */

 public PadraoGatilho processarCandleTempoReal(List<Candle> candles) {
     int n = candles.size();
     if (n < 4) {
         return null;
     }

     while (idxProximaAnaliseTempoReal < n - 3) {
         ResultadoPadrao resultado = detectarPadraoAPartir(candles, idxProximaAnaliseTempoReal);

         if (resultado == null) {
             idxProximaAnaliseTempoReal++;
             continue;
         }

         int proximoInicio = resultado.lastIndex + 1;
         if (proximoInicio <= idxProximaAnaliseTempoReal) {
             proximoInicio = idxProximaAnaliseTempoReal + 1;
         }
         idxProximaAnaliseTempoReal = proximoInicio;

         if (resultado.padrao != null) {
             return resultado.padrao;
         }
     }

     return null;
 }
}