Example #1
0
        /// <summary>
        /// Creates one or more destination orders.
        /// </summary>
        /// <param name="destinationOrders"></param>
        internal static void CreateDestinationOrders(DestinationOrderInfo[] destinationOrders)
        {
            // An instance of the shared data model is required to use its methods.
            DataModel dataModel = new DataModel();

            // Business logic: provide the current time and the user identifier for the new destination order.
            DateTime dateTime = DateTime.UtcNow;
            Guid     userId   = TradingSupport.UserId;

            DataModelTransaction dataModelTransaction = DataModelTransaction.Current;

            StatusRow statusNewRow = DataModel.Status.StatusKeyStatusCode.Find(Status.New);

            statusNewRow.AcquireReaderLock(dataModelTransaction);

            StateRow stateIntialRow = DataModel.State.StateKeyStateCode.Find(State.Initial);

            stateIntialRow.AcquireReaderLock(dataModelTransaction);

            // The entire collection of destination orders is added or rejected as a single transaction.
            foreach (DestinationOrderInfo destinationOrderInfo in destinationOrders)
            {
                Guid destinationOrderId = Guid.NewGuid();
                dataModel.CreateDestinationOrder(
                    destinationOrderInfo.BlotterId,
                    0.0M,
                    null,
                    dateTime,
                    userId,
                    destinationOrderInfo.DestinationId,
                    destinationOrderId,
                    null,
                    null,
                    false,
                    false,
                    null,
                    dateTime,
                    userId,
                    destinationOrderInfo.OrderedQuantity,
                    destinationOrderInfo.OrderTypeId,
                    destinationOrderInfo.SecurityId,
                    dateTime,
                    destinationOrderInfo.SettlementId,
                    destinationOrderInfo.SideCodeId,
                    stateIntialRow.StateId,
                    statusNewRow.StatusId,
                    null,
                    destinationOrderInfo.TimeInForceCodeId,
                    dateTime,
                    null,
                    destinationOrderInfo.WorkingOrderId);
            }
        }
