Exemple #1
0
        /// <summary>
        /// Handles a Destination Order entering the error state.
        /// </summary>
        private static void SetErrorAction(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 Working Order reflects an 'Error' Status if any of its Destination Orders have an error.
            if (workingOrderRow.StatusId != StatusMap.FromCode(Status.Error))
            {
                UpdateWorkingOrderStatus(workingOrderRow, Status.Error);
            }
        }
Exemple #2
0
        /// <summary>
        /// Changes the state of the Working Order to reflect a filledly filled state.
        /// </summary>
        private static void OnFilledAction(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 on a Working Order cannot be cleared with a fill.
            if (workingOrderRow.StatusId != StatusMap.FromCode(Status.Error))
            {
                // The Working Order is 'Filled' when the quantity executed is the same as the quantity ordered.
                Decimal quantityOrdered  = WorkingOrder.GetSourceOrderQuantity(dataModelTransaction, workingOrderRow);
                Decimal quantityExecuted = WorkingOrder.GetExecutionQuantity(dataModelTransaction, workingOrderRow);
                if (quantityOrdered == quantityExecuted)
                {
                    UpdateWorkingOrderStatus(workingOrderRow, Status.Filled);
                }
            }
        }
Exemple #3
0
        /// <summary>
        /// Changes the state of the Working Order to reflect a partially filled status.
        /// </summary>
        private static void OnPartialAction(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 on a Working Order cannot be cleared with a partial fill.  Otherwise, a partial fill on any of the Destination Orders is
            // reflected in the status of the parent Working Order.
            if (workingOrderRow.StatusId != StatusMap.FromCode(Status.Error))
            {
                if (workingOrderRow.StatusId != StatusMap.FromCode(Status.PartiallyFilled))
                {
                    UpdateWorkingOrderStatus(workingOrderRow, Status.PartiallyFilled);
                }
            }
        }
