Пример #1
0
        /// <summary>Inserts a Execution record.</summary>
        /// <param name="transaction">Commits or rejects a set of commands as a unit</param>
        /// <param name="blockOrderId">The value for the BlockOrderId column.</param>
        /// <param name="brokerId">The value for the BrokerId column.</param>
        /// <param name="rowVersion">The value for the RowVersion column.</param>
        /// <param name="quantity">The value for the Quantity column.</param>
        /// <param name="price">The value for the Price column.</param>
        /// <param name="commission">The value for the Commission column.</param>
        /// <param name="accruedInterest">The value for the AccruedInterest column.</param>
        /// <param name="userFee0">The value for the UserFee0 column.</param>
        /// <param name="userFee1">The value for the UserFee1 column.</param>
        /// <param name="userFee2">The value for the UserFee2 column.</param>
        /// <param name="userFee3">The value for the UserFee3 column.</param>
        /// <param name="tradeDate">The value for the TradeDate column.</param>
        /// <param name="settlementDate">The value for the SettlementDate column.</param>
        public static int Insert(
            Transaction transaction,
            int blockOrderId,
            int brokerId,
            ref long rowVersion,
            System.Decimal quantity,
            System.Decimal price,
            object commission,
            object accruedInterest,
            object userFee0,
            object userFee1,
            object userFee2,
            object userFee3,
            System.DateTime tradeDate,
            System.DateTime settlementDate)
        {
            // Provide the created time and current user id to the base class.
            int      createdLoginId = ServerMarketData.LoginId;
            DateTime createdTime    = DateTime.Now;

            // Rule #1: The block order exist.
            ServerMarketData.BlockOrderRow blockOrderRow = ServerMarketData.BlockOrder.FindByBlockOrderId(blockOrderId);
            if (blockOrderRow == null)
            {
                throw new Exception("This block order has been deleted by someone else");
            }

            // Rule #2: The Block Order is active
            if (blockOrderRow.StatusCode == Shadows.Quasar.Common.Status.Closed ||
                blockOrderRow.StatusCode == Shadows.Quasar.Common.Status.Confirmed ||
                blockOrderRow.StatusCode == Shadows.Quasar.Common.Status.Pending)
            {
                throw new Exception("This order isn't active");
            }

            // Rule #3: Quantity executed doesn't exceed the quantity ordered.
            decimal quantityOrdered = 0.0M;

            foreach (ServerMarketData.OrderRow orderSumRow in blockOrderRow.GetOrderRows())
            {
                quantityOrdered += orderSumRow.Quantity;
            }
            decimal quantityExecuted = 0.0M;

            foreach (ServerMarketData.ExecutionRow executionSumRow in blockOrderRow.GetExecutionRows())
            {
                quantityExecuted += executionSumRow.Quantity;
            }
            if (quantityExecuted + quantity > quantityOrdered)
            {
                throw new Exception("The quantity placed is more than the quantity ordered.");
            }

            // Call the base class to insert the execution.
            return(Shadows.WebService.Core.Execution.Insert(transaction, blockOrderId, brokerId, ref rowVersion, null, quantity, price,
                                                            commission, accruedInterest, userFee0, userFee1, userFee2, userFee3, tradeDate, settlementDate, createdTime,
                                                            createdLoginId, createdTime, createdLoginId));
        }
