forked from ta4j/ta4j
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathNetMomentumStrategy.java
More file actions
101 lines (84 loc) · 4.21 KB
/
Copy pathNetMomentumStrategy.java
File metadata and controls
101 lines (84 loc) · 4.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
/*
* SPDX-License-Identifier: MIT
*/
package ta4jexamples.strategies;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.jfree.chart.JFreeChart;
import org.ta4j.core.*;
import org.ta4j.core.backtest.BarSeriesManager;
import org.ta4j.core.criteria.pnl.NetProfitCriterion;
import org.ta4j.core.criteria.pnl.NetProfitLossCriterion;
import org.ta4j.core.indicators.NetMomentumIndicator;
import org.ta4j.core.indicators.RSIIndicator;
import org.ta4j.core.indicators.helpers.ClosePriceIndicator;
import org.ta4j.core.rules.CrossedDownIndicatorRule;
import org.ta4j.core.rules.CrossedUpIndicatorRule;
import java.awt.Color;
import ta4jexamples.charting.workflow.ChartWorkflow;
import ta4jexamples.datasources.JsonFileBarSeriesDataSource;
import java.io.IOException;
import java.io.InputStream;
import java.util.Objects;
public class NetMomentumStrategy {
private static final Logger LOG = LogManager.getLogger(NetMomentumStrategy.class);
private static final int DEFAULT_EXHAUSTION_EXIT_THRESHOLD = 0;
private static final int DEFAULT_MOMENTUM_TIMEFRAME = 200;
private static final int DEFAULT_REBOUND_ENTRY_THRESHOLD = 0;
private static final int DEFAULT_RSI_BARCOUNT = 14;
private static final double DEFAULT_DECAY_FACTOR = 1;
public static void main(String[] args) {
String jsonOhlcResourceFile = "Coinbase-ETH-USD-PT1D-20160517_20251028.json";
BarSeries series = null;
try (InputStream resourceStream = NetMomentumStrategy.class.getClassLoader()
.getResourceAsStream(jsonOhlcResourceFile)) {
series = JsonFileBarSeriesDataSource.DEFAULT_INSTANCE.loadSeries(resourceStream);
} catch (IOException ex) {
LOG.error("IOException while loading resource: {} - {}", jsonOhlcResourceFile, ex.getMessage());
}
Objects.requireNonNull(series, "Bar series was null");
// Running the strategy
runSingleStrategy(series);
}
private static void runSingleStrategy(BarSeries series) {
BarSeriesManager seriesManager = new BarSeriesManager(series);
ClosePriceIndicator closePriceIndicator = new ClosePriceIndicator(series);
RSIIndicator rsiIndicator = new RSIIndicator(closePriceIndicator, DEFAULT_RSI_BARCOUNT);
NetMomentumIndicator rsiM = NetMomentumIndicator.forRsiWithDecay(rsiIndicator, DEFAULT_MOMENTUM_TIMEFRAME,
DEFAULT_DECAY_FACTOR);
Strategy strategy = createStrategy(rsiM);
TradingRecord tradingRecord = seriesManager.run(strategy);
LOG.debug(() -> strategy.toJson());
LOG.debug("{}'s number of positions: {}", strategy.getName(), tradingRecord.getPositionCount());
var netProfitLoss = new NetProfitLossCriterion().calculate(series, tradingRecord);
LOG.debug("{}'s net profit/loss: {}", strategy.getName(), netProfitLoss);
// Charting
ChartWorkflow chartWorkflow = new ChartWorkflow();
JFreeChart chart = chartWorkflow.builder()
.withSeries(series)
.withTradingRecordOverlay(tradingRecord)
.withAnalysisCriterionOverlay(new NetProfitCriterion(), tradingRecord)
.withSubChart(rsiIndicator)
.withHorizontalMarker(50)
.withLineColor(Color.GRAY)
.withOpacity(0.3f)
.withHorizontalMarker(70)
.withLineColor(Color.RED)
.withOpacity(0.3f)
.withHorizontalMarker(30)
.withLineColor(Color.GREEN)
.withOpacity(0.3f)
.withSubChart(rsiM)
.withHorizontalMarker(0)
.withLineColor(Color.GRAY)
.withOpacity(0.3f)
.toChart();
chartWorkflow.displayChart(chart);
chartWorkflow.saveChartImage(chart, series, "net-momentum-strategy", "temp/charts");
}
private static Strategy createStrategy(NetMomentumIndicator rsiM) {
Rule entryRule = new CrossedUpIndicatorRule(rsiM, DEFAULT_REBOUND_ENTRY_THRESHOLD);
Rule exitRule = new CrossedDownIndicatorRule(rsiM, DEFAULT_EXHAUSTION_EXIT_THRESHOLD);
return new BaseStrategy(NetMomentumStrategy.class.getSimpleName(), entryRule, exitRule);
}
}