Subversion Repositories Integrator Subversion

Rev

Rev 767 | Rev 773 | 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;
36
 
37
            Candle ref = p.getReferencia();
770 blopes 38
            Candle g1  = p.getGatilho1();
767 blopes 39
            Candle g2  = p.getGatilho2();
40
            Candle g3  = p.getGatilho3();
41
 
42
            // só interessa padrão completo até G3
43
            if (ref == null || g2 == null || g3 == null) {
44
                continue;
45
            }
46
 
47
            if (ref.isCandleComprador()) {
48
                // GR comprador -> operação VENDIDA
770 blopes 49
                SinalTradeGatilho3 sinal = montarSinalVenda(ref, g1, g2, g3, p);
767 blopes 50
                if (sinal != null) {
51
                    sinais.add(sinal);
52
                }
53
            } else if (ref.isCandleVendedor()) {
54
                // GR vendedor -> operação COMPRADA
770 blopes 55
                SinalTradeGatilho3 sinal = montarSinalCompra(ref, g1, g2, g3, p);
767 blopes 56
                if (sinal != null) {
57
                    sinais.add(sinal);
58
                }
59
            }
60
        }
61
 
62
        return sinais;
63
    }
64
 
65
    /**
66
     * Monta sinal de VENDA (referência comprador):
67
     *  - Fibo preço com base nos candles G2 e G3.
68
     *  - 0% no topo de G3
69
     *  - 100% no fundo de G2
70
     */
770 blopes 71
    private SinalTradeGatilho3 montarSinalVenda(Candle ref, Candle g1, Candle g2, Candle g3, PadraoGatilho padrao) {
767 blopes 72
        BigDecimal topoG3   = g3.getMaxima();
73
        BigDecimal fundoG2  = g2.getMinima();
74
 
75
        // Garantia mínima de geometria: topo > fundo
76
        if (BigDecimalUtils.ehMenorOuIgualQue(topoG3, fundoG2)) {
77
            return null;
78
        }
79
 
80
        // Orientação: 0% = topo (G3), 100% = fundo (G2)
81
        BigDecimal base0   = topoG3;
82
        BigDecimal base100 = fundoG2;
83
 
84
        BigDecimal entrada1 = nivelFibo(base0, base100, 50.0);    // 50%
770 blopes 85
        BigDecimal entrada2 = nivelFibo(base0, base100, 25.0);    // 25%
767 blopes 86
        BigDecimal alvo1    = nivelFibo(base0, base100, 123.6);   // 123,6%
87
        BigDecimal alvo2    = nivelFibo(base0, base100, 300.0);   // 300%
88
        BigDecimal stopFib  = nivelFibo(base0, base100, -100.0);  // -100%
89
 
90
        // Stop alternativo: 25% acima do último fundo relevante (aqui uso fundo de G2)
91
        BigDecimal stopAlt = fundoG2.add(
92
                topoG3.subtract(fundoG2).multiply(BigDecimal.valueOf(0.25))
93
        );
94
 
95
        SinalTradeGatilho3 s = new SinalTradeGatilho3();
96
        s.setPadrao(padrao);
97
        s.setReferencia(ref);
770 blopes 98
        s.setGatilho1(g1);
767 blopes 99
        s.setGatilho2(g2);
100
        s.setGatilho3(g3);
101
 
102
        s.setTipoOperacao(TipoOperacao.VENDA);
103
        s.setContratosTotais(CONTRATOS_TOTAIS);
104
        s.setContratosEntrada1(CONTRATOS_ENTRADA1);
105
        s.setContratosEntrada2(CONTRATOS_ENTRADA2);
106
 
107
        s.setPrecoEntrada1(entrada1.setScale(2, RoundingMode.HALF_UP));
108
        s.setPrecoEntrada2(entrada2.setScale(2, RoundingMode.HALF_UP));
109
        s.setAlvo1(alvo1.setScale(2, RoundingMode.HALF_UP));
110
        s.setAlvo2(alvo2.setScale(2, RoundingMode.HALF_UP));
111
        s.setStopMenos100(stopFib.setScale(2, RoundingMode.HALF_UP));
112
        s.setStopAlternativo(stopAlt.setScale(2, RoundingMode.HALF_UP));
113
 
114
        return s;
115
    }
