Subversion Repositories Integrator Subversion

Rev

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