com.mycompany.supersimplestockmarket.StockMarket.java Source code

Java tutorial

Introduction

Here is the source code for com.mycompany.supersimplestockmarket.StockMarket.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.mycompany.supersimplestockmarket;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import org.apache.commons.math3.stat.StatUtils;

/**
 *
 * @author mark.mcleod
 */
public class StockMarket {
    private final List<Trade> trades = new ArrayList<>();
    private final HashMap<StockSymbol, AbstractStock> stocks = new HashMap<>();
    private final HashMap<AbstractStock, Double> lastTradePrices = new HashMap<>();

    public void recordTrade(Trade trade) throws Exception {
        if (trade.getStock() == null)
            throw new Exception("Cannot trade a null stock");

        trades.add(trade);
        lastTradePrices.put(trade.getStock(), trade.getTradePrice());
    }

    public void addStock(AbstractStock stock) {
        stocks.put(stock.getStockSymbol(), stock);
        lastTradePrices.put(stock, 0.0);
    }

    public AbstractStock[] getStocks() {
        AbstractStock[] stockArray = new AbstractStock[stocks.size()];
        int i = 0;
        for (AbstractStock stock : stocks.values())
            stockArray[i++] = stock;

        return stockArray;
    }

    public AbstractStock getStockByStockSymbol(StockSymbol stockSymbol) {
        return stocks.get(stockSymbol);
    }

    public double getLastTradePrice(AbstractStock stock) {
        return lastTradePrices.get(stock);
    }

    public double calculateDividendYield(StockSymbol symbol, double price) throws Exception {
        AbstractStock stock = getStockByStockSymbol(symbol);

        if (stock == null)
            throw new Exception(String.format("Unknown stock symbol: %s", symbol));

        return stock.getDividendYield(price);
    }

    public double calculatePeRatio(StockSymbol symbol, double price) throws Exception {
        AbstractStock stock = getStockByStockSymbol(symbol);

        if (stock == null)
            throw new Exception(String.format("Unknown stock symbol: %s", symbol));

        return stock.getPeRatio(price);
    }

    public double calculateVolumeWeightedStockPrice(StockSymbol symbol) throws Exception {
        AbstractStock stock = getStockByStockSymbol(symbol);

        if (stock == null)
            throw new Exception(String.format("Unknown stock symbols %s", symbol));

        double totalTradedPriceXquantity = 0.0;
        double totalQuantity = 0.0;

        double volumeWeightedStockPrice = 0.0;

        // ugly - better to use JodaTime here, but lets stick to standard libraries for now
        Date fifteenMinutesAgo = new Date(System.currentTimeMillis() - (15 * 60 * 1000));

        // this is pretty inefficient, however chose for simplicity
        for (Trade trade : trades) {
            if (!trade.getStock().equals(stock))
                continue;

            if (trade.getTimestamp().after(fifteenMinutesAgo)) {
                totalTradedPriceXquantity += (trade.getTradePrice() * trade.getQuantity());
                totalQuantity += trade.getQuantity();
            }
        }

        if (totalQuantity > 0.0) {
            volumeWeightedStockPrice = totalTradedPriceXquantity / totalQuantity;
        }

        return volumeWeightedStockPrice;
    }

    public double calculateGBCEAllShareIndex() throws Exception {
        double allShareIndex = 0.0;

        // build list of all stock prices for stocks that had trades in last 15 minutes (i.e. non zero ones)
        ArrayList<Double> stockPrices = new ArrayList<>();
        for (AbstractStock stock : stocks.values()) {
            double stockPrice = calculateVolumeWeightedStockPrice(stock.getStockSymbol());
            if (stockPrice > 0.0)
                stockPrices.add(stockPrice);
        }

        // convert to array of double, and calculate geometric mean
        if (stockPrices.size() > 0) {
            double[] prices = new double[stockPrices.size()];
            int i = 0;
            for (Double price : stockPrices)
                prices[i++] = price;

            allShareIndex = StatUtils.geometricMean(prices);
        }

        return allShareIndex;
    }
}