Example #2
0
        internal static void Accept(Guid matchId, Int64 rowVersion)
        {
            DataModel dataModel = new DataModel();

            try
            {
                DataModel.DataLock.EnterReadLock();

                MatchRow matchRow = DataModel.Match.MatchKey.Find(matchId);
                if (matchRow != null)
                {
                    // Time stamps and user stamps
                    Guid     createdUserId  = TradingSupport.UserId;
                    DateTime createdTime    = DateTime.UtcNow;
                    Guid     modifiedUserId = createdUserId;
                    DateTime modifiedTime   = createdTime;

                    // Call the internal method to complete the operation.
                    dataModel.UpdateMatch(null, null, null, null, null, null, null, new Object[] { matchRow.MatchId }, rowVersion, StatusMap.FromCode(Status.Accepted), null);

                    // This is the working order associated with the match.
                    WorkingOrderRow workingOrderRow = matchRow.WorkingOrderRow;

                    // This will find the contra order.
                    MatchRow contraMatchRow = DataModel.Match.MatchKeyWorkingOrderIdContraOrderId.Find(
                        matchRow.ContraOrderId,
                        matchRow.WorkingOrderId);
                    if (contraMatchRow == null)
                    {
                        throw new Exception(string.Format("Corruption: the match record for {0}, {1} can't be found", matchRow.ContraOrderId, matchRow.WorkingOrderId));
                    }

                    // When both sides have agreed to the match, the Destination Orders are generated.
                    if (contraMatchRow.StatusId != StatusMap.FromCode(Status.Accepted))
                    {
                        return;
                    }

                    // At this point, both sides have agreed to a trade.  This is the working order of the contra side of the trade.
                    WorkingOrderRow contraOrderRow = contraMatchRow.WorkingOrderRow;

                    // The quantity of this transaction is the lesser of the two sides of the trade.
                    decimal quantity = workingOrderRow.SubmittedQuantity < contraOrderRow.SubmittedQuantity ?
                                       workingOrderRow.SubmittedQuantity :
                                       contraOrderRow.SubmittedQuantity;

                    PriceRow priceRow = DataModel.Price.PriceKey.Find(workingOrderRow.SecurityId, workingOrderRow.SettlementId);
                    if (priceRow == null)
                    {
                        throw new Exception("The price of this trade can't be determined.");
                    }

                    Guid destinationOrderId = Guid.NewGuid();
                    dataModel.CreateDestinationOrder(
                        workingOrderRow.BlotterId,
                        null,
                        null,
                        createdTime,
                        createdUserId,
                        Match.destinationId,
                        destinationOrderId,
                        null,
                        null,
                        false,
                        false,
                        workingOrderRow[DataModel.WorkingOrder.LimitPriceColumn],
                        modifiedTime,
                        modifiedUserId,
                        quantity,
                        workingOrderRow.OrderTypeId,
                        workingOrderRow.SecurityId,
                        createdTime,
                        workingOrderRow.SettlementId,
                        workingOrderRow.SideId,
                        StateMap.FromCode(State.Acknowledged),
                        StatusMap.FromCode(Status.New),
                        workingOrderRow[DataModel.WorkingOrder.StopPriceColumn],
                        workingOrderRow.TimeInForceId,
                        createdTime,
                        createdUserId,
                        workingOrderRow.WorkingOrderId);

                    Guid executionId = Guid.NewGuid();
                    dataModel.CreateExecution(
                        0.0m,
                        workingOrderRow.BlotterId,
                        null,
                        null,
                        0.0m,
                        createdTime,
                        createdUserId,
                        destinationOrderId,
                        StateMap.FromCode(State.Acknowledged),
                        executionId,
                        priceRow.LastPrice,
                        quantity,
                        null,
                        null,
                        false,
                        modifiedTime,
                        modifiedUserId,
                        null,
                        null,
                        null,
                        null,
                        StateMap.FromCode(State.Sent),
                        null,
                        null,
                        null,
                        null);

                    dataModel.UpdateMatch(null, null, null, null, null, null, null, new Object[] { matchId }, matchRow.RowVersion, StatusMap.FromCode(Status.Accepted), null);

                    Guid contraDestinationOrderId = Guid.NewGuid();
                    dataModel.CreateDestinationOrder(
                        contraOrderRow.BlotterId,
                        0.0m,
                        null,
                        createdTime,
                        createdUserId,
                        Match.destinationId,
                        contraDestinationOrderId,
                        null,
                        null,
                        false,
                        false,
                        contraOrderRow[DataModel.WorkingOrder.LimitPriceColumn],
                        modifiedTime,
                        modifiedUserId,
                        quantity,
                        contraOrderRow.OrderTypeId,
                        contraOrderRow.SecurityId,
                        createdTime,
                        contraOrderRow.SettlementId,
                        contraOrderRow.SideId,
                        StateMap.FromCode(State.Acknowledged),
                        StatusMap.FromCode(Status.New),
                        contraOrderRow[DataModel.WorkingOrder.StopPriceColumn],
                        contraOrderRow.TimeInForceId,
                        createdTime,
                        createdUserId,
                        contraOrderRow.WorkingOrderId);

                    Guid contraExecutionId = Guid.NewGuid();
                    dataModel.CreateExecution(
                        0.0m,
                        contraOrderRow.BlotterId,
                        null,
                        null,
                        0.0m,
                        createdTime,
                        createdUserId,
                        contraDestinationOrderId,
                        StateMap.FromCode(State.Acknowledged),
                        contraExecutionId,
                        priceRow.LastPrice,
                        quantity,
                        null,
                        null,
                        false,
                        modifiedTime,
                        modifiedUserId,
                        null,
                        null,
                        null,
                        null,
                        StateMap.FromCode(State.Sent),
                        0.0m,
                        0.0m,
                        0.0m,
                        0.0m);
                }
            }
            finally
            {
                // Release the tables.
                DataModel.DataLock.ExitReadLock();
            }
        }
        /// <summary>Inserts a Negotiation record using Metadata Parameters.</summary>
        internal static void Offer(Guid matchId, Decimal quantity)
        {
            Guid      negotiationId = Guid.Empty;
            DataModel dataModel     = new DataModel();

            try
            {
                DataModel.DataLock.EnterReadLock();

                MatchRow matchRow = DataModel.Match.MatchKey.Find(matchId);
                if (matchRow != null)
                {
                    // Rule #1: Insure that there are no pending offers.
                    foreach (NegotiationRow innerNegotiationRow in matchRow.GetNegotiationRows())
                    {
                        if (innerNegotiationRow.StatusId == StatusMap.FromCode(Status.Pending))
                        {
                            throw new Exception("There is already an offer pending.");
                        }

                        if (innerNegotiationRow.StatusId == StatusMap.FromCode(Status.Declined))
                        {
                            throw new Exception("This offer has previously been declined.");
                        }
                    }

                    // Time stamps and user stamps
                    Guid     createdUserId  = TradingSupport.UserId;
                    DateTime createdTime    = DateTime.UtcNow;
                    Guid     modifiedUserId = TradingSupport.UserId;
                    DateTime modifiedTime   = createdTime;

                    // This will find the contra matching record.
                    MatchRow contraMatchRow = DataModel.Match.MatchKeyWorkingOrderIdContraOrderId.Find(
                        new Object[] { matchRow.ContraOrderId, matchRow.WorkingOrderId });
                    if (contraMatchRow == null)
                    {
                        throw new Exception(
                                  string.Format("Corruption: the match record for {0}, {1} can't be found", matchRow.ContraOrderId, matchRow.WorkingOrderId));
                    }

                    // This is the order on the other side of the match.
                    WorkingOrderRow contraWorkingOrderRow = contraMatchRow.WorkingOrderRow;

                    // When both sides have agreed to the Negotiation, the Destination Orders are generated.
                    NegotiationRow contraNegotiationRow = null;
                    foreach (NegotiationRow innerNegotiationRow in contraMatchRow.GetNegotiationRows())
                    {
                        if (innerNegotiationRow.StatusId == StatusMap.FromCode(Status.Pending))
                        {
                            contraNegotiationRow = innerNegotiationRow;
                            break;
                        }
                    }

                    // This means that there's an offer on the other side.
                    if (contraNegotiationRow == null)
                    {
                        // There is no opposite side of this transaction yet.  It will be placed in the negotation table and wait there
                        // until it times out, or the other side accepts the offer.
                        negotiationId = Guid.NewGuid();
                        dataModel.CreateNegotiation(
                            contraWorkingOrderRow.BlotterId,
                            null,
                            false,
                            contraMatchRow.MatchId,
                            negotiationId,
                            quantity,
                            StatusMap.FromCode(Status.Pending));
                    }
                    else
                    {
                        // At this point, there is an offer on both sides of the match for a follow-on order.  We'll create orders and
                        // executions for both sides of the trade for the minimum agreed upon quantity.
                        WorkingOrderRow workingOrderRow = matchRow.WorkingOrderRow;
                        WorkingOrderRow contraOrderRow  = contraNegotiationRow.MatchRow.WorkingOrderRow;

                        // The quantity of this negotiation will be the minimum of the two offers.
                        decimal matchedQuantity = quantity < contraNegotiationRow.Quantity ? quantity : contraNegotiationRow.Quantity;

                        // Create the order on this side of the trade.
                        Guid destinationOrderId = Guid.NewGuid();
                        dataModel.CreateDestinationOrder(
                            workingOrderRow.BlotterId,
                            null,
                            null,
                            createdTime,
                            createdUserId,
                            destinationId,
                            destinationOrderId,
                            null,
                            null,
                            null,
                            null,
                            workingOrderRow[DataModel.WorkingOrder.LimitPriceColumn],
                            modifiedTime,
                            modifiedUserId,
                            matchedQuantity,
                            workingOrderRow.OrderTypeId,
                            workingOrderRow.SecurityId,
                            modifiedTime,
                            workingOrderRow.SettlementId,
                            workingOrderRow.SideId,
                            StateMap.FromCode(State.Acknowledged),
                            StatusMap.FromCode(Status.New),
                            workingOrderRow[DataModel.WorkingOrder.StopPriceColumn],
                            workingOrderRow.TimeInForceId,
                            modifiedTime,
                            null,
                            workingOrderRow.WorkingOrderId);

                        // The the trade is executed at the current price.
                        PriceRow priceRow = DataModel.Price.PriceKey.Find(workingOrderRow.SecurityId, workingOrderRow.SettlementId);

                        // Create the Execution for this side of the trade.
                        Guid executionId = Guid.NewGuid();
                        dataModel.CreateExecution(
                            null,
                            workingOrderRow.BlotterId,
                            null,
                            null,
                            null,
                            createdTime,
                            createdUserId,
                            destinationOrderId,
                            StateMap.FromCode(State.Acknowledged),
                            executionId,
                            priceRow.LastPrice,
                            matchedQuantity,
                            null,
                            null,
                            null,
                            modifiedTime,
                            modifiedUserId,
                            null,
                            null,
                            null,
                            null,
                            StateMap.FromCode(State.Sent),
                            null,
                            null,
                            null,
                            null);

                        // There is no opposite side of this transaction yet.  It will be placed in the negotation table and wait there
                        // until it times out, or the other side accepts the offer.
                        negotiationId = Guid.NewGuid();
                        dataModel.CreateNegotiation(
                            workingOrderRow.BlotterId,
                            executionId,
                            false,
                            matchId,
                            negotiationId,
                            quantity,
                            StatusMap.FromCode(Status.Accepted));

                        // Create an order for the agreed upon quantity.
                        // Create the order on this side of the trade.
                        Guid contraDestinationOrderId = Guid.NewGuid();
                        dataModel.CreateDestinationOrder(
                            contraWorkingOrderRow.BlotterId,
                            null,
                            null,
                            createdTime,
                            createdUserId,
                            destinationId,
                            contraDestinationOrderId,
                            null,
                            null,
                            null,
                            null,
                            contraWorkingOrderRow[DataModel.WorkingOrder.LimitPriceColumn],
                            modifiedTime,
                            modifiedUserId,
                            matchedQuantity,
                            contraWorkingOrderRow.OrderTypeId,
                            contraWorkingOrderRow.SecurityId,
                            modifiedTime,
                            contraWorkingOrderRow.SettlementId,
                            contraWorkingOrderRow.SideId,
                            StateMap.FromCode(State.Acknowledged),
                            StatusMap.FromCode(Status.New),
                            contraWorkingOrderRow[DataModel.WorkingOrder.StopPriceColumn],
                            contraWorkingOrderRow.TimeInForceId,
                            modifiedTime,
                            null,
                            contraWorkingOrderRow.WorkingOrderId);

                        // Create the Execution for this side of the trade.
                        Guid contraExecutionId = Guid.NewGuid();
                        dataModel.CreateExecution(
                            null,
                            contraWorkingOrderRow.BlotterId,
                            null,
                            null,
                            null,
                            createdTime,
                            createdUserId,
                            contraDestinationOrderId,
                            StateMap.FromCode(State.Acknowledged),
                            contraExecutionId,
                            priceRow.LastPrice,
                            matchedQuantity,
                            null,
                            null,
                            null,
                            modifiedTime,
                            modifiedUserId,
                            null,
                            null,
                            null,
                            null,
                            StateMap.FromCode(State.Sent),
                            null,
                            null,
                            null,
                            null);

                        // Update the contra offer.
                        dataModel.UpdateNegotiation(
                            contraWorkingOrderRow.BlotterId,
                            contraExecutionId,
                            false,
                            null,
                            null,
                            new Object[] { contraNegotiationRow.NegotiationId },
                            null,
                            contraNegotiationRow.RowVersion,
                            StatusMap.FromCode(Status.Accepted));
                    }
                }
            }
            finally
            {
                // Release the tables.
                DataModel.DataLock.ExitReadLock();
            }
        }