How to implement constant volume candlestick bars?

Discussion about JFreeChart related to stockmarket charts.

How to implement constant volume candlestick bars?

Postby ptd26 » Mon Jan 04, 2010 9:02 pm

I want to modify the candlestick renderer and OHLC dataset so that I can create constant volume candlestick bars. This will require that the x-axis is no longer linear with time. I know how to change the renderer and create a new dataset to represent constant volume bars. However, how do I change to a date time axis that does not have constant time spacing?
ptd26
 
Posts: 27
Joined: Sun Nov 08, 2009 10:12 am

Re: How to implement constant volume candlestick bars?

Postby skunk » Tue Jan 05, 2010 2:30 pm

skunk
 
Posts: 1087
Joined: Thu Jun 02, 2005 10:14 pm
Location: Brisbane, Australia

Re: How to implement constant volume candlestick bars?

Postby ptd26 » Wed Mar 17, 2010 10:48 pm

Image

I appreciate the help from skunk below and in the spirit of open source development, I'm happy to share his code, slightly modified, which I used to setup constant volume bars in JFreeChart. It would be great if there was a constant volume bar (non-linear time axis support) built into the next release of JFreeChart. The code posted below which produces the plot shown works, but is very slow, even on a modern system.

Some of this code is specific to some other stuff I am doing and might need to be commented out in order to compile:

Code: Select all
public class Candlestick extends JPanel implements ChartChangeListener {
   private Dataset dataset;
   private ConstVolumeOHLCDataset data;
   private JFreeChart chart;
   private ChartPanel chartpanel;

   public Candlestick(Dataset dataset, Set<ChartCallback> charts)
   {
      this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
      this.setBackground(Color.BLACK);
      this.dataset = dataset;
      data = dataset.getCandlesticks();
      setupCandleStickChart();
      chart.addChangeListener(this);
   }

   private void setupCandleStickChart() {
      chart = ChartFactory.createCandlestickChart(
            null,
            null,
            null,
            data,
            false
      );   

      chartpanel = new ChartPanel(chart);
      XYPlot xyplot = chartpanel.getChart().getXYPlot();
      xyplot.setDomainCrosshairVisible(true);
      xyplot.setDomainCrosshairLockedOnData(false);
      xyplot.setRangeCrosshairVisible(true);
      xyplot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_RIGHT);
      NumberAxis numaxis = (NumberAxis) chart.getXYPlot().getRangeAxis();
      numaxis.setAutoRangeIncludesZero(false);
   
      NumberAxis axis = new NumberAxis();
      xyplot.setDomainAxis(axis);
      axis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
      axis.setNumberFormatOverride(new TranslatingFormat(data));
      
      add(chartpanel);
   }
}


Code: Select all
package JFreeChartext;

import  org.jfree.data.xy.*;

public class ConstVolumeOHLCDataset extends DefaultOHLCDataset {

   public ConstVolumeOHLCDataset(Comparable key, OHLCDataItem[] data) {
      super(key, data);
      // TODO Auto-generated constructor stub
   }

    public double getXValue(int series, int item) {
        if ((item < 0) || (item >= getItemCount(series)))
            return Double.NaN;
        return item;
    }
    public double getDisplayXValue(int series, int item) {
        if ((item < 0) || (item >= getItemCount(series)))
            return Double.NaN;
        return super.getXValue(series, item);
    }
// These are commented out but you WILL need to implement them as soon as you
//  need to call setRange() and need to convert timevalues to data indexes
//
//    public int findFirstXValueGE(long timeval);
//    public int findLastXValueLE(long timeval);
}


Code: Select all
package JFreeChartext;

import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.FieldPosition;
import java.text.SimpleDateFormat;
import java.util.Date;

public class TranslatingFormat extends DecimalFormat {
    final ConstVolumeOHLCDataset constvoldataset;
    final DateFormat fmt = new SimpleDateFormat("HH:mm:ss");

    public TranslatingFormat(ConstVolumeOHLCDataset ds) {
       assert(ds != null);
        constvoldataset = ds;
    }
   
    public StringBuffer format(double number, StringBuffer toAppendTo, FieldPosition pos) {
        if (Double.isNaN(number))
            return toAppendTo;
        double timeval = constvoldataset.getDisplayXValue(0, (int)number);
        if (Double.isNaN(timeval))
            return toAppendTo;
        return toAppendTo.append(fmt.format(new Date((long)timeval)));
    }
}
ptd26
 
Posts: 27
Joined: Sun Nov 08, 2009 10:12 am

Re: How to implement constant volume candlestick bars?

Postby Astrophobos » Tue Apr 20, 2010 2:51 am

ptd26, can you please explain what is going on when you call getCandlesticks on you dataset?

Thank you for sharing ptd26.
Astrophobos
 
Posts: 1
Joined: Tue Apr 20, 2010 2:47 am

Re: How to implement constant volume candlestick bars?

Postby ptd26 » Mon May 03, 2010 8:14 am

getCandlesticks() simply returns a ConstVolumeOHLCDataset.
ptd26
 
Posts: 27
Joined: Sun Nov 08, 2009 10:12 am

Re: How to implement constant volume candlestick bars?

Postby snid3ly » Wed Aug 07, 2013 4:25 am

This thread is over 3 years old. Is there a newer/better way to implement constant volume candlestick bars now?

Thanks!
snid3ly
 
Posts: 22
Joined: Wed Aug 07, 2013 4:21 am


Return to JFreeChart - Stockmarket

Who is online

Users browsing this forum: No registered users and 1 guest