/*
* -------------------------------------------------------------------------
* $Id: Database.java,v 1.8 2004/05/26 18:54:55 estewart Exp $
* -------------------------------------------------------------------------
* Copyright (c) 1999 Visual Numerics Inc. All Rights Reserved.
*
* This software is confidential information which is proprietary to
* and a trade secret of Visual Numerics, Inc. Use, duplication or
* disclosure is subject to the terms of an appropriate license
* agreement.
*
* VISUAL NUMERICS MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE
* SUITABILITY OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING
* BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. VISUAL
* NUMERICS SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
* AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THIS SOFTWARE OR
* ITS DERIVATIVES.
*--------------------------------------------------------------------------
*/
package com.imsl.demo.risk;
import java.util.*;
import java.io.*;
import javax.swing.JOptionPane;
/**
*
* @author brophy
* @created January 24, 2002
*/
class Database implements Serializable {
static public final int INTERVAL_YEAR = 0;
static public final int INTERVAL_MONTH = 1;
static public final int INTERVAL_QUARTER = 2;
static public final int INTERVAL_WEEK = 3;
static public final int INTERVAL_ALL = 4;
///static private final long serialVersionUID = -4975277050625648285L;
private HashMap hashSeries;
/** Creates new Database */
public Database() {
try {
hashSeries = new HashMap(10);
readAll("spx");
readAll("ftse");
readAll("n225");
readAll("tnx");
readAll("xau");
} catch (Exception e) {
e.printStackTrace();
JOptionPane.showMessageDialog(null, e.toString(), "alert", JOptionPane.ERROR_MESSAGE);
}
}
void save(String filename) throws IOException {
FileOutputStream fos = new FileOutputStream(filename);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(this);
oos.close();
fos.close();
}
static Database load(String filename) throws IOException {
try {
FileInputStream fis = new FileInputStream(filename);
ObjectInputStream ois = new ObjectInputStream(fis);
Database db = (Database)ois.readObject();
ois.close();
fis.close();
return db;
} catch (ClassNotFoundException e) {
return null;
}
}
public String[] getTickers() {
Set keys = hashSeries.keySet();
SortedSet ss = new TreeSet();
Iterator iter = keys.iterator();
while (iter.hasNext()) {
ss.add(iter.next());
}
return (String[])ss.toArray(new String[0]);
}
public Series getSeries(String ticker) {
return (Series)hashSeries.get(ticker);
}
public Series getSeries(String ticker, int period, int interval) {
Series daily = getSeries(ticker);
ListSeries listSeries = new ListSeries();
GregorianCalendar calStart = new GregorianCalendar();
switch (interval) {
case INTERVAL_ALL:
calStart.add(GregorianCalendar.YEAR, -200);
break;
case INTERVAL_MONTH:
calStart.add(GregorianCalendar.MONTH, -1);
break;
case INTERVAL_YEAR:
calStart.add(GregorianCalendar.YEAR, -1);
break;
case INTERVAL_QUARTER:
calStart.add(GregorianCalendar.MONTH, -3);
break;
case INTERVAL_WEEK:
calStart.add(GregorianCalendar.DATE, -7);
break;
}
GregorianCalendar cal = new GregorianCalendar();
int lastPeriod = -1;
double open = 0;
double close = 0;
double high = 0;
double low = 0;
Date startDate = null;
for (int k = 0; k < daily.date.length; k++) {
Date date = new java.util.Date((long)daily.date[k]);
cal.setTime(date);
if (cal.before(calStart)) continue;
int thisPeriod = cal.get(period);
if (thisPeriod != lastPeriod) {
if (lastPeriod != -1) {
listSeries.add(startDate, high, low, close, open);
}
startDate = date;
open = daily.open[k];
close = daily.close[k];
high = daily.high[k];
low = daily.low[k];
} else {
close = daily.close[k];
high = Math.max(high,daily.high[k]);
low = Math.min(low,daily.low[k]);
}
lastPeriod = thisPeriod;
}
listSeries.add(startDate, high, low, close, open);
return new Series(listSeries);
}
private void readAll(String ticker) throws Exception {
// read the data
ListSeries listSeries = (ListSeries)hashSeries.get(ticker);
if (listSeries == null) {
listSeries = new ListSeries();
hashSeries.put(ticker, listSeries);
}
String s = "com/imsl/demo/risk/" + ticker + ".csv";
java.io.InputStream is = getClass().getClassLoader().getResourceAsStream(s);
ReadYahooCSV rsd = new ReadYahooCSV(is);
while (rsd.next()) {
listSeries.listDate.add(rsd.getObject("Date"));
listSeries.listOpen.add(rsd.getObject("Open"));
listSeries.listHigh.add(rsd.getObject("High"));
listSeries.listLow.add(rsd.getObject("Low"));
listSeries.listClose.add(rsd.getObject("Close"));
}
rsd.close();
hashSeries.put(ticker, new Series(listSeries));
}
public double[][] getReturns() {
String tickers[] = getTickers();
int nTickers = tickers.length;
Database.Series series[] = new Database.Series[nTickers];
for (int k = 0; k < nTickers; k++) {
series[k] = getSeries(tickers[k]);
}
List list = new ArrayList(1000);
int index[] = new int[nTickers];
//double lastDate = new java.util.Date(100,0,1).getTime();
NEXT_OBS:
while (true) {
if (index[0] >= series[0].date.length) break NEXT_OBS;
double date = series[0].date[index[0]];
//if (date < lastDate) break;
for (int k = 1; k < nTickers; k++) {
while (true) {
if (index[k] >= series[k].date.length) break NEXT_OBS;
double d2 = series[k].date[index[k]];
if (d2 == date) break;
if (d2 > date) {
index[k]++;
continue NEXT_OBS;
} else if (d2 < date) {
for (int j = 0; j < k; j++) {
index[j]++;
}
continue NEXT_OBS;
}
}
}
// if here we know same date exists in all tickers
double x[] = new double[nTickers+1];
for (int k = 0; k < nTickers; k++) {
x[k] = series[k].close[index[k]];
}
list.add(x);
for (int k = 0; k < nTickers; k++) index[k]++;
}
int nObs = list.size();
double obsLast[] = (double[])list.get(0);
double returns[][] = new double[nObs-1][nTickers];
for (int j = 1; j < nObs; j++) {
double obs[] = (double[])list.get(j);
for (int k = 0; k < nTickers; k++) {
returns[j-1][k] = (obs[k]-obsLast[k])/obsLast[k];
}
obsLast = (double[])obs;
}
return returns;
}
static private class ListSeries {
List listDate;
List listHigh;
List listLow;
List listClose;
List listOpen;
ListSeries() {
listDate = new ArrayList(500);
listHigh = new ArrayList(500);
listLow = new ArrayList(500);
listClose = new ArrayList(500);
listOpen = new ArrayList(500);
}
void add(java.util.Date date, double high, double low, double close, double open) {
listDate.add(date);
listHigh.add(new Double(high));
listLow.add(new Double(low));
listClose.add(new Double(close));
listOpen.add(new Double(open));
}
}
static class Series implements Serializable {
static private final long serialVersionUID = 6083341146689785913L;
String ticker;
double date[];
double high[];
double low[];
double close[];
double open[];
Series(ListSeries listSeries) {
int n = listSeries.listDate.size();
date = new double[n];
high = new double[n];
low = new double[n];
close = new double[n];
open = new double[n];
for (int k = 0; k < n; k++) {
date[k] = ((java.util.Date)listSeries.listDate.get(k)).getTime();
high[k] = ((Double)listSeries.listHigh.get(k)).doubleValue();
low[k] = ((Double)listSeries.listLow.get(k)).doubleValue();
close[k] = ((Double)listSeries.listClose.get(k)).doubleValue();
open[k] = ((Double)listSeries.listOpen.get(k)).doubleValue();
}
}
}
}