Subversion Repositories Integrator Subversion

Rev

Rev 776 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

package br.com.kronus.core;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;

import br.com.ec.web.util.TipoOperacao;
import br.com.kronus.core.ResultadoSinalGatilho3.Status;
import br.com.sl.domain.dto.robo.SinalTradeGatilho3;
import br.com.sl.domain.model.tipos.TipoSinal;

/**
 * Resumo consolidado do backtest dos sinais de Gatilho 3.
 *
 * Calcula:
 *  - contagem de cada tipo de resultado (STOP, ALVO1, ALVO2, etc.)
 *  - taxa de acerto (ALVO1 + ALVO2 / trades fechados)
 *  - P&L total e médio (em pontos * contratos)
 */

public class ResumoBacktestGatilho3 {

    private int totalSinais;
    private int totalNaoAcionado;
    private int totalDescartado;
    private int totalStop;
    private int totalAlvo1;
    private int totalAlvo2;
    private int totalAberto;

    // Trades efetivamente fechados (STOP, ALVO1, ALVO2)
    private int totalTradesFechados;

    // P&L em "pontos x contratos" (ou moeda, dependendo da unidade do preço)
    private BigDecimal plTotal;
    private BigDecimal plMedioPorTrade;
    private BigDecimal taxaAcerto; // 0.00 a 1.00 (60% = 0.60)

    public ResumoBacktestGatilho3() {
        this.plTotal = BigDecimal.ZERO;
        this.plMedioPorTrade = BigDecimal.ZERO;
        this.taxaAcerto = BigDecimal.ZERO;
    }

    public int getTotalSinais() {
        return totalSinais;
    }

    public int getTotalNaoAcionado() {
        return totalNaoAcionado;
    }

    public int getTotalDescartado() {
        return totalDescartado;
    }

    public int getTotalStop() {
        return totalStop;
    }

    public int getTotalAlvo1() {
        return totalAlvo1;
    }

    public int getTotalAlvo2() {
        return totalAlvo2;
    }

    public int getTotalAberto() {
        return totalAberto;
    }

    public int getTotalTradesFechados() {
        return totalTradesFechados;
    }

    public BigDecimal getPlTotal() {
        return plTotal;
    }

    public BigDecimal getPlMedioPorTrade() {
        return plMedioPorTrade;
    }

    public BigDecimal getTaxaAcerto() {
        return taxaAcerto;
    }

    /**
     * Cria um resumo a partir da lista de resultados.
     *
     * Regras de P&L:
     *  - Considera somente STOP, ALVO1 e ALVO2 como trades fechados.
     *  - Para COMPRA: (precoSaida - precoEntrada) * contratosTotais
     *  - Para VENDA:  (precoEntrada - precoSaida) * contratosTotais
     *  - NAO_ACIONADO, DESCARTADO e ABERTO não entram no P&L.
     */

    public static ResumoBacktestGatilho3 fromResultados(List<ResultadoSinalGatilho3> resultados) {
        ResumoBacktestGatilho3 resumo = new ResumoBacktestGatilho3();

        if (resultados == null || resultados.isEmpty()) {
            return resumo;
        }

        resumo.totalSinais = resultados.size();

        BigDecimal somaPL = BigDecimal.ZERO;
        int tradesFechados = 0;
        int tradesAcertados = 0;

        for (ResultadoSinalGatilho3 r : resultados) {
            if (r == null) {
                continue;
            }

            Status status = r.getStatus();
            resumo.contabilizarStatus(status);

            // Só consideramos P&L se o trade foi efetivamente aberto e fechado
            if (status == Status.STOP || status == Status.ALVO1 || status == Status.ALVO2) {
                SinalTradeGatilho3 sinal = r.getSinal();
                if (sinal == null) {
                    continue;
                }

                Integer contratos = sinal.getContratosTotais();
                if (contratos == null) {
                    contratos = 1;
                }

                if (r.getPrecoEntradaEfetivo() == null || r.getPrecoSaidaEfetivo() == null) {
                    continue;
                }

                BigDecimal precoEntrada = r.getPrecoEntradaEfetivo();
                BigDecimal precoSaida   = r.getPrecoSaidaEfetivo();
                BigDecimal resultadoTrade;

                if (sinal.getTipoOperacao() == TipoSinal.COMPRA_C) {
                    // COMPRA: ganha quando sai acima da entrada
                    resultadoTrade = precoSaida.subtract(precoEntrada);
                } else {
                    // VENDA: ganha quando sai abaixo da entrada
                    resultadoTrade = precoEntrada.subtract(precoSaida);
                }

                // Multiplica pelos contratos
                resultadoTrade = resultadoTrade.multiply(BigDecimal.valueOf(contratos));

                somaPL = somaPL.add(resultadoTrade);
                tradesFechados++;

                if (status == Status.ALVO1 || status == Status.ALVO2) {
                    tradesAcertados++;
                }
            }
        }

        resumo.plTotal = somaPL;

        if (tradesFechados > 0) {
            resumo.totalTradesFechados = tradesFechados;
            resumo.plMedioPorTrade = somaPL
                    .divide(BigDecimal.valueOf(tradesFechados), 4, RoundingMode.HALF_UP);

            resumo.taxaAcerto = BigDecimal.valueOf(tradesAcertados)
                    .divide(BigDecimal.valueOf(tradesFechados), 4, RoundingMode.HALF_UP);
        }

        return resumo;
    }

    private void contabilizarStatus(Status status) {
        if (status == null) return;

        switch (status) {
            case NAO_ACIONADO:
                totalNaoAcionado++;
                break;
            case DESCARTADO:
                totalDescartado++;
                break;
            case STOP:
                totalStop++;
                break;
            case ALVO1:
                totalAlvo1++;
                break;
            case ALVO2:
                totalAlvo2++;
                break;
            case ABERTO:
                totalAberto++;
                break;
            default:
                break;
        }
    }

    @Override
    public String toString() {
        return "ResumoBacktestGatilho3{" +
                "totalSinais=" + totalSinais +
                ", totalNaoAcionado=" + totalNaoAcionado +
                ", totalDescartado=" + totalDescartado +
                ", totalStop=" + totalStop +
                ", totalAlvo1=" + totalAlvo1 +
                ", totalAlvo2=" + totalAlvo2 +
                ", totalAberto=" + totalAberto +
                ", totalTradesFechados=" + totalTradesFechados +
                ", plTotal=" + plTotal +
                ", plMedioPorTrade=" + plMedioPorTrade +
                ", taxaAcerto=" + taxaAcerto +
                '}';
    }
}