Exemple #4
0
        /// <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>
        /// Delete a WorkingOrderRow.
        /// </summary>
        /// <param name="dataModel">The data model.</param>
        /// <param name="transaction">The current transaction.</param>
        /// <param name="workingOrderRow">The working order row to delete.</param>
        /// <returns>Error code of any failure, or Success.</returns>
        public ErrorCode DeleteRow(DataModel dataModel, DataModelTransaction transaction, WorkingOrderRow workingOrderRow)
        {
            SecurityRow securityRow       = null;
            EntityRow   securityEntityRow = null;

            MatchRow[]         matchRows;
            ConsumerDebtRow[]  consumerDebtRows;
            ConsumerTrustRow[] consumerTrustRows;
            CreditCardRow      creditCardRow = null;
            ConsumerRow        consumerRow   = null;
            Guid    blotterId;
            Guid    securityEntityId         = Guid.Empty;
            Int64   securityEntityRowVersion = 0;
            Guid    consumerId           = Guid.Empty;
            Int64   consumerRowVersion   = 0;
            Guid    creditCardId         = Guid.Empty;
            Int64   creditCardRowVersion = 0;
            Boolean consumerStillInUse   = false;

            workingOrderRow.AcquireWriterLock(transaction.TransactionId, DataModel.LockTimeout);
            if (workingOrderRow.RowState == DataRowState.Deleted ||
                workingOrderRow.RowState == DataRowState.Detached)
            {
                workingOrderRow.ReleaseLock(transaction.TransactionId);
                return(ErrorCode.RecordNotFound);
            }
            else
            {
                transaction.AddLock(workingOrderRow);
            }
            blotterId   = workingOrderRow.BlotterId;
            securityRow = workingOrderRow.SecurityRowByFK_Security_WorkingOrder_SecurityId;
            matchRows   = workingOrderRow.GetMatchRows();

            if (matchRows != null)
            {
                foreach (MatchRow matchRow in matchRows)
                {
                    if (IsSettled(transaction, matchRow))
                    {
                        return(ErrorCode.RecordExists);
                    }
                }
            }

            if (!DataModelFilters.HasAccess(transaction, TradingSupport.UserId, blotterId, AccessRight.Write))
            {
                workingOrderRow.ReleaseLock(transaction.TransactionId);
                return(ErrorCode.AccessDenied);
            }
            securityRow.AcquireWriterLock(transaction.TransactionId, DataModel.LockTimeout);
            if (securityRow.RowState == DataRowState.Deleted ||
                securityRow.RowState == DataRowState.Detached)
            {
                workingOrderRow.ReleaseLock(transaction.TransactionId);
                securityRow.ReleaseWriterLock(transaction.TransactionId);
                return(ErrorCode.RecordNotFound);
            }
            securityEntityRow = securityRow.EntityRow;
            consumerDebtRows  = securityRow.GetConsumerDebtRows();
            consumerTrustRows = securityRow.GetConsumerTrustRows();
            securityRow.ReleaseWriterLock(transaction.TransactionId);

            securityEntityRow.AcquireWriterLock(transaction);
            if (securityEntityRow.RowState == DataRowState.Deleted ||
                securityEntityRow.RowState == DataRowState.Detached)
            {
                workingOrderRow.ReleaseLock(transaction.TransactionId);
                securityEntityRow.ReleaseLock(transaction.TransactionId);
                return(ErrorCode.RecordNotFound);
            }
            securityEntityId         = securityEntityRow.EntityId;
            securityEntityRowVersion = securityEntityRow.RowVersion;
            securityEntityRow.ReleaseLock(transaction.TransactionId);

            if (consumerTrustRows.Length > 0 && consumerDebtRows.Length > 0)
            {
                EventLog.Warning("Deleting a working order associated with both ConsumerDebt and ConsumerTrust rows");
            }
            else if (consumerDebtRows.Length > 1)
            {
                EventLog.Warning("Deleting a working order associated with more than one ConsumerDebt row");
            }
            else if (consumerTrustRows.Length > 1)
            {
                EventLog.Warning("Deleting a working order associated with more than one ConsumerTrust row");
            }

            if (consumerDebtRows.Length == 1)
            {
                ConsumerDebtRow consumerDebtRow = consumerDebtRows[0];

                consumerDebtRow.AcquireWriterLock(transaction);
                if (consumerDebtRow.RowState == DataRowState.Deleted ||
                    consumerDebtRow.RowState == DataRowState.Detached)
                {
                }
                else
                {
                    creditCardRow = consumerDebtRow.CreditCardRow;
                    consumerRow   = consumerDebtRow.ConsumerRow;
                }
                consumerDebtRow.ReleaseLock(transaction.TransactionId);
            }
            else if (consumerTrustRows.Length == 1)
            {
                ConsumerTrustRow consumerTrustRow = consumerTrustRows[0];

                consumerTrustRow.AcquireWriterLock(transaction);
                if (consumerTrustRow.RowState == DataRowState.Deleted ||
                    consumerTrustRow.RowState == DataRowState.Detached)
                {
                }
                else
                {
                    consumerRow = consumerTrustRow.ConsumerRow;
                }
                consumerTrustRow.ReleaseLock(transaction.TransactionId);
            }

            if (consumerRow != null)
            {
                consumerRow.AcquireWriterLock(transaction);
                if (consumerRow.RowState == DataRowState.Deleted ||
                    consumerRow.RowState == DataRowState.Detached)
                {
                    consumerRow = null;
                }
                else
                {
                    consumerStillInUse = consumerRow.GetConsumerDebtRows().Length > 1;
                    consumerId         = consumerRow.ConsumerId;
                    consumerRowVersion = consumerRow.RowVersion;
                }
                consumerRow.ReleaseLock(transaction.TransactionId);
            }

            if (creditCardRow != null)
            {
                creditCardRow.AcquireWriterLock(transaction);
                if (creditCardRow.RowState == DataRowState.Deleted ||
                    creditCardRow.RowState == DataRowState.Detached)
                {
                    creditCardRow = null;
                }
                else
                {
                    creditCardId         = creditCardRow.ConsumerId;
                    creditCardRowVersion = creditCardRow.RowVersion;
                }
                creditCardRow.ReleaseLock(transaction.TransactionId);
            }

            //gonna get the lock on the workingOrder and let the txn commit/rollback get rid of it
            //this will basically wrap the delete row
            //action in a critical section because the first
            //reader lock in the method is on the workingOrder row
            //workingOrderRow.AcquireWriterLock(transaction.TransactionId, DataModel.LockTimeout);
            if (workingOrderRow.RowState == DataRowState.Deleted ||
                workingOrderRow.RowState == DataRowState.Detached)
            {
                workingOrderRow.ReleaseLock(transaction.TransactionId);
                return(ErrorCode.RecordNotFound);
            }
            //securityRow.AcquireWriterLock(transaction.TransactionId, DataModel.LockTimeout);
            //if(securityRow.RowState == DataRowState.Deleted ||
            //        securityRow.RowState == DataRowState.Detached)
            //{
            //    workingOrderRow.ReleaseLock(transaction.TransactionId);
            //    return ErrorCode.RecordNotFound;
            //}
            if (creditCardRow != null && consumerStillInUse)
            {
                dataModel.DestroyCreditCard(new object[] { creditCardId }, creditCardRowVersion);
            }
            if (consumerRow != null && !consumerStillInUse)
            {
                dataModel.DestroyConsumer(new object[] { consumerId }, consumerRowVersion);
            }

            dataModel.DestroyEntity(new object[] { securityEntityId }, securityEntityRowVersion);

            return(ErrorCode.Success);
        }
