x
Solved

# OHLCSeriesCollection

Posted on 2011-03-10
Medium Priority
366 Views
We have class which get data from two different independent sources:
1. avg[0] arrive with irregular interval and has own timestamp avg_ts[0];
2. outY[0] arrive from timer with standard interval 1 sec, but it has not time stamp, so it's timestamp is a system time.
First dataset works perfect and draw candlestick chart well.
The question is how to create second dataset with the same rules and place them into one chart plot with different Y axises because they are completely incomparable:
``````CC avg[0]    = 1.380455
interval: 60000
CC avg[0]    = 1.3804349999999999
interval: 60000
CC outY[0]    = -0.15570024
CC avg[0]    = 1.380445
interval: 60000
CC outY[0]    = -0.15570024
CC outY[0]    = -0.1556916
CC avg[0]    = 1.380445
interval: 60000
CC outY[0]    = -0.1556916
CC avg[0]    = 1.3804349999999999
interval: 60000
CC outY[0]    = -0.15569852
``````
``````public class ChartCommanderEURUSD {

List<Date> datesArrayList = new ArrayList<Date>();
ArrayList pricesArrayList;
long interval;
java.util.Date dates;
java.util.Date[] myDates;
double[] prices;
double[] myPrices;
ApplicationFrame af;
CandlestickRenderer csr;
double open;
double high;
double low;
double close;

private static ChartCommanderEURUSD instance = new ChartCommanderEURUSD();

public static ChartCommanderEURUSD getInstance() {
return instance;
}

public ChartCommanderEURUSD() {

datesArrayList = new ArrayList();
pricesArrayList = new ArrayList();
interval = 60000L;
af = new ApplicationFrame("Chart");
csr = new CandlestickRenderer();
}

public void chartEURUSD(double[] avg, java.util.Date[] avg_ts,
double[] outY) {

if (avg[0] != 0) {
System.out.println("CC avg[0]    = " + avg[0]);
//            System.out.println("CC avg_ts[0]    = " + avg_ts[0]);

java.util.Date[] myDates =
new java.util.Date[datesArrayList.size()];
for (int j = 0; j < myDates.length; j++) {
myDates[j] = (java.util.Date)datesArrayList.get(j);
}
double[] myPrices = new double[pricesArrayList.size()];
for (int j = 0; j < myPrices.length; j++) {
myPrices[j] = ((Double)pricesArrayList.get(j)).doubleValue();
}

//            System.out.println("Dates: ");
for (int j = 0; j < myDates.length; j++) {
//                System.out.println(myDates[j].toString());
}
//            System.out.println("Prices: ");

for (int j = 0; j < myPrices.length; j++) {
//                System.out.println(myPrices[j]);
}
System.out.println("interval: " + interval);

DefaultHighLowDataset dataset =
OHLCData(myDates, myPrices, myDates[0], interval);

JFreeChart chart = createChart(dataset);

ChartPanel chartPanel = new ChartPanel(chart);

af.setContentPane(chartPanel);
af.setSize(700, 400);
af.move(200, 800);

af.setVisible(true);
chartPanel.repaint();

//            lineEURUSD.doEvent_avg(avg);
}
if (outY[0] != 0) {
System.out.println("CC outY[0]    = " + outY[0]);

//            lineEURUSD.doEvent_outY(outY);
}
}

public DefaultHighLowDataset OHLCData(java.util.Date[] dates,
double[] prices,
java.util.Date startDate,
long interval) {

java.util.Date[] finalDates;
double[] highs;
double[] opens;
double[] closes;
double[] lows;
double[] volumes;

ArrayList anchors = new ArrayList();
HashMap h = new HashMap();

long start = startDate.getTime();

for (int j = 0; j < dates.length; j++) {
long cur = dates[j].getTime();
long num = ((cur - start) / interval);
Long anchor = new Long(start + num * interval + interval / 2);
if (h.get(anchor) == null) {
Moment mm = new Moment(dates[j], prices[j]);
h.put(anchor, mm);
} else {
Moment mm = (Moment)h.get(anchor);
mm.update(dates[j], prices[j]);
h.put(anchor, mm);
}

}

Collections.sort(anchors);

finalDates = new java.util.Date[anchors.size()];
opens = new double[anchors.size()];
highs = new double[anchors.size()];
lows = new double[anchors.size()];
closes = new double[anchors.size()];
volumes = new double[anchors.size()];

for (int j = 0; j < anchors.size(); j++) {
Long ttime = (Long)anchors.get(j);
Moment mm = (Moment)h.get(ttime);
finalDates[j] = new java.util.Date(ttime.longValue());
opens[j] = mm.getOpen();
closes[j] = mm.getClose();
highs[j] = mm.getHigh();
lows[j] = mm.getLow();
volumes[j] = 0.0;

}

DefaultHighLowDataset dataset =
new DefaultHighLowDataset("Series 1", finalDates, highs, lows,
opens, closes, volumes);

return dataset;
}

private double width;

private JFreeChart createChart(final DefaultHighLowDataset dataset) {
final JFreeChart chart =
ChartFactory.createCandlestickChart("Candlestick Demo", "Time",
"Price", dataset, false);
width = 10;
NumberAxis yaxis = (NumberAxis)chart.getXYPlot().getRangeAxis();
yaxis.setAutoRangeIncludesZero(false);
csr.setCandleWidth(width);
chart.getXYPlot().setRenderer(csr);

return chart;
}
}
``````
0
Question by:gbcbr
• 14
• 10

