Subversion Repositories Integrator Subversion

Rev

Blame | Last modification | View Log | Download | RSS feed

package br.com.ec.controller;

import java.io.IOException;
import java.io.Serializable;
import java.util.List;

import javax.inject.Named;

import org.primefaces.model.chart.Axis;
import org.primefaces.model.chart.AxisType;
import org.primefaces.model.chart.LineChartModel;
import org.primefaces.model.chart.LineChartSeries;
import org.primefaces.model.chart.OhlcChartModel;
import org.primefaces.model.chart.OhlcChartSeries;
import org.springframework.context.annotation.Scope;

import br.com.ec.core.generic.GenericService;
import br.com.ec.domain.dto.TradeDTO;
import br.com.ec.web.generic.AbstractBean;
import br.com.robo.backtest.Backtester;
import br.com.robo.model.BacktestResult;
import br.com.robo.model.Candle;
import br.com.robo.model.SwingLevelDetector;
import br.com.robo.model.SwingLevelDetector.Level;
import br.com.robo.model.SwingLevelDetector.LevelType;
import br.com.robo.model.Trade;
import br.com.robo.model.TriggerFinder;
import br.com.robo.sim.CandleExcelReader;
import br.com.robo.strategy.FibTriggerStrategy;
import br.com.robo.strategy.Strategy;

@Named
@Scope("view")
public class BacktestBean extends AbstractBean<TradeDTO> implements Serializable {

        private static final long serialVersionUID = 1L;
       
        private Integer quantidadeCandles;
    private Double precoInicial;
    private Integer fastPeriod;
    private Integer slowPeriod;
    private Double capitalInicial;

    private Double capitalFinal;
    private Double retornoPercentual;

    private List<Trade> trades;

    private LineChartModel precoModel;
   
    private List<Candle> candles; // guardar os candles gerados
    private List<TriggerFinder.TriggerPattern> gatilhos; // padrões encontrados
   
    private OhlcChartModel candleOhlcModel;
    private List<Level> niveisPredominantes;

    public BacktestBean() {
    }

    @Override
        public GenericService<TradeDTO> getService() {
                return null;
        }

        @Override
        public TradeDTO getId() {
                return null;
        }
       
        @Override
        public void preCarregamento() {
                limparEntidade();
        }

        @Override
        public void limparEntidade() {
                setEntidade(new TradeDTO());
                quantidadeCandles = 300;
        precoInicial = 20.0;
        fastPeriod = 9;
        slowPeriod = 21;
        capitalInicial = 100_000.0;
        }

    public void executar() {
        Integer tipoTemporizador = new Integer(1);
       
        // 1) Gera candles simulados
        CandleExcelReader reader = new CandleExcelReader();
        /*
        try {
            List<Candle> candles = reader.lerCandles("/dados.xlsx", 2);
            System.out.println("Qtd candles lidos: " + candles.size());
//            candles.stream().forEach(System.out::println);
            setCandles(candles);
        } catch (IOException e) {
            e.printStackTrace();
        }
                 */

       
//      setCandles(Candle.carregarCandles(tipoTemporizador));
//        setCandles(CandleGenerator.gerarSerieSimulada(quantidadeCandles, precoInicial));

        // 2) Estratégia
//        Strategy strategy = new MovingAverageCrossoverStrategy(fastPeriod, slowPeriod);
        Strategy strategy = new FibTriggerStrategy();

        // 3) Backtest
        BacktestResult result = Backtester.rodarBacktest(getCandles(), strategy, capitalInicial);

        this.capitalFinal = result.getCapitalFinal();
        this.retornoPercentual = result.getRetornoPercentual();
        this.trades = result.getTrades();
       
        // Gatilhos
        TriggerFinder finder = new TriggerFinder();
        setGatilhos(finder.findTriggers(getCandles()));
       
        // Fundos/Topos predominantes
        SwingLevelDetector levelDetector = new SwingLevelDetector();
        this.niveisPredominantes = levelDetector.detectPredominantLevels(candles);

        // Monta gráfico de preços (fechamento)
        montarGrafico();
       
        // Gráfico de candles com pavio (OHLC)
        montarGraficoCandles();
    }
   
