Last active
October 21, 2021 02:35
-
-
Save Sietesoles/dae3a4959f36df3632a9 to your computer and use it in GitHub Desktop.
Stock and Portfolio manager in Java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.text.DecimalFormat; | |
import java.text.ParseException; | |
import java.text.SimpleDateFormat; | |
import java.util.ArrayList; | |
import java.util.Calendar; | |
import java.util.HashMap; | |
import javax.swing.JFrame; | |
import org.jfree.chart.ChartPanel; | |
import org.jfree.chart.JFreeChart; | |
import org.jfree.chart.ChartFactory; | |
import org.jfree.chart.labels.StandardXYToolTipGenerator; | |
import org.jfree.chart.plot.XYPlot; | |
import org.jfree.chart.renderer.xy.XYItemRenderer; | |
import org.jfree.data.time.Day; | |
import org.jfree.data.time.MovingAverage; | |
import org.jfree.data.time.TimeSeries; | |
import org.jfree.data.time.TimeSeriesCollection; | |
import org.jfree.data.xy.XYDataset; | |
public class jFreeChart extends JFrame{ | |
/* | |
* Uses the jFreeChart.java library to construct good-looking graphs; | |
* it accepts both Arrays and HashTables. | |
* It is used to produce the moving averages plot. | |
* | |
* | |
* For more information see jFreeChart's documentation | |
*/ | |
private static final long serialVersionUID = 1L; | |
public jFreeChart (String applicationTitle, String chartTitle, String stockName, ArrayList<Object[]> dohlcvac) { | |
super(applicationTitle); | |
XYDataset dataset = arraylistCreateDataset(dohlcvac); | |
JFreeChart chart = createChart(dataset, stockName); | |
ChartPanel chartPanel = new ChartPanel(chart); | |
chartPanel.setPreferredSize(new java.awt.Dimension(500, 270)); | |
chartPanel.setMouseZoomable(true, false); | |
setContentPane(chartPanel); | |
} | |
public jFreeChart (String applicationTitle, String chartTitle, String Portfolio, HashMap<String, Double> dateToValue) { | |
super(applicationTitle); | |
XYDataset dataset = HashMapCreateDataset(dateToValue); | |
JFreeChart chart = createChart(dataset, Portfolio); | |
ChartPanel chartPanel = new ChartPanel(chart); | |
chartPanel.setPreferredSize(new java.awt.Dimension(500, 270)); | |
chartPanel.setMouseZoomable(true, false); | |
setContentPane(chartPanel); | |
} | |
private XYDataset arraylistCreateDataset(ArrayList<Object[]> dohlcvac) { | |
TimeSeries result = createStockTimeSeries(dohlcvac); | |
TimeSeries timeSeries1 = MovingAverage.createMovingAverage(result, "15 day moving average", 15, 15); | |
TimeSeries timeSeries2 = MovingAverage.createMovingAverage(result, "40 day moving average", 40, 40); | |
TimeSeries timeSeries3 = MovingAverage.createMovingAverage(result, "90 day moving average", 90, 90); | |
TimeSeriesCollection timeSeriesCollection = new TimeSeriesCollection(); | |
timeSeriesCollection.addSeries(result); | |
timeSeriesCollection.addSeries(timeSeries1); | |
timeSeriesCollection.addSeries(timeSeries2); | |
timeSeriesCollection.addSeries(timeSeries3); | |
return timeSeriesCollection; | |
} | |
private XYDataset HashMapCreateDataset(HashMap<String, Double> dateToValue) { | |
TimeSeries result = createDrawdownTimeSeries(dateToValue); | |
TimeSeriesCollection timeSeriesCollection = new TimeSeriesCollection(); | |
timeSeriesCollection.addSeries(result); | |
return timeSeriesCollection; | |
} | |
private static TimeSeries createStockTimeSeries(ArrayList<Object[]> dohlcvac) { | |
TimeSeries timeSeries = new TimeSeries("Stock"); | |
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); | |
try { | |
Calendar date = Calendar.getInstance(); | |
for (int i=0; i<dohlcvac.size(); i++) { | |
try { | |
date.setTime(format.parse((String) dohlcvac.get(i)[0])); | |
} catch (ParseException e) { | |
e.printStackTrace(); | |
} | |
timeSeries.add(new Day(date.getTime()), (double)dohlcvac.get(i)[4]); | |
} | |
} catch (Exception exception) { | |
System.err.println(exception.getMessage()); | |
} | |
return timeSeries; | |
} | |
private static TimeSeries createDrawdownTimeSeries(HashMap<String, Double> dateToValue) { | |
TimeSeries timeSeries = new TimeSeries("Value"); | |
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); | |
Calendar date = Calendar.getInstance(); | |
for (String hashDate : dateToValue.keySet()) { | |
try { | |
date.setTime(sdf.parse(hashDate)); | |
} catch (ParseException e) { | |
e.printStackTrace(); | |
} | |
timeSeries.add(new Day(date.getTime()), dateToValue.get(hashDate)); | |
} | |
return timeSeries; | |
} | |
private JFreeChart createChart(XYDataset xyDataset, String stockName) { | |
JFreeChart jfreechart = ChartFactory.createTimeSeriesChart(stockName, "Date", "Value", xyDataset, true, true, false); | |
XYPlot xyPlot = (XYPlot)jfreechart.getPlot(); | |
XYItemRenderer xyItemRenderer = xyPlot.getRenderer(); | |
StandardXYToolTipGenerator standardXYToolTipGenerator = new StandardXYToolTipGenerator("{0}: ({1}, {2})", new SimpleDateFormat("yyyy-MM-dd"), new DecimalFormat("0.00")); | |
xyItemRenderer.setBaseToolTipGenerator(standardXYToolTipGenerator); | |
return jfreechart; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.awt.Dimension; | |
import java.awt.Font; | |
import java.awt.GridLayout; | |
import java.awt.event.MouseAdapter; | |
import java.awt.event.MouseEvent; | |
import java.util.ArrayList; | |
import javax.swing.JPanel; | |
import javax.swing.JScrollPane; | |
import javax.swing.JTable; | |
public class jTable extends JPanel { | |
/* | |
* An object that displays a table of the basic statistics of a stock; | |
* it is also used to display the transaction history of your portfolio. | |
*/ | |
private static final long serialVersionUID = 1L; | |
private boolean DEBUG = false; | |
public jTable(ArrayList<Object[]> information, ArrayList<Object[]> returns) { | |
super(new GridLayout(1,0)); | |
String[] columnNames = {"Date", "Open", "High", "Low", "Volume", "Close", "Returns"}; | |
int len = information.size(); | |
//Build data | |
Object[][] data = new Object[len][7]; | |
for (int i=0; i<len; i++) { | |
data[i][0] = information.get(i)[0]; | |
data[i][1] = information.get(i)[1]; | |
data[i][2] = information.get(i)[2]; | |
data[i][3] = information.get(i)[3]; | |
data[i][4] = information.get(i)[5]; | |
data[i][5] = information.get(i)[4]; | |
if (i<len-1) | |
data[i][6] = returns.get(i)[1]; | |
} | |
final JTable table = new JTable(data, columnNames); | |
table.setPreferredScrollableViewportSize(new Dimension(500, 700)); | |
table.getTableHeader().setFont(new Font("Times New Roman", Font.BOLD, 13)); | |
table.setFillsViewportHeight(true); | |
if (DEBUG) { | |
table.addMouseListener(new MouseAdapter() { | |
public void mouseClicked(MouseEvent e) { | |
printDebugData(table); | |
} | |
}); | |
} | |
JScrollPane scrollPane = new JScrollPane(table); | |
add(scrollPane); | |
} | |
//Stock, Date, numShares, costPerShare | |
public jTable(ArrayList<Object[]> transactions) { | |
super(new GridLayout(1,0)); | |
String[] columnNames = {"Date", "Stock", "# of Shares", "Cost per Share"}; | |
int len = transactions.size(); | |
//Build data | |
Object[][] data = new Object[len][4]; | |
for (int i=0; i<len; i++) { | |
data[i][1] = ((Stock)transactions.get(i)[0]).getName(); //stock | |
data[i][0] = transactions.get(i)[1]; //date | |
data[i][2] = transactions.get(i)[2]; //numShares | |
data[i][3] = transactions.get(i)[3]; //Cost per SHare | |
} | |
final JTable table = new JTable(data, columnNames); | |
table.setPreferredScrollableViewportSize(new Dimension(300, 400)); | |
table.getTableHeader().setFont(new Font("Times New Roman", Font.BOLD, 13)); | |
table.setFillsViewportHeight(true); | |
if (DEBUG) { | |
table.addMouseListener(new MouseAdapter() { | |
public void mouseClicked(MouseEvent e) { | |
printDebugData(table); | |
} | |
}); | |
} | |
JScrollPane scrollPane = new JScrollPane(table); | |
add(scrollPane); | |
} | |
private void printDebugData(JTable table) { | |
int numRows = table.getRowCount(); | |
int numCols = table.getColumnCount(); | |
javax.swing.table.TableModel model = table.getModel(); | |
System.out.println("Value of data: "); | |
for (int i=0; i < numRows; i++) { | |
System.out.print(" row " + i + ":"); | |
for (int j=0; j < numCols; j++) { | |
System.out.print(" " + model.getValueAt(i, j)); | |
} | |
System.out.println(); | |
} | |
System.out.println("--------------------------"); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.awt.Color; | |
import java.awt.Dimension; | |
import java.awt.FlowLayout; | |
import java.awt.event.ActionEvent; | |
import java.awt.event.ActionListener; | |
import java.io.File; | |
import java.text.SimpleDateFormat; | |
import java.util.Arrays; | |
import java.util.Calendar; | |
import java.util.Date; | |
import javax.swing.JButton; | |
import javax.swing.JFileChooser; | |
import javax.swing.JFrame; | |
import javax.swing.JOptionPane; | |
import javax.swing.JTextPane; | |
import org.jfree.ui.RefineryUtilities; | |
public class GUI implements ActionListener{ | |
/* | |
* This class manages all the buttons and the GUI interface of the program. | |
*/ | |
public void loadView() { | |
//update PF | |
portfolio.updatePf(); | |
//Set time for DEMO | |
//enddate.add(Calendar.MONTH, -1); | |
startdate.add(Calendar.YEAR, -1); | |
//startdate.add(Calendar.MONTH, -1); | |
//set up frame | |
frame = new JFrame("Portfolio Manager"); | |
frame.setSize(430, 300); | |
frame.setMinimumSize(new Dimension(400, 300)); | |
frame.setLayout(new FlowLayout()); | |
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); | |
stockframe = new JFrame("Stock Manager"); | |
stockframe.setSize(370, 400);; | |
stockframe.setMaximumSize(new Dimension(370, 400)); | |
stockframe.setLayout(new FlowLayout()); | |
stockframe.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); | |
pfFrame = new JFrame("Portfolio Manager"); | |
pfFrame.setSize(480, 400); | |
pfFrame.setMaximumSize(new Dimension(500, 400)); | |
pfFrame.setLayout(new FlowLayout()); | |
pfFrame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); | |
searchStock.addActionListener(this); | |
searchAnother.addActionListener(this); | |
buyStock.addActionListener(this); | |
movAverages.addActionListener(this); | |
viewReturns.addActionListener(this); | |
sellStock.addActionListener(this); | |
removeStock.addActionListener(this); | |
viewSharpe.addActionListener(this); | |
loadPF.addActionListener(this); | |
viewPF.addActionListener(this); | |
savePF.addActionListener(this); | |
information.addActionListener(this); | |
Quit.addActionListener(this); | |
whatToDo.addActionListener(this); | |
seeDetails.addActionListener(this); | |
viewTransactions.addActionListener(this); | |
viewInvested.addActionListener(this); | |
viewBalance.addActionListener(this); | |
viewPFDetails.addActionListener(this); | |
Drawdown.addActionListener(this); | |
update.addActionListener(this); | |
Simulate.addActionListener(this); | |
changeName.addActionListener(this); | |
clear.addActionListener(this); | |
stockframe.add(searchAnother); | |
stockframe.add(buyStock); | |
stockframe.add(viewSharpe); | |
stockframe.add(viewReturns); | |
stockframe.add(movAverages); | |
stockframe.add(whatToDo); | |
stockframe.add(seeDetails); | |
//pfFrame.add(sellStock); | |
//pfFrame.add(removeStock); | |
pfFrame.add(viewBalance); | |
pfFrame.add(viewInvested); | |
pfFrame.add(viewPFDetails); | |
pfFrame.add(savePF); | |
pfFrame.add(viewTransactions); | |
pfFrame.add(Drawdown); | |
pfFrame.add(update); | |
pfFrame.add(changeName); | |
pfFrame.add(clear); | |
frame.add(searchStock); | |
frame.add(loadPF); | |
frame.add(viewPF); | |
frame.add(information); | |
frame.add(Quit); | |
frame.add(Simulate); | |
textDisplayMain.setText("Welcome!"); | |
textDisplayMain.setSize(new Dimension(400, 400)); | |
textDisplayMain.setBackground(Color.white); | |
frame.add(textDisplayMain); | |
textDisplayPF.setSize(new Dimension(400, 400)); | |
textDisplayPF.setBackground(Color.white); | |
pfFrame.add(textDisplayPF); | |
textDisplayStock.setSize(new Dimension(400, 400)); | |
textDisplayStock.setBackground(Color.white); | |
stockframe.add(textDisplayStock); | |
frame.setVisible(true); | |
RefineryUtilities.positionFrameOnScreen(frame, 0.5, 0.15); | |
} | |
public void actionPerformed(ActionEvent event) { | |
if (event.getSource() == clear) { | |
portfolio.obliterate(); | |
viewPortfolio(); | |
textDisplayMain.setText("Welcome!"); | |
} | |
if (event.getSource() == loadPF) { | |
textDisplayMain.setText("Please wait while we load your Portfolio..."); | |
load(); | |
} | |
if (event.getSource() == viewPF) { | |
viewPortfolio(); | |
pfFrame.setVisible(true); | |
RefineryUtilities.positionFrameOnScreen(pfFrame, 1, 0.15); | |
} | |
if (event.getSource() == changeName) { | |
changeName(); | |
} | |
if (event.getSource() == savePF) { | |
save(); | |
} | |
if (event.getSource() == update) { | |
updatePF(); | |
} | |
if (event.getSource() == Simulate) { | |
simulate(); | |
} | |
if (event.getSource() == viewTransactions) { | |
viewTransactions(); | |
} | |
if (event.getSource() == searchStock) { | |
int x = searchForStock(); | |
if (x==0) { | |
stockframe.setVisible(true); | |
RefineryUtilities.positionFrameOnScreen(stockframe, 0.1, 0.15); | |
} | |
} | |
if (event.getSource() == seeDetails) { | |
seeStockDetails(); | |
} | |
if (event.getSource() == searchAnother) { | |
searchForStock(); | |
} | |
if (event.getSource() == buyStock) { | |
buy(); | |
} | |
if (event.getSource() == viewReturns) { | |
viewReturns(); | |
} | |
if (event.getSource() == viewBalance) { | |
viewBalance(); | |
} | |
if (event.getSource() == viewInvested) { | |
viewInvested(); | |
} | |
if (event.getSource() == viewPFDetails) { | |
viewPortfolio(); | |
} | |
if (event.getSource() == Drawdown) { | |
Drawdown(); | |
} | |
if (event.getSource() == viewSharpe) { | |
sharpe(); | |
} | |
if (event.getSource() == movAverages) { | |
movingAverages(); | |
} | |
if (event.getSource() == information) { | |
information(); | |
} | |
if (event.getSource() == whatToDo) { | |
//0 for today, 1 for yesterday, 2 for the day before, etc... | |
whatToDo(0); | |
} | |
if (event.getSource() == Quit) { | |
System.exit(0); | |
} | |
} | |
//Main Frame | |
private void simulate() { | |
int days = 0; | |
try { | |
String input = JOptionPane.showInputDialog("How many days do you want to go back? (365 max)"); | |
if (input == null) | |
return; | |
days = Integer.parseInt(input); | |
} catch (NumberFormatException exception) { | |
simulate(); | |
} | |
if (days < 0) { | |
textDisplayMain.setText("You cannot go into the future"); | |
return; | |
} | |
days = days*(-1); | |
enddate.add(Calendar.DATE, days); | |
startdate.add(Calendar.DATE, days); | |
textDisplayMain.setText(sdf.format(enddate.getTime())); | |
} | |
private void information() { | |
Date date = new Date(); | |
String text = ("Author: Diego F Rincon Santana\nUNI: dfr2113\nHello \"" + System.getProperty("user.name") + "\" (if that is your real name)\nYou are using Java " + System.getProperty("java.version") | |
+ "\nIt is currently: " + date + "\nAnd you are running this on: " + System.getProperty("os.name") + | |
"\nThis program provides information and statistics about finantial securities\n" + | |
"\nIf you're looking for more detailed information about how to\noperate this program please go to the ReadMe file."); | |
textDisplayMain.setText(text); | |
} | |
private void load() { | |
chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); | |
int val = chooser.showOpenDialog(loadPF); | |
if (val == JFileChooser.APPROVE_OPTION) { | |
File file = chooser.getSelectedFile(); | |
System.out.println(file.getAbsolutePath()); | |
if (portfolio.load(file)==false) { | |
textDisplayMain.setText("\"" + file.getName() +"\" was not loaded into the system. You may have already loaded it before."); | |
} else { | |
portfolio.updatePf(); | |
textDisplayMain.setText("Success! You have loaded \"" + portfolio.getName() + "\" into your system.\nYour Portfolio has also been updated."); | |
} | |
} else { | |
textDisplayMain.setText("Operation cancelled."); | |
} | |
} | |
//Portfolio Frame | |
private void changeName() { | |
String input = null; | |
try { | |
String prompt = String.format("Current name: \"%s\"", portfolio.getName()); | |
input = JOptionPane.showInputDialog(prompt); | |
if (input == null) | |
return; | |
} catch (NumberFormatException exception) { | |
changeName(); | |
} | |
portfolio.setName(input); | |
textDisplayPF.setText("Changed Portfolio's name to: " + input); | |
sentinel = 1; | |
} | |
private void updatePF() { | |
if (portfolio.isEmpty()) { | |
textDisplayPF.setText("Your Portfolio is empty"); | |
return; | |
} | |
portfolio.updatePf(); | |
Calendar today = Calendar.getInstance(); | |
enddate.setTime(today.getTime()); | |
startdate.setTime(enddate.getTime()); | |
startdate.add(Calendar.YEAR, -1); | |
textDisplayMain.setText(sdf.format(enddate.getTime())); | |
viewPortfolio(); | |
} | |
private void viewInvested() { | |
if (portfolio.isEmpty()) { | |
textDisplayPF.setText("Your Portfolio is empty"); | |
return; | |
} | |
double invested = portfolio.getTotalSpent(); | |
int numStocks = portfolio.getNumStocks(); | |
Stock[] stocks = new Stock[numStocks]; | |
String output = String.format("You have invested %.2f$ in the following stocks:\n\n", invested); | |
for (int i=0; i<numStocks; i++) { | |
stocks[i] = portfolio.getPortfolio().get(i); | |
output += stocks[i].getNumShares() + " shares of " + stocks[i].getName() + "\n"; | |
} | |
textDisplayPF.setText(output); | |
} | |
private void viewBalance() { | |
if (portfolio.isEmpty()) { | |
textDisplayPF.setText("Your Portfolio is empty"); | |
return; | |
} | |
double balance = portfolio.getBalance(); | |
double invested = portfolio.getTotalSpent(); | |
double value = portfolio.getCurrentValue(); | |
String output = String.format("Your current balance is: %.2f$\nYou invested: %.2f$\nThe current value of your portfolio is: %.3f$", balance, invested, value); | |
textDisplayPF.setText(output); | |
} | |
private void save() { | |
if (portfolio.isEmpty()) { | |
textDisplayPF.setText("You cannot save an empty Portfolio"); | |
return; | |
} | |
//Sets the chooser to accept only directories | |
chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); | |
chooser.setSelectedFile(new File(portfolio.getName())); | |
//Displays the chooser | |
int save = chooser.showSaveDialog(savePF); | |
//Body of the method | |
if (save == JFileChooser.APPROVE_OPTION) { | |
File file = chooser.getSelectedFile(); | |
//Sets the saving directory | |
portfolio.SavingPath = file.getAbsolutePath(); | |
} else { | |
return; | |
} | |
try { | |
//Calls the portfolio save() method | |
textDisplayMain.setText("Saving..."); | |
portfolio.save(); | |
textDisplayMain.setText("Success! You have saved your portfolio"); | |
} catch (Exception e1) { | |
e1.printStackTrace(); | |
} | |
} | |
private void Drawdown() { | |
Object[] Max = portfolio.getMaxValue(); | |
// for (String date: portfolio.getDateToValue().keySet()) { | |
// System.out.println(date+ " " + portfolio.getDateToValue().get(date)); | |
// } | |
System.out.println(Arrays.toString(Max)); | |
double drawdown = (1-(portfolio.getCurrentValue()/(double)Max[1]))*100; | |
String output = String.format("Drawdown: %.2f%%\nMax attained on %s: %.2f$\nCurrent Value: %.2f$", drawdown, (String)Max[0], (double)Max[1], portfolio.getCurrentValue()); | |
textDisplayPF.setText(output); | |
jFreeChart timeseries = new jFreeChart("Value", "DW", portfolio.getName() + " Value", portfolio.getDateToValue()); | |
jFreeChart timeseries2 = new jFreeChart("Drawdown", "DW", portfolio.getName() + " Drawdown", portfolio.getDateToDrawdown()); | |
timeseries.pack(); | |
timeseries2.pack(); | |
RefineryUtilities.positionFrameOnScreen(timeseries, 0.7, 0.85); | |
RefineryUtilities.positionFrameOnScreen(timeseries2, 0.3, 0.85); | |
timeseries.setVisible(true); | |
timeseries2.setVisible(true); | |
timeseries.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); | |
timeseries2.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); | |
} | |
private void viewTransactions() { | |
if (portfolio.isEmpty()) { | |
textDisplayPF.setText("Your Portfolio is empty"); | |
return; | |
} | |
JFrame frame = new JFrame("Portfolio"); | |
frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); | |
jTable newPane = new jTable(portfolio.getTransactions()); | |
newPane.setOpaque(true); | |
frame.setContentPane(newPane); | |
frame.pack(); | |
frame.setVisible(true); | |
} | |
private void viewPortfolio() { | |
if (portfolio.isEmpty()) { | |
textDisplayPF.setText("Your Portfolio is empty"); | |
return; | |
} | |
String output1 = "You have the following stocks:\n"; | |
for (int i = 0; i<portfolio.getPortfolio().size(); i++) { | |
Stock stock = portfolio.getPortfolio().get(i); | |
output1 += String.format("%d shares of %s\n", stock.getNumShares(), stock.getName()); | |
} | |
String output2 = String.format("\n%s\nPorfolio's balance: %.2f$\nPortfolio's value: %.2f$\nTotal spent: %.2f$\n", sdf.format(enddate.getTime()), portfolio.getBalance(), portfolio.getCurrentValue(), portfolio.getTotalSpent()); | |
textDisplayPF.setText(output1 + output2); | |
} | |
//Stock Frame | |
private void viewReturns() { | |
stockHeld.calcAnnualReturn(); | |
stockHeld.calcMonthReturns(); | |
String output = ""; | |
output = String.format("Annual Return: %.3f%%\n\n", (100*stockHeld.getAnnualReturn())); | |
for (int i=0; i<stockHeld.getMonthReturns().size(); i++) { | |
output += String.format("Monthly Return %s, %.3f%%\n", stockHeld.getMonthReturns().get(i)[0], (100*(double)stockHeld.getMonthReturns().get(i)[1])); | |
} | |
textDisplayStock.setText(output); | |
} | |
private void sharpe() { | |
System.out.println(Double.toString(portfolio.getYearRiskFree())); | |
System.out.println(Double.toString(stockHeld.getSharpeRatio(portfolio.getYearRiskFree()))); | |
double riskfree = stockHeld.getSharpeRatio(portfolio.getYearRiskFree()); | |
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); | |
String date = sdf.format(enddate.getTime()); | |
String output = String.format("The Sharpe Ratio of %s is: %.4f\n\n", stockHeld.getName(), riskfree); | |
output += String.format("The risk free rate (1 year OIS) for %s is: %.4f\n", date, portfolio.getYearRiskFree()); | |
output += String.format("%s's volatility is: %.2f%%", stockHeld.getName(), stockHeld.get1YearVolatility()); | |
textDisplayStock.setText(output); | |
} | |
private void buy() { | |
if (sentinel == 0) { | |
String input = null; | |
try { | |
input = JOptionPane.showInputDialog("Please enter a name for your Portfolio"); | |
if (input == null) | |
return; | |
} catch (NumberFormatException exception) { | |
buy(); | |
} | |
portfolio.setName(input); | |
sentinel = 1; | |
} | |
int numShares= -1; | |
if (portfolio.hasStock(stockHeld.getName())) { | |
try { | |
Stock stock2 = portfolio.getStockbyTicker(stockHeld.getTicker()); | |
String prompt = String.format("You have %d number of shares of %s, how many more do you want to buy?", stock2.getNumShares(), stock2.getName()); | |
String input = JOptionPane.showInputDialog(prompt); | |
if (input == null) | |
return; | |
numShares = Integer.parseInt(input); | |
} catch (NumberFormatException exception) { | |
buy(); | |
} | |
} else { | |
try { | |
String input = JOptionPane.showInputDialog("How many shares of " + stockHeld.getTicker() + " would you like to buy?"); | |
if (input == null) | |
return; | |
numShares = Integer.parseInt(input); | |
} catch (NumberFormatException exception) { | |
buy(); | |
} | |
} | |
if (numShares<0) { | |
textDisplayStock.setText("You cannot buy a negative amount of shares!"); | |
return; | |
} | |
int x = portfolio.buyStock(stockHeld, numShares, enddate.getTime()); | |
double total = numShares*stockHeld.getCloseValues().get(0); | |
String output = String.format("You have bought %d shares of:\n%s at %.2f$ for %.2f$", numShares, stockHeld.getName(), stockHeld.getCloseValues().get(0), total); | |
if (x==-1) | |
textDisplayStock.setText("You already have that stock in your Portfolio!"); | |
textDisplayStock.setText(output); | |
} | |
private int searchForStock() { | |
String stock = JOptionPane.showInputDialog("Search for ticker: "); | |
if (stock == null) | |
return -1; | |
//textDisplayMain.setText("Searching stock details for " + stock); | |
//Get data from Yahoo Finance | |
//Calendar endDate = Calendar.getInstance(); | |
//Calendar startDate = Calendar.getInstance(); | |
//Set endDate to today - using private variable | |
//endDate.setTime(enddate.getTime()); | |
//endDate.add(Calendar.DATE, -20); | |
//set startDate to a year from now - using private variable | |
//One Year from now | |
//startDate.add(Calendar.YEAR, -1); | |
//startDate.add(Calendar.DATE, -20); | |
YahooFinanceURLConstruct KEY = new YahooFinanceURLConstruct(startdate, enddate, stock); | |
YahooFinanceHttp testobj = new YahooFinanceHttp(KEY.constructURL()); | |
if (testobj.getData().size() == 0) { | |
textDisplayMain.setText("No results were found"); | |
return -1; | |
} | |
Stock newStock = new Stock(stock, testobj); | |
textDisplayMain.setText(newStock.getName()); | |
//Set stockHeld, so you can buy the stock you just searched for | |
stockHeld = newStock; | |
String output = String.format("%s: %s is selling for %.2f$", sdf.format(enddate.getTime()), stockHeld.getName(), stockHeld.getCloseValues().get(0)); | |
textDisplayStock.setText(output); | |
return 0; | |
} | |
private void seeStockDetails() { | |
//Create and set up the window | |
String title = stockHeld.getName() +" Information"; | |
JFrame frame = new JFrame(title); | |
frame.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); | |
//Create and set up the content pane | |
jTable newPane = new jTable(stockHeld.getData(), stockHeld.getReturns()); | |
newPane.setOpaque(true); | |
frame.setContentPane(newPane); | |
//Display the window | |
frame.setSize(new Dimension(500, 600)); | |
//frame.pack(); | |
frame.setVisible(true); | |
RefineryUtilities.positionFrameOnScreen(frame, 0, 0.4); | |
} | |
private void movingAverages() { | |
jFreeChart timseries = new jFreeChart("Moving Averages", "Mov", stockHeld.getName(), stockHeld.getData()); | |
timseries.pack(); | |
RefineryUtilities.positionFrameOnScreen(timseries, 0.5, 0.85); | |
timseries.setVisible(true); | |
timseries.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE); | |
} | |
/*0 for today, 1 for yesterday, 2 for the day before, etc... | |
* 100 for good short term, bad mid and long | |
* 011 for bad short, good mid, long | |
* etc... | |
* 0 for bad everything | |
* 111 for good everything. | |
*/ | |
private int whatToDo(int day) { | |
int x = 0; | |
//Short | |
System.out.println((double)stockHeld.getData().get(0)[4]); | |
System.out.println(stockHeld.getMovAvgs().get(0)[0]); | |
System.out.println(stockHeld.getMovAvgs().get(0)[1]); | |
System.out.println(stockHeld.getMovAvgs().get(0)[2]); | |
if ((double)stockHeld.getData().get(day)[4] > stockHeld.getMovAvgs().get(day)[0]) { | |
x += 100; | |
} | |
//Mid | |
if ((double)stockHeld.getData().get(day)[4] > stockHeld.getMovAvgs().get(day)[1]) { | |
x += 10; | |
} | |
//Long | |
if ((double)stockHeld.getData().get(day)[4] > stockHeld.getMovAvgs().get(day)[2]) { | |
x += 1; | |
} | |
if (x==111) { | |
textDisplayStock.setText("Good short, mid, and long opportunity"); | |
} | |
if (x==110) { | |
textDisplayStock.setText("Good short and mid opportunity"); | |
} | |
if (x==101) { | |
textDisplayStock.setText("Good short and long opportunity"); | |
} | |
if (x==100) { | |
textDisplayStock.setText("Good short opportunity"); | |
} | |
if (x==11) { | |
textDisplayStock.setText("Good mid and long opportunity"); | |
} | |
if (x==10) { | |
textDisplayStock.setText("Good mid opportunity"); | |
} | |
if (x==1) { | |
textDisplayStock.setText("Good long opportunity"); | |
} | |
if (x==0) { | |
textDisplayStock.setText("Bad trend-based opportunity"); | |
} | |
return x; | |
} | |
/* VARIABLES */ | |
public Portfolio portfolio = new Portfolio("My PF"); | |
public Stock stockHeld; | |
//Frames: | |
private JFrame frame; | |
private JFrame stockframe; | |
private JFrame pfFrame; | |
//BUTTONS | |
//For Stocks | |
private JButton buyStock = new JButton("Buy Stock"); | |
private JButton movAverages = new JButton("See trends"); | |
private JButton viewSharpe = new JButton("View Sharpe Ratio"); | |
private JButton viewReturns = new JButton("View Returns"); | |
private JButton whatToDo = new JButton("What to do?"); | |
private JButton searchAnother = new JButton("Search another Stock"); | |
private JButton seeDetails = new JButton("See Details"); | |
//For Portfolio | |
private JButton sellStock = new JButton("Sell stock"); | |
private JButton removeStock = new JButton("Remove Stock"); | |
private JButton viewBalance = new JButton("View Balance"); | |
private JButton viewInvested = new JButton("View Invested"); | |
private JButton viewPFDetails = new JButton("Your Portfolio's Details"); | |
private JButton viewTransactions = new JButton("View Transaction History"); | |
private JButton Drawdown = new JButton("View Drawdown"); | |
private JButton update = new JButton("Update Portfolio"); | |
private JButton changeName = new JButton("Change Name"); | |
private JButton clear = new JButton("Clear Portfolio"); | |
//For Frame | |
private JButton searchStock = new JButton("Search a stock"); | |
private JButton loadPF = new JButton("Load Portfolio"); | |
private JButton viewPF = new JButton("View Details of Current Portfolio"); | |
private JButton savePF = new JButton("Save Portfolio"); | |
private JButton Quit = new JButton("Quit"); | |
private JButton information = new JButton("Information"); | |
private JButton Simulate = new JButton("Simulate"); | |
//Chooser and text Displays | |
private JFileChooser chooser = new JFileChooser(); | |
public JTextPane textDisplayMain = new JTextPane(); | |
public JTextPane textDisplayPF = new JTextPane(); | |
public JTextPane textDisplayStock = new JTextPane(); | |
//Sentinel variable for name of portfolio | |
//0 -> name not set | |
//1 -> name set | |
int sentinel = 0; | |
//Calendar variables | |
//Today | |
Calendar enddate = Calendar.getInstance(); | |
//A year from today | |
Calendar startdate = Calendar.getInstance(); | |
//sdf | |
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.*; | |
import java.net.URL; | |
import java.net.URLConnection; | |
import java.text.ParseException; | |
import java.text.SimpleDateFormat; | |
import java.util.ArrayList; | |
import java.util.Calendar; | |
import java.util.Date; | |
import java.util.HashMap; | |
public class Portfolio implements Serializable { | |
/* | |
* Manages a portfolio object that can hold numerous stocks; | |
* the portfolio also manages the statistics of a specific collection of stocks. | |
*/ | |
private static final long serialVersionUID = 1L; | |
private ArrayList<Stock> portfolioOfStocks = new ArrayList<Stock>(); //List of Stocks objects | |
private ArrayList<String> boughtStocksbyName = new ArrayList<String>(); //List of Stocks by name | |
private ArrayList<Object[]> transactions = new ArrayList<Object[]>(); //Stock, Date, numShares, costPerShare | |
private String name; | |
private double totalSpent = 0; | |
private double currentValue = 0; | |
private int numberOfUniqueStocks = 0; | |
public String SavingPath; //For saving a Portfolio | |
public String dateCreated; | |
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); | |
private int numShares = 0; //Number of total shares | |
private Date startDate; //Date the Portfolio was created | |
private HashMap<String, Double> dateToValue = new HashMap<String, Double>(); //Maps dates (Strings) to PF values | |
private HashMap<String, Double> dateToDrawdown = new HashMap<String, Double>(); //Maps dates (Strings) to PF Drawdown values | |
public Portfolio(String pfname) { | |
this.setName(pfname); | |
Calendar date = Calendar.getInstance(); | |
String temp = sdf.format(date.getTime()); | |
dateCreated = temp; | |
} | |
// Clears the Portfolio | |
public void obliterate() { | |
//stocksNshares.clear(); | |
boughtStocksbyName.clear(); | |
transactions.clear(); | |
name = null; | |
totalSpent = 0; | |
currentValue = 0; | |
numberOfUniqueStocks = 0; | |
dateCreated = null; | |
numShares = 0; | |
dateToValue.clear(); | |
dateToDrawdown.clear(); | |
} | |
public boolean isEmpty() { | |
if (numberOfUniqueStocks == 0) { | |
return true; | |
} | |
return false; | |
} | |
public int getTotalNumShares() { | |
return numShares; | |
} | |
public double getYearRiskFree() { | |
try { | |
URL url = new URL("http://www.federalreserve.gov/datadownload/Output.aspx?rel=H15&series=c5025f4bbbed155a6f17c587772ed69e&lastObs=&from=&to=&filetype=csv&label=include&layout=seriescolumn"); | |
URLConnection urlconn = url.openConnection(); | |
InputStreamReader inStream = new InputStreamReader(urlconn.getInputStream()); | |
BufferedReader buf = new BufferedReader(inStream); | |
String line; | |
double result = 0; | |
//Get rid of headers | |
for (int i=0; i<6; i++) { | |
buf.readLine(); | |
} | |
while((line = buf.readLine()) != null) { | |
String [] array = line.split("\\,"); | |
result = Double.parseDouble(array[1]); | |
} | |
return result; | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
return -1; | |
} | |
public void removeStock(String ticker) { | |
for (int i=0; i<portfolioOfStocks.size(); i++) { | |
if (ticker.equals(portfolioOfStocks.get(i).getTicker())) { | |
portfolioOfStocks.remove(i); | |
return; | |
} | |
} | |
} | |
public ArrayList<Object[]> getTransactions() { | |
return transactions; | |
} | |
public Object[] getMaxValue() { | |
Object[] result = new Object[2]; | |
double maxValue = 0; | |
Calendar currentDate = Calendar.getInstance(); //current date | |
int j=0; | |
System.out.println(startDate); | |
System.out.println(currentDate.getTime()); | |
while (currentDate.getTime().after(startDate)) { | |
double value = 0; | |
//Date to store in dateToValue | |
//On Date j what is the value of PF: | |
for (int i=0; i<numberOfUniqueStocks; i++) { | |
int numstocks = portfolioOfStocks.get(i).getNumShares(); | |
value += numstocks*(double)portfolioOfStocks.get(i).getData().get(j)[4]; | |
} | |
//Set dateToValue | |
dateToValue.put((String)portfolioOfStocks.get(0).getData().get(j)[0], value); | |
if (value>maxValue) { | |
maxValue = value; | |
String maxDate = (String) portfolioOfStocks.get(0).getData().get(j)[0]; | |
result[0] = maxDate; | |
result[1] = value; | |
} | |
//Set dateToDrawdown | |
double drawdown = (-1)*(1-(value/maxValue))*100; | |
System.out.println((String)portfolioOfStocks.get(0).getData().get(j)[0] + " " + drawdown); | |
System.out.println((String)portfolioOfStocks.get(0).getData().get(j)[0] + " " + value); | |
System.out.println("......."); | |
dateToDrawdown.put((String)portfolioOfStocks.get(0).getData().get(j)[0], drawdown); | |
try { | |
currentDate.setTime(sdf.parse((String) portfolioOfStocks.get(0).getData().get(j)[0])); | |
} catch (ParseException e) { | |
e.printStackTrace(); | |
} | |
j++; | |
} | |
return result; | |
} | |
public HashMap<String, Double> getDateToValue() { | |
return dateToValue; | |
} | |
public HashMap<String, Double> getDateToDrawdown() { | |
return dateToDrawdown; | |
} | |
public String getDateCreated() { | |
return dateCreated; | |
} | |
public String getCurrentDate() { | |
String date = sdf.format(Calendar.getInstance()); | |
return date; | |
} | |
public ArrayList<Stock> getPortfolio() { | |
return portfolioOfStocks; | |
} | |
public void setPortfolio(ArrayList<Stock> stocks) { | |
this.portfolioOfStocks = stocks; | |
} | |
public String[] getStockTicker() { | |
String[] result = new String[numberOfUniqueStocks]; | |
for (int i=0; i<numberOfUniqueStocks; i++) { | |
String name = portfolioOfStocks.get(i).getTicker(); | |
result[i] = name; | |
} | |
return result; | |
} | |
public int getNumStocks() { | |
return numberOfUniqueStocks; | |
} | |
//return -1 if stock already held, 1 if not | |
public int buyStock(Stock stock, int numShares, Date date1) { | |
String date = sdf.format(date1); | |
String ticker = stock.getTicker(); | |
if (numberOfUniqueStocks==0) { | |
startDate = date1; | |
} | |
if (hasStock(stock.getName())==true) { | |
//Get Cost | |
double cost = stock.getCurrentValue()*numShares; | |
//original numShares | |
int originalNUM = getStockbyTicker(ticker).getNumShares(); | |
//New numShares | |
int newNUM = originalNUM + numShares; | |
//update shares | |
getStockbyTicker(ticker).setNumShares(newNUM); | |
//Log the transaction | |
Object[] transaction = {stock, date, numShares, stock.getCurrentValue()}; | |
transactions.add(transaction); | |
//Update Total Spent | |
totalSpent += cost; | |
//Update total number of shares | |
this.numShares += numShares; | |
//Update current portfolio value | |
currentValue += stock.getCurrentValue() * numShares; | |
return -1; | |
} | |
double cost = stock.getCurrentValue()*numShares; | |
stock.setNumShares(numShares); | |
//stocksNshares.put(stock.getTicker(), numShares); | |
//Log the transaction | |
Object[] transaction = {stock, date, numShares, stock.getCurrentValue()}; | |
transactions.add(transaction); | |
//Add to portfolio | |
portfolioOfStocks.add(stock); | |
//Update Num of Unique Stocks | |
numberOfUniqueStocks++; | |
//Updates stockNshares | |
//stocksNshares.put(stock.getTicker(), numShares); | |
//Update Total Spent | |
totalSpent += cost; | |
//Update Stock by Name | |
boughtStocksbyName.add(stock.getName()); | |
//Update total number of shares | |
this.numShares += numShares; | |
//Update current portfolio value | |
currentValue += stock.getCurrentValue() * numShares; | |
return 1; | |
} | |
public boolean hasStock(String stock) { | |
if (boughtStocksbyName.contains(stock)) { | |
return true; | |
} | |
return false; | |
} | |
//portfolio, name, totalSpent, currentValue, boughStocksbyName, | |
//numShares, numberOfUniqueStocks, transactions, dateCreated, stocksNshares | |
public boolean save() { | |
Object[] allPortfolio = new Object[11]; | |
allPortfolio[0] = this.getPortfolio(); | |
allPortfolio[1] = this.name; | |
allPortfolio[2] = this.totalSpent; | |
allPortfolio[3] = this.currentValue; | |
allPortfolio[4] = this.boughtStocksbyName; | |
allPortfolio[5] = this.numShares; | |
allPortfolio[6] = this.numberOfUniqueStocks; | |
allPortfolio[7] = this.transactions; | |
allPortfolio[8] = this.dateCreated; | |
allPortfolio[9] = this.dateToValue; | |
allPortfolio[10] = this.startDate; | |
//allPortfolio[11] = this.getStocksNShares(); | |
try { | |
//Gets the path from the GUI | |
System.out.println(SavingPath); | |
FileOutputStream fos = new FileOutputStream(SavingPath + ".xml"); | |
ObjectOutputStream oos = new ObjectOutputStream(fos); | |
//Saves the array | |
oos.writeObject(allPortfolio); | |
oos.flush(); | |
oos.close(); | |
} catch (IOException e) { | |
System.err.println("Error Saving File."); | |
e.printStackTrace(); | |
return false; | |
} | |
return true; | |
} | |
@SuppressWarnings("unchecked") | |
public boolean load(File file) { | |
System.out.println(file.getAbsolutePath()); | |
try { | |
//Gets the file from the GUI | |
FileInputStream fis = new FileInputStream(file); | |
ObjectInputStream oip = new ObjectInputStream(fis); | |
Object[] x = (Object[]) oip.readObject(); | |
//Get all the information | |
setPortfolio((ArrayList<Stock>) x[0]); | |
this.name = (String) x[1]; | |
this.totalSpent = (double) x[2]; | |
this.currentValue = (double) x[3]; | |
this.boughtStocksbyName = (ArrayList<String>) x[4]; | |
this.numShares = (int) x[5]; | |
this.numberOfUniqueStocks = (int) x[6]; | |
this.transactions = (ArrayList<Object[]>) x[7]; | |
this.dateCreated = (String) x[8]; | |
this.dateToValue = (HashMap<String, Double>) x[9]; | |
this.startDate = (Date) x[10]; | |
//setStocksNShares((HashMap<String, Integer>) x[12]); | |
oip.close(); | |
} catch (IOException | ClassNotFoundException exception) { | |
exception.printStackTrace(); | |
return false; | |
} | |
return true; | |
} | |
public double getCurrentValue() { | |
return currentValue; | |
} | |
public double getTotalSpent() { | |
return totalSpent; | |
} | |
public double getBalance() { | |
return (currentValue - totalSpent); | |
} | |
//UpdatePF needs to get called every time the program starts | |
//So you can assume that when you call any function | |
//UpdatePF has already been called | |
public void updatePf() { | |
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); | |
Calendar startDate = Calendar.getInstance(); | |
Calendar endDate = Calendar.getInstance(); | |
startDate.add(Calendar.YEAR, -1); | |
System.out.println(sdf.format(startDate.getTime())); | |
System.out.println(sdf.format(endDate.getTime())); | |
this.currentValue = 0; | |
//For each stock | |
for (int i=0; i<portfolioOfStocks.size(); i++) { | |
//Get Stock's Most recent Data | |
YahooFinanceURLConstruct KEY = new YahooFinanceURLConstruct(startDate, endDate, portfolioOfStocks.get(i).getTicker()); | |
YahooFinanceHttp dohlcvac = new YahooFinanceHttp(KEY.constructURL()); | |
//Replace stock's data | |
portfolioOfStocks.get(i).setData(dohlcvac.getData()); | |
portfolioOfStocks.get(i).calcMovAvgs(); | |
portfolioOfStocks.get(i).setCloseValues(dohlcvac.getClose()); | |
this.currentValue += portfolioOfStocks.get(i).getCurrentValue()*portfolioOfStocks.get(i).getNumShares(); | |
} | |
} | |
public Stock getStockbyName(String name) { | |
int i=0; | |
while (!(portfolioOfStocks.get(i).getName().equals(name))) { | |
i++; | |
if (i==portfolioOfStocks.size()) { | |
return null; | |
} | |
} | |
return portfolioOfStocks.get(i); | |
} | |
public Stock getStockbyTicker(String ticker) { | |
int i=0; | |
while (!(portfolioOfStocks.get(i).getTicker().equals(ticker))){ | |
i++; | |
if (i==portfolioOfStocks.size()) { | |
return null; | |
} | |
} | |
return portfolioOfStocks.get(i); | |
} | |
public String getName() { | |
return name; | |
} | |
public void setName(String name) { | |
this.name = name; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.io.BufferedReader; | |
import java.io.IOException; | |
import java.io.InputStreamReader; | |
import java.io.Serializable; | |
import java.net.MalformedURLException; | |
import java.net.URL; | |
import java.net.URLConnection; | |
import java.text.ParseException; | |
import java.text.SimpleDateFormat; | |
import java.util.ArrayList; | |
import java.util.Calendar; | |
public class Stock implements Serializable { | |
/* | |
* This class sets up a Stock object. | |
* Manages a stock object that holds all of its information: | |
* data (date, open, high, low, close, adj. close, and volume), name, ticker, | |
* 1 year volatility, etc� | |
*/ | |
private static final long serialVersionUID = 1L; | |
// Thread-safety not needed - use arraylist instead of Vector | |
private URL url = null; | |
private String ticker; | |
private String name; | |
private ArrayList<Double> closeValues; | |
private ArrayList<Object[]> data; | |
private ArrayList<double[]> movAvgs = new ArrayList<double[]>(); | |
private ArrayList<Object[]> returns = new ArrayList<Object[]>(); | |
private double annReturn; | |
private ArrayList<Object[]> monthReturns = new ArrayList<Object[]>(); | |
private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); | |
private double sharpe = -100; | |
private double volatility = -100; | |
private int numShares = 0; | |
public Stock(String Name, YahooFinanceHttp information) { | |
this.ticker = Name; | |
this.setData(information.getData()); | |
this.setCloseValues(information.getClose()); | |
this.calcMovAvgs(); | |
this.calcReturns(); | |
this.calcAnnualReturn(); | |
} | |
public String getName() { | |
try { | |
//Open Connection to Yahoo Finance | |
String uString = "http://finance.yahoo.com/d/quotes.csv?s=" + ticker + "&f=sn"; | |
this.url = new URL(uString); | |
URLConnection urlConn = url.openConnection(); | |
//Start Reading | |
urlConn = this.url.openConnection(); | |
InputStreamReader inStream = new InputStreamReader(urlConn.getInputStream()); | |
BufferedReader buff = new BufferedReader(inStream); | |
this.name = buff.readLine(); | |
} catch (MalformedURLException e) { | |
System.out.println(e.getMessage()); | |
} catch (IOException e) { | |
System.out.println("No results found."); | |
} | |
return name; | |
} | |
public String getTicker() { | |
return ticker; | |
} | |
public void setNumShares(int num) { | |
numShares = num; | |
} | |
public int getNumShares() { | |
return numShares; | |
} | |
public double getCurrentValue() { | |
double value = (double) getData().get(0)[4]; | |
return value; | |
} | |
public String getCurrentDate() { | |
String date = (String) getData().get(0)[0]; | |
return date; | |
} | |
public String getStartDate() { | |
int len = getData().size(); | |
len--; | |
String date = (String) getData().get(len)[0]; | |
return date; | |
} | |
// Moving verages are: 15, 40, 90 days | |
public void calcMovAvgs() { | |
double avg15; | |
double avg40; | |
double avg100; | |
int size = this.closeValues.size(); | |
for (int i = 0; i < size; i++) { | |
double x = 0; | |
int j=0; | |
int y=0; | |
for (j = i; j < i+15; j++) { | |
if (j >= size) | |
break; | |
x += closeValues.get(j); | |
y++; | |
} | |
avg15 = x/y; | |
x = 0; | |
y = 0; | |
for (j = i; j < i+40; j++) { | |
if (j >= size) | |
break; | |
x += closeValues.get(j); | |
y++; | |
} | |
avg40 = x/y; | |
x = 0; | |
y = 0; | |
for (j = i; j < i+100; j++) { | |
if (j >= size) | |
break; | |
x += closeValues.get(j); | |
y++; | |
} | |
avg100 = x/y; | |
double[] array = {avg15, avg40, avg100}; | |
movAvgs.add(array); | |
//System.out.println(Arrays.toString(array)); | |
} | |
} | |
public ArrayList<double[]> getMovAvgs() { | |
return movAvgs; | |
} | |
//date, return (string), return (double) | |
public void calcReturns() { | |
//for date x, return is (close at x)/(close at x-1) - 1 | |
for (int i=0; i<data.size()-1; i++) { | |
Object returns[] = new Object[3]; | |
double dailyreturn; | |
returns[0] = this.data.get(i)[0]; | |
dailyreturn = ((double)this.data.get(i)[4]/(double)this.data.get(i+1)[4]) - 1; | |
dailyreturn = dailyreturn*100; | |
returns[1] = String.format("%.2f%%", dailyreturn); | |
returns[2] = dailyreturn; | |
this.returns.add(returns); | |
} | |
} | |
public ArrayList<Object[]> getReturns() { | |
return returns; | |
} | |
// Calculates statistics | |
private double get1YearReturnMean() { | |
double sum = 0.0; | |
for(int i=0; i<this.getReturns().size(); i++) { | |
sum += (double)this.getReturns().get(i)[2]; | |
} | |
return sum/getReturns().size(); | |
} | |
private double getVarianceReturn() { | |
double mean = get1YearReturnMean(); | |
double temp = 0; | |
for (int i=0; i<this.getReturns().size(); i++) { | |
temp += Math.pow(mean-(double)getReturns().get(i)[2], 2); | |
} | |
return temp/getReturns().size(); | |
} | |
public double get1YearVolatility() { | |
if (this.volatility == -100) { | |
double result = Math.sqrt(getVarianceReturn()); | |
this.volatility = result; | |
return result; | |
} else { | |
return this.volatility; | |
} | |
} | |
public double getSharpeRatio(double riskFree) { | |
if (this.sharpe == -100){ | |
double effReturn = this.getAnnualReturn()-riskFree; | |
double sharpe = effReturn/this.get1YearReturnMean(); | |
this.sharpe = sharpe; | |
return sharpe; | |
} | |
else { | |
return this.sharpe; | |
} | |
} | |
//Calculates year-to-date returns | |
public void calcAnnualReturn() { | |
//Get date one year from today | |
Calendar prevYear = Calendar.getInstance(); | |
prevYear.add(Calendar.YEAR, -1); | |
String aYearAgo = sdf.format(prevYear.getTime()); | |
int i = 0; | |
Calendar cal1 = Calendar.getInstance(); | |
Calendar nextdate = Calendar.getInstance(); | |
while (true) { | |
if (i==(this.getData().size()-1)) | |
break; | |
String date = (String)this.getData().get(i)[0]; | |
if (date.equals(aYearAgo)) | |
break; | |
try { | |
cal1.setTime(sdf.parse(date)); | |
nextdate.setTime(sdf.parse(aYearAgo)); | |
} catch (ParseException ex) { | |
ex.printStackTrace(); | |
} | |
if (cal1.compareTo(nextdate) < 0) | |
break; | |
i++; | |
} | |
double todayClose = (double)this.getData().get(0)[4]; | |
double lastYearClose = (double)this.getData().get(i)[4]; | |
double Return = (todayClose/lastYearClose) - 1; | |
this.annReturn = Return; | |
} | |
public double getAnnualReturn() { | |
return annReturn; | |
} | |
//Calculates month-to-date returns | |
public void calcMonthReturns() { | |
double todayClose = this.getCloseValues().get(0); | |
Calendar prevMonth = Calendar.getInstance(); | |
//Do this 12 times | |
for (int i=0; i<12; i++) { | |
//Get date for the month to log into return | |
String month = sdf.format(prevMonth.getTime()); | |
//Go to previous month | |
prevMonth.add(Calendar.MONTH, -1); | |
String datesought = sdf.format(prevMonth.getTime()); | |
//System.out.println(month + " " + datesought); | |
//Get the close of a month ago. | |
int j=0; | |
Calendar cal1 = Calendar.getInstance(); | |
Calendar nextDate = Calendar.getInstance(); | |
while (true) { | |
if (j==(this.getData().size()-1)) | |
break; | |
String date1 = (String)this.getData().get(j)[0]; | |
if (date1.equals(datesought)) | |
break; | |
try { | |
cal1.setTime(sdf.parse(date1)); | |
nextDate.setTime(sdf.parse(datesought)); | |
} catch (ParseException e) { | |
e.printStackTrace(); | |
} | |
if (cal1.compareTo(nextDate) < 0) | |
break; | |
//System.out.println(month + " " + (String)this.getData().get(j)[0]); | |
j++; | |
} | |
double lastMonthClose = (double)this.getData().get(j)[4]; | |
//Calculate the annual return of one month | |
double monthReturn = (todayClose/lastMonthClose) - 1; | |
//Add the date and return to the list of returns | |
Object[] array = {month, monthReturn}; | |
System.out.println(month + " - " +sdf.format(prevMonth.getTime()) + " " + monthReturn); | |
System.out.println(); | |
todayClose = lastMonthClose; | |
this.monthReturns.add(array); | |
prevMonth = nextDate; | |
} | |
} | |
public ArrayList<Object[]> getMonthReturns() { | |
return monthReturns; | |
} | |
//dohlcvac = date, open, high, low, close, volume, adj. close | |
public void setData(ArrayList<Object[]> information) { | |
//date, open, high, low, close, volume, adj. close | |
this.data = information; | |
} | |
public ArrayList<Object[]> getData() { | |
return data; | |
} | |
public void setCloseValues(ArrayList<Double> closeValues) { | |
this.closeValues = closeValues; | |
} | |
public ArrayList<Double> getCloseValues() { | |
return closeValues; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class TestYahooFinance { | |
public static void main(String[] args){ | |
GUI gui = new GUI(); | |
gui.loadView(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.net.*; | |
import java.util.ArrayList; | |
import java.io.*; | |
public class YahooFinanceHttp implements Serializable { | |
/* | |
* This class connects to Yahoo Finanace using the url constructor | |
* in YahooFinanceURLConstruct.java and obtains the data sought. | |
*/ | |
YahooFinanceHttp(String urlStr){ | |
try { | |
//Open Connection the Yahoo Finance URL | |
URL url = new URL(urlStr); | |
//Start Reading | |
URLConnection urlConn = url.openConnection(); | |
InputStreamReader inStream = new InputStreamReader(urlConn.getInputStream()); | |
BufferedReader buff= new BufferedReader(inStream); | |
String stringLine; | |
buff.readLine(); //Read the firstLine. This is the header. | |
while((stringLine = buff.readLine()) != null) //While not in the header | |
{ | |
String [] dohlcav = stringLine.split("\\,"); //date, ohlc, adjustedclose | |
String date = dohlcav[0]; | |
double open = Double.parseDouble(dohlcav[1]); | |
double high = Double.parseDouble(dohlcav[2]); | |
double low = Double.parseDouble(dohlcav[3]); | |
double close = Double.parseDouble(dohlcav[4]); | |
long volume = Long.parseLong(dohlcav[5]); | |
double adjClose = Double.parseDouble(dohlcav[6]); | |
Object data[] = new Object[] {date, open, high, low, close, volume, adjClose}; | |
information.add(data); | |
//Set the Data | |
dateStrList.add(date); | |
openList.add(open); | |
highList.add(high); | |
lowList.add(low); | |
closeList.add(close); | |
volumeList.add(volume); | |
adjCloseList.add(adjClose); | |
} | |
}catch (MalformedURLException e) { | |
System.out.println(e.getMessage()); | |
}catch(IOException e){ | |
System.out.println("No results found."); | |
} | |
} | |
//return everything | |
public ArrayList<Object[]> getData() { | |
//dohlcvac | |
//date, open, high, low, close, volume, adj. close | |
return information; | |
} | |
public ArrayList<String> getDate(){ | |
return dateStrList; | |
} | |
public ArrayList<Double> getOpen(){ | |
return openList; | |
} | |
public ArrayList<Double> getHigh(){ | |
return highList; | |
} | |
public ArrayList<Double> getLow(){ | |
return lowList; | |
} | |
public ArrayList<Double> getClose(){ | |
return closeList; | |
} | |
public ArrayList<Double> getAdjClose(){ | |
return adjCloseList; | |
} | |
public ArrayList<Long> getVolume(){ | |
return volumeList; | |
} | |
private static final long serialVersionUID = 1L; | |
//private Object[] information = new Object[7]; | |
private ArrayList<Object[]> information = new ArrayList<Object[]>(); | |
private ArrayList<String> dateStrList = new ArrayList<String>(); | |
private ArrayList<Double> openList = new ArrayList<Double>(); | |
private ArrayList<Double> lowList = new ArrayList<Double>(); | |
private ArrayList<Double> highList = new ArrayList<Double>(); | |
private ArrayList<Double> closeList = new ArrayList<Double>(); | |
private ArrayList<Long> volumeList = new ArrayList<Long>(); | |
private ArrayList<Double> adjCloseList = new ArrayList<Double>(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.Calendar; | |
public class YahooFinanceURLConstruct { | |
/* | |
* Creates a URL for Yahoo Finance HTTP. | |
*/ | |
//Data | |
private String startDateDay, startDateMonth, startDateYear; | |
private String endDateDay, endDateMonth, endDateYear; | |
private String tickerSymbol; | |
// IGNORE: http://ichart.finance.yahoo.com/table.csv?s=AAPL&d=6&e=3&f=2013&g=d&a=8&b=7&c=1984&ignore=.csv | |
//Create a constructor to set the data | |
public YahooFinanceURLConstruct(Calendar startDate, Calendar endDate, String tickerSymbol){ | |
//startingDate | |
this.startDateDay = Integer.toString(startDate.get(Calendar.DATE)); | |
this.startDateMonth = Integer.toString(startDate.get(Calendar.MONTH)); | |
this.startDateYear = Integer.toString(startDate.get(Calendar.YEAR)); | |
//Set the end date values | |
this.endDateDay = Integer.toString(endDate.get(Calendar.DATE)); | |
this.endDateMonth = Integer.toString(endDate.get(Calendar.MONTH)); | |
this.endDateYear = Integer.toString(endDate.get(Calendar.YEAR)); | |
//tickerSymbol | |
this.tickerSymbol = tickerSymbol; | |
} | |
//Create a method to construct the URL given the startDate, endDate, tickerSymbol as input | |
public String constructURL(){ | |
String baseURL = "http://ichart.finance.yahoo.com/table.csv?s="; | |
//YahooFinance URL Reconstructed | |
String urlStr = (baseURL + tickerSymbol+"&d="+endDateMonth+"&e="+endDateDay+"&f="+endDateYear+"&g=d"+"&a="+startDateMonth+"&b="+startDateDay+"&c="+startDateYear); | |
return urlStr; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment