Subversion Repositories Integrator Subversion

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
760 blopes 1
package br.com.robo.strategy;
2
 
3
import java.util.ArrayList;
4
import java.util.List;
5
 
6
import br.com.robo.model.Candle;
7
import br.com.robo.model.TriggerFinder;
8
import br.com.robo.model.TriggerFinder.TriggerPattern;
9
 
10
/**
11
 * Estratégia:
12
 * - Identifica padrões de gatilhos (Ref, G1, G2, G3)
13
 * - Para cada padrão, define um setup de Fibonacci:
14
 *      0%   = fundo do Ref
15
 *      100% = topo do G1
16
 *      50%  = nível de entrada (compra)
17
 * - Compra no 50% após o G2, vende no 100%.
18
 */
19
public class FibTriggerStrategy implements Strategy {
20
 
21
    private static class FibSetup {
22
        int refIndex;
23
        int g1Index;
24
        int g2Index;
25
 
26
        double fib0;    // low(G2)
27
        double fib50;   // nível de compra
28
        double fib100;  // high(G1) = alvo
29
 
30
        boolean triggeredEntry = false; // já entrou?
31
        boolean completed = false;      // trade já encerrado (por TP ou SL)
32
    }
33
 
34
    private List<FibSetup> setups;
35
    private boolean initialized = false;
36
    private List<Candle> lastCandlesRef;
37
 
38
    private FibSetup activeSetup = null;
39
 
40
    @Override
41
    public Signal decide(int index, List<Candle> candles, boolean hasPosition) {
42
        // Inicializa setups na primeira chamada (ou se a lista de candles mudar)
43
        if (!initialized || candles != lastCandlesRef) {
44
            initializeSetups(candles);
45
            lastCandlesRef = candles;
46
            initialized = true;
47
        }
48
 
49
        // Se não há setups, não faz nada
50
        if (setups == null || setups.isEmpty()) {
51
            return Signal.HOLD;
52
        }
53
 
54
        Candle c = candles.get(index);
55
 
56
        // Se JÁ estamos posicionados: procurar alvo (fib100)
57
        if (hasPosition && activeSetup != null && !activeSetup.completed) {
58
            // Take Profit: high >= fib100
59
            if (c.getHigh() >= activeSetup.fib100) {
60
                activeSetup.completed = true;
61
                return Signal.SELL;
62
            }
63
 
64
            // // (Opcional) Stop Loss abaixo do fib0 (fundo do G2)
65
            // double stopLoss = activeSetup.fib0 - 0.01; // pequeno buffer
66
            // if (c.getLow() <= stopLoss) {
67
            //     activeSetup.completed = true;
68
            //     return Signal.SELL;
69
            // }
70
 
71
            return Signal.HOLD;
72
        }
73
 
74
        // Se NÃO estamos posicionados: procurar entrada nos setups ainda não usados
75
        if (!hasPosition) {
76
            for (FibSetup setup : setups) {
77
                if (setup.completed) {
78
                    continue;
79
                }
80
 
81
                // setup só começa a valer após o G2
82
                if (index <= setup.g2Index) {
83
                    continue;
84
                }
85
 
86
                // se já entrou nesse setup antes, ignora
87
                if (setup.triggeredEntry) {
88
                    continue;
89
                }
90
 
91
                // Condição de compra no 50%: candle toca o nível fib50
92
                if (c.getLow() <= setup.fib50 && c.getHigh() >= setup.fib50) {
93
                    setup.triggeredEntry = true;
94
                    activeSetup = setup;
95
                    return Signal.BUY;
96
                }
97
            }
98
        }
99
 
100
        return Signal.HOLD;
101
    }
102
 
103
    /**
104
     * Inicializa os setups de Fibonacci a partir dos padrões de gatilho.
105
     */
106
    private void initializeSetups(List<Candle> candles) {
107
        TriggerFinder finder = new TriggerFinder();
108
        List<TriggerPattern> patterns = finder.findTriggers(candles);
109
 
110
        List<FibSetup> lista = new ArrayList<>();
111
 
112
        for (TriggerPattern p : patterns) {
113
            int refIndex = p.getRefIndex();
114
            int g1Index = p.getG1Index();
115
            int g2Index = p.getG2Index();
116
 
117
            if (g1Index <= g2Index) {
118
                // Garantia: G1 é um topo anterior ao G2
119
                // Se não for, pulamos esse padrão
120
                continue;
121
            }
122
 
123
            Candle ref = candles.get(refIndex);
124
            Candle g1 = candles.get(g1Index);
125
            Candle g2 = candles.get(g2Index);
126
 
127
            double fib0 = ref.getLow();       // início do Fibonacci = fundo do G2
128
            double fib100 = g1.getHigh();    // fim do Fibonacci = topo do G1
129
            double range = fib100 - fib0;
130
            if (range <= 0) {
131
                continue;
132
            }
133
            double fib50 = fib0 + 0.5 * range;
134
 
135
            FibSetup setup = new FibSetup();
136
            setup.refIndex = refIndex;
137
            setup.g1Index = g1Index;
138
            setup.g2Index = g2Index;
139
            setup.fib0 = fib0;
140
            setup.fib50 = fib50;
141
            setup.fib100 = fib100;
142
 
143
            lista.add(setup);
144
        }
145
 
146
        this.setups = lista;
147
        this.activeSetup = null;
148
    }
149
}