Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 760 | blopes | 1 | package br.com.robo.backtest; |
| 2 | |||
| 3 | import java.util.ArrayList; |
||
| 4 | import java.util.List; |
||
| 5 | |||
| 6 | import br.com.robo.model.BacktestResult; |
||
| 7 | import br.com.robo.model.Candle; |
||
| 8 | import br.com.robo.model.Trade; |
||
| 9 | import br.com.robo.strategy.Strategy; |
||
| 10 | |||
| 11 | public class Backtester { |
||
| 12 | |||
| 13 | public static BacktestResult rodarBacktest(List<Candle> candles, Strategy strategy, double capitalInicial) { |
||
| 14 | double cash = capitalInicial; |
||
| 15 | double positionQty = 0.0; |
||
| 16 | List<Trade> trades = new ArrayList<>(); |
||
| 17 | |||
| 18 | Trade tradeAtual = null; |
||
| 19 | |||
| 20 | for (int i = 1; i < candles.size(); i++) { |
||
| 21 | Candle candle = candles.get(i); |
||
| 22 | |||
| 23 | boolean hasPosition = positionQty > 0; |
||
| 24 | Strategy.Signal sinal = strategy.decide(i, candles, hasPosition); |
||
| 25 | |||
| 26 | if (sinal == Strategy.Signal.BUY && !hasPosition) { |
||
| 27 | double preco = candle.getClose(); |
||
| 28 | positionQty = cash / preco; |
||
| 29 | cash = 0.0; |
||
| 30 | |||
| 31 | tradeAtual = new Trade(); |
||
| 32 | tradeAtual.entryIndex = i; |
||
| 33 | tradeAtual.entryPrice = preco; |
||
| 34 | tradeAtual.qty = positionQty; |
||
| 35 | |||
| 36 | } else if (sinal == Strategy.Signal.SELL && hasPosition) { |
||
| 37 | double preco = candle.getClose(); |
||
| 38 | cash = positionQty * preco; |
||
| 39 | |||
| 40 | tradeAtual.exitIndex = i; |
||
| 41 | tradeAtual.exitPrice = preco; |
||
| 42 | trades.add(tradeAtual); |
||
| 43 | |||
| 44 | positionQty = 0.0; |
||
| 45 | tradeAtual = null; |
||
| 46 | } |
||
| 47 | } |
||
| 48 | |||
| 49 | if (positionQty > 0 && !candles.isEmpty()) { |
||
| 50 | Candle last = candles.get(candles.size() - 1); |
||
| 51 | double preco = last.getClose(); |
||
| 52 | cash = positionQty * preco; |
||
| 53 | |||
| 54 | if (tradeAtual == null) { |
||
| 55 | tradeAtual = new Trade(); |
||
| 56 | tradeAtual.entryIndex = candles.size() - 1; |
||
| 57 | tradeAtual.entryPrice = preco; |
||
| 58 | tradeAtual.qty = positionQty; |
||
| 59 | } |
||
| 60 | |||
| 61 | tradeAtual.exitIndex = candles.size() - 1; |
||
| 62 | tradeAtual.exitPrice = preco; |
||
| 63 | trades.add(tradeAtual); |
||
| 64 | } |
||
| 65 | |||
| 66 | double capitalFinal = cash; |
||
| 67 | double retorno = (capitalFinal / capitalInicial - 1.0) * 100.0; |
||
| 68 | |||
| 69 | BacktestResult result = new BacktestResult(); |
||
| 70 | result.setCapitalInicial(capitalInicial); |
||
| 71 | result.setCapitalFinal(capitalFinal); |
||
| 72 | result.setRetornoPercentual(retorno); |
||
| 73 | result.setTrades(trades); |
||
| 74 | |||
| 75 | return result; |
||
| 76 | } |
||
| 77 | |||
| 78 | } |