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
;
}
}