Пример #2
0
        /// <summary>
        /// This thread takes placements off the queue and creates orders in the local order book for them.
        /// </summary>
        private static void PlacementHandler()
        {
            while (true)
            {
                // Wait here for the next tick to come in.
                Broker.placementQueue.WaitOne();

                // Get the next placement from the queue.
                int placementId = Broker.placementQueue.Dequeue();

                try
                {
                    // Lock the tables.
                    Debug.Assert(!ServerMarketData.AreLocksHeld);
                    ServerMarketData.BlockOrderLock.AcquireReaderLock(Timeout.Infinite);
                    ServerMarketData.PlacementLock.AcquireReaderLock(Timeout.Infinite);

                    // Find the placement row.
                    ServerMarketData.PlacementRow placementRow = ServerMarketData.Placement.FindByPlacementId(placementId);
                    if (placementRow == null)
                    {
                        return;
                    }

                    // Information about the security is found in the block.  It isn't part of the placement so a BlockOrder
                    // record is needed to get some of the ancillary data.
                    ServerMarketData.BlockOrderRow blockOrderRow = placementRow.BlockOrderRow;

                    // The execution quantity needs to be calculated to prevent over execution when the simulator is
                    // restarted.  Count up the quantity executed against this placement.  While this calcuation isn't
                    // perfect -- it will miss when there are multiple placements to the same broker -- it is good enough for
                    // the simulator to restart itself.
                    decimal quantityExecuted = 0.0M;
                    foreach (ServerMarketData.ExecutionRow executionRow in blockOrderRow.GetExecutionRows())
                    {
                        if (executionRow.BrokerId == placementRow.BrokerId)
                        {
                            quantityExecuted += executionRow.Quantity;
                        }
                    }
                }
                catch (Exception exception)
                {
                    // Write the error and stack trace out to the debug listener
                    Debug.WriteLine(String.Format("{0}, {1}", exception.Message, exception.StackTrace));
                }
                finally
                {
                    // Release the global tables.
                    if (ServerMarketData.BlockOrderLock.IsReaderLockHeld)
                    {
                        ServerMarketData.BlockOrderLock.ReleaseReaderLock();
                    }
                    if (ServerMarketData.PlacementLock.IsReaderLockHeld)
                    {
                        ServerMarketData.PlacementLock.ReleaseReaderLock();
                    }
                    Debug.Assert(!ServerMarketData.AreLocksHeld);
                }
            }
        }
Пример #3
0
        /// <summary>
        /// This thread takes placements off the queue and creates orders in the local order book for them.
        /// </summary>
        private static void PlacementHandler()
        {
            while (true)
            {
                // Wait here for the next tick to come in.
                Broker.placementQueue.WaitOne();

                // Get the next placement from the queue.
                int placementId = Broker.placementQueue.Dequeue();

                try
                {
                    // Lock the Order Book.
                    Broker.orderBookLock.AcquireWriterLock(CommonTimeout.LockWait);

                    // Lock the tables.
                    Debug.Assert(!ServerMarketData.AreLocksHeld);
                    ServerMarketData.BlockOrderLock.AcquireReaderLock(Timeout.Infinite);
                    ServerMarketData.PlacementLock.AcquireReaderLock(Timeout.Infinite);

                    // Find the placement row.
                    ServerMarketData.PlacementRow placementRow = ServerMarketData.Placement.FindByPlacementId(placementId);
                    if (placementRow == null)
                    {
                        return;
                    }

                    // Information about the security is found in the block.  It isn't part of the placement so a BlockOrder
                    // record is needed to get some of the ancillary data.
                    ServerMarketData.BlockOrderRow blockOrderRow = placementRow.BlockOrderRow;

                    // The execution quantity needs to be calculated to prevent over execution when the simulator is
                    // restarted.  Count up the quantity executed against this placement.  While this calcuation isn't
                    // perfect -- it will miss when there are multiple placements to the same broker -- it is good enough for
                    // the simulator to restart itself.
                    decimal quantityExecuted = 0.0M;
                    foreach (ServerMarketData.ExecutionRow executionRow in blockOrderRow.GetExecutionRows())
                    {
                        if (executionRow.BrokerId == placementRow.BrokerId)
                        {
                            quantityExecuted += executionRow.Quantity;
                        }
                    }

                    // Create a new order book record and copy the data from the placement into the order.
                    OrderBook.OrderRow orderRow = Broker.orderBook.Order.NewOrderRow();
                    orderRow.BlockOrderId     = placementRow.BlockOrderId;
                    orderRow.BrokerId         = placementRow.BrokerId;
                    orderRow.SecurityId       = blockOrderRow.SecurityId;
                    orderRow.QuantityOrdered  = placementRow.Quantity;
                    orderRow.QuantityExecuted = quantityExecuted;
                    orderRow.TimeInForceCode  = placementRow.TimeInForceCode;
                    orderRow.OrderTypeCode    = placementRow.OrderTypeCode;
                    if (!placementRow.IsPrice1Null())
                    {
                        orderRow.Price1 = placementRow.Price1;
                    }
                    if (!placementRow.IsPrice2Null())
                    {
                        orderRow.Price2 = placementRow.Price2;
                    }

                    // Add the new record to the book and accept the changes.
                    Broker.orderBook.Order.AddOrderRow(orderRow);
                    orderRow.AcceptChanges();

                    // Signal to the execution thread that there are orders in the local book to be filled.
                    Broker.orderBookEvent.Set();
                }
                catch (Exception exception)
                {
                    // Write the error and stack trace out to the debug listener
                    Debug.WriteLine(String.Format("{0}, {1}", exception.Message, exception.StackTrace));
                }
                finally
                {
                    // Release the order book.
                    if (Broker.orderBookLock.IsWriterLockHeld)
                    {
                        Broker.orderBookLock.ReleaseWriterLock();
                    }

                    // Release the global tables.
                    if (ServerMarketData.BlockOrderLock.IsReaderLockHeld)
                    {
                        ServerMarketData.BlockOrderLock.ReleaseReaderLock();
                    }
                    if (ServerMarketData.PlacementLock.IsReaderLockHeld)
                    {
                        ServerMarketData.PlacementLock.ReleaseReaderLock();
                    }
                    Debug.Assert(!ServerMarketData.AreLocksHeld);
                }
            }
        }