    private void montarGraficoComGatilhos() {
        if (candles == null || candles.isEmpty()) {
            precoModel = null;
            return;
        }

        precoModel = new LineChartModel();
        precoModel.setTitle("Preço (Fechamento) + Gatilhos + Níveis Predominantes");
        precoModel.setLegendPosition("e");
        precoModel.setZoom(true);

        // --- Série do preço (Fechamento) - AZUL ---
        LineChartSeries seriePreco = new LineChartSeries();
        seriePreco.setLabel("Fechamento");
        seriePreco.setShowMarker(false); // só linha

        int lastIndex = candles.size() - 1;
        for (int i = 0; i <= lastIndex; i++) {
            Candle c = candles.get(i);
            seriePreco.set(i, c.getClose());
        }
        precoModel.addSeries(seriePreco);

        // --- Séries para Ref, G1, G2, G3 (já tínhamos) ---
        LineChartSeries serieRef = new LineChartSeries();
        serieRef.setLabel("Ref");
        serieRef.setShowLine(false);
        serieRef.setMarkerStyle("diamond");

        LineChartSeries serieG1 = new LineChartSeries();
        serieG1.setLabel("G1");
        serieG1.setShowLine(false);
        serieG1.setMarkerStyle("triangle");

        LineChartSeries serieG2 = new LineChartSeries();
        serieG2.setLabel("G2");
        serieG2.setShowLine(false);
        serieG2.setMarkerStyle("circle");

        LineChartSeries serieG3 = new LineChartSeries();
        serieG3.setLabel("G3");
        serieG3.setShowLine(false);
        serieG3.setMarkerStyle("square");

        if (gatilhos != null) {
            for (TriggerFinder.TriggerPattern p : gatilhos) {
                int refIndex = p.getRefIndex();
                int g1Index = p.getG1Index();
                int g2Index = p.getG2Index();
                int g3Index = p.getG3Index();

                Candle ref = candles.get(refIndex);
                Candle g1 = candles.get(g1Index);
                Candle g2 = candles.get(g2Index);
                Candle g3 = candles.get(g3Index);

                serieRef.set(refIndex, ref.getClose());
                serieG1.set(g1Index, g1.getClose());
                serieG2.set(g2Index, g2.getClose());
                serieG3.set(g3Index, g3.getClose());
            }
        }

        precoModel.addSeries(serieRef);
        precoModel.addSeries(serieG1);
        precoModel.addSeries(serieG2);
        precoModel.addSeries(serieG3);

        // --- Linhas horizontais dos fundos e topos predominantes ---
        if (niveisPredominantes != null && !niveisPredominantes.isEmpty()) {
            int contadorTopo = 1;
            int contadorFundo = 1;

            for (Level nivel : niveisPredominantes) {
                LineChartSeries serieNivel = new LineChartSeries();
                if (nivel.getType() == LevelType.HIGH) {
                    serieNivel.setLabel("Topo Pred. " + contadorTopo++);
                } else {
                    serieNivel.setLabel("Fundo Pred. " + contadorFundo++);
                }
                serieNivel.setShowMarker(false); // só linha horizontal

                double y = nivel.getPrice();
                // linha horizontal do candle 0 até o último
                serieNivel.set(0, y);
                serieNivel.set(lastIndex, y);

                precoModel.addSeries(serieNivel);
            }
        }

        // As 5 primeiras cores: Fechamento, Ref, G1, G2, G3
        // As linhas de níveis usarão as cores padrão subsequentes do theme
        precoModel.setSeriesColors("0000FF,000000,FF0000,FFA500,00AA00");

        Axis xAxis = precoModel.getAxis(AxisType.X);
        xAxis.setLabel("Candle");

        Axis yAxis = precoModel.getAxis(AxisType.Y);
        yAxis.setLabel("Preço");
    }

   
    private void montarGrafico() {
        if (candles == null || candles.isEmpty()) {
            precoModel = null;
            return;
        }

        precoModel = new LineChartModel();
        precoModel.setTitle("Preço Simulado (Fechamento) + Gatilhos");
        precoModel.setLegendPosition("e");
        precoModel.setZoom(true);

        // Série do preço (Fechamento) - AZUL
        LineChartSeries seriePreco = new LineChartSeries();
        seriePreco.setLabel("Fechamento");
        seriePreco.setShowMarker(false); // só linha, sem marcadores

        int idx = 0;
        for (Candle c : candles) {
            seriePreco.set(idx++, c.getClose());
        }
        precoModel.addSeries(seriePreco);

        // Séries para marcar Ref, G1, G2, G3 (apenas pontos)
        LineChartSeries serieRef = new LineChartSeries();
        serieRef.setLabel("Ref");
        serieRef.setShowLine(false);     // só ponto
        serieRef.setMarkerStyle("diamond");

        LineChartSeries serieG1 = new LineChartSeries();
        serieG1.setLabel("G1");
        serieG1.setShowLine(false);
        serieG1.setMarkerStyle("triangle");

        LineChartSeries serieG2 = new LineChartSeries();
        serieG2.setLabel("G2");
        serieG2.setShowLine(false);
        serieG2.setMarkerStyle("circle");

        LineChartSeries serieG3 = new LineChartSeries();
        serieG3.setLabel("G3");
        serieG3.setShowLine(false);
        serieG3.setMarkerStyle("square");

        if (gatilhos != null) {
            for (TriggerFinder.TriggerPattern p : gatilhos) {
                int refIndex = p.getRefIndex();
                int g1Index = p.getG1Index();
                int g2Index = p.getG2Index();
                int g3Index = p.getG3Index();

                Candle ref = candles.get(refIndex);
                Candle g1 = candles.get(g1Index);
                Candle g2 = candles.get(g2Index);
                Candle g3 = candles.get(g3Index);

                // Usamos o índice como X e o close como Y
                serieRef.set(refIndex, ref.getClose());
                serieG1.set(g1Index, g1.getClose());
                serieG2.set(g2Index, g2.getClose());
                serieG3.set(g3Index, g3.getClose());
            }
        }

        precoModel.addSeries(serieRef);
        precoModel.addSeries(serieG1);
        precoModel.addSeries(serieG2);
        precoModel.addSeries(serieG3);

        // Definindo cores específicas (ordem das séries acima)
        // Fechamento = azul, Ref = preto, G1 = vermelho, G2 = laranja, G3 = verde
        precoModel.setSeriesColors("0000FF,000000,FF0000,FFA500,00AA00");

        Axis xAxis = precoModel.getAxis(AxisType.X);
        xAxis.setLabel("Candle");

        Axis yAxis = precoModel.getAxis(AxisType.Y);
        yAxis.setLabel("Preço");
    }