Author Comment

ID: 35096801
To create priceArrayList from outY[0] is not a problem it will be exactly similar like for avg[0],
we can't use avg_ts[0] for date ArrayList because of irregularity of it.
So, we need to create this array from system time.
0

LVL 47

Accepted Solution

for_yan earned 2000 total points
ID: 35096973
Still try to put them both - they are not that different in scale of numbers.
With time there should be no great issue - just run

java.util.Date now = new java.util.Date()

at every moment new outY arrives and store this
date in the ArrayList
0

Author Comment

ID: 35097114
OK, this finished, but how now to add dataset2.
I think is reasonable to move ChartPanel parameters to the end of the method
0

Author Comment

ID: 35097456
Now it looks like this
``````public class ChartCommanderEURUSD {

List<Date> datesArrayList = new ArrayList<Date>();
ArrayList pricesArrayList;
List<Date> datesArrayList2 = new ArrayList<Date>();
ArrayList pricesArrayList2;
long interval;
java.util.Date dates;
java.util.Date[] myDates;
java.util.Date[] myDates2;
java.util.Date now;
double[] prices;
double[] myPrices;
double[] myPrices2;
ApplicationFrame af;
CandlestickRenderer csr;
double open;
double high;
double low;
double close;

private static ChartCommanderEURUSD instance = new ChartCommanderEURUSD();

public static ChartCommanderEURUSD getInstance() {
return instance;
}

public ChartCommanderEURUSD() {

datesArrayList = new ArrayList();
pricesArrayList = new ArrayList();
datesArrayList2 = new ArrayList();
pricesArrayList2 = new ArrayList();
now = new java.util.Date();
interval = 60000L;
af = new ApplicationFrame("Chart");
csr = new CandlestickRenderer();
}

public void chartEURUSD(double[] avg, java.util.Date[] avg_ts,
double[] outY) {

if (avg[0] != 0) {
System.out.println("CC avg[0]    = " + avg[0]);
//            System.out.println("CC avg_ts[0]    = " + avg_ts[0]);

java.util.Date[] myDates =
new java.util.Date[datesArrayList.size()];

for (int j = 0; j < myDates.length; j++) {
myDates[j] = (java.util.Date)datesArrayList.get(j);
}

double[] myPrices = new double[pricesArrayList.size()];
for (int j = 0; j < myPrices.length; j++) {
myPrices[j] = ((Double)pricesArrayList.get(j)).doubleValue();
}

//            System.out.println("Dates: ");
for (int j = 0; j < myDates.length; j++) {
//                System.out.println(myDates[j].toString());
}
//            System.out.println("Prices: ");

for (int j = 0; j < myPrices.length; j++) {
//                System.out.println(myPrices[j]);
}
System.out.println("interval: " + interval);

DefaultHighLowDataset dataset =
OHLCData(myDates, myPrices, myDates[0], interval);

JFreeChart chart = createChart(dataset);

//            lineEURUSD.doEvent_avg(avg);
}
if (outY[0] != 0) {
System.out.println("CC outY[0]    = " + outY[0]);

java.util.Date[] myDates2 =
new java.util.Date[datesArrayList2.size()];

for (int j = 0; j < myDates2.length; j++) {
myDates2[j] = (java.util.Date)datesArrayList2.get(j);
}

double[] myPrices2 = new double[pricesArrayList2.size()];
for (int j = 0; j < myPrices2.length; j++) {
myPrices2[j] = ((Double)pricesArrayList2.get(j)).doubleValue();
}

//            System.out.println("Dates: ");
for (int j = 0; j < myDates2.length; j++) {
//                System.out.println(myDates[j].toString());
}
//            System.out.println("Prices: ");

for (int j = 0; j < myPrices2.length; j++) {
//                System.out.println(myPrices[j]);
}
System.out.println("interval: " + interval);

DefaultHighLowDataset dataset2 =
OHLCData(myDates2, myPrices2, myDates2[0], interval);

JFreeChart chart = createChart(dataset);

ChartPanel chartPanel = new ChartPanel(chart);

af.setContentPane(chartPanel);
af.setSize(800, 500);
//            af.move(200, 800);
af.setLocation(1200, 800);
af.setVisible(true);
chartPanel.repaint();

//            lineEURUSD.doEvent_outY(outY);
}
}

public DefaultHighLowDataset OHLCData(java.util.Date[] dates,
double[] prices,
java.util.Date startDate,
long interval) {
java.util.Date[] finalDates;
double[] highs;
double[] opens;
double[] closes;
double[] lows;
double[] volumes;

ArrayList anchors = new ArrayList();
HashMap h = new HashMap();

long start = startDate.getTime();

for (int j = 0; j < dates.length; j++) {
long cur = dates[j].getTime();
long num = ((cur - start) / interval);
Long anchor = new Long(start + num * interval + interval / 2);
if (h.get(anchor) == null) {
Moment mm = new Moment(dates[j], prices[j]);
h.put(anchor, mm);
} else {
Moment mm = (Moment)h.get(anchor);
mm.update(dates[j], prices[j]);
h.put(anchor, mm);
}
}

Collections.sort(anchors);

finalDates = new java.util.Date[anchors.size()];
opens = new double[anchors.size()];
highs = new double[anchors.size()];
lows = new double[anchors.size()];
closes = new double[anchors.size()];
volumes = new double[anchors.size()];

for (int j = 0; j < anchors.size(); j++) {
Long ttime = (Long)anchors.get(j);
Moment mm = (Moment)h.get(ttime);
finalDates[j] = new java.util.Date(ttime.longValue());
opens[j] = mm.getOpen();
closes[j] = mm.getClose();
highs[j] = mm.getHigh();
lows[j] = mm.getLow();
volumes[j] = 0.0;
}

DefaultHighLowDataset dataset =
new DefaultHighLowDataset("Series 1", finalDates, highs, lows,
opens, closes, volumes);
return dataset;
}

private JFreeChart createChart(final DefaultHighLowDataset dataset,final DefaultHighLowDataset dataset2) {
final JFreeChart chart =
ChartFactory.createCandlestickChart("Candlestick Demo", "Time","Price", dataset, false);

NumberAxis yaxis = (NumberAxis)chart.getXYPlot().getRangeAxis();
yaxis.setAutoRangeIncludesZero(false);

csr.setCandleWidth(10);
chart.getXYPlot().setRenderer(csr);

return chart;
}

}
``````
But I can't manage where to put
JFreeChart chart = createChart(dataset, dataset2);
0

