Ejemplo n.º 1
0
        /// <summary>
        /// Handles a change to a filled state.
        /// </summary>
        /// <param name="workingOrderRow">The parent working order.</param>
        static void OnFilledAction(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;
            }

            // This will mark the working order as filled when the quantity executed is the same as the quantity ordered.  The only exception to this is when ng
            // the workiorder is in an error state.
            if (workingOrderRow.StatusCode != StatusCode.Error)
            {
                Decimal quantityOrdered  = WorkingOrderService.GetSourceOrderQuantity(dataModelTransaction, workingOrderRow);
                Decimal quantityExecuted = WorkingOrderService.GetExecutionQuantity(dataModelTransaction, workingOrderRow);
                if (quantityOrdered == quantityExecuted)
                {
                    WorkingOrderService.UpdateWorkingOrderStatus(workingOrderRow, StatusCode.Filled);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Handles a change to a cancelled state.
        /// </summary>
        /// <param name="workingOrderRow">The parent working order.</param>
        static void OnCanceledAction(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;
            }

            // When a destination order is canceled we will return the order to its previous state (as determined by aggregating the executed and destination
            // quantities).  The only exception to this is when the working order is in the error state.
            if (workingOrderRow.StatusCode != StatusCode.Error)
            {
                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);
                }
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Validates the source order row when it is deleted.
        /// </summary>
        /// <param name="sourceOrderRow">The source order row that was deleted.</param>
        static void OnSourceOrderDelete(DataModel.SourceOrderRow sourceOrderRow)
        {
            // We'll need to add several rows to the transaction as we validate the source order deletion.
            DataModelTransaction dataModelTransaction = DataModel.CurrentTransaction;

            // There is no implicit locking mechanism for deleted rows, so we need to lock the record manually as we access the parent working order of the deleted
            // source order.
            DataModel.WorkingOrderRow workingOrderRow = null;
            try
            {
                DataModel.DataLock.EnterReadLock();
                workingOrderRow = ((DataModel.WorkingOrderRow)(sourceOrderRow.GetParentRow(DataModel.SourceOrder.WorkingOrderSourceOrderRelation, DataRowVersion.Original)));
            }
            finally
            {
                DataModel.DataLock.ExitReadLock();
            }
            workingOrderRow.AcquireReaderLock(dataModelTransaction);

            // This will insure that the quantity ordered doesn't fall below the quantity placed with brokers and exchanges.
            Decimal sourceOrderQuantity      = WorkingOrderService.GetSourceOrderQuantity(dataModelTransaction, workingOrderRow);
            Decimal destinationOrderQuantity = WorkingOrderService.GetDestinationOrderQuantity(dataModelTransaction, workingOrderRow);

            if (sourceOrderQuantity < destinationOrderQuantity)
            {
                throw new FaultException <DestinationQuantityFault>(
                          new DestinationQuantityFault(workingOrderRow.WorkingOrderId, sourceOrderQuantity, destinationOrderQuantity));
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Validates the source order row when it changes.
        /// </summary>
        /// <param name="sourceOrderRow">The source order row that was changed.</param>
        static void OnSourceOrderChange(DataModel.SourceOrderRow sourceOrderRow)
        {
            // We can't allow the quantity of source order shares to drop below the quantity of destination order shares.  We only need to check for this condition
            // when the quantity of the source order record has changed.
            Decimal originalQuantity = (Decimal)sourceOrderRow[DataModel.SourceOrder.OrderedQuantityColumn, DataRowVersion.Original];
            Decimal currentQuantity  = (Decimal)sourceOrderRow[DataModel.SourceOrder.OrderedQuantityColumn, DataRowVersion.Current];

            if (originalQuantity < currentQuantity)
            {
                // We'll need to lock several records in order to check source order and destination order totals.
                DataModelTransaction dataModelTransaction = DataModel.CurrentTransaction;

                // Get the working order associated with this source order and lock it.
                DataModel.WorkingOrderRow workingOrderRow = sourceOrderRow.WorkingOrderRow;
                workingOrderRow.AcquireReaderLock(dataModelTransaction);

                // Now aggregate the source order quantities and the destination order quantities.  Throw an exception if the source orders are less than the
                // destination orders (we can't have less quantity ordered than we've placed with brokers and exchanges).
                Decimal sourceOrderQuantity      = WorkingOrderService.GetSourceOrderQuantity(dataModelTransaction, workingOrderRow);
                Decimal destinationOrderQuantity = WorkingOrderService.GetDestinationOrderQuantity(dataModelTransaction, workingOrderRow);
                if (sourceOrderQuantity < destinationOrderQuantity)
                {
                    throw new FaultException <DestinationQuantityFault>(
                              new DestinationQuantityFault(workingOrderRow.WorkingOrderId, sourceOrderQuantity, destinationOrderQuantity));
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Handles a change to the WorkingOrder row.
        /// </summary>
        /// <param name="sender">The object that originated the event.</param>
        /// <param name="workingOrderRowChangeEventArgs">The event arguments.</param>
        protected override void OnWorkingOrderRowChanged(Object sender, DataModel.WorkingOrderRowChangeEventArgs workingOrderRowChangeEventArgs)
        {
            // Validate the parameters.
            if (sender == null)
            {
                throw new ArgumentNullException("sender");
            }
            if (workingOrderRowChangeEventArgs == null)
            {
                throw new ArgumentNullException("workingOrderRowChangeEventArgs");
            }

            // If the new working order belongs to this blotter or one of its descendants, then add it in the proper place.
            if (workingOrderRowChangeEventArgs.Action == DataRowAction.Add)
            {
                DataModel.WorkingOrderRow workingOrderRow = workingOrderRowChangeEventArgs.Row;
                if (this.BlotterIdSet.Contains(workingOrderRow.BlotterId))
                {
                    Int32 index = this.BinarySearch(order => order.WorkingOrderId, workingOrderRow.WorkingOrderId);
                    this.Insert(~index, this.CreateInstanceCore(workingOrderRowChangeEventArgs.Row));
                }
            }

            // This will copy the modified elements from the data model into the collection and commit the changes.
            if (workingOrderRowChangeEventArgs.Action == DataRowAction.Change)
            {
                DataModel.WorkingOrderRow workingOrderRow = workingOrderRowChangeEventArgs.Row;
                if (this.BlotterIdSet.Contains(workingOrderRow.BlotterId))
                {
                    Int32 index = this.BinarySearch(order => order.WorkingOrderId, workingOrderRow.WorkingOrderId);
                    TType equityWorkingOrder = this[index];
                    this.View.EditItem(equityWorkingOrder);
                    equityWorkingOrder.IsActive           = workingOrderRow.StatusRow.StatusCode != StatusCode.Filled;
                    equityWorkingOrder.BlotterName        = workingOrderRow.BlotterRow.EntityRow.Name;
                    equityWorkingOrder.CreatedBy          = workingOrderRow.UserRowByFK_User_WorkingOrder_CreatedUserId.EntityRow.Name;
                    equityWorkingOrder.CreatedTime        = workingOrderRow.CreatedTime;
                    equityWorkingOrder.IsCrossing         = workingOrderRow.CrossingRow.CrossingCode == CrossingCode.AlwaysMatch;
                    equityWorkingOrder.IsBrokerMatch      = workingOrderRow.IsBrokerMatch;
                    equityWorkingOrder.IsHedgeMatch       = workingOrderRow.IsHedgeMatch;
                    equityWorkingOrder.IsInstitutionMatch = workingOrderRow.IsInstitutionMatch;
                    equityWorkingOrder.LimitPrice         = workingOrderRow.IsLimitPriceNull() ? 0.0M : workingOrderRow.LimitPrice;
                    equityWorkingOrder.ModifiedBy         = workingOrderRow.UserRowByFK_User_WorkingOrder_ModifiedUserId.EntityRow.Name;
                    equityWorkingOrder.ModifiedTime       = workingOrderRow.ModifiedTime;
                    equityWorkingOrder.RowVersion         = workingOrderRow.RowVersion;
                    equityWorkingOrder.OrderTypeMnemonic  = workingOrderRow.OrderTypeRow.Mnemonic;
                    equityWorkingOrder.OrderTypeCode      = workingOrderRow.OrderTypeRow.OrderTypeCode;
                    equityWorkingOrder.SecurityName       = workingOrderRow.SecurityRowByFK_Security_WorkingOrder_SecurityId.EntityRow.Name;
                    equityWorkingOrder.SettlementDate     = workingOrderRow.SettlementDate;
                    equityWorkingOrder.SideCode           = workingOrderRow.SideRow.SideCode;
                    equityWorkingOrder.SideMnemonic       = workingOrderRow.SideRow.Mnemonic;
                    equityWorkingOrder.StatusCode         = workingOrderRow.StatusRow.StatusCode;
                    equityWorkingOrder.StopPrice          = workingOrderRow.IsStopPriceNull() ? 0.0M : workingOrderRow.StopPrice;
                    equityWorkingOrder.Symbol             = workingOrderRow.SecurityRowByFK_Security_WorkingOrder_SecurityId.Symbol;
                    equityWorkingOrder.TimeInForceCode    = workingOrderRow.TimeInForceRow.TimeInForceCode;
                    equityWorkingOrder.TradeDate          = workingOrderRow.TradeDate;
                    equityWorkingOrder.WorkingOrderId     = workingOrderRow.WorkingOrderId;
                    this.View.CommitEdit();
                }
            }
        }
        /// <summary>
        /// Handles generic faults.
        /// </summary>
        /// <param name="workingOrders">The batch of Working Order updates.</param>
        /// <param name="batchFault">The generic FaultException.</param>
        void HandleFaultException(WebService.WorkingOrder[] workingOrders, FaultException faultException)
        {
            // This will try to make the generic faults less generic.  The same thing could have been accomplished with a 'Catch' clause but then we would have
            // needed a separate foreground handler for each kind of fault.  This will test to see if we had an 'InsufficientClaims' fault which will invoke a
            // specific message.
            FaultException <InsufficientClaimsFault> insufficientClaimsFault = faultException as FaultException <InsufficientClaimsFault>;

            if (insufficientClaimsFault != null)
            {
                // The user doesn't have the required permission to execute this method.
                MessageBox.Show(
                    Properties.Resources.InsufficientClaimsExceptionError,
                    Settings.Default.ApplicationName,
                    MessageBoxButton.OK,
                    MessageBoxImage.Error);
            }
            else
            {
                // Check to see if the record is busy.
                FaultException <OptimisticConcurrencyFault> optimisticConcurrencyFault = faultException as FaultException <OptimisticConcurrencyFault>;
                if (optimisticConcurrencyFault != null)
                {
                    // This record is busy - please try again later.
                    MessageBox.Show(
                        Properties.Resources.OptimisticConcurrencyExceptionError,
                        Settings.Default.ApplicationName,
                        MessageBoxButton.OK,
                        MessageBoxImage.Error);
                }
                else
                {
                    // If we haven't recognized what kind of fault was generated, then we'll just emit to the user whatever message came with this fault.
                    MessageBox.Show(faultException.Message, Settings.Default.ApplicationName, MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }

            // When the entire batch fails, we'll restore the entire Model View back to it's original state (the one it had before generating the batch).
            WorkingOrderCollection <EquityWorkingOrder> workingOrderCollection = this.equityWorkingOrderView.WorkingOrders;

            foreach (WebService.WorkingOrder workingOrder in workingOrders)
            {
                DataModel.WorkingOrderRow workingOrderRow = DataModel.WorkingOrder.WorkingOrderKey.Find(workingOrder.WorkingOrderId);
                Int32 index = workingOrderCollection.Find(workingOrderRow.WorkingOrderId);
                if (index >= 0)
                {
                    EquityWorkingOrder equityWorkingOrder = workingOrderCollection[index];
                    workingOrderCollection.View.EditItem(equityWorkingOrder);
                    equityWorkingOrder.IsBrokerMatch      = workingOrderRow.IsBrokerMatch;
                    equityWorkingOrder.IsHedgeMatch       = workingOrderRow.IsHedgeMatch;
                    equityWorkingOrder.IsInstitutionMatch = workingOrderRow.IsInstitutionMatch;
                    workingOrderCollection.View.CommitEdit();
                }
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Handler for validating Destination Order records.
        /// </summary>
        /// <param name="sender">The object that originated the event.</param>
        /// <param name="e">The event arguments.</param>
        static void OnDestinationOrderAdd(DataModel.DestinationOrderRow destinationOrderRow)
        {
            // A transaction is needed to handle the change.
            DataModelTransaction dataModelTransaction = DataModel.CurrentTransaction;

            DataModel.WorkingOrderRow workingOrderRow = destinationOrderRow.WorkingOrderRow;
            workingOrderRow.AcquireReaderLock(dataModelTransaction);

            Decimal sourceOrderQuantity      = WorkingOrderService.GetSourceOrderQuantity(dataModelTransaction, workingOrderRow);
            Decimal destinationOrderQuantity = WorkingOrderService.GetDestinationOrderQuantity(dataModelTransaction, workingOrderRow);

            if (sourceOrderQuantity < destinationOrderQuantity)
            {
                throw new FaultException <DestinationQuantityFault>(
                          new DestinationQuantityFault(workingOrderRow.WorkingOrderId, sourceOrderQuantity, destinationOrderQuantity));
            }
        }
Ejemplo n.º 8
0
        /// <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);
                }
            }
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Handler for validating Destination Order records.
        /// </summary>
        /// <param name="sender">The object that originated the event.</param>
        /// <param name="e">The event arguments.</param>
        static void OnDestinationOrderDelete(DataModel.DestinationOrderRow destinationOrderRow)
        {
            // A transaction is needed to handle the change.
            DataModelTransaction dataModelTransaction = DataModel.CurrentTransaction;

            // If the StatusCode of the destination order has changed then find the right handler for the state change and go execute the business logic for this
            // change.  The 'statusChangeMap' is a two dimensional Dictionary (hash table) using the previous and current states to find the right handler.  Note
            // that on a deletion, we don't have easy access to the original working order, so we need to extract it from the deleted record.
            StatusCode previousStatusCode = (StatusCode)destinationOrderRow[DataModel.DestinationOrder.StatusCodeColumn, DataRowVersion.Original];
            StatusCode currentStatusCode  = StatusCode.Deleted;
            Guid       workingOrderId     = (Guid)destinationOrderRow[DataModel.DestinationOrder.WorkingOrderIdColumn, DataRowVersion.Original];

            DataModel.WorkingOrderRow workingOrderRow = DataModel.WorkingOrder.WorkingOrderKey.Find(new Object[] { workingOrderId });
            if (workingOrderRow != null)
            {
                statusChangeMap[previousStatusCode][currentStatusCode](workingOrderRow);
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Handles a change to a error state.
        /// </summary>
        /// <param name="workingOrderRow">The parent working order.</param>
        static void OnSetErrorAction(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;
            }

            // This logic is simple enough, set to an error state if we're not already there.
            if (workingOrderRow.StatusCode != StatusCode.Error)
            {
                WorkingOrderService.UpdateWorkingOrderStatus(workingOrderRow, StatusCode.Error);
            }
        }
Ejemplo n.º 11
0
 /// <summary>
 /// Handles the deletion of a SourceOrder row.
 /// </summary>
 /// <param name="sender">The object that originated the event.</param>
 /// <param name="sourceOrderRowChangeEventArgs">The event arguments.</param>
 void OnSourceOrderRowDeleted(Object sender, DataModel.SourceOrderRowChangeEventArgs sourceOrderRowChangeEventArgs)
 {
     // We're only interested in deletes that affect the WorkingOrder records in this blotter.
     if (sourceOrderRowChangeEventArgs.Action == DataRowAction.Delete)
     {
         // Filtering requires a little more work with a deleted record.  We need to first find the original record and then look up the working order to
         // which it belonged.  We don't need to check for the existence of the working order as we know that this order was just deleted and, for it to have
         // existed in the first place, there must have been a working order.
         DataModel.SourceOrderRow sourceOrderRow = sourceOrderRowChangeEventArgs.Row;
         Guid workingOrderId = (Guid)sourceOrderRow[DataModel.SourceOrder.WorkingOrderIdColumn, DataRowVersion.Original];
         DataModel.WorkingOrderRow workingOrderRow = DataModel.WorkingOrder.WorkingOrderKey.Find(workingOrderId);
         if (this.blotterIdSet.Contains(workingOrderRow.BlotterId))
         {
             // Once the quantity has been removed from the totals, the percent ordered and executed can be updated.
             this.SourceOrderQuantity -= (Decimal)sourceOrderRow[DataModel.SourceOrder.OrderedQuantityColumn, DataRowVersion.Original];
             this.OrderedPercent       = this.SourceOrderQuantity == 0.0m ? 0.0 : Convert.ToDouble(this.DestinationOrderQuantity / this.SourceOrderQuantity);
         }
     }
 }
Ejemplo n.º 12
0
        /// <summary>
        /// Handles a change to a partially executed state.
        /// </summary>
        /// <param name="workingOrderRow">The parent working order.</param>
        static void OnPartialAction(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 working order is considered partially filled if any of its destination orders are partially filled.  The only exception to this is when the
            // working order is in an error state.
            if (workingOrderRow.StatusCode != StatusCode.Error && workingOrderRow.StatusCode != StatusCode.PartiallyFilled)
            {
                WorkingOrderService.UpdateWorkingOrderStatus(workingOrderRow, StatusCode.PartiallyFilled);
            }
        }
Ejemplo n.º 13
0
 /// <summary>
 /// Handles a change to the Execution row.
 /// </summary>
 /// <param name="sender">The object that originated the event.</param>
 /// <param name="executionRowChangeEventArgs">The event arguments.</param>
 void OnExecutionRowChanged(Object sender, DataModel.ExecutionRowChangeEventArgs executionRowChangeEventArgs)
 {
     // We're only interested in additions and changes that affect the WorkingOrder records in this blotter.
     if (executionRowChangeEventArgs.Action == DataRowAction.Add || executionRowChangeEventArgs.Action == DataRowAction.Change)
     {
         // This is designed to filter out all events that don't pertain to this blotter.
         DataModel.ExecutionRow        executionRow        = executionRowChangeEventArgs.Row;
         DataModel.DestinationOrderRow destinationOrderRow = executionRow.DestinationOrderRow;
         DataModel.WorkingOrderRow     workingOrderRow     = destinationOrderRow.WorkingOrderRow;
         if (this.blotterIdSet.Contains(workingOrderRow.BlotterId))
         {
             // Once the previous execution is subtracted and the current execution added to the totals we can calculate the percent executed.
             if (executionRow.HasVersion(DataRowVersion.Original))
             {
                 this.executionQuantityField -= (Decimal)executionRow[DataModel.Execution.ExecutionQuantityColumn, DataRowVersion.Original];
             }
             this.ExecutionQuantity += executionRow.ExecutionQuantity;
             this.ExecutedPercent    = this.DestinationOrderQuantity == 0.0m ? 0.0 : Convert.ToDouble(this.ExecutionQuantity / this.DestinationOrderQuantity);
         }
     }
 }
Ejemplo n.º 14
0
        /// <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 override void Copy(DataModel.WorkingOrderRow workingOrderRow)
        {
            // Validate the parameters.
            if (workingOrderRow == null)
            {
                throw new ArgumentNullException("workingOrderRow");
            }

            // Allow the base class to copy the core of the working order.
            base.Copy(workingOrderRow);

            // Copy the scalar that are specific to the Equity instruments directly from the data model.
            this.IsCrossing         = workingOrderRow.CrossingRow.CrossingCode == CrossingCode.AlwaysMatch;
            this.IsBrokerMatch      = workingOrderRow.IsBrokerMatch;
            this.IsHedgeMatch       = workingOrderRow.IsHedgeMatch;
            this.IsInstitutionMatch = workingOrderRow.IsInstitutionMatch;
            this.LimitPrice         = workingOrderRow.IsLimitPriceNull() ? 0.0M : workingOrderRow.LimitPrice;
            this.OrderTypeMnemonic  = workingOrderRow.OrderTypeRow.Mnemonic;
            this.OrderTypeCode      = workingOrderRow.OrderTypeRow.OrderTypeCode;
            this.StopPrice          = workingOrderRow.IsStopPriceNull() ? 0.0M : workingOrderRow.StopPrice;
            this.TimeInForceCode    = workingOrderRow.TimeInForceRow.TimeInForceCode;
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Handler for validating Destination Order records.
        /// </summary>
        /// <param name="sender">The object that originated the event.</param>
        /// <param name="e">The event arguments.</param>
        static void OnDestinationOrderChange(DataModel.DestinationOrderRow destinationOrderRow)
        {
            // A transaction is needed to handle the change.
            DataModelTransaction dataModelTransaction = DataModel.CurrentTransaction;

            // If the quantity has changed then we need to make sure that the quantity sent to a destination (broker, exchange, etc.) is not less than the amount
            // ordered.  That is, we can't accept a change that leaves us overcommited with a destination.
            Decimal originalQuantity = (Decimal)destinationOrderRow[DataModel.DestinationOrder.OrderedQuantityColumn, DataRowVersion.Original];
            Decimal currentQuantity  = (Decimal)destinationOrderRow[DataModel.DestinationOrder.OrderedQuantityColumn, DataRowVersion.Current];

            if (originalQuantity < currentQuantity)
            {
                // We need to aggregate at the working order, so we need to lock the working order while we do our sums.
                DataModel.WorkingOrderRow workingOrderRow = destinationOrderRow.WorkingOrderRow;
                workingOrderRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                dataModelTransaction.AddLock(workingOrderRow);

                // This will aggregate the source and destination orders and throw an exception if this transaction would leave us overcommitted with the
                // destination.
                Decimal sourceOrderQuantity      = WorkingOrderService.GetSourceOrderQuantity(dataModelTransaction, workingOrderRow);
                Decimal destinationOrderQuantity = WorkingOrderService.GetDestinationOrderQuantity(dataModelTransaction, workingOrderRow);
                if (sourceOrderQuantity < destinationOrderQuantity)
                {
                    throw new FaultException <DestinationQuantityFault>(
                              new DestinationQuantityFault(workingOrderRow.WorkingOrderId, sourceOrderQuantity, destinationOrderQuantity));
                }
            }

            // If the StatusCode of the destination order has changed then find the right handler for the state change and go execute the business logic for this
            // change.  The 'statusChangeMap' is a two dimensional Dictionary (hash table) using the previous and current states to find the right handler.
            StatusCode previousStatusCode = (StatusCode)destinationOrderRow[DataModel.DestinationOrder.StatusCodeColumn, DataRowVersion.Original];
            StatusCode currentStatusCode  = destinationOrderRow.StatusCode;

            if (previousStatusCode != currentStatusCode)
            {
                statusChangeMap[previousStatusCode][currentStatusCode](destinationOrderRow.WorkingOrderRow);
            }
        }
Ejemplo n.º 16
0
        /// <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 override void Copy(DataModel.WorkingOrderRow workingOrderRow)
        {
            // Validate the parameters.
            if (workingOrderRow == null)
            {
                throw new ArgumentNullException("workingOrderRow");
            }

            // Allow the base class to copy the core of the working order.
            base.Copy(workingOrderRow);

            // The working order requires information from the Debt Security being ordered.
            foreach (DataModel.DebtRow debtRow in workingOrderRow.SecurityRowByFK_Security_WorkingOrder_SecurityId.GetDebtRowsByFK_Security_Debt_DebtId())
            {
                // Copy the scalar that are specific to the Debt instruments directly from the data model.
                this.MaturityDate = debtRow == null ? DateTime.MinValue : debtRow.MaturityDate;

                foreach (DataModel.DebtAttributeRow debtAttributeRow in debtRow.GetDebtAttributeRows())
                {
                    this.BetaAdjustedKrd10Year = debtAttributeRow.BetaAdjustedKrd10Year;
                    this.BetaAdjustedKrd20Year = debtAttributeRow.BetaAdjustedKrd20Year;
                    this.BetaAdjustedKrd2Year  = debtAttributeRow.BetaAdjustedKrd2Year;
                    this.BetaAdjustedKrd30Year = debtAttributeRow.BetaAdjustedKrd30Year;
                    this.BetaAdjustedKrd5Year  = debtAttributeRow.BetaAdjustedKrd5Year;
                    this.BetaAdjustedKrd6Month = debtAttributeRow.BetaAdjustedKrd6Month;
                    this.Coupon             = debtAttributeRow.Coupon;
                    this.CreditRating0Value = debtAttributeRow.CreditRatingRowByFK_CreditRating_DebtAttribute_CreditRatingId0.Value;
                    this.CreditRating0Scale = debtAttributeRow.CreditRatingRowByFK_CreditRating_DebtAttribute_CreditRatingId0.Scale;
                    this.CreditRating1Value = debtAttributeRow.CreditRatingRowByFK_CreditRating_DebtAttribute_CreditRatingId1.Value;
                    this.CreditRating1Scale = debtAttributeRow.CreditRatingRowByFK_CreditRating_DebtAttribute_CreditRatingId1.Scale;
                    this.CreditRating2Value = debtAttributeRow.CreditRatingRowByFK_CreditRating_DebtAttribute_CreditRatingId2.Value;
                    this.CreditRating2Scale = debtAttributeRow.CreditRatingRowByFK_CreditRating_DebtAttribute_CreditRatingId2.Scale;
                    this.CurrentYield       = debtAttributeRow.CurrentYield;
                    this.MssaBucket         = debtAttributeRow.MssaBucketRow.Name;
                    this.SubordinateType    = debtAttributeRow.SubordinateTypeRow.Description;
                }
            }
        }
Ejemplo n.º 17
0
 /// <summary>
 /// Updates the status of the Working Order.
 /// </summary>
 /// <param name="workingOrderRow">The Working Order to be modified.</param>
 /// <param name="statusCode">The new status of the Working Order.</param>
 internal static void UpdateWorkingOrderStatus(DataModel.WorkingOrderRow workingOrderRow, StatusCode statusCode)
 {
     // This will update only the status on the working order.
     DataModel.TenantDataModel.UpdateWorkingOrder(
         null,
         null,
         null,
         null,
         null,
         null,
         null,
         null,
         null,
         null,
         null,
         null,
         null,
         null,
         null,
         null,
         workingOrderRow.RowVersion,
         null,
         null,
         null,
         null,
         null,
         statusCode,
         null,
         null,
         null,
         null,
         null,
         null,
         null,
         null,
         new Object[] { workingOrderRow.WorkingOrderId });
 }
Ejemplo n.º 18
0
        /// <summary>
        /// Handles a change to the WorkingOrder row.
        /// </summary>
        /// <param name="sender">The object that originated the event.</param>
        /// <param name="workingOrderRowChangeEventArgs">The event arguments.</param>
        void OnWorkingOrderRowChanged(Object sender, DataModel.WorkingOrderRowChangeEventArgs workingOrderRowChangeEventArgs)
        {
            // If the new working order belongs to this blotter or one of its descendants, then add it in the proper place.
            if (workingOrderRowChangeEventArgs.Action == DataRowAction.Add)
            {
                DataModel.WorkingOrderRow workingOrderRow = workingOrderRowChangeEventArgs.Row;
                if (this.blotterIdSet.Contains(workingOrderRow.BlotterId))
                {
                    this.WorkingOrderCount++;
                }
            }

            // This will handle changes to the working order.
            if (workingOrderRowChangeEventArgs.Action == DataRowAction.Change)
            {
                // This is designed to filter out all events that don't pertain to this blotter.
                DataModel.WorkingOrderRow workingOrderRow = workingOrderRowChangeEventArgs.Row;
                if (this.blotterIdSet.Contains(workingOrderRow.BlotterId))
                {
                    // In order to minimize the number of times we update a propertie that is bound to a visual control, we'll get copies of the current statistics
                    // and perform the updates on them.
                    Int32 filledOrderCount  = this.FilledOrderCount;
                    Int32 partialOrderCount = this.PartialOrderCount;
                    Int32 newOrderCount     = this.NewOrderCount;

                    // This will remove the previous status code (if there was a previous value) from the statistics.
                    if (workingOrderRow.HasVersion(DataRowVersion.Original))
                    {
                        StatusCode oldStatusCode = (StatusCode)workingOrderRow[DataModel.WorkingOrder.StatusCodeColumn, DataRowVersion.Original];
                        if (oldStatusCode == StatusCode.Filled)
                        {
                            filledOrderCount--;
                        }
                        if (oldStatusCode == StatusCode.PartiallyFilled)
                        {
                            partialOrderCount--;
                        }
                        if (oldStatusCode == StatusCode.New)
                        {
                            newOrderCount--;
                        }
                    }

                    // This will update the statistics with the current status of the working order.
                    StatusCode newStatusCode = workingOrderRow.StatusCode;
                    if (newStatusCode == StatusCode.Filled)
                    {
                        filledOrderCount++;
                    }
                    if (newStatusCode == StatusCode.PartiallyFilled)
                    {
                        partialOrderCount++;
                    }
                    if (newStatusCode == StatusCode.New)
                    {
                        newOrderCount++;
                    }

                    // We've updated all the statistics and can put them back into the properties tied to the metadata controls.
                    this.FilledOrderCount  = filledOrderCount;
                    this.PartialOrderCount = partialOrderCount;
                    this.NewOrderCount     = newOrderCount;
                }
            }
        }
Ejemplo n.º 19
0
 /// <summary>
 /// Do no action for the working order.
 /// </summary>
 /// <param name="workingOrderRow">The working order.</param>
 static void OnDoNothing(DataModel.WorkingOrderRow workingOrderRow)
 {
 }
Ejemplo n.º 20
0
        /// <summary>
        /// The sum total of the quantities of all the source 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 source orders associated with the working order.</returns>
        internal static Decimal GetSourceOrderQuantity(DataModelTransaction dataModelTransaction, DataModel.WorkingOrderRow workingOrderRow)
        {
            // This will aggregate all the source order quantities.  Note that the rows are kept locked for the duration of the transaction.  This guarantees
            // the integrity of the aggregate values.
            Decimal sourceOrderQuantity = 0.0m;

            foreach (DataModel.SourceOrderRow sourceOrderRow in workingOrderRow.GetSourceOrderRows())
            {
                try
                {
                    sourceOrderRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                    sourceOrderQuantity += sourceOrderRow.OrderedQuantity;
                }
                finally
                {
                    sourceOrderRow.ReleaseLock(dataModelTransaction.TransactionId);
                }
            }

            // This is the sum total of all the source orders in the given working order.
            return(sourceOrderQuantity);
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Creates orders in the simulated order book.
        /// </summary>
        private static void OrderHandler()
        {
            // This thread will create orders in the simulated order book from destination orders placed in the queue.  This thread
            // is necessary due to the locking architecture that prevents accessing the data model during a commit operation (which
            // is where the event indicating a new or changed destination order originates).
            while (MarketSimulator.IsBrokerSimulatorThreadRunning)
            {
                // This thread will wait here until a destination order is available in the queue.
                DataModel.DestinationOrderRow destinationOrderRow = MarketSimulator.orderQueue.Dequeue();

                // The code that adds an order to the simulated book must have exclusive access to the simulated data model.
                lock (MarketSimulator.syncRoot)
                {
                    // The primary data model needs to be accessed also for ancillary data associated with the new order.
                    using (TransactionScope transactionScope = new TransactionScope())
                    {
                        try
                        {
                            // This context is used to keep track of the locks aquired for the ancillary data.
                            DataModelTransaction dataModelTransaction = DataModel.CurrentTransaction;

                            // Lock the destination order.
                            destinationOrderRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                            dataModelTransaction.AddLock(destinationOrderRow);

                            // Lock the Security.
                            DataModel.SecurityRow securityRow = destinationOrderRow.SecurityRowByFK_Security_DestinationOrder_SecurityId;
                            securityRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                            dataModelTransaction.AddLock(securityRow);

                            // The working order row must be locked to examine the flags
                            DataModel.WorkingOrderRow workingOrderRow = destinationOrderRow.WorkingOrderRow;
                            workingOrderRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                            dataModelTransaction.AddLock(workingOrderRow);

                            // Lock the Entity.
                            DataModel.EntityRow entityRow = securityRow.EntityRow;
                            entityRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                            dataModelTransaction.AddLock(entityRow);

                            // Calculate the quantity executed on this order (some orders are created with executions, such as crossed orders.)
                            Decimal quantityExecuted = 0.0M;
                            foreach (DataModel.ExecutionRow executionRow in destinationOrderRow.GetExecutionRows())
                            {
                                executionRow.AcquireReaderLock(dataModelTransaction);
                                dataModelTransaction.AddLock(executionRow);
                                quantityExecuted += executionRow.ExecutionQuantity;
                            }

                            // The simulated order is added to the book.  This collects all the information required to simulate the execution of this order.
                            DataSetMarket.OrderRow orderRow = MarketSimulator.dataSetMarket.Order.NewOrderRow();
                            orderRow.BlotterId          = destinationOrderRow.BlotterId;
                            orderRow.DestinationOrderId = destinationOrderRow.DestinationOrderId;
                            orderRow.OrderTypeCode      = OrderTypeMap.FromId(destinationOrderRow.OrderTypeId);
                            orderRow.QuantityOrdered    = destinationOrderRow.OrderedQuantity;
                            orderRow.QuantityExecuted   = quantityExecuted;
                            orderRow.SideCode           = SideMap.FromId(destinationOrderRow.SideId);
                            orderRow.Symbol             = securityRow.Symbol;
                            orderRow.TimeInForceCode    = TimeInForceMap.FromId(destinationOrderRow.TimeInForceId);
                            MarketSimulator.dataSetMarket.Order.AddOrderRow(orderRow);

                            // Adding the first order to the simulated order book will enable the simulation thread to begin processing the orders.  The order
                            // simulation thread will continue until the book is filled.
                            if (MarketSimulator.dataSetMarket.Order.Count == 1)
                            {
                                MarketSimulator.orderEvent.Set();
                            }
                        }
                        catch { }

                        // The locks are no longer required.
                        transactionScope.Complete();
                    }
                }
            }
        }
Ejemplo n.º 22
0
        /// <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);
        }
Ejemplo n.º 23
0
        /// <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;
        }
Ejemplo n.º 24
0
 public WorkingOrder(DataModel.WorkingOrderRow workingOrderRow)
 {
     // The new instance is initialized with a copy of the data from the data model.
     this.Copy(workingOrderRow);
 }