Exemple #6
0
        internal static void ClearDestinationOrders()
        {
            int batchCounter = 0;
            int batchSize    = 1000;

            DataModel dataModel = new DataModel();

            try
            {
                DataModel.DataLock.EnterReadLock();

                // This context is used to keep track of the locks aquired for the ancillary data.
                TransactionScope     transactionScope     = new TransactionScope();
                DataModelTransaction dataModelTransaction = DataModelTransaction.Current;

                List <ExecutionRow> executionRows = new List <ExecutionRow>();
                foreach (ExecutionRow executionRow in DataModel.Execution.Rows)
                {
                    executionRows.Add(executionRow);
                }

                // Destroy all the executions.
                foreach (ExecutionRow executionRow in executionRows)
                {
                    executionRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                    dataModelTransaction.AddLock(executionRow);
                    dataModel.DestroyExecution(new object[] { executionRow.ExecutionId }, executionRow.RowVersion);

                    if (batchCounter++ == batchSize)
                    {
                        batchCounter = 0;
                        transactionScope.Complete();
                        transactionScope.Dispose();
                        transactionScope     = new TransactionScope();
                        dataModelTransaction = DataModelTransaction.Current;
                    }
                }

                List <DestinationOrderRow> destinationOrderRows = new List <DestinationOrderRow>();
                foreach (DestinationOrderRow destinationOrderRow in DataModel.DestinationOrder.Rows)
                {
                    destinationOrderRows.Add(destinationOrderRow);
                }

                // Destroy all the Destination Orders.
                foreach (DestinationOrderRow destinationOrderRow in destinationOrderRows)
                {
                    destinationOrderRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                    dataModelTransaction.AddLock(destinationOrderRow);
                    dataModel.DestroyDestinationOrder(new object[] { destinationOrderRow.DestinationOrderId }, destinationOrderRow.RowVersion);

                    if (batchCounter++ == batchSize)
                    {
                        batchCounter = 0;
                        transactionScope.Complete();
                        transactionScope.Dispose();
                        transactionScope     = new TransactionScope();
                        dataModelTransaction = DataModelTransaction.Current;
                    }
                }

                transactionScope.Complete();
                transactionScope.Dispose();
            }
            finally
            {
                DataModel.DataLock.ExitReadLock();
            }
        }