1
votes

I'm having a Problem constructing a combined Candlestick Chart and Line Chart (both on the same plot). For the Candlesticks I use OHLCDataset and for the "moving average" linechart I use TimeSeries. However the Linecharts get drawn at the wrong timepoint along the axis. I have printed all DateTime Elements to make shure I did not set the wrong time or date but when printed they show exactly the date times they are supposed to. In the Chart however they start 6 hours too early. I first thought this would be a Timezone Issue but I'm setting the timezone on both to EST.

Here are the code snippets that create the dataset and assign it to the XYPlot

The OHLCDataset retrieving method (time[i] is a Date Object):

public OHLCDataset getOHLCDataset(){
    OHLCSeries ohlcSeries = new OHLCSeries("Candlesticks");
    for(int i=0; i<close.length; i++){
        ohlcSeries.add(RegularTimePeriod.createInstance(Minute.class, time[i], TimeZone.getTimeZone("EST")), open[i], max[i], min[i], close[i]);
    }
    OHLCSeriesCollection ohlcCollection = new OHLCSeriesCollection();
    ohlcCollection.addSeries(ohlcSeries);
    return ohlcCollection;
}

The TimeSeries retrieving method (time[i] is a Date Object - the same as above):

public XYDataset getAverageXYDataset(int periods, int frame){
    TimeSeries x = new TimeSeries("moving average " + periods + " periods");
    if(frame>60){
        for(int i=periods-1; i<close.length; i++){
            double sum = 0;
            for(int j=i; j>i-periods; j--){
                sum += close[j];
            }
            x.add(RegularTimePeriod.createInstance(Hour.class, time[i], TimeZone.getTimeZone("EST")), sum/periods);
        }
    }else{
        for(int i=periods-1; i<close.length; i++){
            double sum = 0;
            for(int j=i; j>i-periods; j--){
                sum += close[j];
            }
            x.add(RegularTimePeriod.createInstance(Minute.class, time[i], TimeZone.getTimeZone("EST")), sum/periods);
        }
    }
    return new TimeSeriesCollection(x);
}

The code that adds the datasets to the plot:

OHLCDataset dataset1 = dataset.getOHLCDataset();
XYDataset smallAverageDataset = dataset.getAverageXYDataset(20, period);
XYDataset bigAverageDataset = dataset.getAverageXYDataset(50, period);

// create the jfreechart - add candlestickdataset first
String title2 = dataset.getTime()[0] + " - " + dataset.getTime()[dataset.getTime().length-1];
JFreeChart chart = createChart(dataset1, title2);

// get the xyplot and set other datasets
chart.getXYPlot().setDataset(1, smallAverageDataset);
chart.getXYPlot().setDataset(2, bigAverageDataset);

Here is the method createChart:

private static JFreeChart createChart(final OHLCDataset dataset, String title) {
    DateAxis xAxis = createXAxis();
    NumberAxis yAxis = createYAxis();
    MyCandlestickRenderer candlestickRenderer = createCandlestickRenderer();
    plot = new XYPlot(dataset, xAxis, yAxis, candlestickRenderer);
    JFreeChart chart = new JFreeChart(
            title, 
            new Font("SansSerif", Font.BOLD, 24), 
            plot, 
            false
    );
    return chart;        
}

And here is the createXAxis method:

private static DateAxis createXAxis(){
    DateAxis domainAxis = new DateAxis();
    domainAxis.setAutoRange(true);
    domainAxis.setTickLabelsVisible(true);
    domainAxis.setAutoTickUnitSelection(true);
    return domainAxis;
}

I cannot figure out why there is such an offset on the linecharts but as you see I set the same Timezones for all Datasets.

Thanks in advance for the Help.

1
Please edit your question to include a minimal reproducible example with representative data that exhibits the problem you describe, for example.trashgod
I will do that as soon as I have time to. Thank you.ulanBator

1 Answers

0
votes

In JFreeChart's TimeSeries class, the x-values are time periods rather than specific points in time. The TimeSeriesCollection class presents this data via the XYDataset interface and has to choose a specific x-value for each data item. The setXPosition method (in TimeSeriesCollection) sets a flag that determines which point in the time period is used (start, middle or end).