LVL 47

Assisted Solution

for_yan earned 2000 total points
ID: 35097660
I guess you cannot create with two adatasets but you can add the soecond one
Let me see...
0

Author Comment

ID: 35097694
I'm already create public DefaultHighLowDataset OHLCData2( and return dataset 2, but I'm confused with chartPanel and charts creation
0

Author Comment

ID: 35097722
In line chart I have:
``````private JFreeChart createChart(XYDataset dataset) {

JFreeChart chart =
ChartFactory.createTimeSeriesChart("EUR/USD - 3", // title
"Time", // x-axis label
"inX[0]", // y-axis label
dataset, // data
true, // create legend?
true, // generate tooltips?
false) // generate URLs?
;
XYPlot plot = (XYPlot)chart.getPlot();
XYDataset dataset2 = createDataset2();
plot.setDataset(0, dataset);
plot.setDataset(1, dataset2);
DateAxis axis = (DateAxis)plot.getDomainAxis();
axis.setDateFormatOverride(new SimpleDateFormat("hh:mm:ss"));
XYItemRenderer r = plot.getRenderer();
XYItemRenderer renderer2 = new XYLineAndShapeRenderer();
r.setSeriesPaint(0, Color.blue);
r.setSeriesPaint(1, Color.red);
renderer2.setSeriesPaint(0, Color.red);
plot.setRenderer(1, renderer2);
plot.setBackgroundPaint(Color.lightGray);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
plot.setAxisOffset(new RectangleInsets(1.0, 1.0, 1.0, 1.0));
NumberAxis axis2 = new NumberAxis("outX[0]");
axis2.setAutoRangeIncludesZero(false);
axis2.setLabelPaint(Color.red);
axis2.setTickLabelPaint(Color.green);
plot.setRangeAxis(1, axis2);
plot.setRangeAxisLocation(1, AxisLocation.BOTTOM_OR_RIGHT);
plot.mapDatasetToRangeAxis(1, 1);

return chart;
}

