com.jpmorgan.assgn.sss02mvn.service.StockTradeServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.jpmorgan.assgn.sss02mvn.service.StockTradeServiceImpl.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.jpmorgan.assgn.sss02mvn.service;

import org.apache.commons.collections.Predicate;

import com.jpmorgan.assgn.sss02mvn.model.Stock;
import com.jpmorgan.assgn.sss02mvn.model.Trade;
import com.jpmorgan.assgn.sss02mvn.repository.StockTradeRepository;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
// import java.util.HashMap;
import java.util.Map;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.math3.stat.StatUtils;
import org.apache.log4j.Logger;

/**
 *
 * @author esko02
 */
public class StockTradeServiceImpl implements StockTradeService {
    private static final Logger logger = Logger.getLogger(StockTradeServiceImpl.class);

    private StockTradeRepository stockTradeRepository = null;

    @Override
    public double calculateDividendYield(String pstocksymbol) throws Exception {
        // EMK 20160605
        double dividendYield = -1.0;
        // double dividendYield = 0.0;

        logger.debug("Calculating Dividend Yield for the stock symbol: " + pstocksymbol);

        Stock stock = stockTradeRepository.getStockBySymbol(pstocksymbol);

        if (stock == null) {
            // throw new Exception("The stock symbol ["+pstocksymbol+"] is not supported by the Super Simple Stock system.");

            logger.warn("The stock symbol [" + pstocksymbol + "] is not supported");

            return dividendYield;
        }

        if (stock.getTickerPrice() <= 0.0) {
            // throw new Exception("The ticker price for the stock ["+pstocksymbol+"] should be greater than zero (0).");

            logger.warn("The ticker price for the stock [" + pstocksymbol + "] should be greater than zero");

            return dividendYield;
        }

        dividendYield = stock.getDividendYield();

        logger.debug("Dividend Yield calculated: " + dividendYield);

        return dividendYield;
    }

    @Override
    public double calculatePERatio(String pstocksymbol) throws Exception {
        double peRatio = -1.0;

        logger.debug("Calculating P/E Ratio for the stock symbol: " + pstocksymbol);

        Stock stock = stockTradeRepository.getStockBySymbol(pstocksymbol);

        // If the stock is not supported the a exception is raised
        if (stock == null) {
            // throw new Exception("The stock symbol ["+stockSymbol+"] is not supported by the Super Simple Stock system.");

            logger.warn("The stock symbol [" + pstocksymbol + "] is not supported.");

            return peRatio;
        }

        // Ticker price with value zero does not make any sense and could produce a zero division
        if (stock.getTickerPrice() <= 0.0) {
            // throw new Exception("The ticker price for the stock ["+stockSymbol+"] should be greater than zero (0)");

            logger.warn("The ticker price for the stock [" + pstocksymbol + "] should be greater than zero");

            return peRatio;
        }

        peRatio = stock.getPeRatio();

        logger.debug(" P/E Ratiocalculated: " + peRatio);

        return peRatio;
    }

    @Override
    public double calculateStockPrice(String pstocksymbol, int minutes) throws Exception {
        double stockPrice = 0.0;

        logger.debug("Trades in the original collection: " + getTradesNumber());

        @SuppressWarnings("unchecked")
        Collection<Trade> trades = CollectionUtils.select(stockTradeRepository.getTrades(),
                new StockPredicate(pstocksymbol, minutes));

        logger.debug(
                "Trades in the filtered collection by [" + pstocksymbol + "," + minutes + "]: " + trades.size());

        // Calculate the summation
        double shareQuantityAcum = 0.0;
        double tradePriceAcum = 0.0;
        for (Trade trade : trades) {
            // Calculate the summation of Trade Price x Quantity
            tradePriceAcum += (trade.getPrice() * trade.getShareQuantity());
            // Acumulate Quantity
            shareQuantityAcum += trade.getShareQuantity();
        }

        // calculate the stock price
        if (shareQuantityAcum > 0.0) {
            stockPrice = tradePriceAcum / shareQuantityAcum;
        }

        return stockPrice;
    }

