/*
* OpenTrader Trading Platform
* The solution for online trading, technical analysis and automated trading.
*
* Copyright (C) 2011 Andrey Pudov
* Andrey Pudov <syscreat@gmail.com>
*
* http://opentrader.github.com/
*/
/*
* CDDL HEADER START
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright 2011 Andrey Pudov. All rights reserved.
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*
*
* Copyright 2011 Andrey Pudov. All rights reserved.
* Use is subject to license terms.
*
* Contributor(s):
*
* Portions Copyrighted 2011 Andrey Pudov.
*
*/
package com.opentrader.ui.components;
/**
* @author Andrey Pudov <syscreat@gmail.com>
* @version 0.00.00
* %name Chart.java
* %pkg com.opentrader.ui.components
* %date 11:43:28 AM, Apr 23, 2011
*/
public class Chart extends java.awt.Canvas
implements java.awt.event.ComponentListener {
private static final long serialVersionUID = 6_639_826_293_774_293_930L;
private static final java.util.logging.Logger LOG
= java.util.logging.Logger.getLogger("opentrader");
private com.opentrader.market.Symbol symbol;
private java.util.List<com.opentrader.market.Historic> historic;
private java.awt.Image image;
public Chart() {
super();
addComponentListener(this);
}
public void setHistoric(com.opentrader.market.Symbol symbol,
java.util.List<com.opentrader.market.Historic> historic) {
if ((symbol == null) || (historic == null)) {
return;
}
this.symbol = symbol;
this.historic = java.util.Collections.unmodifiableList(historic);
repaint();
}
@Override
public void paint(java.awt.Graphics g) {
if (image != null) {
g.drawImage(image, 0, 0, this.getWidth(), this.getHeight(), this);
return;
}
if ((historic != null) && (symbol != null)) {
// Defining Line
double[] volume = new double[historic.size()];
double volumeMin = Double.MAX_VALUE;
double volumeMax = Double.MIN_VALUE;
int volumeMinIndex = 0;
int volumeMaxIndex = 0;
for (int i = 0; i < historic.size(); ++i) {
volume[i] = historic.get(i).getVolume();
if (volume[i] < volumeMin) {
volumeMin = volume[i];
volumeMinIndex = i;
}
if (volume[i] > volumeMax) {
volumeMax = volume[i];
volumeMaxIndex = i;
}
}
double[] open = new double[historic.size()];
double openMin = Double.MAX_VALUE;
double openMax = Double.MIN_VALUE;
for (int i = 0; i < historic.size(); ++i) {
open[i] = historic.get(i).getOpen();
if (open[i] < openMin) {
openMin = open[i];
}
if (open[i] > openMax) {
openMax = open[i];
}
}
double[] adjClose = new double[historic.size()];
double adjCloseMin = Double.MAX_VALUE;
double adjCloseMax = Double.MIN_VALUE;
for (int i = 0; i < historic.size(); ++i) {
adjClose[i] = historic.get(i).getAdjClose();
if (adjClose[i] < adjCloseMin) {
adjCloseMin = adjClose[i];
}
if (adjClose[i] > adjCloseMax) {
adjCloseMax = adjClose[i];
}
}
double[] close = new double[historic.size()];
double closeMin = Double.MAX_VALUE;
double closeMax = Double.MIN_VALUE;
for (int i = 0; i < historic.size(); ++i) {
close[i] = historic.get(i).getClose();
if (close[i] < closeMin) {
closeMin = close[i];
}
if (close[i] > closeMax) {
closeMax = close[i];
}
}
double[] high = new double[historic.size()];
double highMin = Double.MAX_VALUE;
double highMax = Double.MIN_VALUE;
for (int i = 0; i < historic.size(); ++i) {
high[i] = historic.get(i).getHigh();
if (high[i] < highMin) {
highMin = high[i];
}
if (high[i] > highMax) {
highMax = high[i];
}
}
double[] low = new double[historic.size()];
double lowMin = Double.MAX_VALUE;
double lowMax = Double.MIN_VALUE;
for (int i = 0; i < historic.size(); ++i) {
low[i] = historic.get(i).getLow();
if (low[i] < lowMin) {
lowMin = low[i];
}
if (low[i] > lowMax) {
lowMax = low[i];
}
}
com.googlecode.charts4j.Line lineVolume
= com.googlecode.charts4j.Plots.newLine(
com.googlecode.charts4j.DataUtil.scaleWithinRange(
volumeMin, volumeMax, volume),
com.googlecode.charts4j.Color.BLUE,
"Volume");
lineVolume.setLineStyle(
com.googlecode.charts4j.LineStyle.newLineStyle(1, 1, 0));
lineVolume.addShapeMarkers(
com.googlecode.charts4j.Shape.CIRCLE,
com.googlecode.charts4j.Color.ROYALBLUE, 5);
lineVolume.addShapeMarker(
com.googlecode.charts4j.Shape.VERTICAL_LINE_PARTIAL,
com.googlecode.charts4j.Color.BLUE, 1, volumeMinIndex);
lineVolume.addShapeMarker(
com.googlecode.charts4j.Shape.VERTICAL_LINE_PARTIAL,
com.googlecode.charts4j.Color.BLUE, 1, volumeMaxIndex);
lineVolume.setFillAreaColor(com.googlecode.charts4j.Color.DODGERBLUE);
com.googlecode.charts4j.Line lineOpen
= com.googlecode.charts4j.Plots.newLine(
com.googlecode.charts4j.DataUtil.scaleWithinRange(
openMin, openMax, open),
com.googlecode.charts4j.Color.ROYALBLUE,
"Open");
lineOpen.setLineStyle(
com.googlecode.charts4j.LineStyle.newLineStyle(1, 1, 0));
com.googlecode.charts4j.Line lineAdjClose
= com.googlecode.charts4j.Plots.newLine(
com.googlecode.charts4j.DataUtil.scaleWithinRange(
adjCloseMin, adjCloseMax, adjClose),
com.googlecode.charts4j.Color.PALEGREEN,
"AdjClose");
lineAdjClose.setLineStyle(
com.googlecode.charts4j.LineStyle.newLineStyle(4, 1, 0));
com.googlecode.charts4j.Line lineClose
= com.googlecode.charts4j.Plots.newLine(
com.googlecode.charts4j.DataUtil.scaleWithinRange(
closeMin, closeMax, close),
com.googlecode.charts4j.Color.GREEN,
"Close");
lineClose.setLineStyle(
com.googlecode.charts4j.LineStyle.newLineStyle(1, 1, 0));
com.googlecode.charts4j.Line lineHigh
= com.googlecode.charts4j.Plots.newLine(
com.googlecode.charts4j.DataUtil.scaleWithinRange(
highMin, highMax, high),
com.googlecode.charts4j.Color.RED,
"High");
lineHigh.setLineStyle(
com.googlecode.charts4j.LineStyle.newLineStyle(1, 1, 0));
com.googlecode.charts4j.Line lineLow
= com.googlecode.charts4j.Plots.newLine(
com.googlecode.charts4j.DataUtil.scaleWithinRange(
lowMin, lowMax, low),
com.googlecode.charts4j.Color.FUCHSIA,
"Low");
lineLow.setLineStyle(
com.googlecode.charts4j.LineStyle.newLineStyle(1, 1, 0));
// Defining chart.
com.googlecode.charts4j.LineChart chart
= com.googlecode.charts4j.GCharts.newLineChart(
lineVolume, lineOpen, lineAdjClose, lineClose, lineHigh, lineLow);
if ((this.getWidth() + this.getHeight()) > 1000) {
double scale = 1000.0 / (this.getWidth() + this.getHeight());
int width = (int) Math.round(this.getWidth() * scale);
int height = (int) Math.round(this.getHeight() * scale);
chart.setSize(width, height);
} else {
chart.setSize(this.getWidth(), this.getHeight());
}
chart.setTitle(
symbol.getCode() + "|" + getFirstDate() + " - "
+ getLastDate(),
com.googlecode.charts4j.Color.BLACK, 14);
// Defining axis info and styles
com.googlecode.charts4j.AxisStyle axisStyle
= com.googlecode.charts4j.AxisStyle.newAxisStyle(
com.googlecode.charts4j.Color.BLACK, 12,
com.googlecode.charts4j.AxisTextAlignment.CENTER);
com.googlecode.charts4j.AxisLabels yAxis
= com.googlecode.charts4j.AxisLabelsFactory.newNumericRangeAxisLabels(
0, volume[volume.length-1]);
yAxis.setAxisStyle(axisStyle);
com.googlecode.charts4j.AxisLabels xAxis1
= com.googlecode.charts4j.AxisLabelsFactory.newAxisLabels(
java.util.Arrays.asList("Min", "Max"),
java.util.Arrays.asList(volumeMinIndex, volumeMaxIndex));
xAxis1.setAxisStyle(axisStyle);
com.googlecode.charts4j.AxisLabels xAxis2
= com.googlecode.charts4j.AxisLabelsFactory.newNumericRangeAxisLabels(1962, 2008);
xAxis2.setAxisStyle(axisStyle);
com.googlecode.charts4j.AxisLabels xAxis3
= com.googlecode.charts4j.AxisLabelsFactory.newAxisLabels(
"Time", 50.0);
xAxis3.setAxisStyle(com.googlecode.charts4j.AxisStyle.newAxisStyle(
com.googlecode.charts4j.Color.BLACK, 14,
com.googlecode.charts4j.AxisTextAlignment.CENTER));
// Adding axis info to chart.
chart.addYAxisLabels(yAxis);
chart.addXAxisLabels(xAxis1);
chart.addXAxisLabels(xAxis2);
chart.addXAxisLabels(xAxis3);
chart.setGrid(100, 6.78, 5, 0);
// Defining background and chart fills.
chart.setBackgroundFill(
com.googlecode.charts4j.Fills.newSolidFill(
com.googlecode.charts4j.Color.WHITE));
chart.setAreaFill(
com.googlecode.charts4j.Fills.newSolidFill(
com.googlecode.charts4j.Color.WHITE));
String url = chart.toURLString();
try {
image = getImage(url);
g.drawImage(image, 0, 0, this.getWidth(), this.getHeight(),
this);
} catch (Exception e) {
LOG.warning(e.getMessage());
}
}
}
private static java.awt.Image getImage(String path)
throws java.io.IOException {
java.awt.Image image = null;
java.net.URL server = new java.net.URL(path);
java.net.HttpURLConnection connection
= (java.net.HttpURLConnection) server.openConnection();
connection.setRequestMethod("GET");
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setUseCaches(false);
connection.addRequestProperty("Accept",
"image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, "
+ "application/msword, application/vnd.ms-excel, "
+ "application/vnd.ms-powerpoint, "
+ "application/x-shockwave-flash, */*");
connection.addRequestProperty("Accept-Language", "en-us,zh-cn;q=0.5");
connection.addRequestProperty("Accept-Encoding", "gzip, deflate");
connection.addRequestProperty("User-Agent",
"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; "
+ ".NET CLR 2.0.50727; MS-RTC LM 8)");
connection.connect();
java.io.InputStream is = connection.getInputStream();
image = javax.imageio.ImageIO.read(is);
return image;
}
private String getFirstDate() {
java.text.SimpleDateFormat format
= new java.text.SimpleDateFormat("MM/dd/yyyy");
com.opentrader.market.Historic entry = historic.get(0);
return format.format(new java.util.Date(entry.getDate()));
}
private String getLastDate() {
java.text.SimpleDateFormat format
= new java.text.SimpleDateFormat("MM/dd/yyyy");
com.opentrader.market.Historic entry = historic.get(historic.size() - 1);
return format.format(new java.util.Date(entry.getDate()));
}
/*
* Catch the different events of these components by using four methods
* of Component Listener
*/
@Override
public void componentResized(java.awt.event.ComponentEvent e) {
image = null;
}
@Override
public void componentMoved(java.awt.event.ComponentEvent e) {
//throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void componentShown(java.awt.event.ComponentEvent e) {
//throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public void componentHidden(java.awt.event.ComponentEvent e) {
//throw new UnsupportedOperationException("Not supported yet.");
}
}