Page 1 of 1

Series.delete() corrupts Candle data?

Posted: Tue Nov 30, 2010 11:28 am
by 15357837
Hi,

I have come across a problem when deleting the first point from a Candle Series using:

Code: Select all

Series.delete(int index),
whereby the OHLC values become corrupt. A standalone Java class to illustrate the problem is contained at the footer of this post. To reproduce, click the 'Add Data' button, then click the 'Delete Point' button.

Prior to the call on line 65:

Code: Select all

candleChart.delete(0);
the OHLC values in the chart are:
0 X value:08:54:00 Open:1.59465 High:1.59845 Low:1.59465 Close:1.59845
1 X value:08:55:00 Open:1.59908 High:1.6033 Low:1.59908 Close:1.60087
2 X value:08:56:00 Open:1.60083 High:1.60087 Low:1.59798 Close:1.60083
3 X value:08:57:00 Open:1.60087 High:1.60087 Low:1.59524 Close:1.59555
4 X value:08:58:00 Open:1.59524 High:1.5976 Low:1.59155 Close:1.59155
After the delete call, the values are:
0 X value:08:55:00 Open:1.59465 High:1.59845 Low:1.59465 Close:1.60087
1 X value:08:56:00 Open:1.59908 High:1.6033 Low:1.59908 Close:1.60083
2 X value:08:57:00 Open:1.60083 High:1.60087 Low:1.59798 Close:1.59555
3 X value:08:58:00 Open:1.60087 High:1.60087 Low:1.59524 Close:1.59155
What appears to have happened is the Open, High, Low values have been shifted to next time point, with the Close value retained.

Is it possible for the Candle Series to delete the specified point without merging the data in this way?

Please can someone comment/investigate. It is possible there is a problem with the way I am using the API, apologies in advance should this be the case.

Many thanks in advance,
Yours humbly,

Robert

Code: Select all

package test;

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.steema.teechart.DateTimeStep;
import com.steema.teechart.TChart;
import com.steema.teechart.styles.Candle;
import com.steema.teechart.styles.CandleStyle;
import com.steema.teechart.styles.SeriesOHLCPoint;

public class TeeChartTest extends JPanel {

	private static final Log LOG = LogFactory.getLog(TeeChartTest.class);

	private TChart chart;
	private Candle candleChart;
	private DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");

	public TeeChartTest() {
		initializeChart();
		initializeCandleSeries();
		add(chart, BorderLayout.CENTER);
		JButton addButton = new JButton("Add Data");
		addButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				addData();
			}
		});
		JButton deleteButton = new JButton("Delete Point");
		deleteButton.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				deleteFirstPoint();
			}
		});
		JPanel buttonPanel = new JPanel(new BorderLayout());
		buttonPanel.add(addButton, BorderLayout.WEST);
		buttonPanel.add(deleteButton, BorderLayout.EAST);

		add(buttonPanel, BorderLayout.SOUTH);
	}

	private void deleteFirstPoint() {
		if (candleChart.getCount() == 0) {
			LOG.info("No points present");
			return;
		}
		LOG.info("Points summary before deletion:");
		LOG.info(logPoints());
		candleChart.delete(0);
		LOG.info("First point deleted");
		LOG.info("Points summary after deletion:");
		LOG.info(logPoints());
	}

	private String logPoints() {
		StringBuffer result = new StringBuffer();
		int count = candleChart.getCount();
		for (int i = 0; i < count; i++) {
			SeriesOHLCPoint point = candleChart.getOHLCPoint(i);
			result.append(System.getProperty("line.separator"));
			try {
				result.append(Integer.toString(i) + " X value:" + dateFormat.format(point.getDate()) + " Open:"
						+ point.getOpen() + " High:" + point.getHigh() + " Low:" + point.getLow() + " Close:"
						+ point.getClose());
			} catch (Throwable t) {
				LOG.error("Problem logging point", t);
			}
		}
		return result.toString();
	}

	private void addData() {
		if (candleChart.getCount() > 0) {
			LOG.info("Data Cleared");
			candleChart.clear();
		}
		try {
			// time, open, high, low, close
			candleChart.add(dateFormat.parse("08:54:00").getTime(), 1.59465, 1.59845, 1.59465, 1.59845);
			candleChart.add(dateFormat.parse("08:55:00").getTime(), 1.59908, 1.6033, 1.59908, 1.60087);
			candleChart.add(dateFormat.parse("08:56:00").getTime(), 1.60083, 1.60087, 1.59798, 1.60083);
			candleChart.add(dateFormat.parse("08:57:00").getTime(), 1.60087, 1.60087, 1.59524, 1.59555);
			candleChart.add(dateFormat.parse("08:58:00").getTime(), 1.59524, 1.5976, 1.59155, 1.59155);
			LOG.info("Data Added");
		} catch (ParseException e) {
			LOG.error(e);
		}
	}

	private void initializeCandleSeries() {
		candleChart = new Candle(chart.getChart());
		candleChart.setStyle(CandleStyle.CANDLESTICK);
		chart.addSeries(candleChart);
	}

	private void initializeChart() {
		chart = new TChart();
		chart.setForeground(com.steema.teechart.drawing.Color.WHITE);
		chart.setOpaque(false);
		chart.getAxes().getBottom().getLabels().setDateTimeFormat("HH:mm:ss");
		chart.getAxes().getBottom().setIncrement(DateTimeStep.ONEMINUTE);
		chart.getAxes().getBottom().getLabels().setDateTimeFormat("HH:mm");
		chart.getAxes().getBottom().setAutomatic(true);
		chart.getAxes().getLeft().setAutomatic(true);
	}

	public static void main(String[] args) throws Exception {
		JFrame f = new JFrame();
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.add(new TeeChartTest());
		f.setSize(500, 500);
		f.setLocation(100, 100);
		f.setVisible(true);
	}

}

Re: Series.delete() corrupts Candle data?

Posted: Wed Dec 01, 2010 11:09 am
by yeray
Hi Robert,

I've seen you are right. It seems that the delete method doesn't work as expected with the Candle series. I've added it to the defect list to be fixed in future releases (TJ71015299).
In the meanwhile you can use something like this:

Code: Select all

    private void deleteCandleAt(com.steema.teechart.styles.Candle candle, int ValueIndex) {
        candle.getXValues().removeAt(ValueIndex);
        candle.getLowValues().removeAt(ValueIndex);
        candle.getCloseValues().removeAt(ValueIndex);
        candle.getHighValues().removeAt(ValueIndex);
        candle.getOpenValues().removeAt(ValueIndex);

        candle.repaint();
    }

Re: Series.delete() corrupts Candle data?

Posted: Wed Dec 01, 2010 12:10 pm
by yeray
Hi Robert,

I've added an override to the Series.delete(int index) method for the Candle.delete(int index) and now it seems to work as expected. The fix will be available with the next maintenance release.
In the meanwhile you could use the workaround suggested in my previous post.

Re: Series.delete() corrupts Candle data?

Posted: Mon Dec 13, 2010 2:05 pm
by narcis
Hi Robert,

A maintenance release fixing this issue has just been posted at the client area.