/// <summary> /// Changes the state of the Working Order to reflect a filledly filled state. /// </summary> private static void ClearErrorAction(Object[] key, params Object[] parameters) { // A middle tier context is also required for a transacted update. DataModelTransaction dataModelTransaction = DataModelTransaction.Current; // It is possible that the Working Order that is the object of this status update operation may have been deleted since the action was // created. This is not an error condition. If there is no Working Order to update, then the operation is just terminated prematurely. WorkingOrderRow workingOrderRow = DataModel.WorkingOrder.WorkingOrderKey.Find(key); if (workingOrderRow == null) { return; } workingOrderRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout); dataModelTransaction.AddLock(workingOrderRow); if (workingOrderRow.RowState == DataRowState.Detached) { return; } // The 'Error' status is only cleared when all the Destination Orders are valid. Boolean isErrorStatus = false; foreach (DestinationOrderRow siblingOrderRow in workingOrderRow.GetDestinationOrderRows()) { siblingOrderRow.AcquireReaderLock(dataModelTransaction); if (siblingOrderRow.StatusId == StatusMap.FromCode(Status.Error)) { isErrorStatus = true; break; } } // The proper Working Order status must be evaluated when the error status is cleared. if (!isErrorStatus) { // The aggregates will determine the new state of the Working Order. Decimal quantityExecuted = WorkingOrder.GetExecutionQuantity(dataModelTransaction, workingOrderRow); Decimal quantityOrdered = WorkingOrder.GetSourceOrderQuantity(dataModelTransaction, workingOrderRow); // This restores the 'New' status when the canceled Destination Order was the only order with any fills. if (quantityExecuted == 0.0M && workingOrderRow.StatusId != StatusMap.FromCode(Status.New)) { UpdateWorkingOrderStatus(workingOrderRow, Status.New); } // This restores the 'Partially Filled' status when other executions remain. if (0.0M < quantityExecuted && quantityExecuted < quantityOrdered && workingOrderRow.StatusId != StatusMap.FromCode(Status.PartiallyFilled)) { UpdateWorkingOrderStatus(workingOrderRow, Status.PartiallyFilled); } // This restores the 'Filled' status when the quantity executed is the same as the quantity ordered. if (quantityExecuted == quantityOrdered && workingOrderRow.StatusId != StatusMap.FromCode(Status.Filled)) { UpdateWorkingOrderStatus(workingOrderRow, Status.Filled); } } }
/// <summary> /// The sum total of the quantities of all the destination orders in a given working order. /// </summary> /// <param name="dataModelTransaction"></param> /// <param name="workingOrderRow">A working order row.</param> /// <returns>The total quantity of all the destination orders associated with the working order.</returns> internal static Decimal GetDestinationOrderQuantity(DataModelTransaction dataModelTransaction, WorkingOrderRow workingOrderRow) { // This is the accumulator for the quantity held in the destination orders. Decimal destinationOrderQuantity = 0.0m; // This will aggregate all the destination order quantities. The tables must be locked in succession as they are // read from the table. foreach (DestinationOrderRow destinationOrderRow in workingOrderRow.GetDestinationOrderRows()) { destinationOrderRow.AcquireReaderLock(dataModelTransaction); destinationOrderQuantity += destinationOrderRow.OrderedQuantity; } // This is the sum total of all the destination orders in the given working order. return(destinationOrderQuantity); }
/// <summary> /// The sum total of the quantities of all the destination orders in a given working order. /// </summary> /// <param name="dataModelTransaction"></param> /// <param name="workingOrderRow">A working order row.</param> /// <returns>The total quantity of all the destination orders associated with the working order.</returns> internal static Decimal GetExecutionQuantity(DataModelTransaction dataModelTransaction, WorkingOrderRow workingOrderRow) { // This will aggregate all the execution quantities. Note that the records are locked for the duration of the transaction to insure the integrity // of the aggregates. Decimal executionQuantity = 0.0m; foreach (DestinationOrderRow destinationOrderRow in workingOrderRow.GetDestinationOrderRows()) { destinationOrderRow.AcquireReaderLock(dataModelTransaction); if (destinationOrderRow.StatusId != StatusMap.FromCode(Status.Canceled)) { foreach (ExecutionRow executionRow in destinationOrderRow.GetExecutionRows()) { executionRow.AcquireReaderLock(dataModelTransaction); executionQuantity += executionRow.ExecutionQuantity; } } } // This is the aggregate quantity executed for the given working order. return(executionQuantity); }
/// <summary> /// Initialize the data used in this application. /// </summary> private void InitializeData(object parameter) { String title = String.Empty; String symbol = String.Empty; String name = String.Empty; String logoSource = null; Decimal leavesQuantity = 0.0m; NegotiationState negotiationState = NegotiationState.None; lock (DataModel.SyncRoot) { // Find the Match record. MatchRow matchRow = DataModel.Match.MatchKey.Find(this.matchId); WorkingOrderRow workingOrderRow = matchRow.WorkingOrderRow; OrderTypeRow orderTypeRow = workingOrderRow.OrderTypeRow; SecurityRow securityRow = workingOrderRow.SecurityRowByFK_Security_WorkingOrder_SecurityId; symbol = securityRow.Symbol; name = securityRow.EntityRow.Name; logoSource = securityRow.IsLogoNull() ? String.Empty : securityRow.Logo; title = String.Format("{0} of {1}", orderTypeRow.Description, symbol); leavesQuantity = 0.0M; foreach (SourceOrderRow sourceOrderRow in workingOrderRow.GetSourceOrderRows()) { leavesQuantity += sourceOrderRow.OrderedQuantity; } foreach (DestinationOrderRow destinationOrderRow in workingOrderRow.GetDestinationOrderRows()) { foreach (ExecutionRow executionRow in destinationOrderRow.GetExecutionRows()) { leavesQuantity -= executionRow.ExecutionQuantity; } } leavesQuantity /= securityRow.QuantityFactor; } this.Dispatcher.Invoke(DispatcherPriority.Normal, new SetDialogAttributesDelegate(SetDialogAttributes), title, symbol, name, logoSource, leavesQuantity, negotiationState); }