Subversion Repositories Integrator Subversion

Rev

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

package br.com.robo.backtest;

import java.util.ArrayList;
import java.util.List;

import br.com.robo.model.BacktestResult;
import br.com.robo.model.Candle;
import br.com.robo.model.Trade;
import br.com.robo.strategy.Strategy;

public class Backtester {

    public static BacktestResult rodarBacktest(List<Candle> candles, Strategy strategy, double capitalInicial) {
        double cash = capitalInicial;
        double positionQty = 0.0;
        List<Trade> trades = new ArrayList<>();

        Trade tradeAtual = null;

        for (int i = 1; i < candles.size(); i++) {
            Candle candle = candles.get(i);

            boolean hasPosition = positionQty > 0;
            Strategy.Signal sinal = strategy.decide(i, candles, hasPosition);

            if (sinal == Strategy.Signal.BUY && !hasPosition) {
                double preco = candle.getClose();
                positionQty = cash / preco;
                cash = 0.0;

                tradeAtual = new Trade();
                tradeAtual.entryIndex = i;
                tradeAtual.entryPrice = preco;
                tradeAtual.qty = positionQty;

            } else if (sinal == Strategy.Signal.SELL && hasPosition) {
                double preco = candle.getClose();
                cash = positionQty * preco;

                tradeAtual.exitIndex = i;
                tradeAtual.exitPrice = preco;
                trades.add(tradeAtual);

                positionQty = 0.0;
                tradeAtual = null;
            }
        }

        if (positionQty > 0 && !candles.isEmpty()) {
            Candle last = candles.get(candles.size() - 1);
            double preco = last.getClose();
            cash = positionQty * preco;

            if (tradeAtual == null) {
                tradeAtual = new Trade();
                tradeAtual.entryIndex = candles.size() - 1;
                tradeAtual.entryPrice = preco;
                tradeAtual.qty = positionQty;
            }

            tradeAtual.exitIndex = candles.size() - 1;
            tradeAtual.exitPrice = preco;
            trades.add(tradeAtual);
        }

        double capitalFinal = cash;
        double retorno = (capitalFinal / capitalInicial - 1.0) * 100.0;

        BacktestResult result = new BacktestResult();
        result.setCapitalInicial(capitalInicial);
        result.setCapitalFinal(capitalFinal);
        result.setRetornoPercentual(retorno);
        result.setTrades(trades);

        return result;
    }
   
}