Пример #4
0
        /// <summary>Updates a Execution record.</summary>
        /// <param name="transaction">Commits or rejects a set of commands as a unit</param>
        /// <param name="executionId">The value for the ExecutionId column.</param>
        /// <param name="blockOrderId">The value for the BlockOrderId column.</param>
        /// <param name="brokerId">The value for the BrokerId column.</param>
        /// <param name="rowVersion">The value for the RowVersion column.</param>
        /// <param name="quantity">The value for the Quantity column.</param>
        /// <param name="price">The value for the Price column.</param>
        /// <param name="commission">The value for the Commission column.</param>
        /// <param name="accruedInterest">The value for the AccruedInterest column.</param>
        /// <param name="userFee0">The value for the UserFee0 column.</param>
        /// <param name="userFee1">The value for the UserFee1 column.</param>
        /// <param name="userFee2">The value for the UserFee2 column.</param>
        /// <param name="userFee3">The value for the UserFee3 column.</param>
        /// <param name="tradeDate">The value for the TradeDate column.</param>
        /// <param name="settlementDate">The value for the SettlementDate column.</param>
        public static void Update(
            Transaction transaction,
            int executionId,
            object blockOrderId,
            object brokerId,
            ref long rowVersion,
            object quantity,
            object price,
            object commission,
            object accruedInterest,
            object userFee0,
            object userFee1,
            object userFee2,
            object userFee3,
            object tradeDate,
            object settlementDate)
        {
            // Provide the modified time and current user id to the base class.
            int      modifiedLoginId = ServerMarketData.LoginId;
            DateTime modifiedTime    = DateTime.Now;

            // Rule #1: Make sure the record exists before updating it.
            ServerMarketData.ExecutionRow executionRow = ServerMarketData.Execution.FindByExecutionId(executionId);
            if ((executionRow == null))
            {
                throw new Exception("This Execution has been deleted by someone else");
            }

            // Rule #2: The block order exist.
            ServerMarketData.BlockOrderRow blockOrderRow = ServerMarketData.BlockOrder.FindByBlockOrderId((int)blockOrderId);
            if (blockOrderRow == null)
            {
                throw new Exception("This block order has been deleted by someone else");
            }

            // Rule #3: The Block Order is active
            if (blockOrderRow.StatusCode == Shadows.Quasar.Common.Status.Closed ||
                blockOrderRow.StatusCode == Shadows.Quasar.Common.Status.Confirmed ||
                blockOrderRow.StatusCode == Shadows.Quasar.Common.Status.Pending)
            {
                throw new Exception("This order isn't active");
            }

            // Rule #4: Quantity executed doesn't exceed the quantity ordered.
            decimal quantityOrdered = 0.0M;

            foreach (ServerMarketData.OrderRow orderSumRow in blockOrderRow.GetOrderRows())
            {
                quantityOrdered += orderSumRow.Quantity;
            }
            decimal quantityPlaced = 0.0M;

            foreach (ServerMarketData.ExecutionRow executionSumRow in blockOrderRow.GetExecutionRows())
            {
                quantityPlaced += executionSumRow.Quantity;
            }
            if (quantityPlaced - executionRow.Quantity + (decimal)quantity > quantityOrdered)
            {
                throw new Exception("The quantity placed is more than the quantity ordered.");
            }

            // Call the base class to insert the execution.
            Shadows.WebService.Core.Execution.Update(transaction, executionId, blockOrderId, brokerId, ref rowVersion, null, quantity,
                                                     price, commission, accruedInterest, userFee0, userFee1, userFee2, userFee3, tradeDate, settlementDate, null, null,
                                                     modifiedTime, modifiedLoginId);
        }