private XYDataset createDataset() {

TimeSeriesCollection dataset = new TimeSeriesCollection();

return dataset;
}

private XYDataset createDataset2() {

TimeSeriesCollection dataset2 = new TimeSeriesCollection();

return dataset2;
}

public JPanel createDemoPanel() {
JFreeChart chart = createChart(createDataset());
ChartPanel panel = new ChartPanel(chart);
panel.setFillZoomRectangle(true);
panel.setMouseWheelEnabled(true);

return panel;
}
ChartPanel chartPanel = (ChartPanel)createDemoPanel();

}
``````
But there all methods separated, but here we create dataset and jpanel on one method, ok with one dataset it works perfect, but when we add second dataset everything in mess.
0

LVL 47

Expert Comment

ID: 35097780
Did you try to replace this method below and then
also modify the place where you call it and provide

`````` private JFreeChart createChart(final DefaultHighLowDataset dataset1, final DefaultHighLowDataset dataset2) {
final JFreeChart chart =
ChartFactory.createCandlestickChart("Candlestick Demo", "Time",
"Price", dataset1, false);
width = 10;
chart.setDataset(1, dataset2);
NumberAxis yaxis = (NumberAxis)chart.getXYPlot().getRangeAxis();
yaxis.setAutoRangeIncludesZero(false);
csr.setCandleWidth(width);
chart.getXYPlot().setRenderer(csr);

return chart;
}
``````
0

Author Comment

ID: 35098025
I make it like this
``````private JFreeChart createChart(final DefaultHighLowDataset dataset) {
final JFreeChart chart =
ChartFactory.createCandlestickChart("Candlestick EUR/USD", "Time","Price", dataset, false);
XYPlot plot = (XYPlot)chart.getPlot();
XYDataset dataset2 = OHLCData2(myDates2, myPrices2, myDates2[0], interval);
plot.setDataset(0, dataset);
plot.setDataset(1, dataset2);
NumberAxis yaxis = (NumberAxis)chart.getXYPlot().getRangeAxis();
yaxis.setAutoRangeIncludesZero(false);

csr.setCandleWidth(10);
chart.getXYPlot().setRenderer(csr);

return chart;
}
``````
but NPE at
XYDataset dataset2 = OHLCData2(myDates2, myPrices2, myDates2[0], interval);
How I can get dataset2 from
public DefaultHighLowDataset OHLCData2(....){
...............
return dataset2
}
0

LVL 47

Expert Comment

ID: 35098074
No, you can't do that - you should create both datset1 and dataset2 in one place
side by side with each other then you call this createChart with two parameters - and the with one dataset you create chart
only for the sceon dataset you use setDataset method.
But creation should be outside
0

Author Comment

