import java.awt.*; import java.applet.*; // Domain Logic public class TradeExecution extends DomainLogic { // inherits from DomainLogic public TradeExecution(TextArea textArea1) { super(textArea1); } void chgCash(Account account, double amount) { // adjust cash after BUY/SELL account.CASH = account.CASH + amount; } private Holding getHolding(Account account, Stock stock) { // find the holding record Holding holding = null; for (int i=0; i holding.QTY) textArea1.append("Account only has " + holding.QTY + " shares of "+ stock.SYM + "\n"); else OK = true; } return OK; } // new buyer has to pay at least as much as pending seller wants, vice versa for a new seller private boolean chkPrices(String type, double p1, double p2) { boolean OK = false; if (type.equals("BUY")) { if (p1 >= p2) OK = true; } else // SELL if (p1 <= p2) OK = true; return OK; } // process a sale for buyer/seller updating cash, holdings, transaction. //Also, this sale price represents the stocks new "value", used in all portfolios private void doSale(Account sellAccount,Account buyAccount,Stock stock,int qty, double price){ chgCash(sellAccount,+qty*price); chgCash(buyAccount,-qty*price); chgHolding(sellAccount,stock,-qty); chgHolding(buyAccount,stock,+qty); new Transaction(sellAccount,stock,"SELL",price,qty); new Transaction(buyAccount,stock, "BUY",price,qty); stock.PRICE = price; } // main algorithm (see pseudocode) for matching buys with sells private void scanOrders(Account account, Stock stock, String type, int qty1, double price) { int qty2, qty; Heap heap = stock.buyheap; if (type.equals("BUY")) heap = stock.sellheap; while (true) { if (qty1 <= 0) break; Order order = (Order) heap.testRoot(); if (order == null) break; if (!chkPrices(type, price,order.PRICE)) break; order = heap.getRoot(); qty2 = order.QTY; Account acct2 = order.account; if (qty1 <= qty2) qty = qty1; else qty = qty2; Account seller; Account buyer; if (type.equals("BUY")) { buyer = account; seller = acct2; } else { seller = account; buyer = acct2; } qty1 -= qty; qty2 -= qty; doSale(seller,buyer,stock,qty,price); chkOrder(order,qty2); textArea1.append("Sale completed: " + qty + " shares of " + stock.SYM + " at $" + price + " with account: " + acct2.ACCOUNT_NO + "\n"); } // while if (qty1 <= 0) textArea1.append(type + " completed.\n"); else { new Order(account, stock, type, price, qty1); textArea1.append("Current outstanding order: " + type + " " + qty1 + " shares of " + stock.SYM + " at $" + price + "\n"); } } // StockApplet calls doOrder when a BUY/SELL button is pushed // Validate the input fields and lookup the stock in the hashtable public void doOrder(String type, String sym, String shares, String price) { sym = sym.toUpperCase(); if (chkLogin()) if ((sym.equals("")) || (shares.equals("")) || (price.equals(""))) textArea1.append("Must enter Stock, Shares, and Price.\n"); else { Stock stock = (Stock)Stock.stocks.get(sym); if (stock == null) textArea1.append("Stock does not exist: " + sym); else if (validOrder(account,stock,type,price,shares)) scanOrders(account,stock,type,toInt(shares),toDouble(price)); } } } // class TradeExecution