Subversion Repositories Integrator Subversion

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
778 blopes 1
package br.com.ec.controller;
2
 
3
import java.io.IOException;
4
import java.io.Serializable;
5
import java.util.List;
6
 
7
import javax.inject.Named;
8
 
9
import org.primefaces.model.chart.Axis;
10
import org.primefaces.model.chart.AxisType;
11
import org.primefaces.model.chart.LineChartModel;
12
import org.primefaces.model.chart.LineChartSeries;
13
import org.primefaces.model.chart.OhlcChartModel;
14
import org.primefaces.model.chart.OhlcChartSeries;
15
import org.springframework.context.annotation.Scope;
16
 
17
import br.com.ec.core.generic.GenericService;
18
import br.com.ec.domain.dto.TradeDTO;
19
import br.com.ec.web.generic.AbstractBean;
20
import br.com.robo.backtest.Backtester;
21
import br.com.robo.model.BacktestResult;
22
import br.com.robo.model.Candle;
23
import br.com.robo.model.SwingLevelDetector;
24
import br.com.robo.model.SwingLevelDetector.Level;
25
import br.com.robo.model.SwingLevelDetector.LevelType;
26
import br.com.robo.model.Trade;
27
import br.com.robo.model.TriggerFinder;
28
import br.com.robo.sim.CandleExcelReader;
29
import br.com.robo.strategy.FibTriggerStrategy;
30
import br.com.robo.strategy.Strategy;
31
 
