Subversion Repositories Integrator Subversion

Rev

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

Rev Author Line No. Line
767 blopes 1
package br.com.kronus.strategy;
2
 
3
import java.math.BigDecimal;
4
import java.math.RoundingMode;
5
import java.util.ArrayList;
6
import java.util.List;
7
 
8
import br.com.kronus.core.PadraoGatilho;
9
import br.com.sl.domain.dto.robo.SinalTradeGatilho3;
10
import br.com.sl.domain.model.Candle;
779 blopes 11
import br.com.sl.domain.model.tipos.TipoSinal;
767 blopes 12
import br.com.sl.domain.util.BigDecimalUtils;
13
 
14
public class EstrategiaGatilhoTipo3Sinais {
15
 
16
    private static final int CONTRATOS_TOTAIS = 6;
17
    private static final int CONTRATOS_ENTRADA1 = 4; // 2/3
18
    private static final int CONTRATOS_ENTRADA2 = 2; // 1/3
19
 
20
    /**
21
     * Gera sinais de trade (sem executar backtest) para todos os padrões
22
     * que tenham gatilho 3 identificado.
23
     *
24
     * @param padroes lista de padrões (GR, G1, G2, G3, G4)
25
     * @return lista de sinais de trade conforme a estratégia do Gatilho 3
26
     */
27
    public List<SinalTradeGatilho3> gerarSinais(List<PadraoGatilho> padroes) {
28
        List<SinalTradeGatilho3> sinais = new ArrayList<>();
29
 
30
        if (padroes == null || padroes.isEmpty()) {
31
            return sinais;
32
        }
33
 
34
        for (PadraoGatilho p : padroes) {
35
            if (p == null) continue;
776 blopes 36
 
37
            // só interessa padrão completo até G3
38
            if (p.getTipoPadrao() != PadraoGatilho.TipoPadrao.COMPLETO_G3) {
39
                continue;
40
            }
794 blopes 41
 
767 blopes 42
            Candle ref = p.getReferencia();
770 blopes 43
            Candle g1  = p.getGatilho1();
767 blopes 44
            Candle g2  = p.getGatilho2();
45
            Candle g3  = p.getGatilho3();
46
 
47
            // só interessa padrão completo até G3
48
            if (ref == null || g2 == null || g3 == null) {
49
                continue;
50
            }
51
 
773 blopes 52
            if (g3.isCandleVendedor()) {
53
                // G3 vendedor -> operação VENDIDA
770 blopes 54
                SinalTradeGatilho3 sinal = montarSinalVenda(ref, g1, g2, g3, p);
767 blopes 55
                if (sinal != null) {
56
                    sinais.add(sinal);
57
                }
773 blopes 58
            } else if (g3.isCandleComprador()) {
59
                // G3 comprador -> operação COMPRADA
770 blopes 60
                SinalTradeGatilho3 sinal = montarSinalCompra(ref, g1, g2, g3, p);
767 blopes 61
                if (sinal != null) {
62
                    sinais.add(sinal);
63
                }
64
            }
65
        }
66
 
67
        return sinais;
68
    }
69
 
70
    /**
71
     * Monta sinal de VENDA (referência comprador):
72
     *  - Fibo preço com base nos candles G2 e G3.
776 blopes 73
     *  - 0% no topo de G2
74
     *  - 100% no fundo de G3
767 blopes 75
     */
770 blopes 76
    private SinalTradeGatilho3 montarSinalVenda(Candle ref, Candle g1, Candle g2, Candle g3, PadraoGatilho padrao) {
776 blopes 77
        BigDecimal topoG2   = g2.getMaxima();
78
        BigDecimal fundoG3  = g3.getMinima();
767 blopes 79
 
80
        // Garantia mínima de geometria: topo > fundo
776 blopes 81
        if (BigDecimalUtils.ehMenorOuIgualQue(topoG2, fundoG3)) {
767 blopes 82
            return null;
83
        }
776 blopes 84
 
767 blopes 85
        // Orientação: 0% = topo (G3), 100% = fundo (G2)
776 blopes 86
        BigDecimal base0   = topoG2;
87
        BigDecimal base100 = fundoG3;
767 blopes 88
 
89
        BigDecimal entrada1 = nivelFibo(base0, base100, 50.0);    // 50%
770 blopes 90
        BigDecimal entrada2 = nivelFibo(base0, base100, 25.0);    // 25%
773 blopes 91
        BigDecimal alvo1    = nivelFibo(base0, base100, 100.0);   // 100%
92
        BigDecimal alvo2    = nivelFibo(base0, base100, 123.6);   // 123,6%
767 blopes 93
        BigDecimal stopFib  = nivelFibo(base0, base100, -100.0);  // -100%
94
 
95
        // Stop alternativo: 25% acima do último fundo relevante (aqui uso fundo de G2)
776 blopes 96
        BigDecimal stopAlt = fundoG3.add(
97
                        topoG2.subtract(fundoG3).multiply(BigDecimal.valueOf(0.25))
767 blopes 98
        );
99
 
100
        SinalTradeGatilho3 s = new SinalTradeGatilho3();
794 blopes 101
        s.setIdAtivo(padrao.getIdAtivo());
767 blopes 102
        s.setPadrao(padrao);
103
        s.setReferencia(ref);
770 blopes 104
        s.setGatilho1(g1);
767 blopes 105
        s.setGatilho2(g2);
106
        s.setGatilho3(g3);
107
 
779 blopes 108
        s.setTipoOperacao(TipoSinal.VENDA_V);
767 blopes 109
        s.setContratosTotais(CONTRATOS_TOTAIS);
110
        s.setContratosEntrada1(CONTRATOS_ENTRADA1);
111
        s.setContratosEntrada2(CONTRATOS_ENTRADA2);
112
 
113
        s.setPrecoEntrada1(entrada1.setScale(2, RoundingMode.HALF_UP));
114
        s.setPrecoEntrada2(entrada2.setScale(2, RoundingMode.HALF_UP));
115
        s.setAlvo1(alvo1.setScale(2, RoundingMode.HALF_UP));
116
        s.setAlvo2(alvo2.setScale(2, RoundingMode.HALF_UP));
117
        s.setStopMenos100(stopFib.setScale(2, RoundingMode.HALF_UP));
118
        s.setStopAlternativo(stopAlt.setScale(2, RoundingMode.HALF_UP));
119
 
120
        return s;
121
    }
122
 
123
    /**
124
     * Monta sinal de COMPRA (referência vendedor):
125
     *  - Fibo preço com base nos candles G2 e G3.
776 blopes 126
     *  - 0% no fundo de G2
127
     *  - 100% no topo de G3
767 blopes 128
     */
770 blopes 129
    private SinalTradeGatilho3 montarSinalCompra(Candle ref, Candle g1, Candle g2, Candle g3, PadraoGatilho padrao) {
776 blopes 130
        BigDecimal topoG3   = g3.getMaxima();
131
        BigDecimal fundoG2  = g2.getMinima();
767 blopes 132
 
776 blopes 133
        if (BigDecimalUtils.ehMenorOuIgualQue(topoG3, fundoG2)) {
767 blopes 134
            return null;
135
        }
136
 
137
        // Orientação: 0% = fundo (G3), 100% = topo (G2)
776 blopes 138
        BigDecimal base0   = fundoG2;
139
        BigDecimal base100 = topoG3;
767 blopes 140
 
141
        BigDecimal entrada1 = nivelFibo(base0, base100, 50.0);    // 50%
770 blopes 142
        BigDecimal entrada2 = nivelFibo(base0, base100, 25.0);    // 25%
773 blopes 143
        BigDecimal alvo1    = nivelFibo(base0, base100, 100.0);   // 100%
144
        BigDecimal alvo2    = nivelFibo(base0, base100, 123.6);   // 123,6%
767 blopes 145
        BigDecimal stopFib  = nivelFibo(base0, base100, -100.0);  // -100%
146
 
147
        // Stop alternativo: 25% abaixo do último topo relevante (aqui uso topo de G2)
776 blopes 148
        BigDecimal stopAlt = topoG3.subtract(
149
                        topoG3.subtract(fundoG2).multiply(BigDecimal.valueOf(0.25))
767 blopes 150
        );
151
 
152
        SinalTradeGatilho3 s = new SinalTradeGatilho3();
794 blopes 153
        s.setIdAtivo(padrao.getIdAtivo());
767 blopes 154
        s.setPadrao(padrao);
155
        s.setReferencia(ref);
770 blopes 156
        s.setGatilho1(g1);
767 blopes 157
        s.setGatilho2(g2);
158
        s.setGatilho3(g3);
159
 
779 blopes 160
        s.setTipoOperacao(TipoSinal.COMPRA_C);
767 blopes 161
        s.setContratosTotais(CONTRATOS_TOTAIS);
162
        s.setContratosEntrada1(CONTRATOS_ENTRADA1);
163
        s.setContratosEntrada2(CONTRATOS_ENTRADA2);
164
 
165
        s.setPrecoEntrada1(entrada1.setScale(2, RoundingMode.HALF_UP));
166
        s.setPrecoEntrada2(entrada2.setScale(2, RoundingMode.HALF_UP));
167
        s.setAlvo1(alvo1.setScale(2, RoundingMode.HALF_UP));
168
        s.setAlvo2(alvo2.setScale(2, RoundingMode.HALF_UP));
169
        s.setStopMenos100(stopFib.setScale(2, RoundingMode.HALF_UP));
170
        s.setStopAlternativo(stopAlt.setScale(2, RoundingMode.HALF_UP));
171
 
172
        return s;
173
    }
174
 
175
    /**
176
     * Cálculo genérico do nível de Fibonacci:
177
     * base0 = 0% , base100 = 100%
178
     */
179
    private BigDecimal nivelFibo(BigDecimal base0, BigDecimal base100, double percentual) {
180
        BigDecimal range = base100.subtract(base0);
181
        BigDecimal fator = BigDecimal.valueOf(percentual).movePointLeft(2); // /100
182
        return base0.add(range.multiply(fator));
183
    }
184
 
185
}