/// <summary> /// Handler for validating Execution records. /// </summary> /// <param name="sender">The object that originated the event.</param> /// <param name="e">The event arguments.</param> internal static void OnExecutionRowValidate(object sender, DataModel.ExecutionRowChangeEventArgs e) { DataModel.DestinationOrderRow destinationOrderRow; Decimal executedQuantity; DataModelTransaction dataModelTransaction; Decimal orderedQuantity; // The Business Rules will be enforced on this Execution. Note that it is locked at the point this handler is called. DataModel.ExecutionRow executionRow = e.Row; // The action on the row determines which rule to evaluate. switch (e.Action) { case DataRowAction.Add: // This rule will update the status of the owning Destination Order based on the quantity executed. dataModelTransaction = DataModel.CurrentTransaction; // The aggregate of the quantities executed will determine whether the Destination Order requires a status change. destinationOrderRow = executionRow.DestinationOrderRow; destinationOrderRow.AcquireReaderLock(dataModelTransaction); if (destinationOrderRow.RowState == DataRowState.Detached) { return; } // This calculates the quantity outstanding on an order and the quantity executed on the order. orderedQuantity = destinationOrderRow.OrderedQuantity - destinationOrderRow.CanceledQuantity; executedQuantity = 0.0M; foreach (DataModel.ExecutionRow siblingRow in destinationOrderRow.GetExecutionRows()) { siblingRow.AcquireReaderLock(dataModelTransaction); executedQuantity += siblingRow.ExecutionQuantity; } // This rule will set the status on the owning Destination Order based on the amont outstanding and the amount ordered. First, if the quantity // executed is greater than the quantity ordered, the Order goes into an error state. We can't reject executions as they come from an external // source, but the order can be flag and put into an error state. if (executedQuantity > orderedQuantity) { if (destinationOrderRow.StatusCode != StatusCode.Error) { DestinationOrderService.UpdateDestinationOrderStatus(destinationOrderRow, StatusCode.Error); } } else { // When the total quantity executed is reduced to zero then the order goes back into the initial state. if (executedQuantity == 0.0m) { if (destinationOrderRow.StatusCode != StatusCode.New) { DestinationOrderService.UpdateDestinationOrderStatus(destinationOrderRow, StatusCode.New); } } else { // While the executed quantity is still less than the outstanding quantity the order is consdered to be partially filled. Otherwise, // the order is completely filled. if (executedQuantity < orderedQuantity) { if (destinationOrderRow.StatusCode != StatusCode.PartiallyFilled) { DestinationOrderService.UpdateDestinationOrderStatus(destinationOrderRow, StatusCode.PartiallyFilled); } } else { if (destinationOrderRow.StatusCode != StatusCode.Filled) { DestinationOrderService.UpdateDestinationOrderStatus(destinationOrderRow, StatusCode.Filled); } } } } break; case DataRowAction.Delete: // A middle tier context is required to lock the rows so the quantities can be aggregated. dataModelTransaction = DataModel.CurrentTransaction; // The aggregate of the quantities executed will determine whether the Destination Order requires a status change. destinationOrderRow = (DataModel.DestinationOrderRow)executionRow.GetParentRow( DataModel.Execution.DestinationOrderExecutionRelation, DataRowVersion.Original); destinationOrderRow.AcquireReaderLock(dataModelTransaction); if (destinationOrderRow.RowState == DataRowState.Detached) { return; } // This calculates the quantity outstanding on an order and the quantity executed on the order. orderedQuantity = destinationOrderRow.OrderedQuantity - destinationOrderRow.CanceledQuantity; executedQuantity = 0.0M; foreach (DataModel.ExecutionRow siblingRow in destinationOrderRow.GetExecutionRows()) { siblingRow.AcquireReaderLock(dataModelTransaction); executedQuantity += siblingRow.ExecutionQuantity; } // When the total quantity executed is reduced to zero then the order goes back into the initial state. Note that it is impossible for the // order to transition into a error state by deleting an execution. if (executedQuantity == 0.0m) { if (destinationOrderRow.StatusCode != StatusCode.New) { DestinationOrderService.UpdateDestinationOrderStatus(destinationOrderRow, StatusCode.New); } } else { // While the executed quantity is still less than the outstanding quantity the order is consdered to be partially filled. Note that it is // impossible for the order to transition to a filled state by deleting an execution. if (executedQuantity < orderedQuantity) { if (destinationOrderRow.StatusCode != StatusCode.PartiallyFilled) { DestinationOrderService.UpdateDestinationOrderStatus(destinationOrderRow, StatusCode.PartiallyFilled); } } } break; } }
public void CreateDestinationOrders(DestinationOrderInfo[] destinationOrders) { // Create the orders. DestinationOrderService.CreateDestinationOrders(destinationOrders); }
public void DestroyDestinationOrders(DestinationOrderReference[] destinationOrders) { // Destroy the orders. DestinationOrderService.DestroyDestinationOrders(destinationOrders); }
public void ClearOrders() { // Clear all the executions and then all the destination orders. ExecutionService.Truncate(); DestinationOrderService.Truncate(); }