ID: 35098148
How I can set in plot.setDataset(1, dataset2); if it's here:
``````public void chartEURUSD(double[] avg, java.util.Date[] avg_ts,
double[] outY) {

if (avg[0] != 0) {
System.out.println("CC avg[0]    = " + avg[0]);
............................

DefaultHighLowDataset dataset =
OHLCData(myDates, myPrices, myDates[0], interval);

JFreeChart chart = createChart(dataset);
ChartPanel chartPanel = new ChartPanel(chart);

af.setContentPane(chartPanel);
af.setSize(800, 500);
af.setLocation(1200, 800);
af.setVisible(true);
chartPanel.repaint();

//            lineEURUSD.doEvent_avg(avg);
}
if (outY[0] != 0) {
System.out.println("CC outY[0]    = " + outY[0]);

java.util.Date[] myDates2 =
new java.util.Date[datesArrayList2.size()];

for (int j = 0; j < myDates2.length; j++) {
myDates2[j] = (java.util.Date)datesArrayList2.get(j);
}

double[] myPrices2 = new double[pricesArrayList2.size()];
for (int j = 0; j < myPrices2.length; j++) {
myPrices2[j] = ((Double)pricesArrayList2.get(j)).doubleValue();
}

//            System.out.println("Dates: ");
for (int j = 0; j < myDates2.length; j++) {
//                System.out.println(myDates[j].toString());
}
//            System.out.println("Prices: ");

for (int j = 0; j < myPrices2.length; j++) {
//                System.out.println(myPrices[j]);
}
System.out.println("interval: " + interval);

DefaultHighLowDataset dataset2 =
OHLCData2(myDates2, myPrices2, myDates2[0], interval);
.......................

private JFreeChart createChart(final DefaultHighLowDataset dataset) {
final JFreeChart chart =
ChartFactory.createCandlestickChart("Candlestick EUR/USD", "Time","Price", dataset, false);
XYPlot plot = (XYPlot)chart.getPlot();
plot.setDataset(0, dataset);
plot.setDataset(1, dataset2);
``````
0

LVL 47

Expert Comment

ID: 35098455

Before this line you create both of your datasets:
JFreeChart chart = createChart(dataset);

Then you replace

JFreeChart chart = createChart(dataset);

with

JFreeChart chart = createChart(dataset1, dataset2);

Then you replace the method createChart itself
by the method I posted above.
(be careful grab the method I posted, not the one which you changed).

0

Author Comment

ID: 35098496
>> Before this line
before which line?
plot.setDataset(1, dataset2); ?
0

Author Comment

ID: 35099005
When I try to join them, one of datasets invisible

``````DefaultHighLowDataset dataset =
OHLCData(myDates, myPrices, myDates[0], interval);

JFreeChart chart = createChart(dataset, dataset2);
ChartPanel chartPanel = new ChartPanel(chart);

af.setContentPane(chartPanel);
af.setSize(800, 500);
af.setLocation(1600, 800);
af.setVisible(true);
chartPanel.repaint();
``````
when it's inside of any 'if' operator.
When I move this ChartPanel creation out of them, at the bottom of method, both of them invisible.
I told you from very beginning that I can't find solution for this.
I don't understand how to join these two datasets in
JFreeChart chart = createChart(dataset, dataset2);
0

LVL 47

Assisted Solution

for_yan earned 2000 total points
ID: 35099256
Well, you are ambiguous.

Did you do exactly as I wrote ?- in this code I see how you create only one dataset,
did you create the second one also? Where is that line?
Did you modify the createChart - creating it with dataset1 and then setting the second
one with id = 1 ?

If you did it, then try setting the second one with id = 2 .
Do all this and write unambifguously.

With all that I'm not 100% sure, that JFreeChart would
support the chrt with two different candlesticks sets.
In my mind I don't recall ever seeing such kind of graph - it may not
be a common task. They definitely should
support line graph overlaid on top of highLowDataset -
like say moving average over stock candles,
about two different set of candles - I'm not so sure.

Waht is the source of these tasks -is it some class assignement (then they know it can be done),
is it some real business necessity (then we don't know if that can be accomplished).

With all that I am not quite sure that
0

Author Comment

ID: 35099570
>>Did you do exactly as I wrote ?- in this code I see how you create only one dataset,
>>did you create the second one also? Where is that line?
>>Did you modify the createChart - creating it with dataset1 and then setting the second
>>one with id = 1 ?

>>If you did it, then try setting the second one with id = 2 .
>>Do all this and write unambifguously.

I'm already post it two times
I can't make
JFreeChart chart = createChart(dataset, dataset2);

At the moment I try to make two separate chartplots, because I 'm also suppose that these candles will lay on each other and I'll net get desired result.
Better I'll locate them one above the other and compare them in this way
0

LVL 47

Expert Comment

ID: 35099798
Yes, that seems like a good idea; I see no reason why it should not allow to do two separate chartplots.

0

Author Comment

ID: 35099817
I even split this class to make everything absolutely clear and don't make changes in your code for preparation second dataset.
0

LVL 47

Expert Comment

ID: 35099875
Good.
0

Author Comment

ID: 35100421
Now I have another problem, these two charts eat whole memory
``````Exception in thread "AWT-EventQueue-0" java.lang.OutOfMemoryError: Java heap space
``````
How to clean it?
0

LVL 47

Expert Comment

ID: 35100574
when you start java program start it with the command:

java -Xmx250M your_class_name your_arguments
0

Author Comment

ID: 35100622
I run it now from JDeveloper and I set -Xmx1024M, but it still not enough, I'll increase now up to 4096 and will see.
But it looks like garbage collector doesn't destroy unused elements.
0

LVL 47

Expert Comment

ID: 35100674
Well, if you really have may points coming quickly, then
we should probably think about replacing creation of the chart every time by
setting dataset. Still we need to create the datasets rather quickly - Ididn't think
you do have such huge amounts of data. Maybe you should not do 10 seconds candles.
At least in the stocks area never saw candles faster than 1 min
0

Author Comment

ID: 35100737
I have 60000L, means 60 seconds, correct?
Anyway question solved, by another way, but solved.
Thank you
0

## Featured Post

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.