Beispiel #1
0
        /// <summary>Inserts a Order 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="accountId">The value for the AccountId column.</param>
        /// <param name="securityId">The value for the SecurityId column.</param>
        /// <param name="settlementId">The value for the SettlementId column.</param>
        /// <param name="brokerId">The value for the BrokerId column.</param>
        /// <param name="transactionTypeCode">The value for the TransactionTypeCode column.</param>
        /// <param name="timeInForceCode">The value for the TimeInForceCode column.</param>
        /// <param name="orderTypeCode">The value for the OrderTypeCode column.</param>
        /// <param name="conditionCode">The value for the ConditionCode column.</param>
        /// <param name="rowVersion">The value for the RowVersion column.</param>
        /// <param name="isAgency">The value for the Agency column.</param>
        /// <param name="quantity">The value for the Quantity column.</param>
        /// <param name="price1">The value for the Price1 column.</param>
        /// <param name="price2">The value for the Price2 column.</param>
        /// <param name="note">The value for the Note column.</param>
        public static int Execute(
            Transaction transaction,
            int blockOrderId,
            int brokerId,
            int timeInForceCode,
            int orderTypeCode,
            object conditionCode,
            ref long rowVersion,
            decimal quantity,
            object price1,
            object price2)
        {
            // Find the destination blockOrder for the block order.
            ServerMarketData.BlockOrderRow blockOrderRow = ServerMarketData.BlockOrder.FindByBlockOrderId(blockOrderId);
            if (blockOrderRow == null)
            {
                throw new Exception(String.Format("BlockOrder {0} has been deleted.", blockOrderId));
            }

            bool     isRouted       = true;
            bool     isDeleted      = false;
            DateTime createdTime    = DateTime.Now;
            int      createdLoginId = ServerMarketData.LoginId;

            // If there is no blocking algorithm associated with this block order, then create a new block for every individual
            // order that hits the desk.
            return(Shadows.WebService.Core.Placement.Insert(transaction, blockOrderRow.BlockOrderId, brokerId, timeInForceCode,
                                                            orderTypeCode, ref rowVersion, isDeleted, isRouted, quantity, price1, price2, createdTime, createdLoginId, createdTime,
                                                            createdLoginId));
        }
Beispiel #2
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));
        }
Beispiel #3
0
        /// <summary>Updates a Placement record.</summary>
        /// <param name="transaction">Commits or rejects a set of commands as a unit</param>
        /// <param name="placementId">The value for the PlacementId column.</param>
        /// <param name="blockOrderId">The value for the BlockOrderId column.</param>
        /// <param name="brokerId">The value for the BrokerId column.</param>
        /// <param name="timeInForceCode">The value for the TimeInForceCode column.</param>
        /// <param name="orderTypeCode">The value for the OrderTypeCode column.</param>
        /// <param name="rowVersion">The value for the RowVersion column.</param>
        /// <param name="isRouted">The value for the IsRouted column.</param>
        /// <param name="quantity">The value for the Quantity column.</param>
        /// <param name="price1">The value for the Price1 column.</param>
        /// <param name="price2">The value for the Price2 column.</param>
        public static void Update(Transaction transaction, int placementId, object blockOrderId, object brokerId, object timeInForceCode, object orderTypeCode, ref long rowVersion, object isRouted, object quantity, object price1, object price2)
        {
            // These values are provided by the server.
            DateTime modifiedTime    = DateTime.Now;
            int      modifiedLoginId = ServerMarketData.LoginId;

            // Rule #1: Make sure the record exists before updating it.
            ServerMarketData.PlacementRow placementRow = ServerMarketData.Placement.FindByPlacementId(placementId);
            if ((placementRow == null))
            {
                throw new Exception("This Placement 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.PlacementRow placementSumRow in blockOrderRow.GetPlacementRows())
            {
                quantityPlaced += placementSumRow.Quantity;
            }
            if (quantityPlaced - placementRow.Quantity + (decimal)quantity > quantityOrdered)
            {
                throw new Exception("The quantity placed is more than the quantity ordered.");
            }

            // Call the primitive library to handle the rest of the operation.
            Shadows.WebService.Core.Placement.Update(transaction, placementId, blockOrderId, brokerId, timeInForceCode, orderTypeCode,
                                                     ref rowVersion, null, isRouted, quantity, price1, price2, null, null, modifiedTime, modifiedLoginId);
        }
Beispiel #4
0
        /// <summary>Inserts a Placement 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="timeInForceCode">The value for the TimeInForceCode column.</param>
        /// <param name="orderTypeCode">The value for the OrderTypeCode column.</param>
        /// <param name="rowVersion">The value for the RowVersion column.</param>
        /// <param name="isRouted">The value for the IsRouted column.</param>
        /// <param name="quantity">The value for the Quantity column.</param>
        /// <param name="price1">The value for the Price1 column.</param>
        /// <param name="price2">The value for the Price2 column.</param>
        /// <param name="createdTime">The value for the CreatedTime column.</param>
        /// <param name="createdLoginId">The value for the CreatedLoginId column.</param>
        /// <param name="modifiedTime">The value for the ModifiedTime column.</param>
        /// <param name="modifiedLoginId">The value for the ModifiedLoginId column.</param>
        public static int Insert(Transaction transaction, int blockOrderId, int brokerId, int timeInForceCode, int orderTypeCode, ref long rowVersion, object isRouted, System.Decimal quantity, object price1, object price2)
        {
            // Provide the created time and login identifier 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 quantityPlaced = 0.0M;

            foreach (ServerMarketData.PlacementRow placementSumRow in blockOrderRow.GetPlacementRows())
            {
                quantityPlaced += placementSumRow.Quantity;
            }
            if (quantityPlaced + quantity > quantityOrdered)
            {
                throw new Exception("The quantity placed is more than the quantity ordered.");
            }

            // Call the core class to complete the method.
            return(Shadows.WebService.Core.Placement.Insert(transaction, blockOrderId, brokerId, timeInForceCode, orderTypeCode,
                                                            ref rowVersion, null, isRouted, quantity, price1, price2, createdTime, createdLoginId, createdTime, createdLoginId));
        }
Beispiel #5
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);
                }
            }
        }
Beispiel #6
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);
                }
            }
        }
Beispiel #7
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);
        }