32
@Named
33
@Scope("view")
34
public class BacktestBean extends AbstractBean<TradeDTO> implements Serializable {
35
 
36
        private static final long serialVersionUID = 1L;
37
 
38
        private Integer quantidadeCandles;
39
    private Double precoInicial;
40
    private Integer fastPeriod;
41
    private Integer slowPeriod;
42
    private Double capitalInicial;
43
 
44
    private Double capitalFinal;
45
    private Double retornoPercentual;
46
 
47
    private List<Trade> trades;
48
 
49
    private LineChartModel precoModel;
50
 
51
    private List<Candle> candles; // guardar os candles gerados
52
    private List<TriggerFinder.TriggerPattern> gatilhos; // padrões encontrados
53
 
54
    private OhlcChartModel candleOhlcModel;
55
    private List<Level> niveisPredominantes;
56
 
57
    public BacktestBean() {
58
    }
59
 
60
    @Override
61
        public GenericService<TradeDTO> getService() {
62
                return null;
63
        }
64
 
65
        @Override
66
        public TradeDTO getId() {
67
                return null;
68
        }
69
 
70
        @Override
71
        public void preCarregamento() {
72
                limparEntidade();
73
        }
74
 
75
        @Override
76
        public void limparEntidade() {
77
                setEntidade(new TradeDTO());
78
                quantidadeCandles = 300;
79
        precoInicial = 20.0;
80
        fastPeriod = 9;
81
        slowPeriod = 21;
82
        capitalInicial = 100_000.0;
83
        }
84
 
85
    public void executar() {
86
        Integer tipoTemporizador = new Integer(1);
87
 
88
        // 1) Gera candles simulados
89
        CandleExcelReader reader = new CandleExcelReader();
90
        /*
91
        try {
92
            List<Candle> candles = reader.lerCandles("/dados.xlsx", 2);
93
            System.out.println("Qtd candles lidos: " + candles.size());
94
//            candles.stream().forEach(System.out::println);
95
            setCandles(candles);
96
        } catch (IOException e) {
97
            e.printStackTrace();
98
        }
99
                 */
100
 
101
//      setCandles(Candle.carregarCandles(tipoTemporizador));
102
//        setCandles(CandleGenerator.gerarSerieSimulada(quantidadeCandles, precoInicial));
103
 
104
        // 2) Estratégia
105
//        Strategy strategy = new MovingAverageCrossoverStrategy(fastPeriod, slowPeriod);
106
        Strategy strategy = new FibTriggerStrategy();
107
 
108
        // 3) Backtest
109
        BacktestResult result = Backtester.rodarBacktest(getCandles(), strategy, capitalInicial);
110
 
111
        this.capitalFinal = result.getCapitalFinal();
112
        this.retornoPercentual = result.getRetornoPercentual();
113
        this.trades = result.getTrades();
114
 
115
        // Gatilhos
116
        TriggerFinder finder = new TriggerFinder();
117
        setGatilhos(finder.findTriggers(getCandles()));
118
 
119
        // Fundos/Topos predominantes
120
        SwingLevelDetector levelDetector = new SwingLevelDetector();
121
        this.niveisPredominantes = levelDetector.detectPredominantLevels(candles);
122
 
123
        // Monta gráfico de preços (fechamento)
124
        montarGrafico();
125
 
126
        // Gráfico de candles com pavio (OHLC)
127
        montarGraficoCandles();
128
    }
129
 
130
    private void montarGraficoComGatilhos() {
131
        if (candles == null || candles.isEmpty()) {
132
            precoModel = null;
133
            return;
134
        }
135
 
136
        precoModel = new LineChartModel();
137
        precoModel.setTitle("Preço (Fechamento) + Gatilhos + Níveis Predominantes");
138
        precoModel.setLegendPosition("e");
139
        precoModel.setZoom(true);
140
 
141
        // --- Série do preço (Fechamento) - AZUL ---
142
        LineChartSeries seriePreco = new LineChartSeries();
143
        seriePreco.setLabel("Fechamento");
144
        seriePreco.setShowMarker(false); // só linha
145
 
146
        int lastIndex = candles.size() - 1;
147
        for (int i = 0; i <= lastIndex; i++) {
148
            Candle c = candles.get(i);
149
            seriePreco.set(i, c.getClose());
150
        }
151
        precoModel.addSeries(seriePreco);
152
 
153
        // --- Séries para Ref, G1, G2, G3 (já tínhamos) ---
154
        LineChartSeries serieRef = new LineChartSeries();
155
        serieRef.setLabel("Ref");
156
        serieRef.setShowLine(false);
157
        serieRef.setMarkerStyle("diamond");
158
 
159
        LineChartSeries serieG1 = new LineChartSeries();
160
        serieG1.setLabel("G1");
161
        serieG1.setShowLine(false);
162
        serieG1.setMarkerStyle("triangle");
163
 
164
        LineChartSeries serieG2 = new LineChartSeries();
165
        serieG2.setLabel("G2");
166
        serieG2.setShowLine(false);
167
        serieG2.setMarkerStyle("circle");
168
 
169
        LineChartSeries serieG3 = new LineChartSeries();
170
        serieG3.setLabel("G3");
171
        serieG3.setShowLine(false);
172
        serieG3.setMarkerStyle("square");
173
 
174
        if (gatilhos != null) {
175
            for (TriggerFinder.TriggerPattern p : gatilhos) {
176
                int refIndex = p.getRefIndex();
177
                int g1Index = p.getG1Index();
178
                int g2Index = p.getG2Index();
179
                int g3Index = p.getG3Index();
180
 
181
                Candle ref = candles.get(refIndex);
182
                Candle g1 = candles.get(g1Index);
183
                Candle g2 = candles.get(g2Index);
184
                Candle g3 = candles.get(g3Index);
185
 
186
                serieRef.set(refIndex, ref.getClose());
187
                serieG1.set(g1Index, g1.getClose());
188
                serieG2.set(g2Index, g2.getClose());
189
                serieG3.set(g3Index, g3.getClose());
190
            }
191
        }
192
 
193
        precoModel.addSeries(serieRef);
194
        precoModel.addSeries(serieG1);
195
        precoModel.addSeries(serieG2);
196
        precoModel.addSeries(serieG3);
197
 
198
        // --- Linhas horizontais dos fundos e topos predominantes ---
199
        if (niveisPredominantes != null && !niveisPredominantes.isEmpty()) {
200
            int contadorTopo = 1;
201
            int contadorFundo = 1;
202
 
203
            for (Level nivel : niveisPredominantes) {
204
                LineChartSeries serieNivel = new LineChartSeries();
205
                if (nivel.getType() == LevelType.HIGH) {
206
                    serieNivel.setLabel("Topo Pred. " + contadorTopo++);
207
                } else {
208
                    serieNivel.setLabel("Fundo Pred. " + contadorFundo++);
209
                }
210
                serieNivel.setShowMarker(false); // só linha horizontal
211
 
212
                double y = nivel.getPrice();
213
                // linha horizontal do candle 0 até o último
214
                serieNivel.set(0, y);
215
                serieNivel.set(lastIndex, y);
216
 
217
                precoModel.addSeries(serieNivel);
218
            }
219
        }
220
 
221
        // As 5 primeiras cores: Fechamento, Ref, G1, G2, G3
222
        // As linhas de níveis usarão as cores padrão subsequentes do theme
223
        precoModel.setSeriesColors("0000FF,000000,FF0000,FFA500,00AA00");
224
 
225
        Axis xAxis = precoModel.getAxis(AxisType.X);
226
        xAxis.setLabel("Candle");
227
 
228
        Axis yAxis = precoModel.getAxis(AxisType.Y);
229
        yAxis.setLabel("Preço");
230
    }
231
 
232
 
233
    private void montarGrafico() {
234
        if (candles == null || candles.isEmpty()) {
235
            precoModel = null;
236
            return;
237
        }
238
 
239
        precoModel = new LineChartModel();
240
        precoModel.setTitle("Preço Simulado (Fechamento) + Gatilhos");
241
        precoModel.setLegendPosition("e");
242
        precoModel.setZoom(true);
243
 
244
        // Série do preço (Fechamento) - AZUL
245
        LineChartSeries seriePreco = new LineChartSeries();
246
        seriePreco.setLabel("Fechamento");
247
        seriePreco.setShowMarker(false); // só linha, sem marcadores
248
 
249
        int idx = 0;
250
        for (Candle c : candles) {
251
            seriePreco.set(idx++, c.getClose());
252
        }
253
        precoModel.addSeries(seriePreco);
254
 
255
        // Séries para marcar Ref, G1, G2, G3 (apenas pontos)
256
        LineChartSeries serieRef = new LineChartSeries();
257
        serieRef.setLabel("Ref");
258
        serieRef.setShowLine(false);     // só ponto
259
        serieRef.setMarkerStyle("diamond");
260
 
261
        LineChartSeries serieG1 = new LineChartSeries();
262
        serieG1.setLabel("G1");
263
        serieG1.setShowLine(false);
264
        serieG1.setMarkerStyle("triangle");
265
 
266
        LineChartSeries serieG2 = new LineChartSeries();
267
        serieG2.setLabel("G2");
268
        serieG2.setShowLine(false);
269
        serieG2.setMarkerStyle("circle");
270
 
271
        LineChartSeries serieG3 = new LineChartSeries();
272
        serieG3.setLabel("G3");
273
        serieG3.setShowLine(false);
274
        serieG3.setMarkerStyle("square");
275
 
276
        if (gatilhos != null) {
277
            for (TriggerFinder.TriggerPattern p : gatilhos) {
278
                int refIndex = p.getRefIndex();
279
                int g1Index = p.getG1Index();
280
                int g2Index = p.getG2Index();
281
                int g3Index = p.getG3Index();
282
 
283
                Candle ref = candles.get(refIndex);
284
                Candle g1 = candles.get(g1Index);
285
                Candle g2 = candles.get(g2Index);
286
                Candle g3 = candles.get(g3Index);
287
 
288
                // Usamos o índice como X e o close como Y
289
                serieRef.set(refIndex, ref.getClose());
290
                serieG1.set(g1Index, g1.getClose());
291
                serieG2.set(g2Index, g2.getClose());
292
                serieG3.set(g3Index, g3.getClose());
293
            }
294
        }
295
 
296
        precoModel.addSeries(serieRef);
297
        precoModel.addSeries(serieG1);
298
        precoModel.addSeries(serieG2);
299
        precoModel.addSeries(serieG3);
300
 
301
        // Definindo cores específicas (ordem das séries acima)
302
        // Fechamento = azul, Ref = preto, G1 = vermelho, G2 = laranja, G3 = verde
303
        precoModel.setSeriesColors("0000FF,000000,FF0000,FFA500,00AA00");
304
 
305
        Axis xAxis = precoModel.getAxis(AxisType.X);
306
        xAxis.setLabel("Candle");
307
 
308
        Axis yAxis = precoModel.getAxis(AxisType.Y);
309
        yAxis.setLabel("Preço");
310
    }
311
 
312
    private void montarGraficoCandles() {
313
        if (candles == null || candles.isEmpty()) {
314
            candleOhlcModel = null;
315
            return;
316
        }
317
 
318
        candleOhlcModel = new OhlcChartModel();
319
        candleOhlcModel.setTitle("Candles (Open / High / Low / Close)");
320
        candleOhlcModel.setZoom(true);
321
 
322
        // Para não poluir demais, vamos pegar só os últimos N candles
323
        int total = candles.size();
324
//        int maxPontos = 80; // por exemplo
325
//        int start = Math.max(0, total - maxPontos);
326
 
327
        for (int i = 0; i < total; i++) {
328
            Candle c = candles.get(i);
329
 
330
            OhlcChartSeries s = new OhlcChartSeries();
331
            s.setValue(i); // pode usar índice como eixo X (0,1,2...)
332
            s.setOpen(c.getOpen());
333
            s.setHigh(c.getHigh());
334
            s.setLow(c.getLow());
335
            s.setClose(c.getClose());
336
 
337
            candleOhlcModel.add(s);
338
        }
339
    }
340
 
341
    // GETTERS e SETTERS
342
 
343
    public Integer getQuantidadeCandles() {
344
        return quantidadeCandles;
345
    }
346
 
347
    public void setQuantidadeCandles(Integer quantidadeCandles) {
348
        this.quantidadeCandles = quantidadeCandles;
349
    }
350
 
351
    public Double getPrecoInicial() {
352
        return precoInicial;
353
    }
354
 
355
    public void setPrecoInicial(Double precoInicial) {
356
        this.precoInicial = precoInicial;
357
    }
358
 
359
    public Integer getFastPeriod() {
360
        return fastPeriod;
361
    }
362
 
363
    public void setFastPeriod(Integer fastPeriod) {
364
        this.fastPeriod = fastPeriod;
365
    }
366
 
367
    public Integer getSlowPeriod() {
368
        return slowPeriod;
369
    }
370
 
371
    public void setSlowPeriod(Integer slowPeriod) {
372
        this.slowPeriod = slowPeriod;
373
    }
374
 
375
    public Double getCapitalInicial() {
376
        return capitalInicial;
377
    }
378
 
379
    public void setCapitalInicial(Double capitalInicial) {
380
        this.capitalInicial = capitalInicial;
381
    }
382
 
383
    public Double getCapitalFinal() {
384
        return capitalFinal;
385
    }
386
 
387
    public Double getRetornoPercentual() {
388
        return retornoPercentual;
389
    }
390
 
391
    public List<Trade> getTrades() {
392
        return trades;
393
    }
394
 
395
    public LineChartModel getPrecoModel() {
396
        return precoModel;
397
    }
398
 
399
    public List<TriggerFinder.TriggerPattern> getGatilhos() {
400
        return gatilhos;
401
    }
402
 
403
    public List<Candle> getCandles() {
404
                return candles;
405
        }
406
    public void setCandles(List<Candle> candles) {
407
                this.candles = candles;
408
        }
409
 
410
    public void setGatilhos(List<TriggerFinder.TriggerPattern> gatilhos) {
411
                this.gatilhos = gatilhos;
412
        }
413
 
414
    public OhlcChartModel getCandleOhlcModel() {
415
        return candleOhlcModel;
416
    }
417
 
418
    public List<Level> getNiveisPredominantes() {
419
        return niveisPredominantes;
420
    }
421
 
422
}