    @Override
    public double calculateStockPriceLast15mins(String pstocksymbol) throws Exception {
        double stockPrice = 0.0;

        logger.debug("Calculating Stock Price for the stock symbol: " + pstocksymbol);
        Stock stock = stockTradeRepository.getStockBySymbol(pstocksymbol);

        // If the stock is not supported the a exception is raised
        if (stock == null) {
            throw new Exception("The stock symbol [" + pstocksymbol + "] is not supported");
        }

        stockPrice = calculateStockPrice(pstocksymbol, 15);

        logger.debug(" Stock Price for stock symbol '" + pstocksymbol + "' calculated: " + stockPrice);

        return stockPrice;
    }

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

        // Calculate stock price for all stock in the system
        Map<String, Stock> stocks = stockTradeRepository.getStocks();
        ArrayList<Double> stockPrices = new ArrayList<Double>();

        for (String stockSymbol : stocks.keySet()) {
            double stockPrice = calculateStockPrice(stockSymbol, 0);

            if (stockPrice > 0) {
                stockPrices.add(stockPrice);
            }
        }

        if (stockPrices.size() >= 1) {
            double[] stockPricesArray = new double[stockPrices.size()];

            for (int i = 0; i <= (stockPrices.size() - 1); i++) {
                // stockPricesArray[i] = stockPrices.get(i).doubleValue();
                stockPricesArray[i] = stockPrices.get(i);
            }

            // Calculates the GBCE All Share Index
            allShareIndex = StatUtils.geometricMean(stockPricesArray);
        }

        return allShareIndex;
    }

    @Override
    public boolean recordTrade(Trade ptrade) throws Exception {
        if (ptrade == null) {
            logger.info("Trade object was null");

            return false;
        }

        if (ptrade.getStock() == null) {
            logger.info("Stock in trade '" + ptrade + "' was null");

            return false;
        }

        if (ptrade.getPrice() <= 0) {
            logger.info("Trade '" + ptrade + "' price was <= 0");

            return false;
        }

        if (ptrade.getShareQuantity() <= 0) {
            logger.info("Trade '" + ptrade + "' shares quantity was <= 0");

            return false;
        }

        boolean retval = false;

        retval = this.stockTradeRepository.recordTrade(ptrade);

        // Update the ticker price for the stock
        if (retval) {
            ptrade.getStock().setTickerPrice(ptrade.getPrice());
        }

        return retval;
    }

    public void setStockTradeRepository(StockTradeRepository stockTradeRepository) {
        this.stockTradeRepository = stockTradeRepository;
    }

    private int getTradesNumber() throws Exception {
        return stockTradeRepository.getTrades().size();
    }

    private class StockPredicate implements Predicate {
        /**
         *
         */
        private final Logger logger = Logger.getLogger(StockPredicate.class);

        /**
         * 
         */
        private String stockSymbol = "";

        /**
         * 
         */
        private Calendar dateRange = null;

        /**
         * 
         * @param stockSymbol
         * @param minutesRange
         */
        public StockPredicate(String stockSymbol, int minutesRange) {
            this.stockSymbol = stockSymbol;

            if (minutesRange > 0) {
                dateRange = Calendar.getInstance();
                dateRange.add(Calendar.MINUTE, -minutesRange);
                logger.debug(String.format("Filter date pivot: %tF %tT", dateRange.getTime(), dateRange.getTime()));
            }

        }

        /**
         * 
         */
        public boolean evaluate(Object tradeObject) {
            if (tradeObject instanceof Trade == false) {
                return false;
            }

            Trade trade = (Trade) tradeObject;

            boolean shouldBeIncluded = trade.getStock().getStockSymbol().equals(stockSymbol);

            if (shouldBeIncluded && dateRange != null) {
                shouldBeIncluded = dateRange.getTime().compareTo(trade.getTimeStamp()) <= 0;
            }

            return shouldBeIncluded;
        }

    }

}