I have some problem with Timeline function (at least i think so). I want to draw candlestick chart, with no gaps between the candles. This means that i can haveeg. 1 minute candles like this:
8:00
8:01
8:02
8:05
8:08
8:09
8:10
8:11
and so on. Also i have gaps during weekends. I tried to use SegmentedTimeLine with default exclude weekends mechanism, but this don't clears the empty bars problem in minute chart, or some other charts. I found some workaround with this problem using addException(start.getTime(), end.getTime()) to timeline, but then performance of the chart - of moving chart forth and backward has been highly decerased. Here is how i did the coding part:
Code: Select all
private void clearGaps(DateAxis domainAxis, ArrayList<String[]> ListOfDates)
{
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm");
try
{
SegmentedTimeline stml = new SegmentedTimeline(SegmentedTimeline.MINUTE_SEGMENT_SIZE,this.TF,0);
for(String[]d:ListOfDates)
{
Date start = df.parse(d[0]);
Calendar cal = Calendar.getInstance();
cal.setTime(start);
cal.add(Calendar.MINUTE, this.TF);
start = cal.getTime();
Date end = df.parse(d[1]);
stml.addException(start.getTime(), end.getTime());
}
domainAxis.setTimeline(stml);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private JFreeChart CandleStickChart(String title)
{
JFreeChart chart;
DbEngeine dbe = new DbEngeine();
dbe.fillArrays("SELECT FIRST 500 a.TS_, a.\"OPEN_\", a.\"HIGH_\", a.\"LOW_\", a.\"CLOSE_\" FROM \""+this.Symbol+""+this.TF+"\" a order by a.TS_ desc");
//GET OHLC DATA FROM DATABASE
ArrayList<OHLCDataItem> candles = new ArrayList<OHLCDataItem>();
for(int i = 0;i<dbe.open.size();i++)
{
candles.add(new OHLCDataItem(dbe.ts.get(i),dbe.open.get(i),dbe.high.get(i),dbe.low.get(i),dbe.close.get(i),0));
}
//CREATE DATA TO DISPLAY
OHLCDataItem[] data = candles.toArray(new OHLCDataItem[candles.size()]);
//FOR GAP CLEARING
//CHECK EACH BAR BY BAR COMPARING TIME
//IF IT IS MISSING BAR (if the difference between time of current bar and time of prior bar is > than timeframe
//then it means that some data is missing and should be hidden. Eg. if we are on 1 minute chart, and
//we have space between this and prior bar higher than 1 minute then it means that bar is missing.
//I'm writing the date & time of such bars to this arraylist
ArrayList<String[]> ListOfDates = new ArrayList<String[]>();
for(int i = 0;i<data.length-1;i++)
{
OHLCDataItem item = data[i];
OHLCDataItem pitem = data[i+1];
if(item.getDate().getTime()-pitem.getDate().getTime()>(1000 * 60 * this.TF))
{
String[] restriction = {pitem.getDate().toString(),item.getDate().toString()};
ListOfDates.add(restriction);
}
}
//CREATE DATASET
DefaultOHLCDataset dataset = new DefaultOHLCDataset(title,data);
DateAxis domainAxis = new DateAxis("");//new DateAxis("");
NumberAxis rangeAxis = new NumberAxis("");
CandlestickRenderer renderer = new CandlestickRenderer();
//USING PREPARED LIST I'M EXCLUDING EMPTY BARS WITH clearGaps FUNCTION
clearGaps(domainAxis, ListOfDates);
XYPlot mainPlot = new XYPlot(dataset, domainAxis, rangeAxis, null);
Color dnColor = Color.green.darker();
Color upColor = Color.red;
renderer.setSeriesPaint(0, Color.black);
renderer.setAutoWidthMethod(1);
renderer.setUpPaint(upColor);
renderer.setDownPaint(dnColor);
renderer.setDrawVolume(false);
mainPlot.setRenderer(0, renderer);
mainPlot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_RIGHT);
Paint gradient = new GradientPaint(0, 0, Color.white, 1000, 0, Color.white);
mainPlot.setBackgroundPaint(gradient);
mainPlot.getRangeAxis().setLabelPaint(Color.black);
mainPlot.getRangeAxis().setTickLabelPaint(Color.black);
mainPlot.getRangeAxis().setTickLabelFont(new Font("sansserif", Font.BOLD, 12));
mainPlot.getDomainAxis().setTickLabelPaint(Color.black);
mainPlot.getDomainAxis().setLabelPaint(Color.black);
mainPlot.getDomainAxis().setTickLabelFont(new Font("sansserif", Font.BOLD, 12));
mainPlot.setDomainGridlinesVisible(false);
mainPlot.setRangeGridlinesVisible(false);
mainPlot.setOutlinePaint(Color.black);
rangeAxis.setAutoRangeIncludesZero(false);
chart = new JFreeChart(title, null, mainPlot, false);
Paint gradient2 = new GradientPaint(0, 0, Color.white, 1000, 0, Color.white);
chart.setBackgroundPaint(gradient2);
chart.getTitle().setPaint(new Color(192,64,0));
RenderingHints rh = chart.getRenderingHints();
rh.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
rh.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
rh.put(RenderingHints.KEY_TEXT_LCD_CONTRAST, 250);
//ADJUSTMENT OF THE VISIBLE BARS
//TO SCROLL THE CHART I ADDED <> BUTTONS AND I'm LOADING MORE DATA
//EG 500 bars, but at once i'm showing 100 - restricting view by range.
//Then if some click > or < i'm updating visible range dynamicly
domainAxis.setMinimumDate(candles.get(100).getDate());
domainAxis.setMaximumDate(candles.get(0).getDate());
double max = 0;
double min = 99999;
for(int i = 0;i<=100;i++)
{
if(candles.get(i).getHigh().doubleValue() > max) max = candles.get(i).getHigh().doubleValue();
if(candles.get(i).getLow().doubleValue() < min) min = candles.get(i).getLow().doubleValue();
}
if(this.Symbol.contains("JPY") )
rangeAxis.setRange(min-0.05, max+0.05);
else
rangeAxis.setRange(min-0.0005, max+0.0005);
return chart;
}
Now, my question is: is there any other - simple way to remove gaps between 1 minute candles ? Or, how to improve performance of the SegmentedTimeLine?