Subversion Repositories Integrator Subversion

Rev

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