/* * SPDX-License-Identifier: MIT */ package ta4jexamples.indicators; import java.awt.Color; import java.awt.Dimension; import java.util.Date; import org.jfree.chart.ChartFactory; import org.jfree.chart.ChartPanel; import org.jfree.chart.JFreeChart; import org.jfree.chart.axis.NumberAxis; import org.jfree.chart.plot.DatasetRenderingOrder; import org.jfree.chart.plot.XYPlot; import org.jfree.chart.renderer.xy.CandlestickRenderer; import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; import org.jfree.chart.ui.ApplicationFrame; import org.jfree.chart.ui.UIUtils; import org.jfree.data.time.Second; import org.jfree.data.time.TimeSeries; import org.jfree.data.time.TimeSeriesCollection; import org.jfree.data.xy.DefaultHighLowDataset; import org.jfree.data.xy.OHLCDataset; import org.ta4j.core.Bar; import org.ta4j.core.BarSeries; import org.ta4j.core.indicators.helpers.ClosePriceIndicator; import ta4jexamples.datasources.BitStampCsvTradesFileBarSeriesDataSource; /** * This class builds a traditional candlestick chart. */ public class CandlestickChart { /** * Builds a JFreeChart OHLC dataset from a ta4j bar series. * * @param series the bar series * @return an Open-High-Low-Close dataset */ private static OHLCDataset createOHLCDataset(BarSeries series) { final int nbBars = series.getBarCount(); Date[] dates = new Date[nbBars]; double[] opens = new double[nbBars]; double[] highs = new double[nbBars]; double[] lows = new double[nbBars]; double[] closes = new double[nbBars]; double[] volumes = new double[nbBars]; for (int i = 0; i < nbBars; i++) { Bar bar = series.getBar(i); dates[i] = new Date(bar.getEndTime().toEpochMilli()); opens[i] = bar.getOpenPrice().doubleValue(); highs[i] = bar.getHighPrice().doubleValue(); lows[i] = bar.getLowPrice().doubleValue(); closes[i] = bar.getClosePrice().doubleValue(); volumes[i] = bar.getVolume().doubleValue(); } return new DefaultHighLowDataset("btc", dates, highs, lows, opens, closes, volumes); } /** * Builds an additional JFreeChart dataset from a ta4j bar series. * * @param series the bar series * @return an additional dataset */ private static TimeSeriesCollection createAdditionalDataset(BarSeries series) { ClosePriceIndicator indicator = new ClosePriceIndicator(series); TimeSeriesCollection dataset = new TimeSeriesCollection(); TimeSeries chartTimeSeries = new TimeSeries("Btc price"); for (int i = 0; i < series.getBarCount(); i++) { Bar bar = series.getBar(i); chartTimeSeries.add(new Second(new Date(bar.getEndTime().toEpochMilli())), indicator.getValue(i).doubleValue()); } dataset.addSeries(chartTimeSeries); return dataset; } /** * Displays a chart in a frame. The frame is configured to avoid stealing focus * when launched from tests or scripts. * * @param chart the chart to be displayed */ private static void displayChart(JFreeChart chart) { // Chart panel ChartPanel panel = new ChartPanel(chart); panel.setFillZoomRectangle(true); panel.setMouseWheelEnabled(true); panel.setPreferredSize(new Dimension(740, 300)); // Application frame ApplicationFrame frame = new ApplicationFrame("Ta4j example - Candlestick chart"); frame.setContentPane(panel); frame.pack(); UIUtils.centerFrameOnScreen(frame); frame.setFocusableWindowState(false); frame.setVisible(true); frame.setAlwaysOnTop(false); frame.setAutoRequestFocus(false); } public static void main(String[] args) { /* * Getting bar series */ BarSeries series = BitStampCsvTradesFileBarSeriesDataSource.loadBitstampSeries(); /* * Creating the OHLC dataset */ OHLCDataset ohlcDataset = createOHLCDataset(series); /* * Creating the additional dataset */ TimeSeriesCollection xyDataset = createAdditionalDataset(series); /* * Creating the chart */ JFreeChart chart = ChartFactory.createCandlestickChart("Bitstamp BTC price", "Time", "USD", ohlcDataset, true); // Candlestick rendering CandlestickRenderer renderer = new CandlestickRenderer(); renderer.setAutoWidthMethod(CandlestickRenderer.WIDTHMETHOD_SMALLEST); XYPlot plot = chart.getXYPlot(); plot.setRenderer(renderer); // Additional dataset int index = 1; plot.setDataset(index, xyDataset); plot.mapDatasetToRangeAxis(index, 0); XYLineAndShapeRenderer renderer2 = new XYLineAndShapeRenderer(true, false); renderer2.setSeriesPaint(index, Color.blue); plot.setRenderer(index, renderer2); // Misc plot.setRangeGridlinePaint(Color.lightGray); plot.setBackgroundPaint(Color.white); NumberAxis numberAxis = (NumberAxis) plot.getRangeAxis(); numberAxis.setAutoRangeIncludesZero(false); plot.setDatasetRenderingOrder(DatasetRenderingOrder.FORWARD); /* * Displaying the chart */ displayChart(chart); } }