/// <summary> /// Gets the sum total of all the destination orders. /// </summary> /// <param name="dataModelTransaction">The data model transaction.</param> /// <param name="workingOrderRow">The working order row.</param> /// <returns>The aggregate quantity of destination orders for the specified working order.</returns> internal static Decimal GetDestinationOrderQuantity(DataModelTransaction dataModelTransaction, DataModel.WorkingOrderRow workingOrderRow) { // Aggregate the destination orders. Decimal destinationOrderQuantity = 0.0m; foreach (DataModel.DestinationOrderRow destinationOrderRow in workingOrderRow.GetDestinationOrderRows()) { destinationOrderRow.AcquireReaderLock(dataModelTransaction); destinationOrderQuantity += destinationOrderRow.OrderedQuantity; } return(destinationOrderQuantity); }
/// <summary> /// Handles a change to a error state. /// </summary> /// <param name="workingOrderRow">The parent working order.</param> static void OnClearErrorAction(DataModel.WorkingOrderRow workingOrderRow) { // A transaction is needed to handle the change. DataModelTransaction dataModelTransaction = DataModel.CurrentTransaction; // This will lock the WorkingOrderRow while we examine it. workingOrderRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout); dataModelTransaction.AddLock(workingOrderRow); if (workingOrderRow.RowState == DataRowState.Detached) { return; } // The error status is cleared only when none of the sibling destination orders has an error. Boolean isErrorStatus = false; foreach (DataModel.DestinationOrderRow siblingOrderRow in workingOrderRow.GetDestinationOrderRows()) { siblingOrderRow.AcquireReaderLock(dataModelTransaction); if (siblingOrderRow.StatusCode == StatusCode.Error) { isErrorStatus = true; break; } } // If none of the siblings has an error, the we're going to set the working order's status to what it was before the error occurred. if (!isErrorStatus) { Decimal quantityExecuted = WorkingOrderService.GetExecutionQuantity(dataModelTransaction, workingOrderRow); Decimal quantityOrdered = WorkingOrderService.GetSourceOrderQuantity(dataModelTransaction, workingOrderRow); if (quantityExecuted == 0.0M && workingOrderRow.StatusCode != StatusCode.New) { WorkingOrderService.UpdateWorkingOrderStatus(workingOrderRow, StatusCode.New); } if (0.0M < quantityExecuted && quantityExecuted < quantityOrdered && workingOrderRow.StatusCode != StatusCode.PartiallyFilled) { WorkingOrderService.UpdateWorkingOrderStatus(workingOrderRow, StatusCode.PartiallyFilled); } if (quantityExecuted == quantityOrdered && workingOrderRow.StatusCode != StatusCode.Filled) { WorkingOrderService.UpdateWorkingOrderStatus(workingOrderRow, StatusCode.Filled); } } }
/// <summary> /// Updates the aggregates associated with an Execution. /// </summary> /// <param name="workingOrderRow">The working order to which the Execution belongs.</param> void UpdateExecutionQuantity(WorkingOrder workingOrder, DataModel.WorkingOrderRow workingOrderRow) { // Aggregate the execution and destination order quantities. Decimal executionQuantity = 0.0m; Decimal destinationOrderQuantity = 0.0m; foreach (DataModel.DestinationOrderRow destinationOrderRow in workingOrderRow.GetDestinationOrderRows()) { destinationOrderQuantity += (destinationOrderRow.OrderedQuantity - destinationOrderRow.CanceledQuantity); foreach (DataModel.ExecutionRow executionRow in destinationOrderRow.GetExecutionRows()) { executionQuantity += executionRow.ExecutionQuantity; } } // Update and commit the changes to the WorkingOrder record. this.workingOrderCollectionView.EditItem(workingOrder); workingOrder.ExecutionQuantity = executionQuantity; workingOrder.LeavesQuantity = destinationOrderQuantity - executionQuantity; this.workingOrderCollectionView.CommitEdit(); }
/// <summary> /// Gets the sum total of all the executions. /// </summary> /// <param name="dataModelTransaction">The data model transaction.</param> /// <param name="workingOrderRow">The working order row.</param> /// <returns>The aggregate quantity of executed orders for the specified working order.</returns> internal static Decimal GetExecutionQuantity(DataModelTransaction dataModelTransaction, DataModel.WorkingOrderRow workingOrderRow) { // Aggregate the executed orders. Decimal executionQuantity = 0.0m; foreach (DataModel.DestinationOrderRow destinationOrderRow in workingOrderRow.GetDestinationOrderRows()) { destinationOrderRow.AcquireReaderLock(dataModelTransaction); if (destinationOrderRow.StatusCode != StatusCode.Canceled) { foreach (DataModel.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> /// Copy the values from the data model. /// </summary> /// <param name="workingOrderRow">The data model row that is the source of the data.</param> public virtual void Copy(DataModel.WorkingOrderRow workingOrderRow) { // Validate the parameters. if (workingOrderRow == null) { throw new ArgumentNullException("workingOrderRow"); } // Find the price associated with the security in this order and copy. DataModel.PriceRow priceRow = DataModel.Price.PriceKey.Find( workingOrderRow.SecurityRowByFK_Security_WorkingOrder_SecurityId.SecurityId, workingOrderRow.SecurityRowByFK_Security_WorkingOrder_SettlementId.SecurityId); if (priceRow != null) { this.AskPrice.Price = priceRow.AskPrice; this.BidPrice.Price = priceRow.BidPrice; this.LastPrice.Price = priceRow.LastPrice; } // Any order that is not filled is considered active. this.IsActive = workingOrderRow.StatusRow.StatusCode != StatusCode.Filled; // Copy the scalar values directly from the data model. this.BlotterName = workingOrderRow.BlotterRow.EntityRow.Name; this.CreatedBy = workingOrderRow.UserRowByFK_User_WorkingOrder_CreatedUserId.EntityRow.Name; this.CreatedTime = workingOrderRow.CreatedTime; this.ModifiedBy = workingOrderRow.UserRowByFK_User_WorkingOrder_ModifiedUserId.EntityRow.Name; this.ModifiedTime = workingOrderRow.ModifiedTime; this.RowVersion = workingOrderRow.RowVersion; this.SecurityName = workingOrderRow.SecurityRowByFK_Security_WorkingOrder_SecurityId.EntityRow.Name; this.SideCode = workingOrderRow.SideRow.SideCode; this.SideMnemonic = workingOrderRow.SideRow.Mnemonic; this.SettlementDate = workingOrderRow.SettlementDate; this.StatusCode = workingOrderRow.StatusRow.StatusCode; this.Symbol = workingOrderRow.SecurityRowByFK_Security_WorkingOrder_SecurityId.Symbol; this.TradeDate = workingOrderRow.TradeDate; this.WorkingOrderId = workingOrderRow.WorkingOrderId; // These factors are needed to compute the proper quantities and prices. Decimal quantityFactor = workingOrderRow.SecurityRowByFK_Security_WorkingOrder_SecurityId.QuantityFactor; Decimal priceFactor = workingOrderRow.SecurityRowByFK_Security_WorkingOrder_SecurityId.PriceFactor; // Aggregate the Destiantion Order and Execution Quantities. Decimal destinationOrderQuantity = 0.0m; Decimal executionQuantity = 0.0m; foreach (DataModel.DestinationOrderRow destinationOrderRow in workingOrderRow.GetDestinationOrderRows()) { destinationOrderQuantity += destinationOrderRow.OrderedQuantity; foreach (DataModel.ExecutionRow executionRow in destinationOrderRow.GetExecutionRows()) { executionQuantity += executionRow.ExecutionQuantity; } } this.DestinationOrderQuantity = destinationOrderQuantity; this.ExecutionQuantity = executionQuantity; // Aggregate the Source Order Quantity. Decimal sourceOrderQuantity = 0.0m; foreach (DataModel.SourceOrderRow sourceOrderRow in workingOrderRow.GetSourceOrderRows()) { sourceOrderQuantity += sourceOrderRow.OrderedQuantity; } this.SourceOrderQuantity = sourceOrderQuantity; // These derived values must be calcualted after the value columns. this.AvailableQuantity = this.SourceOrderQuantity - this.DestinationOrderQuantity; this.MarketValue = sourceOrderQuantity * quantityFactor * this.LastPrice.Price * priceFactor; this.LeavesQuantity = this.DestinationOrderQuantity - this.ExecutionQuantity; }