/src/main/java/com/portfolio/management/util/alphavantage/AlphavantageParserUtil.java
Java | 607 lines | 420 code | 113 blank | 74 comment | 56 complexity | eb93fbee878fdd10e74ed2ccee904f39 MD5 | raw file
- package com.portfolio.management.util.alphavantage;
- import com.alibaba.fastjson.JSON;
- import com.alibaba.fastjson.JSONArray;
- import com.alibaba.fastjson.JSONObject;
- import com.portfolio.management.dao.StockDao;
- import com.portfolio.management.model.RealTimeStock;
- import org.apache.commons.lang.StringUtils;
- import org.apache.log4j.Logger;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Service;
- import java.time.LocalDate;
- import java.time.LocalDateTime;
- import java.time.format.DateTimeFormatter;
- import java.time.format.DateTimeParseException;
- import java.util.ArrayList;
- import java.util.Collections;
- import java.util.Comparator;
- import java.util.List;
- import java.util.concurrent.ExecutorService;
- import java.util.concurrent.Executors;
- import java.util.concurrent.TimeUnit;
- @Service
- public class AlphavantageParserUtil {
- @Autowired StockDao stockDao;
- private static final Logger LOGGER = Logger.getLogger(AlphavantageParserUtil.class);
- private static final String API_KEY = "X8RO597ZV071YDUA";
- // deprecated: replace this with multithreading method getRealTimeStock
- public static List<StockQuote> getAll(String symbols){
- String result = AlphavantageUtil.getAll(symbols);
- List<StockQuote> stocks = new ArrayList<StockQuote>();
- JSONObject jsonObject = JSON.parseObject(result);
- if (StringUtils.isEmpty(result)){
- for(String sym:symbols.split(",")){
- StockQuote stockq = new StockQuote();
- stockq.setSymbol(sym);
- stocks.add(stockq);
- }
- return stocks;
- }else {
- JSONArray josnArray = jsonObject.getJSONArray("Stock Quotes");
- for(int i=0;i<josnArray.size();i++){
- JSONObject jsonobj = josnArray.getJSONObject(i);
- StockQuote stockq = new StockQuote();
- stockq.setSymbol(jsonobj.getString("1. symbol"));
- stockq.setPrice(jsonobj.getString("2. price"));
- stockq.setVolume(jsonobj.getString("3. volume"));
- stockq.setTime(jsonobj.getString("4. timestamp"));
- stocks.add(stockq);
- }
- return stocks;
- }
- }
- // turn positive number to green or red in stock market style
- public static String getStyledChange(Float change){
- if(change >= 0.0)
- return "<span style='color:green'>" + String.valueOf(Math.round(change *100.0)/100.0) + "</span>";
- return "<span style='color:red'>" + String.valueOf(Math.round(change *100.0)/100.0) + "</span>";
- }
- // populate RealTimeStock model
- public List<RealTimeStock> getRealTimeStock(List<String> symbols){
- ExecutorService executorService = Executors.newCachedThreadPool();
- List<RealTimeStock> realTimeStocks = new ArrayList<>();
- for(String symbol: symbols){
- executorService.execute(new Runnable() {
- @Override
- public void run() {
- LOGGER.info(Thread.currentThread().getName());
- List<TimeSeriesDailyAdjustedStock> stocks = AlphavantageParserUtil.parseTimeSeriesDailyAdjusted(symbol,"","",API_KEY);
- stocks.sort(Comparator.comparing(TimeSeriesDailyAdjustedStock::getTime));
- Collections.reverse(stocks);
- RealTimeStock realTimeStock = new RealTimeStock();
- TimeSeriesDailyAdjustedStock todayStock = stocks.get(0);
- Float todayPrice = Float.parseFloat(todayStock.getAdjustedClose());
- Float yesterdayPrice = Float.parseFloat((stocks.get(1).getAdjustedClose()));
- String company = stockDao.queryCompanyBySymbol(symbol);
- realTimeStock.setSymbol(todayStock.getSymbol());
- realTimeStock.setVolume(todayStock.getVolume());
- realTimeStock.setPrice(todayPrice);
- realTimeStock.setChange(todayPrice - yesterdayPrice);
- realTimeStock.setStyledChange(getStyledChange(todayPrice - yesterdayPrice));
- realTimeStock.setPercentageChange((todayPrice-yesterdayPrice)/yesterdayPrice*100);
- realTimeStock.setStyledPercentageChange(getStyledChange((todayPrice-yesterdayPrice)/yesterdayPrice*100));
- if(company!=null)
- realTimeStock.setCompany(company);
- else
- LOGGER.info(symbol);
- realTimeStocks.add(realTimeStock);
- }
- });
- }
- executorService.shutdown();
- try{
- if(!executorService.awaitTermination(10, TimeUnit.SECONDS)){
- executorService.shutdownNow();
- }
- }catch (InterruptedException e){
- executorService.shutdownNow();
- return realTimeStocks;
- }
- return realTimeStocks;
- }
- // parse RSI indicator
- public static String parseRSI(String symbol){
- String result = AlphavantageUtil.getRSI(symbol);
- if(StringUtils.isEmpty(result))
- return "";
- JSONObject timeSeries = JSON.parseObject(result)
- .getJSONObject("Technical Analysis: RSI");
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
- String today = formatter.format(LocalDate.now().minusDays(1));
- JSONObject jsonObject = timeSeries.getJSONObject(today);
- if(jsonObject == null){
- for (int i = 2; i < 7; i++) {
- String altDay = formatter.format(LocalDate.now().minusDays(i));
- jsonObject = timeSeries.getJSONObject(altDay);
- if(jsonObject != null)
- return jsonObject.getString("RSI");
- }
- }
- else return jsonObject.getString("RSI");
- return "";
- }
- /**
- * AlphavantageTimeSeries-Intraday
- *
- * @param symbol
- * @param interval
- * @param outputsize
- * @param datatype
- * @param apikey
- * @return
- */
- public static List<TimeSeriesIntradayStock> parseTimeSeriesIntraday(String symbol, int interval, String outputsize, String datatype, String apikey){
- String intervalStr = interval + "min";
- String result = AlphavantageUtil.getTimeSeriesIntraday(symbol, intervalStr, outputsize, datatype, apikey);
- List<TimeSeriesIntradayStock> stocks = new ArrayList<TimeSeriesIntradayStock>();
- JSONObject jsonObject = JSON.parseObject(result);
- if (StringUtils.isEmpty(result)){
- return stocks;
- }else {
- JSONObject metaData = jsonObject.getJSONObject("Meta Data");
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
- LocalDateTime lastRefreshed = LocalDateTime.parse(metaData.getString("3. Last Refreshed"),formatter);
- String key = String.format("Time Series (%s)", intervalStr);
- JSONObject timeSeries = jsonObject.getJSONObject(key);
- int size = timeSeries.size();
- for (int i = 0;i < size;i++){
- TimeSeriesIntradayStock stock = new TimeSeriesIntradayStock();
- stock.setInterval(intervalStr);
- stock.setSymbol(symbol);
- LocalDateTime time = lastRefreshed.minusMinutes(i * interval);
- stock.setTime(time);
- JSONObject row = timeSeries.getJSONObject(time.format(formatter));
- stock.setOpen(row.getString("1. open"));
- stock.setHigh(row.getString("2. high"));
- stock.setLow(row.getString("3. low"));
- stock.setClose(row.getString("4. close"));
- stock.setVolume(row.getString("5. volume"));
- stocks.add(stock);
- }
- return stocks;
- }
- }
- /**
- * AlphavantageTimeSeries-Daily
- *
- * @param symbol
- * @param outputsize
- * @param datatype
- * @param apikey
- * @return
- */
- public static List<TimeSeriesDailyStock> parseTimeSeriesDaily(String symbol,String outputsize,String datatype,String apikey){
- String result = AlphavantageUtil.getTimeSeriesDaily(symbol, outputsize, datatype, apikey);
- List<TimeSeriesDailyStock> stocks = new ArrayList<TimeSeriesDailyStock>();
- JSONObject jsonObject = JSON.parseObject(result);
- if (StringUtils.isEmpty(result)){
- return stocks;
- }else {
- JSONObject metaData = jsonObject.getJSONObject("Meta Data");
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
- LocalDate lastRefreshed = LocalDate.parse(metaData.getString("3. Last Refreshed"),formatter);
- String key = String.format("Time Series (%s)", "Daily");
- JSONObject timeSeries = jsonObject.getJSONObject(key);
- int size = timeSeries.size();
- for (int i = 0;i < size;i++){
- TimeSeriesDailyStock stock = new TimeSeriesDailyStock();
- stock.setSymbol(symbol);
- LocalDate time = lastRefreshed.minusDays(i);
- stock.setTime(time);
- JSONObject row = timeSeries.getJSONObject(time.format(formatter));
- if (row != null){
- stock.setOpen(row.getString("1. open"));
- stock.setHigh(row.getString("2. high"));
- stock.setLow(row.getString("3. low"));
- stock.setClose(row.getString("4. close"));
- stock.setVolume(row.getString("5. volume"));
- stocks.add(stock);
- }else {
- size++;
- }
- }
- return stocks;
- }
- }
- /**
- * AlphavantageTimeSeries-DailyAdjusted
- *
- * @param symbol
- * @param outputsize
- * @param datatype
- * @param apikey
- * @return
- */
- public static List<TimeSeriesDailyAdjustedStock> parseTimeSeriesDailyAdjusted(String symbol,String outputsize,String datatype,String apikey){
- String result = AlphavantageUtil.getTimeSeriesDailyAdjusted(symbol, outputsize, datatype, apikey);
- List<TimeSeriesDailyAdjustedStock> stocks = new ArrayList<TimeSeriesDailyAdjustedStock>();
- JSONObject jsonObject = JSON.parseObject(result);
- if (StringUtils.isEmpty(result)){
- return stocks;
- }else {
- JSONObject metaData = jsonObject.getJSONObject("Meta Data");
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
- LocalDate lastRefreshed = LocalDate.parse(metaData.getString("3. Last Refreshed"),formatter);
- String key = String.format("Time Series (%s)", "Daily");
- JSONObject timeSeries = jsonObject.getJSONObject(key);
- int size = timeSeries.size();
- for (int i = 0;i < size;i++){
- TimeSeriesDailyAdjustedStock stock = new TimeSeriesDailyAdjustedStock();
- stock.setSymbol(symbol);
- LocalDate time = lastRefreshed.minusDays(i);
- stock.setTime(time);
- JSONObject row = timeSeries.getJSONObject(time.format(formatter));
- if (row != null){
- stock.setOpen(row.getString("1. open"));
- stock.setHigh(row.getString("2. high"));
- stock.setLow(row.getString("3. low"));
- stock.setClose(row.getString("4. close"));
- stock.setAdjustedClose(row.getString("5. adjusted close"));
- stock.setVolume(row.getString("6. volume"));
- stock.setDividendAmount(row.getString("7. dividend amount"));
- stock.setSplitCoefficient(row.getString("8. split coefficient"));
- stocks.add(stock);
- }else {
- size++;
- }
- }
- return stocks;
- }
- }
- /**
- * AlphavantageTimeSeries-Weekly
- *
- * @param symbol
- * @param datatype
- * @param apikey
- * @return
- */
- public static List<TimeSeriesWeeklyStock> parseTimeSeriesWeekly(String symbol,String datatype,String apikey){
- String result = AlphavantageUtil.getTimeSeriesWeekly(symbol, datatype, apikey);
- List<TimeSeriesWeeklyStock> stocks = new ArrayList<TimeSeriesWeeklyStock>();
- JSONObject jsonObject = JSON.parseObject(result);
- if (StringUtils.isEmpty(result)){
- return stocks;
- }else {
- JSONObject metaData = jsonObject.getJSONObject("Meta Data");
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
- LocalDate lastRefreshed = LocalDate.parse(metaData.getString("3. Last Refreshed"),formatter);
- String key = "Weekly Time Series";
- JSONObject timeSeries = jsonObject.getJSONObject(key);
- int size = timeSeries.size();
- for (int i = 0;i < size;i++){
- TimeSeriesWeeklyStock stock = new TimeSeriesWeeklyStock();
- stock.setSymbol(symbol);
- LocalDate time = lastRefreshed.minusDays(i * 7);
- stock.setTime(time);
- JSONObject row = timeSeries.getJSONObject(time.format(formatter));
- if (row == null){
- for (int j = 1;j < 7;j++){
- LocalDate tmp = time.minusDays(j);
- JSONObject rowTmp = timeSeries.getJSONObject(tmp.format(formatter));
- if (rowTmp != null){
- row = rowTmp;
- break;
- }
- }
- }
- stock.setOpen(row.getString("1. open"));
- stock.setHigh(row.getString("2. high"));
- stock.setLow(row.getString("3. low"));
- stock.setClose(row.getString("4. close"));
- stock.setVolume(row.getString("5. volume"));
- stocks.add(stock);
- }
- return stocks;
- }
- }
- /**
- * AlphavantageTimeSeries-WeeklyAdjusted
- *
- * @param symbol
- * @param datatype
- * @param apikey
- * @return
- */
- public static List<TimeSeriesWeeklyAdjustedStock> parseTimeSeriesWeeklyAdjusted(String symbol,String datatype,String apikey){
- String result = AlphavantageUtil.getTimeSeriesWeeklyAdjusted(symbol, datatype, apikey);
- List<TimeSeriesWeeklyAdjustedStock> stocks = new ArrayList<TimeSeriesWeeklyAdjustedStock>();
- JSONObject jsonObject = JSON.parseObject(result);
- if (StringUtils.isEmpty(result)){
- return stocks;
- }else {
- JSONObject metaData = jsonObject.getJSONObject("Meta Data");
- LocalDate lastRefreshed;
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
- try {
- lastRefreshed = LocalDate.parse(metaData.getString("3. Last Refreshed"), formatter);
- } catch (DateTimeParseException e) {
- DateTimeFormatter tempFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
- lastRefreshed = LocalDate.parse(metaData.getString("3. Last Refreshed"), tempFormatter);
- }
- String key = "Weekly Adjusted Time Series";
- JSONObject timeSeries = jsonObject.getJSONObject(key);
- int size = timeSeries.size();
- for (int i = 0;i < size;i++){
- TimeSeriesWeeklyAdjustedStock stock = new TimeSeriesWeeklyAdjustedStock();
- stock.setSymbol(symbol);
- LocalDate time = lastRefreshed.minusDays(i * 7);
- stock.setTime(time);
- JSONObject row = timeSeries.getJSONObject(time.format(formatter));
- if (row == null){
- for (int j = 1;j < 7;j++){
- LocalDate tmp = time.minusDays(j);
- JSONObject rowTmp = timeSeries.getJSONObject(tmp.format(formatter));
- if (rowTmp != null){
- row = rowTmp;
- break;
- }
- }
- }
- try {
- if (row != null) {
- stock.setOpen(row.getString("1. open"));
- stock.setHigh(row.getString("2. high"));
- stock.setLow(row.getString("3. low"));
- stock.setClose(row.getString("4. close"));
- stock.setAdjustedClose(row.getString("5. adjusted close"));
- stock.setVolume(row.getString("6. volume"));
- stock.setDividendAmount(row.getString("7. dividend amount"));
- stocks.add(stock);
- }
- } catch (NullPointerException e) {
- // LOGGER.info(e.getMessage());
- // LOGGER.info(stock.toString());
- }
- }
- return stocks;
- }
- }
- /**
- * AlphavantageTimeSeries-Monthly
- *
- * @param symbol
- * @param datatype
- * @param apikey
- * @return
- */
- public static List<TimeSeriesMonthlyStock> parseTimeSeriesMonthly(String symbol,String datatype,String apikey){
- String result = AlphavantageUtil.getTimeSeriesMonthly(symbol, datatype, apikey);
- List<TimeSeriesMonthlyStock> stocks = new ArrayList<TimeSeriesMonthlyStock>();
- JSONObject jsonObject = JSON.parseObject(result);
- LOGGER.info(jsonObject);
- if (StringUtils.isEmpty(result)){
- return stocks;
- }else {
- JSONObject metaData = jsonObject.getJSONObject("Meta Data");
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
- LocalDate lastRefreshed = LocalDate.parse(metaData.getString("3. Last Refreshed"),formatter);
- String key = "Monthly Time Series";
- JSONObject timeSeries = jsonObject.getJSONObject(key);
- LOGGER.info(timeSeries);
- int size = timeSeries.size();
- for (int i = 0;i < size;i++){
- TimeSeriesMonthlyStock stock = new TimeSeriesMonthlyStock();
- stock.setSymbol(symbol);
- LocalDate time = lastRefreshed.withDayOfMonth(1).minusMonths(i).minusDays(1);
- stock.setTime(time);
- JSONObject row = timeSeries.getJSONObject(time.format(formatter));
- if (row == null){
- int daysOfMonth = time.getDayOfMonth();
- for (int j = 1;j < daysOfMonth;j++){
- LocalDate tmp = time.minusDays(j);
- JSONObject rowTmp = timeSeries.getJSONObject(tmp.format(formatter));
- if (rowTmp != null){
- stock.setTime(tmp);
- row = rowTmp;
- break;
- }
- }
- }
- stock.setOpen(row.getString("1. open"));
- stock.setHigh(row.getString("2. high"));
- stock.setLow(row.getString("3. low"));
- stock.setClose(row.getString("4. close"));
- stock.setVolume(row.getString("5. volume"));
- stocks.add(stock);
- }
- return stocks;
- }
- }
- /**
- * AlphavantageTimeSeries-MonthlyAdjusted
- *
- * @param symbol
- * @param datatype
- * @param apikey
- * @return
- */
- public static List<TimeSeriesMonthlyAdjustedStock> parseTimeSeriesMonthlyAdjusted(String symbol,String datatype,String apikey){
- String result = AlphavantageUtil.getTimeSeriesMonthlyAdjusted(symbol, datatype, apikey);
- List<TimeSeriesMonthlyAdjustedStock> stocks = new ArrayList<TimeSeriesMonthlyAdjustedStock>();
- JSONObject jsonObject = JSON.parseObject(result);
- if (StringUtils.isEmpty(result)){
- return stocks;
- }else {
- JSONObject metaData = jsonObject.getJSONObject("Meta Data");
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
- LocalDate lastRefreshed = LocalDate.parse(metaData.getString("3. Last Refreshed"),formatter);
- String key = "Monthly Adjusted Time Series";
- JSONObject timeSeries = jsonObject.getJSONObject(key);
- int size = timeSeries.size();
- for (int i = 0;i < size - 1;i++){
- TimeSeriesMonthlyAdjustedStock stock = new TimeSeriesMonthlyAdjustedStock();
- stock.setSymbol(symbol);
- LocalDate time = lastRefreshed.withDayOfMonth(1).minusMonths(i).minusDays(1);
- stock.setTime(time);
- JSONObject row = timeSeries.getJSONObject(time.format(formatter));
- if (row == null){
- int daysOfMonth = time.getDayOfMonth();
- for (int j = 1;j < daysOfMonth;j++){
- LocalDate tmp = time.minusDays(j);
- JSONObject rowTmp = timeSeries.getJSONObject(tmp.format(formatter));
- if (rowTmp != null){
- stock.setTime(tmp);
- row = rowTmp;
- break;
- }
- }
- }
- stock.setOpen(row.getString("1. open"));
- stock.setHigh(row.getString("2. high"));
- stock.setLow(row.getString("3. low"));
- stock.setClose(row.getString("4. close"));
- stock.setAdjustedClose(row.getString("5. adjusted close"));
- stock.setVolume(row.getString("6. volume"));
- stock.setDividendAmount(row.getString("7. dividend amount"));
- stocks.add(stock);
- }
- return stocks;
- }
- }
- /**
- * AlphavantageTimeSeries-BatchStockQuotes
- *
- * @param symbols
- * @param datatype
- * @param apikey
- * @return
- */
- public static List<StockQuote> parseBatchStockQuotes(String symbols,String datatype,String apikey){
- String result = AlphavantageUtil.getBatchStockQuotes(symbols, datatype, apikey);
- List<StockQuote> stockQuotes = new ArrayList<StockQuote>();
- JSONObject jsonObject = JSON.parseObject(result);
- if (StringUtils.isEmpty(result)){
- return stockQuotes;
- }else{
- String key = "Stock Quotes";
- JSONArray stockQuoteJsonArray = jsonObject.getJSONArray(key);
- int size = stockQuoteJsonArray.size();
- for (int i = 0;i < size;i++){
- JSONObject stockQuoteJsonObject = stockQuoteJsonArray.getJSONObject(i);
- StockQuote stockQuote = new StockQuote();
- stockQuote.setSymbol(stockQuoteJsonObject.getString("1. symbol"));
- stockQuote.setPrice(stockQuoteJsonObject.getString("2. price"));
- stockQuote.setVolume(stockQuoteJsonObject.getString("3. volume"));
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
- LocalDateTime timestamp = LocalDateTime.parse(stockQuoteJsonObject.getString("4. timestamp"),formatter);
- stockQuote.setTimestamp(timestamp);
- stockQuotes.add(stockQuote);
- }
- return stockQuotes;
- }
- }
- }