116
 
117
    /**
118
     * Monta sinal de COMPRA (referência vendedor):
119
     *  - Fibo preço com base nos candles G2 e G3.
120
     *  - 0% no fundo de G3
121
     *  - 100% no topo de G2
122
     */
770 blopes 123
    private SinalTradeGatilho3 montarSinalCompra(Candle ref, Candle g1, Candle g2, Candle g3, PadraoGatilho padrao) {
767 blopes 124
        BigDecimal topoG2   = g2.getMaxima();
125
        BigDecimal fundoG3  = g3.getMinima();
126
 
127
        if (BigDecimalUtils.ehMenorOuIgualQue(topoG2, fundoG3)) {
128
            return null;
129
        }
130
 
131
        // Orientação: 0% = fundo (G3), 100% = topo (G2)
132
        BigDecimal base0   = fundoG3;
133
        BigDecimal base100 = topoG2;
134
 
135
        BigDecimal entrada1 = nivelFibo(base0, base100, 50.0);    // 50%
770 blopes 136
        BigDecimal entrada2 = nivelFibo(base0, base100, 25.0);    // 25%
767 blopes 137
        BigDecimal alvo1    = nivelFibo(base0, base100, 123.6);   // 123,6%
138
        BigDecimal alvo2    = nivelFibo(base0, base100, 300.0);   // 300%
139
        BigDecimal stopFib  = nivelFibo(base0, base100, -100.0);  // -100%
140
 
141
        // Stop alternativo: 25% abaixo do último topo relevante (aqui uso topo de G2)
142
        BigDecimal stopAlt = topoG2.subtract(
143
                topoG2.subtract(fundoG3).multiply(BigDecimal.valueOf(0.25))
144
        );
145
 
146
        SinalTradeGatilho3 s = new SinalTradeGatilho3();
147
        s.setPadrao(padrao);
148
        s.setReferencia(ref);
770 blopes 149
        s.setGatilho1(g1);
767 blopes 150
        s.setGatilho2(g2);
151
        s.setGatilho3(g3);
152
 
153
        s.setTipoOperacao(TipoOperacao.COMPRA);
154
        s.setContratosTotais(CONTRATOS_TOTAIS);
155
        s.setContratosEntrada1(CONTRATOS_ENTRADA1);
156
        s.setContratosEntrada2(CONTRATOS_ENTRADA2);
157
 
158
        s.setPrecoEntrada1(entrada1.setScale(2, RoundingMode.HALF_UP));
159
        s.setPrecoEntrada2(entrada2.setScale(2, RoundingMode.HALF_UP));
160
        s.setAlvo1(alvo1.setScale(2, RoundingMode.HALF_UP));
161
        s.setAlvo2(alvo2.setScale(2, RoundingMode.HALF_UP));
162
        s.setStopMenos100(stopFib.setScale(2, RoundingMode.HALF_UP));
163
        s.setStopAlternativo(stopAlt.setScale(2, RoundingMode.HALF_UP));
164
 
165
        return s;
166
    }
167
 
168
    /**
169
     * Cálculo genérico do nível de Fibonacci:
170
     * base0 = 0% , base100 = 100%
171
     */
172
    private BigDecimal nivelFibo(BigDecimal base0, BigDecimal base100, double percentual) {
173
        BigDecimal range = base100.subtract(base0);
174
        BigDecimal fator = BigDecimal.valueOf(percentual).movePointLeft(2); // /100
175
        return base0.add(range.multiply(fator));
176
    }
177
 
178
}