Subversion Repositories Integrator Subversion

Rev

Rev 773 | Rev 779 | Go to most recent revision | 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.dto.robo.SinalTradeGatilho3.TipoOperacao;
11
import br.com.sl.domain.model.Candle;
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
            }
767 blopes 41
 
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
 
85
        if (g3.getContadorCandle().equals(524)) {
86
                System.out.println("524");
87
        }
767 blopes 88
 
89
        // Orientação: 0% = topo (G3), 100% = fundo (G2)
776 blopes 90
        BigDecimal base0   = topoG2;
91
        BigDecimal base100 = fundoG3;
767 blopes 92
 
93
        BigDecimal entrada1 = nivelFibo(base0, base100, 50.0);    // 50%
770 blopes 94
        BigDecimal entrada2 = nivelFibo(base0, base100, 25.0);    // 25%
773 blopes 95
        BigDecimal alvo1    = nivelFibo(base0, base100, 100.0);   // 100%
96
        BigDecimal alvo2    = nivelFibo(base0, base100, 123.6);   // 123,6%
767 blopes 97
        BigDecimal stopFib  = nivelFibo(base0, base100, -100.0);  // -100%
98
 
99
        // Stop alternativo: 25% acima do último fundo relevante (aqui uso fundo de G2)
776 blopes 100
        BigDecimal stopAlt = fundoG3.add(
101
                        topoG2.subtract(fundoG3).multiply(BigDecimal.valueOf(0.25))
767 blopes 102
        );
103
 
104
        SinalTradeGatilho3 s = new SinalTradeGatilho3();
105
        s.setPadrao(padrao);
106
        s.setReferencia(ref);
770 blopes 107
        s.setGatilho1(g1);
767 blopes 108
        s.setGatilho2(g2);
109
        s.setGatilho3(g3);
110
 
111
        s.setTipoOperacao(TipoOperacao.VENDA);
112
        s.setContratosTotais(CONTRATOS_TOTAIS);
113
        s.setContratosEntrada1(CONTRATOS_ENTRADA1);
114
        s.setContratosEntrada2(CONTRATOS_ENTRADA2);
115
 
116
        s.setPrecoEntrada1(entrada1.setScale(2, RoundingMode.HALF_UP));
117
        s.setPrecoEntrada2(entrada2.setScale(2, RoundingMode.HALF_UP));
118
        s.setAlvo1(alvo1.setScale(2, RoundingMode.HALF_UP));
119
        s.setAlvo2(alvo2.setScale(2, RoundingMode.HALF_UP));
120
        s.setStopMenos100(stopFib.setScale(2, RoundingMode.HALF_UP));
121
        s.setStopAlternativo(stopAlt.setScale(2, RoundingMode.HALF_UP));
122
 
123
        return s;
124
    }
125
 
126
    /**
127
     * Monta sinal de COMPRA (referência vendedor):
128
     *  - Fibo preço com base nos candles G2 e G3.
776 blopes 129
     *  - 0% no fundo de G2
130
     *  - 100% no topo de G3
767 blopes 131
     */
770 blopes 132
    private SinalTradeGatilho3 montarSinalCompra(Candle ref, Candle g1, Candle g2, Candle g3, PadraoGatilho padrao) {
776 blopes 133
        BigDecimal topoG3   = g3.getMaxima();
134
        BigDecimal fundoG2  = g2.getMinima();
767 blopes 135
 
776 blopes 136
        if (BigDecimalUtils.ehMenorOuIgualQue(topoG3, fundoG2)) {
767 blopes 137
            return null;
138
        }
139
 
140
        // Orientação: 0% = fundo (G3), 100% = topo (G2)
776 blopes 141
        BigDecimal base0   = fundoG2;
142
        BigDecimal base100 = topoG3;
767 blopes 143
 
144
        BigDecimal entrada1 = nivelFibo(base0, base100, 50.0);    // 50%
770 blopes 145
        BigDecimal entrada2 = nivelFibo(base0, base100, 25.0);    // 25%
773 blopes 146
        BigDecimal alvo1    = nivelFibo(base0, base100, 100.0);   // 100%
147
        BigDecimal alvo2    = nivelFibo(base0, base100, 123.6);   // 123,6%
767 blopes 148
        BigDecimal stopFib  = nivelFibo(base0, base100, -100.0);  // -100%
149
 
150
        // Stop alternativo: 25% abaixo do último topo relevante (aqui uso topo de G2)
776 blopes 151
        BigDecimal stopAlt = topoG3.subtract(
152
                        topoG3.subtract(fundoG2).multiply(BigDecimal.valueOf(0.25))
767 blopes 153
        );
154
 
155
        SinalTradeGatilho3 s = new SinalTradeGatilho3();
156
        s.setPadrao(padrao);
157
        s.setReferencia(ref);
770 blopes 158
        s.setGatilho1(g1);
767 blopes 159
        s.setGatilho2(g2);
160
        s.setGatilho3(g3);
161
 
162
        s.setTipoOperacao(TipoOperacao.COMPRA);
163
        s.setContratosTotais(CONTRATOS_TOTAIS);
164
        s.setContratosEntrada1(CONTRATOS_ENTRADA1);
165
        s.setContratosEntrada2(CONTRATOS_ENTRADA2);
166
 
167
        s.setPrecoEntrada1(entrada1.setScale(2, RoundingMode.HALF_UP));
168
        s.setPrecoEntrada2(entrada2.setScale(2, RoundingMode.HALF_UP));
169
        s.setAlvo1(alvo1.setScale(2, RoundingMode.HALF_UP));
170
        s.setAlvo2(alvo2.setScale(2, RoundingMode.HALF_UP));
171
        s.setStopMenos100(stopFib.setScale(2, RoundingMode.HALF_UP));
172
        s.setStopAlternativo(stopAlt.setScale(2, RoundingMode.HALF_UP));
173
 
174
        return s;
175
    }
176
 
177
    /**
178
     * Cálculo genérico do nível de Fibonacci:
179
     * base0 = 0% , base100 = 100%
180
     */
181
    private BigDecimal nivelFibo(BigDecimal base0, BigDecimal base100, double percentual) {
182
        BigDecimal range = base100.subtract(base0);
183
        BigDecimal fator = BigDecimal.valueOf(percentual).movePointLeft(2); // /100
184
        return base0.add(range.multiply(fator));
185
    }
186
 
187
}