Java tutorial
/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package nl.tudelft.ewi.st.atlantis.tudelft.v1.services.orderprocessorservice.impl; import nl.tudelft.ewi.st.atlantis.tudelft.external.v1.types.RemoteQuoteData; import nl.tudelft.ewi.st.atlantis.tudelft.v1.services.configurationservice.SharedConfigurationServiceV1Consumer; import nl.tudelft.ewi.st.atlantis.tudelft.v1.services.quoteservice.SharedQuoteServiceV1Consumer; import nl.tudelft.ewi.st.atlantis.tudelft.v1.types.GetQSLocationsRequest; import nl.tudelft.ewi.st.atlantis.tudelft.v1.types.GetQSLocationsResponse; import nl.tudelft.ewi.st.atlantis.tudelft.v1.types.GetQuotesRequest; import nl.tudelft.ewi.st.atlantis.tudelft.v1.types.GetQuotesResponse; import nl.tudelft.stocktrader.Holding; import nl.tudelft.stocktrader.Order; import nl.tudelft.stocktrader.dal.DAOException; import nl.tudelft.stocktrader.dal.DAOFactory; import nl.tudelft.stocktrader.dal.OrderDAO; import nl.tudelft.stocktrader.util.StockTraderUtility; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.math.BigDecimal; import java.net.URL; import java.util.Calendar; public class OrderProcessManager { private static final Log logger = LogFactory.getLog(OrderProcessManager.class); private OrderDAO orderDAO = null; public void processAndCompleteOrder(Order order) throws DAOException { if (logger.isDebugEnabled()) { logger.debug("ProcessOrder.processAndCompleteOrder(OrderDataModel) \nOrderID :" + order.getOrderID() + "\nOrderType :" + order.getOrderType() + "\nSymbol :" + order.getSymbol() + "\nQuantity :" + order.getQuantity() + "\nOrder Status :" + order.getOrderStatus() + "\nOrder Open Date :" + order.getOpenDate() + "\nCompletionDate :" + order.getCompletionDate()); } try { DAOFactory factory = DAOFactory.getFactory(); orderDAO = factory.getOrderDAO(); orderDAO.beginTransaction(); BigDecimal total = null; int holdingId = -1; //Quote quote = orderDAO.getQuoteForUpdate(order.getSymbol()); /* Tiago: making this more dynamic. query config service for a * quote service, then use quote service to get quote data */ SharedConfigurationServiceV1Consumer consumer = new SharedConfigurationServiceV1Consumer( "OrderProcessorService", "production"); GetQSLocationsResponse response = consumer.getQSLocations(new GetQSLocationsRequest()); if (response.getLocations().size() == 0) { System.out.println("Unable to locate a quote service"); return; } /* Got the QS Endpoint */ String qsEndpoint = response.getLocations().get(0).getServiceURL(); SharedQuoteServiceV1Consumer qsConsumer = new SharedQuoteServiceV1Consumer("OrderProcessorService", "production"); GetQuotesRequest request = new GetQuotesRequest(); request.getSymbols().add(order.getSymbol()); qsConsumer.getService().setServiceLocation(new URL(qsEndpoint)); GetQuotesResponse qsResponse = qsConsumer.getQuotes(request); if (qsResponse.getQuoteData().size() == 0) { System.out.println("Unable to locate a quote entry for the symbol :" + order.getSymbol()); return; } RemoteQuoteData quoteData = qsResponse.getQuoteData().get(0); BigDecimal price = BigDecimal.valueOf(quoteData.getValue()); order.setPrice(price); System.out.println("order type is:" + order.getOrderType()); if (StockTraderUtility.ORDER_TYPE_BUY.equals(order.getOrderType())) { holdingId = orderDAO.createHolding(order); BigDecimal orderQuantity = BigDecimal.valueOf(order.getQuantity()); BigDecimal orderPrice = order.getPrice(); total = orderQuantity.multiply(orderPrice); BigDecimal orderFee = order.getOrderFee(); if (orderFee != null) { total = total.add(orderFee); } } else if (StockTraderUtility.ORDER_TYPE_SELL.equals(order.getOrderType())) { holdingId = sellHolding(order); if (holdingId == -1) { return; } BigDecimal orderQuantity = BigDecimal.valueOf(-1 * order.getQuantity()); BigDecimal orderPrice = order.getPrice(); total = orderQuantity.multiply(orderPrice); BigDecimal orderFee = order.getOrderFee(); if (total != null) { total = total.add(orderFee); } } orderDAO.updateAccountBalance(order.getAccountId(), total); orderDAO.updateStockPriceVolume(order.getQuantity(), quoteData); order.setOrderStatus(StockTraderUtility.ORDER_STATUS_CLOSED); order.setCompletionDate(Calendar.getInstance()); order.setHoldingId(holdingId); orderDAO.closeOrder(order); orderDAO.commitTransaction(); } catch (Exception e) { e.printStackTrace(); try { orderDAO.rollbackTransaction(); logger.error("", e); } catch (DAOException e1) { logger.error("", e1); } } finally { if (orderDAO != null) { try { orderDAO.close(); } catch (DAOException e) { logger.error("", e); } } } } private int sellHolding(Order order) throws DAOException { if (logger.isDebugEnabled()) { logger.debug("ProcessOrder.sellHolding(OrderDataModel) \nOrderID :" + order.getOrderID() + "\nOrderType :" + order.getOrderType() + "\nSymbol :" + order.getSymbol() + "\nQuantity :" + order.getQuantity() + "\nOrder Status :" + order.getOrderStatus() + "\nOrder Open Date :" + order.getOpenDate() + "\nCompletionDate :" + order.getCompletionDate()); } Holding holding = orderDAO.getHoldingForUpdate(order.getOrderID()); if (holding == null) { // TODO : DAOException .. throw new RuntimeException("Unable to locate a holding entry for orderID :" + order.getOrderID()); } order.setAccountId(holding.getAccountID()); // There are three distinct business cases here, each needs different // treatment: // a) Quantity requested is less than total shares in the holding -- // update holding. // b) Quantity requested is equal to total shares in the holding -- // delete holding. // c) Quantity requested is greater than total shares in the holding -- // delete holding, update order table. if (order.getQuantity() < holding.getQuantity()) { orderDAO.updateHolding(holding.getHoldingID(), order.getQuantity()); } else if (holding.getQuantity() == order.getQuantity()) { orderDAO.deleteHolding(holding.getHoldingID()); } else if (order.getQuantity() > holding.getQuantity()) { // We now need to back-update the order record quantity to reflect // fact not all shares originally requested were sold since the // holding had less shares in it, perhaps due to other orders placed // against that holding that completed before this one. So we will // sell the remaining shares, but need to update the final order to // reflect this. orderDAO.deleteHolding(holding.getHoldingID()); order.setQuantity(holding.getQuantity()); order.setAccountId(holding.getAccountID()); orderDAO.updateOrder(order); } return holding.getHoldingID(); } }