Subversion Repositories Integrator Subversion

Rev

Rev 779 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

package br.com.kronus.strategy;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.List;

import br.com.kronus.core.PadraoGatilho;
import br.com.sl.domain.dto.robo.SinalTradeGatilho3;
import br.com.sl.domain.model.Candle;
import br.com.sl.domain.model.tipos.TipoSinal;
import br.com.sl.domain.util.BigDecimalUtils;

public class EstrategiaGatilhoTipo3Sinais {

    private static final int CONTRATOS_TOTAIS = 6;
    private static final int CONTRATOS_ENTRADA1 = 4; // 2/3
    private static final int CONTRATOS_ENTRADA2 = 2; // 1/3

    /**
     * Gera sinais de trade (sem executar backtest) para todos os padrões
     * que tenham gatilho 3 identificado.
     *
     * @param padroes lista de padrões (GR, G1, G2, G3, G4)
     * @return lista de sinais de trade conforme a estratégia do Gatilho 3
     */

    public List<SinalTradeGatilho3> gerarSinais(List<PadraoGatilho> padroes) {
        List<SinalTradeGatilho3> sinais = new ArrayList<>();

        if (padroes == null || padroes.isEmpty()) {
            return sinais;
        }

        for (PadraoGatilho p : padroes) {
            if (p == null) continue;
           
            // só interessa padrão completo até G3
            if (p.getTipoPadrao() != PadraoGatilho.TipoPadrao.COMPLETO_G3) {
                continue;
            }
           
            Candle ref = p.getReferencia();
            Candle g1  = p.getGatilho1();
            Candle g2  = p.getGatilho2();
            Candle g3  = p.getGatilho3();

            // só interessa padrão completo até G3
            if (ref == null || g2 == null || g3 == null) {
                continue;
            }

            if (g3.isCandleVendedor()) {
                // G3 vendedor -> operação VENDIDA
                SinalTradeGatilho3 sinal = montarSinalVenda(ref, g1, g2, g3, p);
                if (sinal != null) {
                    sinais.add(sinal);
                }
            } else if (g3.isCandleComprador()) {
                // G3 comprador -> operação COMPRADA
                SinalTradeGatilho3 sinal = montarSinalCompra(ref, g1, g2, g3, p);
                if (sinal != null) {
                    sinais.add(sinal);
                }
            }
        }

        return sinais;
    }

    /**
     * Monta sinal de VENDA (referência comprador):
     *  - Fibo preço com base nos candles G2 e G3.
     *  - 0% no topo de G2
     *  - 100% no fundo de G3
     */

    private SinalTradeGatilho3 montarSinalVenda(Candle ref, Candle g1, Candle g2, Candle g3, PadraoGatilho padrao) {
        BigDecimal topoG2   = g2.getMaxima();
        BigDecimal fundoG3  = g3.getMinima();

        // Garantia mínima de geometria: topo > fundo
        if (BigDecimalUtils.ehMenorOuIgualQue(topoG2, fundoG3)) {
            return null;
        }
       
        // Orientação: 0% = topo (G3), 100% = fundo (G2)
        BigDecimal base0   = topoG2;
        BigDecimal base100 = fundoG3;

        BigDecimal entrada1 = nivelFibo(base0, base100, 50.0);    // 50%
        BigDecimal entrada2 = nivelFibo(base0, base100, 25.0);    // 25%
        BigDecimal alvo1    = nivelFibo(base0, base100, 100.0);   // 100%
        BigDecimal alvo2    = nivelFibo(base0, base100, 123.6);   // 123,6%
        BigDecimal stopFib  = nivelFibo(base0, base100, -100.0);  // -100%

        // Stop alternativo: 25% acima do último fundo relevante (aqui uso fundo de G2)
        BigDecimal stopAlt = fundoG3.add(
                        topoG2.subtract(fundoG3).multiply(BigDecimal.valueOf(0.25))
        );

        SinalTradeGatilho3 s = new SinalTradeGatilho3();
        s.setIdAtivo(padrao.getIdAtivo());
        s.setPadrao(padrao);
        s.setReferencia(ref);
        s.setGatilho1(g1);
        s.setGatilho2(g2);
        s.setGatilho3(g3);

        s.setTipoOperacao(TipoSinal.VENDA_V);
        s.setContratosTotais(CONTRATOS_TOTAIS);
        s.setContratosEntrada1(CONTRATOS_ENTRADA1);
        s.setContratosEntrada2(CONTRATOS_ENTRADA2);

        s.setPrecoEntrada1(entrada1.setScale(2, RoundingMode.HALF_UP));
        s.setPrecoEntrada2(entrada2.setScale(2, RoundingMode.HALF_UP));
        s.setAlvo1(alvo1.setScale(2, RoundingMode.HALF_UP));
        s.setAlvo2(alvo2.setScale(2, RoundingMode.HALF_UP));
        s.setStopMenos100(stopFib.setScale(2, RoundingMode.HALF_UP));
        s.setStopAlternativo(stopAlt.setScale(2, RoundingMode.HALF_UP));

        return s;
    }

