1)window closing
You must implement window listener and dispose it safely.
2)how do i add additional lines to the candlestick chart? eg. EMA, SMA, etc etc. can i add points (coordinates) on the candlestick chart?
plot.setDataset(plot.getDatasetCount(), dataset);//dataset should be a timeseries
plot.setRenderer(plot.getDatasetCount() - 1, new XYLineAndShapeRenderer(true, false));
for 2) and 5)
Code: Select all
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Calendar;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.CandlestickRenderer;
import org.jfree.chart.renderer.xy.HighLowRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.data.time.Minute;
import org.jfree.data.time.Month;
import org.jfree.data.time.Second;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.time.ohlc.OHLCSeries;
import org.jfree.data.time.ohlc.OHLCSeriesCollection;
import org.jfree.data.xy.OHLCDataset;
import org.jfree.data.xy.XYDataset;
/**
* Example to combine Candlestick and Line Charts in same chart
* and also convert candlestick to line.
* plus to update the timeseries.
*
* @author Maneesh Nanu
*
*/
public class OHLC extends JFrame implements ActionListener
{
private static final long serialVersionUID = 1L;
private OHLCDataset dataset;
public static OHLCSeries ohlcSeries;
private CandlestickRenderer CandleStickRenderer;
private DateAxis domainAxis;
private NumberAxis rangeAxis;
public static XYPlot plot;
private JFreeChart jfreechart;
public ChartPanel chartPanel;
private JPanel panel;
private XYLineAndShapeRenderer LineRenderer;
private HighLowRenderer OHLCRenderer;
protected static int datasetcnt = 1;
private JButton btnRen;
private JButton btnAvg;
public static ArrayList<Month> Date = new ArrayList<Month>();
public static ArrayList<Double> Close = new ArrayList<Double>();
public static ArrayList<Double> Open = new ArrayList<Double>();
public static ArrayList<Double> High = new ArrayList<Double>();
public static ArrayList<Double> Low = new ArrayList<Double>();
public OHLC()
{
setBackground(Color.WHITE);
getContentPane().setLayout(new BorderLayout(0, 0));
dataset = createDataset();
JFreeChart chart = createChart(dataset);
chartPanel = new ChartPanel(chart);
chartPanel.setMouseZoomable(true);
panel = new JPanel(new BorderLayout());
panel.add(chartPanel, BorderLayout.CENTER);
getContentPane().add(panel);
chart.setBackgroundPaint(Color.WHITE);
chartPanel.setBackground(Color.WHITE);
panel.setBackground(Color.WHITE);
btnRen = new JButton("rendererNUpdate");
panel.add(btnRen, BorderLayout.NORTH);
btnRen.addActionListener(this);
btnAvg = new JButton("new series");
panel.add(btnAvg, BorderLayout.SOUTH);
btnAvg.addActionListener(this);
this.setVisible(true);
this.setSize(400, 400);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
public OHLCDataset createDataset()
{
try
{
ohlcSeries = new OHLCSeries("");
Calendar date[] = new Calendar[Date.size()];
int i;
Minute minute;
Second secondOfDay;
double open, high, low, close;
try
{
for (i = 0; i<Date.size(); i++)
{
date[i] = Calendar.getInstance();
date[i].setTimeInMillis(Date.get(i).getFirstMillisecond());
minute = new Minute(date[i].get(Calendar.MINUTE),
date[i].get(Calendar.HOUR_OF_DAY),
date[i].get(Calendar.DAY_OF_MONTH),
date[i].get(Calendar.MONTH) + 1,
date[i].get(Calendar.YEAR));
secondOfDay = new Second(date[i].get(Calendar.SECOND),
minute);
open = Open.get(i);
high = High.get(i);
low = Low.get(i);
close = Close.get(i);
System.out
.println(open + "" + high + "" + low + "" + close);
ohlcSeries.add(secondOfDay, open, high, low, close);
}
} catch (Exception e)
{
System.out.println(e.getMessage());
}
OHLCSeriesCollection ohlcCollection = new OHLCSeriesCollection();
ohlcSeries.getItemCount();
ohlcCollection.addSeries(ohlcSeries);
return ohlcCollection;
} catch (Exception e)
{
System.out.println("Error: " + e);
}
return null;
}
@SuppressWarnings("deprecation")
private JFreeChart createChart(final OHLCDataset dataset)
{
CandleStickRenderer = new CandlestickRenderer();
CandleStickRenderer.setSeriesStroke(0, new BasicStroke(1.0f,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL));
CandleStickRenderer.setSeriesPaint(0, Color.black);
LineRenderer = new XYLineAndShapeRenderer(true, false);
LineRenderer.setStroke(new BasicStroke(1f, BasicStroke.CAP_BUTT,
BasicStroke.JOIN_BEVEL));
LineRenderer.setSeriesPaint(0, Color.BLACK);
LineRenderer.setSeriesPaint(1, Color.BLUE);
LineRenderer.setSeriesPaint(2, Color.RED);
OHLCRenderer = new HighLowRenderer();
OHLCRenderer.setSeriesStroke(0, new BasicStroke(1.0f,
BasicStroke.CAP_ROUND, BasicStroke.JOIN_BEVEL));
OHLCRenderer.setSeriesPaint(0, Color.black);
domainAxis = new DateAxis();
domainAxis.setAutoRange(true);
domainAxis.setTickLabelsVisible(true);
domainAxis.setAutoTickUnitSelection(true);
rangeAxis = new NumberAxis();
rangeAxis.setStandardTickUnits(NumberAxis.createStandardTickUnits());
// rangeAxis.setFixedAutoRange(50.0);
rangeAxis.setAutoRange(true);
plot = new XYPlot(dataset, domainAxis, rangeAxis, LineRenderer);
plot.setBackgroundPaint(Color.LIGHT_GRAY);
plot.setDomainGridlinePaint(Color.WHITE);
plot.setRangeGridlinePaint(Color.WHITE);
plot.setDomainGridlinesVisible(true);
plot.setRangeGridlinesVisible(true);
jfreechart = new JFreeChart("Stock Exchange price (IBM)", new Font(
"SansSerif", Font.BOLD, 24), plot, false);
return jfreechart;
}
public static void main(String[] args)
{
TAFunction();
new OHLC();
}
public void generateDate()
{
try{
s1.add(new Month(7, 2002), 132.8);
}
catch(Exception e){}
}
@Override
public void actionPerformed(ActionEvent ae)
{
XYPlot xyplot = (XYPlot) jfreechart.getPlot();
if (ae.getSource() == btnAvg)
{
XYDataset collec = createMADataset();
// XYDataset dset = new TimeSeriesCollection();
xyplot.setDataset(2, collec);
xyplot.setRenderer(2, LineRenderer);
} else if (ae.getSource() == btnRen)
{
xyplot.setRenderer(CandleStickRenderer);
try{
s1.addOrUpdate(new Month(7, 2002), a=a+10);
}
catch(Exception e){
// e.printStackTrace();
System.out.println(e.getMessage());
}
}
}
static int a = 143;
TimeSeries s1;
@SuppressWarnings("deprecation")
private TimeSeriesCollection createMADataset()
{
s1 = new TimeSeries("Budget", "Year", "$ Million",
Month.class);
try
{
s1.add(new Month(2, 2001), 181.8);
s1.add(new Month(3, 2001), 167.3);
s1.add(new Month(4, 2001), 153.8);
s1.add(new Month(5, 2001), 167.6);
s1.add(new Month(6, 2001), 158.8);
s1.add(new Month(7, 2001), 148.3);
s1.add(new Month(8, 2001), 153.9);
s1.add(new Month(9, 2001), 142.7);
s1.add(new Month(10, 2001), 123.2);
s1.add(new Month(11, 2001), 131.8);
s1.add(new Month(12, 2001), 139.6);
s1.add(new Month(1, 2002), 142.9);
s1.add(new Month(2, 2002), 138.7);
s1.add(new Month(3, 2002), 137.3);
s1.add(new Month(4, 2002), 143.9);
s1.add(new Month(5, 2002), 139.8);
s1.add(new Month(6, 2002), 137.0);
s1.add(new Month(7, 2002), 132.8);
} catch (Exception exception)
{
System.err.println(exception.getMessage());
}
TimeSeriesCollection timeseriescollection = new TimeSeriesCollection(s1);
return timeseriescollection;
}
public static void TAFunction()
{
Date.add(new Month(2, 2001));
Date.add(new Month(3, 2001));
Date.add(new Month(4, 2001));
Date.add(new Month(5, 2001));
Date.add(new Month(6, 2001));
Date.add(new Month(7, 2001));
Date.add(new Month(8, 2001));
Date.add(new Month(9, 2001));
Date.add(new Month(10, 2001));
Date.add(new Month(11, 2001));
Date.add(new Month(12, 2001));
Date.add(new Month(1, 2002));
Date.add(new Month(2, 2002));
Date.add(new Month(3, 2002));
Date.add(new Month(4, 2002));
Date.add(new Month(5, 2002));
Date.add(new Month(6, 2002));
Date.add(new Month(7, 2002));
Date.add(new Month(8, 2002));
Date.add(new Month(9, 2002));
Close.add(5.0);
Close.add(40.0);
Close.add(52.0);
Close.add(13.0);
Close.add(13.0);
Close.add(14.0);
Close.add(22.0);
Close.add(40.0);
Close.add(30.0);
Close.add(54.0);
Close.add(46.0);
Close.add(41.0);
Close.add(13.0);
Close.add(57.0);
Close.add(74.0);
Close.add(29.0);
Close.add(34.0);
Close.add(46.0);
Close.add(45.0);
Close.add(73.0);
Close.add(64.0);
Close.add(92.0);
Open.add(10.0);
Open.add(50.0);
Open.add(62.0);
Open.add(23.0);
Open.add(23.0);
Open.add(5.0);
Open.add(32.0);
Open.add(45.0);
Open.add(32.0);
Open.add(45.0);
Open.add(67.0);
Open.add(43.0);
Open.add(23.0);
Open.add(67.0);
Open.add(84.0);
Open.add(23.0);
Open.add(34.0);
Open.add(76.0);
Open.add(45.0);
Open.add(73.0);
Open.add(67.0);
Open.add(96.0);
High.add(20.0);
High.add(60.0);
High.add(72.0);
High.add(33.0);
High.add(33.0);
High.add(15.0);
High.add(22.0);
High.add(55.0);
High.add(42.0);
High.add(55.0);
High.add(77.0);
High.add(53.0);
High.add(33.0);
High.add(77.0);
High.add(94.0);
High.add(33.0);
High.add(44.0);
High.add(86.0);
High.add(55.0);
High.add(83.0);
High.add(77.0);
High.add(106.0);
Low.add(10.0);
Low.add(50.0);
Low.add(62.0);
Low.add(23.0);
Low.add(23.0);
Low.add(5.0);
Low.add(32.0);
Low.add(45.0);
Low.add(32.0);
Low.add(45.0);
Low.add(67.0);
Low.add(43.0);
Low.add(23.0);
Low.add(67.0);
Low.add(84.0);
Low.add(23.0);
Low.add(34.0);
Low.add(76.0);
Low.add(45.0);
Low.add(73.0);
Low.add(67.0);
Low.add(96.0);
}
}
3)how do i allow the user to draw trend lines
Code: Select all
//For creating line on mouse click.
XYLineAnnotation xYLineAnnotation = new XYLineAnnotation(oldxPoint, oldyPoint, newxPoint, newyPoint, new BasicStroke(1.0f), Color.blue);
//For creating a pointer at a specific location
XYPointerAnnotation xypointerannotation = new XYPointerAnnotation("Buy", 1.273559399999E12, 126.89, 200D);//
xypointerannotation.setText("Buy");
xypointerannotation.setTextAnchor(TextAnchor.BOTTOM_RIGHT);
xyplot.addAnnotation(xypointerannotation);
4) new plots for macd,STO, etc etc
Code: Select all
package org.jfree.chart.demo;
import org.jfree.chart.ChartFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CombinedDomainXYPlot;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.CandlestickRenderer;
import org.jfree.chart.renderer.xy.XYBarRenderer;
import org.jfree.data.xy.*;
import java.awt.*;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
public class CandlestickVolumeDemo {
public static void main(String[] args) {
ChartFrame chartFrame = new ChartFrame("Candlestick + Volume Demo", buildChart());
chartFrame.setSize(600,600);
chartFrame.setVisible(true);
}
public static JFreeChart buildChart() {
//Shared date axis
DateAxis domainAxis = new DateAxis("Date");
//Build Candlestick Chart based on stock price OHLC
OHLCDataset priceDataset = getPriceDataSet("MSFT");
NumberAxis priceAxis = new NumberAxis("Price");
CandlestickRenderer priceRenderer = new CandlestickRenderer();
XYPlot pricePlot = new XYPlot(priceDataset, domainAxis, priceAxis, priceRenderer);
priceRenderer.setSeriesPaint(0, Color.BLACK);
priceRenderer.setDrawVolume(false);
priceAxis.setAutoRangeIncludesZero(false);
//Build Bar Chart for volume by wrapping price dataset with an IntervalXYDataset
IntervalXYDataset volumeDataset = getVolumeDataset(priceDataset, 24 * 60 * 60 * 1000); // Each bar is 24 hours wide.
NumberAxis volumeAxis = new NumberAxis("Volume");
XYBarRenderer volumeRenderer = new XYBarRenderer();
XYPlot volumePlot = new XYPlot(volumeDataset, domainAxis, volumeAxis, volumeRenderer);
volumeRenderer.setSeriesPaint(0, Color.BLUE);
//Build Combined Plot
CombinedDomainXYPlot mainPlot = new CombinedDomainXYPlot(domainAxis);
mainPlot.add(pricePlot);
mainPlot.add(volumePlot);//4) how do i add additional technical charts like MACD, STO, etc etc below the original candlestick chart?
return new JFreeChart("Microsoft", null, mainPlot, false);
}
protected static OHLCDataset getPriceDataSet(String symbol) {
List<OHLCDataItem> dataItems = new ArrayList<OHLCDataItem>();
try {
String strUrl= "http://ichart.finance.yahoo.com/table.csv?s="+symbol+"&a=0&b=1&c=2008&d=3&e=30&f=2008&ignore=.csv";
URL url = new URL(strUrl);
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
DateFormat df = new SimpleDateFormat("y-M-d");
String inputLine;
in.readLine();
while ((inputLine = in.readLine()) != null) {
StringTokenizer st = new StringTokenizer(inputLine, ",");
Date date = df.parse( st.nextToken() );
double open = Double.parseDouble( st.nextToken() );
double high = Double.parseDouble( st.nextToken() );
double low = Double.parseDouble( st.nextToken() );
double close = Double.parseDouble( st.nextToken() );
double volume = Double.parseDouble( st.nextToken() );
@SuppressWarnings("unused")
double adjClose = Double.parseDouble( st.nextToken() );
OHLCDataItem item = new OHLCDataItem(date, open, high, low, close, volume);
dataItems.add(item);
}
in.close();
}
catch (Exception e) {
e.printStackTrace();
}
Collections.reverse(dataItems);
OHLCDataItem[] data = dataItems.toArray(new OHLCDataItem[dataItems.size()]);
return new DefaultOHLCDataset(symbol, data);
}
@SuppressWarnings("serial")
protected static IntervalXYDataset getVolumeDataset(final OHLCDataset priceDataset, final long barWidthInMilliseconds){
return new AbstractIntervalXYDataset(){
public int getSeriesCount() {
return priceDataset.getSeriesCount();
}
@SuppressWarnings("unchecked")
public Comparable getSeriesKey(int series) {
return priceDataset.getSeriesKey(series) + "-Volume";
}
public int getItemCount(int series) {
return priceDataset.getItemCount(series);
}
public Number getX(int series, int item) {
return priceDataset.getX(series, item);
}
public Number getY(int series, int item) {
return priceDataset.getVolume(series, item);
}
public Number getStartX(int series, int item) {
return priceDataset.getX(series, item).doubleValue() - barWidthInMilliseconds/2;
}
public Number getEndX(int series, int item) {
return priceDataset.getX(series, item).doubleValue() + barWidthInMilliseconds/2;
}
public Number getStartY(int series, int item) {
return new Double(0.0);
}
public Number getEndY(int series, int item) {
return priceDataset.getVolume(series, item);
}
};
}
}
CombinedDomainXYPlot mainPlot = new CombinedDomainXYPlot(domainAxis);
mainPlot.add(pricePlot);
mainPlot.add(volumePlot);
5) how do i make the values update-able, instead of having to draw a new chart every time?(i want to make a live/realtime chart)
For dynamic update/realtime update. without recreating the plot...
Code: Select all
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.time.Millisecond;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.data.xy.XYDataset;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
/**
* A demonstration application showing a time series chart where you can dynamically add
* (random) data by clicking on a button.
*
*/
public class DynamicDataDemo extends ApplicationFrame implements ActionListener {
private static final long serialVersionUID = -2257917348073435624L;
/** The time series data. */
private TimeSeries series;
/** The most recent value added. */
private double lastValue = 100.0;
/**
* Constructs a new demonstration application.
*
* @param title the frame title.
*/
@SuppressWarnings("deprecation")
public DynamicDataDemo(final String title) {
super(title);
this.series = new TimeSeries("Random Data", Millisecond.class);
final TimeSeriesCollection dataset = new TimeSeriesCollection(this.series);
final JFreeChart chart = createChart(dataset);
final ChartPanel chartPanel = new ChartPanel(chart);
final JButton button = new JButton("Add New Data Item");
button.setActionCommand("ADD_DATA");
button.addActionListener(this);
final JPanel content = new JPanel(new BorderLayout());
content.add(chartPanel);
content.add(button, BorderLayout.SOUTH);
chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
setContentPane(content);
}
/**
* Creates a sample chart.
*
* @param dataset the dataset.
*
* @return A sample chart.
*/
private JFreeChart createChart(final XYDataset dataset) {
final JFreeChart result = ChartFactory.createTimeSeriesChart(
"Dynamic Data Demo",
"Time",
"Value",
dataset,
true,
true,
false
);
final XYPlot plot = result.getXYPlot();
ValueAxis axis = plot.getDomainAxis();
axis.setAutoRange(true);
axis.setFixedAutoRange(60000.0); // 60 seconds
axis = plot.getRangeAxis();
axis.setRange(0.0, 200.0);
return result;
}
// ****************************************************************************
// * JFREECHART DEVELOPER GUIDE *
// * The JFreeChart Developer Guide, written by David Gilbert, is available *
// * to purchase from Object Refinery Limited: *
// * *
// * http://www.object-refinery.com/jfreechart/guide.html *
// * *
// * Sales are used to provide funding for the JFreeChart project - please *
// * support us so that we can continue developing free software. *
// ****************************************************************************
/**
* Handles a click on the button by adding new (random) data.
*
* @param e the action event.
*/
public void actionPerformed(final ActionEvent e) {
if (e.getActionCommand().equals("ADD_DATA")) {
final double factor = 0.90 + 0.2 * Math.random();
this.lastValue = this.lastValue * factor;
final Millisecond now = new Millisecond();
System.out.println("Now = " + now.toString());
this.series.add(new Millisecond(), this.lastValue);
}
}
/**
* Starting point for the demonstration application.
*
* @param args ignored.
*/
public static void main(final String[] args) {
final DynamicDataDemo demo = new DynamicDataDemo("Dynamic Data Demo");
demo.pack();
RefineryUtilities.centerFrameOnScreen(demo);
demo.setVisible(true);
}
}
timeseries.add(new Millisecond(), value);