package trade2017.orderbook;import trade2017.exceptions.NullParameterException;
import trade2017.exceptions.InvalidTradableQuantityException;
import trade2017.exceptions.TradableAlreadyExistsException;
import trade2017.exceptions.TradableDoesNotExistException;
import trade2017.exceptions.BadParameterException;
import trade2017.price.Price;
import trade2017.price.InvalidPriceOperation;
import java.util.ArrayList;
import java.util.HashMap;
import trade2017.publishers.CancelReportPublisher;
import trade2017.publishers.ExecutionReportPublisher;
import trade2017.tradable.Tradable;
public class OrderBook {
private final HashMap sides = new HashMap();
private String symbol;
public long addTime, removeTime;
public OrderBook(String s) throws BadParameterException {
setSymbol(s);
sides.put(BookSide.BUY, new OrderBookSide(BookSide.BUY));
sides.put(BookSide.SELL, new OrderBookSide(BookSide.SELL));
}
public synchronized Price topOfBookPrice(BookSide side) {
return sides.get(side).topOfBookPrice();
}
public synchronized int topOfBookQuantity(BookSide side) {
return sides.get(side).totalQuantityAtPrice(topOfBookPrice(side));
}
public synchronized int topOfBookEntries(BookSide side) {
return sides.get(side).numEntriesAtPrice(topOfBookPrice(side));
}
public synchronized void addTradable(Tradable t) throws NullParameterException, TradableAlreadyExistsException, InvalidTradableQuantityException, TradableDoesNotExistException, InvalidPriceOperation {
long start = System.nanoTime();
if (crossesOpposite(t)) {
executeTrade(t);
}
if (t.getRemainingQuantity() > 0) {
sides.get(t.getSide()).addEntry(t);
}
long end = System.nanoTime();
addTime += (end – start);
}
private synchronized void executeTrade(Tradable t) throws InvalidTradableQuantityException, TradableDoesNotExistException, NullParameterException, InvalidPriceOperation {
boolean done = false;
while (!done) {
switch (t.getSide()) {
case BUY: {
if (sides.get(BookSide.SELL).numberOfTradables() == 0) {
done = true;
break;
}
if (t.getPrice().lessThan(sides.get(BookSide.SELL).topOfBookPrice())) {
return;
}
int min = Math.min(t.getRemainingQuantity(), sides.get(BookSide.SELL).nextQuantityAtPrice(sides.get(BookSide.SELL).topOfBookPrice()));
Price price = t.getPrice().subtract(sides.get(BookSide.SELL).topOfBookPrice());
if (price.isNegative()) {
price = price.multiply(-1);
}
price = price.divide(2);
Price tradePrice;
if (t.getPrice().lessThan(sides.get(BookSide.SELL).topOfBookPrice())) {
tradePrice = t.getPrice();
} else {
tradePrice = sides.get(BookSide.SELL).topOfBookPrice();
}
tradePrice.add(price);
Tradable contra = sides.get(BookSide.SELL).reduceQuantityFromTop(min, tradePrice);
t.reduceQuantity(min);
TradeRecord tr = new TradeRecord(t, contra, min, tradePrice);
ExecutionReportPublisher.getInstance().addReport(tr);
break;
}
case SELL: {
if (sides.get(BookSide.BUY).numberOfTradables() == 0) {
done = true;
break;
}
if (t.getPrice().greaterThan(sides.get(BookSide.BUY).topOfBookPrice())) {
return;
}
Price p = sides.get(BookSide.BUY).topOfBookPrice();
int q = sides.get(BookSide.BUY).nextQuantityAtPrice(p);
int min = Math.min(t.getRemainingQuantity(), sides.get(BookSide.BUY).nextQuantityAtPrice(sides.get(BookSide.BUY).topOfBookPrice()));
Price price = t.getPrice().subtract(sides.get(BookSide.BUY).topOfBookPrice());
if (price.isNegative()) {
price = price.multiply(-1);
}
price = price.divide(2);
Price tradePrice;
if (t.getPrice().lessThan(sides.get(BookSide.BUY).topOfBookPrice())) {
tradePrice = t.getPrice();
} else {
tradePrice = sides.get(BookSide.BUY).topOfBookPrice();
}
tradePrice.add(price);
//System.err.println(“MIN2 is ” + min + “, Tradable: ” + t.getQuantity() + “, Book: ” + sides.get(BookSide.BUY).nextQuantityAtPrice(sides.get(BookSide.BUY).topOfBookPrice()));
Tradable contra = sides.get(BookSide.BUY).reduceQuantityFromTop(min, tradePrice);
t.reduceQuantity(min);
TradeRecord tr = new TradeRecord(t, contra, min, tradePrice);
ExecutionReportPublisher.getInstance().addReport(tr);
break;
}
}
if (t.getRemainingQuantity() == 0) {
done = true;
}
}
}
private synchronized boolean crossesOpposite(Tradable t) {
switch (t.getSide()) {
case BUY:
if (sides.get(BookSide.SELL).numberOfTradables() == 0) {
return false;
}
return t.getPrice().greaterOrEqual(sides.get(BookSide.SELL).topOfBookPrice());
case SELL:
return t.getPrice().lessOrEqual(sides.get(BookSide.BUY).topOfBookPrice());
default:
return false;
}
}
private BookSide opposite(BookSide bs) {
switch (bs) {
case BUY:
return BookSide.SELL;
case SELL:
return BookSide.BUY;
default:
return null;
}
}
public synchronized Tradable removeTradable(long id) throws TradableDoesNotExistException, NullParameterException {
long start = System.nanoTime();
for (OrderBookSide bs : sides.values()) {
if (bs.hasTradable(id)) {
Tradable tr = bs.removeEntry(id);
long end = System.nanoTime();
removeTime += (end – start);
CancelReportPublisher.getInstance().addReport(tr);
return tr;
}
}
long end = System.nanoTime();
removeTime += (end – start);
return null;
}
private void setSymbol(String s) throws BadParameterException {
if (s == null || s.isEmpty()) {
throw new BadParameterException(“Null or Empty string passed to OrderBook:setSymbol”);
}
symbol = s;
}
public synchronized ArrayList getBookedIds() {
ArrayList idList = new ArrayList();
idList.addAll(sides.get(BookSide.BUY).getBookedIds());
idList.addAll(sides.get(BookSide.SELL).getBookedIds());
return idList;
}
public synchronized String toString() {
StringBuilder sb = new StringBuilder(“\n———————————-\nOrder Book: ” + symbol + “\n”);
ArrayList data = new ArrayList();
int max = 0;
for (BookSide bs : sides.keySet()) {
String[] d = sides.get(bs).getBookDepth();
data.add(d);
if (d.length > max) {
max = d.length;
}
}
for (int i = 0; i < max; i++) {
for (int j = 0; j < sides.size(); j++) {
if (data.get(j).length
Alarm 2
DAILY_MF
3/25/2009 19:00
E:\NewProj\sounds\Explosion.wav
3
Check email!
Alarm 3
ONCE
3/25/2009 20:30
E:\clock2\Alarm.wav
1
Go to fundraiser planning meeting
Software Requirements Specification for “Java Clock” ™
9
I
nternazionale
mmobiliare, llc
3.2.6 Alarm Snooze
3.2.6.1 Description and Priority
The Alarm Snooze feature allows the user to re-submit an alarm a short time in future
once the alarm executes (similar to the conventional “snooze” feature of an alarm clock).
Refer to Section 4, “Interface Requirements”, sub-section 4.1.7 for GUI sketches of this
feature. Priority: Low.
3.2.6.2 Functional Requirements
The user can utilize the snooze feature to re-submit an executed alarm a short period in
the future, using a set of pre-defined “snooze” times: 1, 2, 5, 10, 15, 30 or 60 minutes. The
snooze time duration is selectable by the user via a pull-down combo-box.
When the specified snooze time delay has passed, the alarm will again execute. There is
no limit on how many times an alarm may be “snoozed”.
3.3 GUI Features & Customizations
3.3.1 12/24 Hour Time Display Format
3.3.1.1 Description and Priority
This feature allows the user to toggle the time display between a 12-hour time display
(i.e., 3:30 pm) and a 24-hour time display (i.e., 15:30). Refer to Section 4, “Interface
Requirements”, subsection 4.1.1 for GUI sketches of this feature. Priority: Low.
3.3.1.2 Functional Requirements
This feature is invoked by left-clicking anywhere on the time display text. Left-clicking
when the clock is showing the 12 hour display changes to the 24 hour display. Leftclicking when the clock is showing the 24 hour display changes to the 12 hour display.
3.3.2 Time Display Font Customization
3.3.2.1 Description and Priority
This feature allows the user to change both the time display font, and the time display
font size. Refer to Section 4, “Interface Requirements”, sub-sections 4.1.1 and 4.1.8 for
GUI sketches of this feature. Priority: Low.
3.3.2.2 Functional Requirements
This feature is invoked by Ctrl-clicking anywhere on the time display text. A fontchooser window will be displayed listing all available fonts and the available font sizes
that the user may select. Fonts can be selected as “bold” or “italics” from this window as
well. All font selections can be previewed from this window before applying the font
change.
Software Requirements Specification for “Java Clock” ™
10
I
nternazionale
mmobiliare, llc
3.3.3 Time Display Font Color Customization
3.3.3.1 Description and Priority
This feature allows the user to change the color of the time display text. Refer to Section
4, “Interface Requirements”, sub-sections 4.1.1 and 4.1.9 for GUI sketches of this feature.
Priority: Low.
3.3.3.2 Functional Requirements
This feature is invoked by Shift-clicking anywhere on the time display text. A color
selection window will be displayed that will allow the user to specify their desired time
display text color. The color can be chosen by either selecting a color swatch, by
specifying HSB color values, or by specifying RGB values. All color selections can be
previewed from this window before applying the color change.
3.3.4 Time Display Background Color Customization
3.3.4.1 Description and Priority
This feature allows the user to change the color behind the time display text. Refer to
Section 4, “Interface Requirements”, sub-sections 4.1.1 and 4.1.10 for GUI sketches of this
feature. Priority: Low.
3.3.4.2 Functional Requirements
This feature is invoked by Alt-clicking anywhere on the time display text. A color
selection window will be displayed that will allow the user to specify the desired time
display background color. The color can be chosen by either selecting a color swatch, by
specifying HSB color values, or by specifying RGB values. All color selections can be
previewed from this window before applying the color change.
3.3.5 Clock Face Color Customization
3.3.5.1 Description and Priority
This feature allows the user to change the color of the Java Clock GUI window. Refer to
Section 4, “Interface Requirements”, sub-sections 4.1.1 and 4.1.11 for GUI sketches of this
feature. Priority: Low.
3.3.5.2 Functional Requirements
This feature is invoked by Ctrl-clicking, Shift-clicking, or Alt-clicking anywhere outside
of the time display section or the Alarm Button section of the Java Clock GUI window. A
color selection window will be displayed that will allow the user to specify their desired
color. The color can be chosen by either selecting a color swatch, by specifying HSB color
values, or by specifying RGB values. All color selections can be previewed from this
window before applying the color change.
Software Requirements Specification for “Java Clock” ™
11
I
nternazionale
mmobiliare, llc
3.3.6 Alarm Button Color Customization
3.3.6.1 Description and Priority
This feature allows the user to change the color of the Java Clock Alarm button. Refer to
Section 4, “Interface Requirements”, sub-sections 4.1.1 and 4.1.12 for GUI sketches of this
feature. Priority: Low.
3.3.6.2 Functional Requirements
This feature is invoked by Right-clicking anywhere on the Java Clock GUI’s alarm
button. A color selection window will be displayed that will allow the user to specify
their desired color. The color can be chosen by either selecting a color swatch, by
specifying HSB color values, or by specifying RGB values. All color selections can be
previewed from this window before applying the color change.
3.3.7 System Tray Minimization
3.3.7.1 Description and Priority
When minimized, the Java Clock GUI will minimize to the System Tray (not to the
Taskbar). Refer to Section 4, “Interface Requirements”, sub-sections 4.1.13 for GUI
sketches of this feature. Priority: Medium.
3.3.7.2 Functional Requirements
Minimizing the Java Clock GUI will minimize the GUI to the System Tray. Note this is
not minimized to the usual minimization to the Taskbar. Double clicking on the
minimized System Tray icon will restore the GUI. Right-clicking the minimized System
Tray icon will display a menu of options that includes “Open” (restore the GUI), “Close”
(minimize to the System Tray), and “Exit”(stop the Java Clock application).
Software Requirements Specification for “Java Clock” ™
12
I
nternazionale
mmobiliare, llc
4. Interface Requirements
4.1 User Interfaces
The following are Graphical User Interface prototype diagrams of the Java Clock applications
GUI.
Nonobvious GUI based functionality is detailed with each GUI window diagram.
4.1.1 Main Java Clock Application Window
4.1.2 Alarms Window
Table columns can be drag-n-dropped (to the left or to the right) to create a view with an alternate column order:
Alarm Time, Recurrence, Alarm, etc. – or – Recurrence, Alarm Sound, Alarm Time, etc.
Software Requirements Specification for “Java Clock” ™
13
I
nternazionale
mmobiliare, llc
4.1.3 New Alarm Window
4.1.4 Edit Alarm Window
Software Requirements Specification for “Java Clock” ™
14
I
nternazionale
mmobiliare, llc
4.1.5 Delete Alarm Confirmation Window
4.1.6 Delete All Confirmation Window
4.1.7 Alarm Execution Display Window
Software Requirements Specification for “Java Clock” ™
15
I
nternazionale
mmobiliare, llc
4.1.8 Font Selection Window
4.1.9 Time Display Font Color Selection Window & Tabs (Swatches, HSB, RGB)
Software Requirements Specification for “Java Clock” ™
16
I
nternazionale
mmobiliare, llc
4.1.10 Time Display Background Color Selection Window & Tabs (Swatches, HSB, RGB)
4.1.11 Clock Face Color Selection Window & Tabs (Swatches, HSB, RGB)
Software Requirements Specification for “Java Clock” ™
17
I
nternazionale
mmobiliare, llc
4.1.12 Alarm Button Color Selection Window & Tabs (Swatches, HSB, RGB)
Software Requirements Specification for “Java Clock” ™
18
I
nternazionale
mmobiliare, llc
4.1.13 System Tray Icon
5. Other Nonfunctional Requirements
5.1 Usability Requirements
o
o
o
GUI
•
Each GUI component on each GUI window should have “tool-tip” text (text that
is displayed when mouse arrow hovers over a GUI element for a few moments)
that tells the user what is expected in that data field and any limitations to that
data that might exist.
Errors
• Any errors generated by the application, whether due to user data entry issues or
internal application issues, should be displayed to the user as a plain, nontechnical error message. For example: “The ‘Alarm Name’ field cannot be left
empty” – not “InvalidDataException: Bad name found - alarmNameIn string size
< 0”
Java “exception” text should never be used in user-visible messages or pop-up window.
5.2 Reliability Requirements
o
o
o
o
The Java Clock application should never “crash” as a result of user-entered data. All
errors based upon user inputs should be properly handled such that the application can
continue.
Internal application errors should not crash the application. An indication should be
provided to the user what has happened only if user action is needed. For example, if
XML file access fails somehow, the application should not unceremoniously crash.
The Java Clock application can be left running indefinitely with no change in
performance or function.
There is no application limit on the number of Alarms that can be added to Java Clock.
Software Requirements Specification for “Java Clock” ™
19
I
nternazionale
mmobiliare, llc
5.3 Performance Requirements
o
o
The Java Clock Alarm Maintenance functions have no specific minimum execution time
requirements, but the maximum execution time for any of the alarm maintenance
functions is one second. (This refers to actual time, not the time it takes to enter the data
in the GUI).
As more & more Alarms are added to Java Clock, the performance of any “Alarm
Maintenance” function should never exceed 150% of the time the function takes to
execute with no alarms loaded
For example, if an alarm can be added to Java Clock when no alarms are yet present in
180 ms, then as more & more alarms are added – 5, 10, 50, 100, etc. – adding an alarm to
Java Clock should take no more than (180 ms * 150%) = 270 ms. Or, if executing an
alarm takes 4 ms, then the function should take no more than (4 ms * 150%) = 6 ms with
a large number of alarms present.
5.4 Supportability Requirements
•
The “JavaClockAlarms.xml” XML file should be exportable. This exporting function serves 3
purposes:
o External editing - This file may be edited outside the Java Clock application if desired.
Alarms can be added, removed, edited, etc.
o Application migration – moving the Java Clock application to a new computer will
require the Java Clock alarms to be moved there as well.
o Backup – The exported XML alarm file can act as a backup in case something happens to
the active XML alarm file.
6. Other Requirements
6.1 Interface Requirements
No interaction with any external systems.
6.2 Implementation Requirements
•
•
•
•
Implementation Language: Java
Alarm File Format: XML
Target Platform(s): Windows, Mac OS, Linux (any java compatible platform)
Coding standards - Code Conventions for the Java Programming Language
(http://java.sun.com/docs/codeconv/)
Software Requirements Specification for “Java Clock” ™
20
I
nternazionale
mmobiliare, llc
6.3 Operational Requirements
No operational support needed.
6.4 Packaging Requirements
•
•
The Java Clock application will be distributed via compressed “ZIP” file containing a folder that
will contain all files needed to run the application.
Java (at least the JRE) must be installed on the end-user’s computer.
6.5 Legal Requirements
No known legal requirements.
Software Requirements Specification for “Java Clock” ™
21