143 lines
5.1 KiB
Java
143 lines
5.1 KiB
Java
/*
|
|
* SPDX-License-Identifier: MIT
|
|
*/
|
|
package ta4jexamples.backtesting;
|
|
|
|
import org.apache.logging.log4j.LogManager;
|
|
import org.apache.logging.log4j.Logger;
|
|
import org.ta4j.core.*;
|
|
import org.ta4j.core.backtest.BarSeriesManager;
|
|
import org.ta4j.core.criteria.pnl.GrossReturnCriterion;
|
|
import org.ta4j.core.indicators.averages.SMAIndicator;
|
|
import org.ta4j.core.indicators.helpers.ClosePriceIndicator;
|
|
import org.ta4j.core.num.DecimalNum;
|
|
import org.ta4j.core.num.Num;
|
|
import org.ta4j.core.rules.OverIndicatorRule;
|
|
import org.ta4j.core.rules.UnderIndicatorRule;
|
|
|
|
import java.time.Duration;
|
|
import java.time.Instant;
|
|
import java.time.ZoneOffset;
|
|
import java.time.ZonedDateTime;
|
|
|
|
public class SimpleMovingAverageBacktest {
|
|
|
|
private static final Logger LOG = LogManager.getLogger(SimpleMovingAverageBacktest.class);
|
|
|
|
public static void main(String[] args) throws InterruptedException {
|
|
BarSeries series = createBarSeries();
|
|
|
|
Strategy strategy3DaySma = create3DaySmaStrategy(series);
|
|
|
|
BarSeriesManager seriesManager = new BarSeriesManager(series);
|
|
TradingRecord tradingRecord3DaySma = seriesManager.run(strategy3DaySma, Trade.TradeType.BUY,
|
|
DecimalNum.valueOf(50));
|
|
LOG.debug(tradingRecord3DaySma.toString());
|
|
|
|
Strategy strategy2DaySma = create2DaySmaStrategy(series);
|
|
TradingRecord tradingRecord2DaySma = seriesManager.run(strategy2DaySma, Trade.TradeType.BUY,
|
|
DecimalNum.valueOf(50));
|
|
LOG.debug(tradingRecord2DaySma.toString());
|
|
|
|
var criterion = new GrossReturnCriterion();
|
|
Num calculate3DaySma = criterion.calculate(series, tradingRecord3DaySma);
|
|
Num calculate2DaySma = criterion.calculate(series, tradingRecord2DaySma);
|
|
|
|
LOG.debug(calculate3DaySma.toString());
|
|
LOG.debug(calculate2DaySma.toString());
|
|
}
|
|
|
|
private static BarSeries createBarSeries() {
|
|
final var series = new BaseBarSeriesBuilder().build();
|
|
series.barBuilder()
|
|
.timePeriod(Duration.ofDays(1))
|
|
.endTime(createDay(1))
|
|
.openPrice(100.0)
|
|
.highPrice(100.0)
|
|
.lowPrice(100.0)
|
|
.closePrice(100.0)
|
|
.volume(1060)
|
|
.add();
|
|
series.barBuilder()
|
|
.timePeriod(Duration.ofDays(1))
|
|
.endTime(createDay(2))
|
|
.openPrice(110.0)
|
|
.highPrice(110.0)
|
|
.lowPrice(110.0)
|
|
.closePrice(110.0)
|
|
.volume(1070)
|
|
.add();
|
|
series.barBuilder()
|
|
.timePeriod(Duration.ofDays(1))
|
|
.endTime(createDay(3))
|
|
.openPrice(140.0)
|
|
.highPrice(140.0)
|
|
.lowPrice(140.0)
|
|
.closePrice(140.0)
|
|
.volume(1080)
|
|
.add();
|
|
series.barBuilder()
|
|
.timePeriod(Duration.ofDays(1))
|
|
.endTime(createDay(4))
|
|
.openPrice(119.0)
|
|
.highPrice(119.0)
|
|
.lowPrice(119.0)
|
|
.closePrice(119.0)
|
|
.volume(1090)
|
|
.add();
|
|
series.barBuilder()
|
|
.timePeriod(Duration.ofDays(1))
|
|
.endTime(createDay(5))
|
|
.openPrice(100.0)
|
|
.highPrice(100.0)
|
|
.lowPrice(100.0)
|
|
.closePrice(100.0)
|
|
.volume(1100)
|
|
.add();
|
|
series.barBuilder()
|
|
.timePeriod(Duration.ofDays(1))
|
|
.endTime(createDay(6))
|
|
.openPrice(110.0)
|
|
.highPrice(110.0)
|
|
.lowPrice(110.0)
|
|
.closePrice(110.0)
|
|
.volume(1110)
|
|
.add();
|
|
series.barBuilder()
|
|
.timePeriod(Duration.ofDays(1))
|
|
.endTime(createDay(7))
|
|
.openPrice(120.0)
|
|
.highPrice(120.0)
|
|
.lowPrice(120.0)
|
|
.closePrice(120.0)
|
|
.volume(1120)
|
|
.add();
|
|
series.barBuilder()
|
|
.timePeriod(Duration.ofDays(1))
|
|
.endTime(createDay(8))
|
|
.openPrice(130.0)
|
|
.highPrice(130.0)
|
|
.lowPrice(130.0)
|
|
.closePrice(130.0)
|
|
.volume(1130)
|
|
.add();
|
|
return series;
|
|
}
|
|
|
|
private static Instant createDay(int day) {
|
|
return ZonedDateTime.of(2018, 01, day, 12, 0, 0, 0, ZoneOffset.UTC).toInstant();
|
|
}
|
|
|
|
private static Strategy create3DaySmaStrategy(BarSeries series) {
|
|
var closePrice = new ClosePriceIndicator(series);
|
|
var sma = new SMAIndicator(closePrice, 3);
|
|
return new BaseStrategy(new UnderIndicatorRule(sma, closePrice), new OverIndicatorRule(sma, closePrice));
|
|
}
|
|
|
|
private static Strategy create2DaySmaStrategy(BarSeries series) {
|
|
var closePrice = new ClosePriceIndicator(series);
|
|
var sma = new SMAIndicator(closePrice, 2);
|
|
return new BaseStrategy(new UnderIndicatorRule(sma, closePrice), new OverIndicatorRule(sma, closePrice));
|
|
}
|
|
}
|