/* * Copyright 2009-2010 Eric Bruno, Greg Bollella. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * Neither the name of the Book, * "Real-Time Java Programming with Java RTS" * nor the names of its authors may be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * See the GNU General Public License version 2 for more details. * You should have received a copy of the GNU General Public License * version 2 along with this work; if not, write to the: * Free Software Foundation, Inc. * 51 Franklin St, Fifth Floor * Boston, MA 02110-1301 USA. */ package com.sun.oss.trader.tradingengine; import java.util.*; import java.io.*; import joprt.RtThread; import joprt.SwEvent; public class MarketManager implements Runnable { static final String SYMBOL_TAG = "<symbol>"; static final String SYMBOL_END_TAG = "</symbol>"; static final String PRICE_TAG = "<price>"; static final String PRICE_END_TAG = "</price>"; private boolean fDebug = false; // The Market Book is a hashmap of prices (stored as StringBuffer objects) // that are looked up by stock symbol (StringBuffer) as the key public static final int INITIAL_CAPACITY = 128; HashMap<String,StringBuffer> marketBook = new HashMap<String,StringBuffer>(INITIAL_CAPACITY); private static final int MAX_UPDATE_XML_SIZE = 512; public MarketManager() { } public void close() { } public void displayMarketBook() { System.out.println("************************************************"); System.out.println("Current Market Book:"); Set<String> keys = marketBook.keySet(); Iterator<String> iter = keys.iterator(); while ( iter.hasNext() ) { String symbol = iter.next(); double price = getLastTradePrice(symbol); System.out.println( "Last trade price for " + symbol + ":" + price); } System.out.println(" "); System.out.println(" "); } // Display the last trade price for a symbol public double getLastTradePrice(String symbol) { // Get the order book for this symbol if it exists try { return Double.parseDouble( marketBook.get(symbol).toString() ); } catch ( Exception e ) { } return 0; } public void run() { JOPReader reader = new JOPReader(2*MAX_UPDATE_XML_SIZE); while (true) { try { if (reader.availableLines() > 0) { String msg = reader.readLine(); onMessage(msg); } } catch (IOException e) { e.printStackTrace(); } boolean madePeriod = RtThread.currentRtThread().waitForNextPeriod(); if (!madePeriod) { System.out.print('M'); } } } public void onMessage(String msg) { try { /* * SAMPLE UPDATE XML: <updates> <update> <symbol>SUNW</symbol> <datetime>2006-09-20T13:59:25.993-04:00</datetime> <price>4.9500</price> </update> </updates> */ // To preserve memory when running within a no-heap realtime thread // (NHRT) the XML String is walked manually, without the use of // a DOM or SAX parser that would otherwise create lots of objects // String sUpdate = msg; int start = 0; boolean fParse = true; while ( fParse ) //@WCA loop <= 1 { int sBegin = sUpdate.indexOf(SYMBOL_TAG, start); if ( sBegin < 0 ) break; int sEnd = sUpdate.indexOf(SYMBOL_END_TAG, sBegin); String symbol = sUpdate.substring(sBegin+(SYMBOL_TAG.length()), sEnd); int pBegin = sUpdate.indexOf(PRICE_TAG, start); int pEnd = sUpdate.indexOf(PRICE_END_TAG, pBegin); String price = sUpdate.substring(pBegin+(PRICE_TAG.length()), pEnd); start = pEnd; onUpdate(symbol, price ); } } catch ( Exception e ) { e.printStackTrace(); } } private void onUpdate(String symbol, String price) { //log("Symbol: " + symbol + ", Quote: " + price); // Look for the symbol in the existing market book. If it's not there // then create a new StringBuffer with an initial capacity, so that // as updates occur memory will not be constantly allocated // StringBuffer sbPrice = marketBook.get(symbol); if ( sbPrice == null ) { sbPrice = new StringBuffer(15); marketBook.put(symbol, sbPrice); } // Replace the existing contents of the price StringBuffer // to avoid allocating more memory // sbPrice.replace(0, price.length(), price); } private void log(String m) { if ( fDebug ) System.out.println(m); } }