Skip to main content

OrderRecord

Represents a single order and its complete state. This is the internal representation of an order, tracked by broker ID. Thread-safe through careful synchronization in OrderRegistry.

OrderRecord.java
package com.bookmap.ordermanagement.model;

/**
* Represents a single order and its complete state.
*
* This is the internal representation of an order, tracked by broker ID.
* Thread-safe through careful synchronization in OrderRegistry.
*/
public class OrderRecord {

// Identifiers
private final String brokerId;
private final String familyId;

// Order specification
private final OrderType orderType;
private final Direction direction;
private final int requestedSize;

// State tracking
private volatile OrderState state;
private volatile int filledQuantity;
private volatile double totalFillValue; // For average price calculation

// Timestamps
private final long createdTime;
private volatile long lastUpdateTime;

/**
* Creates a new order record.
*
* @param brokerId The broker-assigned order ID
* @param familyId The family this order belongs to
* @param orderType ENTRY, TAKE_PROFIT, or STOP_LOSS
* @param direction BUY or SELL
* @param requestedSize Number of contracts
*/
public OrderRecord(String brokerId, String familyId, OrderType orderType,
Direction direction, int requestedSize) {
this.brokerId = brokerId;
this.familyId = familyId;
this.orderType = orderType;
this.direction = direction;
this.requestedSize = requestedSize;
this.state = OrderState.CREATED;
this.filledQuantity = 0;
this.totalFillValue = 0.0;
this.createdTime = System.currentTimeMillis();
this.lastUpdateTime = this.createdTime;
}

// =========================================================================
// Getters
// =========================================================================

public String getBrokerId() {
return brokerId;
}

public String getFamilyId() {
return familyId;
}

public OrderType getOrderType() {
return orderType;
}

public Direction getDirection() {
return direction;
}

public int getRequestedSize() {
return requestedSize;
}

public OrderState getState() {
return state;
}

public int getFilledQuantity() {
return filledQuantity;
}

public int getRemainingQuantity() {
return requestedSize - filledQuantity;
}

public long getCreatedTime() {
return createdTime;
}

public long getLastUpdateTime() {
return lastUpdateTime;
}

/**
* Returns the average fill price, or 0 if no fills yet.
*/
public double getAverageFillPrice() {
if (filledQuantity == 0) return 0.0;
return totalFillValue / filledQuantity;
}

// =========================================================================
// State Queries
// =========================================================================

public boolean isActive() {
return state.isActive();
}

public boolean isTerminal() {
return state.isTerminal();
}

public boolean isFilled() {
return state == OrderState.FILLED;
}

public boolean isEntry() {
return orderType.isEntry();
}

public boolean isExit() {
return orderType.isExit();
}

// =========================================================================
// State Updates
// =========================================================================

/**
* Updates the order state.
*
* @param newState The new state
*/
public void setState(OrderState newState) {
this.state = newState;
this.lastUpdateTime = System.currentTimeMillis();
}

/**
* Records a fill execution.
*
* @param quantity Number of contracts filled
* @param price Fill price
*/
public void addFill(int quantity, double price) {
this.filledQuantity += quantity;
this.totalFillValue += quantity * price;
this.lastUpdateTime = System.currentTimeMillis();

// Update state based on fill
if (this.filledQuantity >= this.requestedSize) {
this.state = OrderState.FILLED;
} else if (this.filledQuantity > 0) {
this.state = OrderState.PARTIALLY_FILLED;
}
}

// =========================================================================
// Formatting
// =========================================================================

@Override
public String toString() {
return String.format("Order[%s|%s|%s|%s|%d/%d|%.2f]",
brokerId,
orderType.getShortName(),
direction,
state,
filledQuantity,
requestedSize,
getAverageFillPrice());
}

/**
* Returns a detailed multi-line description.
*/
public String toDetailedString() {
return String.format(
"OrderRecord {\n" +
" brokerId: %s\n" +
" familyId: %s\n" +
" type: %s\n" +
" direction: %s\n" +
" size: %d (filled: %d)\n" +
" state: %s\n" +
" avgPrice: %.2f\n" +
"}",
brokerId, familyId, orderType, direction,
requestedSize, filledQuantity, state, getAverageFillPrice());
}
}