    private void montarGraficoCandles() {
        if (candles == null || candles.isEmpty()) {
            candleOhlcModel = null;
            return;
        }

        candleOhlcModel = new OhlcChartModel();
        candleOhlcModel.setTitle("Candles (Open / High / Low / Close)");
        candleOhlcModel.setZoom(true);

        // Para não poluir demais, vamos pegar só os últimos N candles
        int total = candles.size();
//        int maxPontos = 80; // por exemplo
//        int start = Math.max(0, total - maxPontos);

        for (int i = 0; i < total; i++) {
            Candle c = candles.get(i);

            OhlcChartSeries s = new OhlcChartSeries();
            s.setValue(i); // pode usar índice como eixo X (0,1,2...)
            s.setOpen(c.getOpen());
            s.setHigh(c.getHigh());
            s.setLow(c.getLow());
            s.setClose(c.getClose());

            candleOhlcModel.add(s);
        }
    }

    // GETTERS e SETTERS

    public Integer getQuantidadeCandles() {
        return quantidadeCandles;
    }

    public void setQuantidadeCandles(Integer quantidadeCandles) {
        this.quantidadeCandles = quantidadeCandles;
    }

    public Double getPrecoInicial() {
        return precoInicial;
    }

    public void setPrecoInicial(Double precoInicial) {
        this.precoInicial = precoInicial;
    }

    public Integer getFastPeriod() {
        return fastPeriod;
    }

    public void setFastPeriod(Integer fastPeriod) {
        this.fastPeriod = fastPeriod;
    }

    public Integer getSlowPeriod() {
        return slowPeriod;
    }

    public void setSlowPeriod(Integer slowPeriod) {
        this.slowPeriod = slowPeriod;
    }

    public Double getCapitalInicial() {
        return capitalInicial;
    }

    public void setCapitalInicial(Double capitalInicial) {
        this.capitalInicial = capitalInicial;
    }

    public Double getCapitalFinal() {
        return capitalFinal;
    }

    public Double getRetornoPercentual() {
        return retornoPercentual;
    }

    public List<Trade> getTrades() {
        return trades;
    }

    public LineChartModel getPrecoModel() {
        return precoModel;
    }
   
    public List<TriggerFinder.TriggerPattern> getGatilhos() {
        return gatilhos;
    }

    public List<Candle> getCandles() {
                return candles;
        }
    public void setCandles(List<Candle> candles) {
                this.candles = candles;
        }
   
    public void setGatilhos(List<TriggerFinder.TriggerPattern> gatilhos) {
                this.gatilhos = gatilhos;
        }
   
    public OhlcChartModel getCandleOhlcModel() {
        return candleOhlcModel;
    }
   
    public List<Level> getNiveisPredominantes() {
        return niveisPredominantes;
    }
       
}