    /**
     * Monta sinal de COMPRA (referência vendedor):
     *  - Fibo preço com base nos candles G2 e G3.
     *  - 0% no fundo de G2
     *  - 100% no topo de G3
     */

    private SinalTradeGatilho3 montarSinalCompra(Candle ref, Candle g1, Candle g2, Candle g3, PadraoGatilho padrao) {
        BigDecimal topoG3   = g3.getMaxima();
        BigDecimal fundoG2  = g2.getMinima();

        if (BigDecimalUtils.ehMenorOuIgualQue(topoG3, fundoG2)) {
            return null;
        }

        // Orientação: 0% = fundo (G3), 100% = topo (G2)
        BigDecimal base0   = fundoG2;
        BigDecimal base100 = topoG3;

        BigDecimal entrada1 = nivelFibo(base0, base100, 50.0);    // 50%
        BigDecimal entrada2 = nivelFibo(base0, base100, 25.0);    // 25%
        BigDecimal alvo1    = nivelFibo(base0, base100, 100.0);   // 100%
        BigDecimal alvo2    = nivelFibo(base0, base100, 123.6);   // 123,6%
        BigDecimal stopFib  = nivelFibo(base0, base100, -100.0);  // -100%

        // Stop alternativo: 25% abaixo do último topo relevante (aqui uso topo de G2)
        BigDecimal stopAlt = topoG3.subtract(
                        topoG3.subtract(fundoG2).multiply(BigDecimal.valueOf(0.25))
        );

        SinalTradeGatilho3 s = new SinalTradeGatilho3();
        s.setIdAtivo(padrao.getIdAtivo());
        s.setPadrao(padrao);
        s.setReferencia(ref);
        s.setGatilho1(g1);
        s.setGatilho2(g2);
        s.setGatilho3(g3);

        s.setTipoOperacao(TipoSinal.COMPRA_C);
        s.setContratosTotais(CONTRATOS_TOTAIS);
        s.setContratosEntrada1(CONTRATOS_ENTRADA1);
        s.setContratosEntrada2(CONTRATOS_ENTRADA2);

        s.setPrecoEntrada1(entrada1.setScale(2, RoundingMode.HALF_UP));
        s.setPrecoEntrada2(entrada2.setScale(2, RoundingMode.HALF_UP));
        s.setAlvo1(alvo1.setScale(2, RoundingMode.HALF_UP));
        s.setAlvo2(alvo2.setScale(2, RoundingMode.HALF_UP));
        s.setStopMenos100(stopFib.setScale(2, RoundingMode.HALF_UP));
        s.setStopAlternativo(stopAlt.setScale(2, RoundingMode.HALF_UP));

        return s;
    }

    /**
     * Cálculo genérico do nível de Fibonacci:
     * base0 = 0% , base100 = 100%
     */

    private BigDecimal nivelFibo(BigDecimal base0, BigDecimal base100, double percentual) {
        BigDecimal range = base100.subtract(base0);
        BigDecimal fator = BigDecimal.valueOf(percentual).movePointLeft(2); // /100
        return base0.add(range.multiply(fator));
    }
   
}