示例#1
0
        /// <summary>
        /// Creates a proposed order record.
        /// </summary>
        /// <param name="proposedOrderRow">A proposed order record from the primary ADO database.</param>
        /// <returns>A ProposedOrder record based on the ADO record.</returns>
        internal static ProposedOrder Make(ClientMarketData.ProposedOrderRow proposedOrderRow)
        {
            // Initialize the object
            DataRowVersion dataRowVersion = proposedOrderRow.RowState == DataRowState.Deleted ? DataRowVersion.Original : DataRowVersion.Current;

            // Extract the data from the ADO record.
            int             proposedOrderId  = (int)proposedOrderRow[ClientMarketData.ProposedOrder.ProposedOrderIdColumn, dataRowVersion];
            TransactionType transactionType  = (TransactionType)proposedOrderRow[ClientMarketData.ProposedOrder.TransactionTypeCodeColumn, dataRowVersion];
            int             accountId        = (int)proposedOrderRow[ClientMarketData.ProposedOrder.AccountIdColumn, dataRowVersion];
            int             securityId       = (int)proposedOrderRow[ClientMarketData.ProposedOrder.SecurityIdColumn, dataRowVersion];
            int             positionTypeCode = Common.TransactionType.GetPosition((int)transactionType);
            Position        position         = Position.Make(accountId, securityId, positionTypeCode);
            TIF             tif      = (TIF)proposedOrderRow[ClientMarketData.ProposedOrder.TimeInForceCodeColumn, dataRowVersion];
            PricedAt        pricedAt = (PricedAt)proposedOrderRow[ClientMarketData.ProposedOrder.OrderTypeCodeColumn, dataRowVersion];
            decimal         quantity = (decimal)proposedOrderRow[ClientMarketData.ProposedOrder.QuantityColumn, dataRowVersion];
            object          price1   = proposedOrderRow[ClientMarketData.ProposedOrder.Price1Column, dataRowVersion];
            object          price2   = proposedOrderRow[ClientMarketData.ProposedOrder.Price2Column, dataRowVersion];

            // Create a new record based on the data extracted from the ADO database.
            return(new ProposedOrder(proposedOrderId, position, tif, pricedAt, quantity, price1, price2));
        }
示例#2
0
        /// <summary>
        /// Handles the primary Market Data events and passes the events along to the Langauge Primitives.
        /// </summary>
        /// <param name="sender">The object that originated the event.</param>
        /// <param name="proposedOrderRowChangeEvent">The record change event argument.</param>
        public static void ProposedOrderHandler(object sender, ClientMarketData.ProposedOrderRowChangeEvent proposedOrderRowChangeEvent)
        {
            // Extract the record from the event argument.
            ClientMarketData.ProposedOrderRow proposedOrderRow = proposedOrderRowChangeEvent.Row;

            // Translate the ADO.NET row states into a record state used by the Rules Engine.
            Action action = Action.Nothing;

            switch (proposedOrderRowChangeEvent.Action)
            {
            case DataRowAction.Add: action = Action.Add; break;

            case DataRowAction.Delete: action = Action.Delete; break;

            case DataRowAction.Change: action = Action.Change; break;

            case DataRowAction.Commit: return;
            }

            // Place the event into a list that will be processed when the tables are no longer locked.
            ProposedOrder.proposedOrderEventArgList.Add(new ProposedOrderEventArgs(action, ProposedOrder.Make(proposedOrderRow)));
        }
示例#3
0
        /// <summary>
        /// Recursively creates instructions to delete proposed order of the given position.
        /// </summary>
        /// <param name="remoteBatch">The object type containing the method to delete the order relationship.</param>
        /// <param name="remoteTransaction">Groups several commands into a unit for execution.</param>
        /// <param name="accountRow">An account record, used to select proposed order records.</param>
        private static void Delete(RemoteBatch remoteBatch, RemoteTransaction remoteTransaction,
                                   ClientMarketData.AccountRow accountRow, ClientMarketData.SecurityRow securityRow, int positionTypeCode)
        {
            // Run through each of the proposed orders in this account and create a record to have them deleted.
            object[] key = new object[] { accountRow.AccountId, securityRow.SecurityId, positionTypeCode };
            foreach (DataRowView dataRowView in
                     MarketData.ProposedOrder.UKProposedOrderAccountIdSecurityIdPositionTypeCode.FindRows(key))
            {
                // This is used to reference the current proposed order that matches the position criteria.
                ClientMarketData.ProposedOrderRow proposedOrderRow = (ClientMarketData.ProposedOrderRow)dataRowView.Row;

                // Child proposed orders aren't deleted directly, they can only be deleted when the parent is deleted.  The best
                // example of this is cash.  An account can have both child cash (related to an equity trade) or parent cash (cash
                // added directly to the account with no offsetting trade).  If a reqest is made to delete cash, only the parent
                // cash should be deleted.  The account will appear to have a cash balance until the equity attached to the child
                // cash is deleted.
                if (!Relationship.IsChildProposedOrder(proposedOrderRow))
                {
                    Delete(remoteBatch, remoteTransaction, proposedOrderRow);
                }
            }
        }
示例#4
0
        /// <summary>
        /// Creates a batch command to delete a proposed order and it's links.
        /// </summary>
        /// <param name="remoteBatch"></param>
        /// <param name="remoteTransaction"></param>
        /// <param name="parentProposedOrder"></param>
        public static void Delete(RemoteBatch remoteBatch, RemoteTransaction remoteTransaction,
                                  ClientMarketData.ProposedOrderRow parentProposedOrder)
        {
            // These define the assembly and the types within those assemblies that will be used to create the proposed orders on
            // the middle tier.
            RemoteAssembly remoteAssembly        = remoteBatch.Assemblies.Add("Service.Core");
            RemoteType     proposedOrderType     = remoteAssembly.Types.Add("Shadows.WebService.Core.ProposedOrder");
            RemoteType     proposedOrderTreeType = remoteAssembly.Types.Add("Shadows.WebService.Core.ProposedOrderTree");

            // Proposed orders have a hierarchy.  For example, orders for equities will be linked to
            foreach (ClientMarketData.ProposedOrderTreeRow proposedOrderTree in
                     parentProposedOrder.GetProposedOrderTreeRowsByFKProposedOrderProposedOrderTreeParentId())
            {
                // Create a command to delete the relationship between the parent and child.
                RemoteMethod deleteRelation = proposedOrderTreeType.Methods.Add("Delete");
                deleteRelation.Transaction = remoteTransaction;
                deleteRelation.Parameters.Add("rowVersion", proposedOrderTree.RowVersion);
                deleteRelation.Parameters.Add("parentId", proposedOrderTree.ParentId);
                deleteRelation.Parameters.Add("childId", proposedOrderTree.ChildId);

                // This relatioship will give us access to the child proposed order.
                ClientMarketData.ProposedOrderRow childProposedOrder =
                    proposedOrderTree.ProposedOrderRowByFKProposedOrderProposedOrderTreeChildId;

                // Create a command to delete the child proposed order.
                RemoteMethod deleteChild = proposedOrderType.Methods.Add("Delete");
                deleteChild.Transaction = remoteTransaction;
                deleteChild.Parameters.Add("rowVersion", childProposedOrder.RowVersion);
                deleteChild.Parameters.Add("proposedOrderId", childProposedOrder.ProposedOrderId);
            }

            // Create a command to delete the parent proposed order.
            RemoteMethod deleteParent = proposedOrderType.Methods.Add("Delete");

            deleteParent.Transaction = remoteTransaction;
            deleteParent.Parameters.Add("rowVersion", parentProposedOrder.RowVersion);
            deleteParent.Parameters.Add("proposedOrderId", parentProposedOrder.ProposedOrderId);
        }
示例#5
0
        /// <summary>
        /// Creates an element in the Appraisal Document that represents a fund's or account's position.
        /// </summary>
        /// <param name="appraisalDocument">The parent document.</param>
        /// <param name="driverAccount">Identifies the individual position at the account/security/position level.</param>
        public AccountElement(AppraisalDocument appraisalDocument, AppraisalSet.AccountRow driverAccount) :
            base("Account", appraisalDocument)
        {
            // Get the account record from the account id.  This record drives most of the data that appears in this element.
            ClientMarketData.AccountRow accountRow =
                ClientMarketData.Account.FindByAccountId(driverAccount.AccountId);

            // Count up the compliance violations
            int violationCount = 0;

            foreach (DataRowView dataRowView in
                     ClientMarketData.Violation.UKViolationAccountIdSecurityIdPositionTypeCode.FindRows(
                         new object[] { driverAccount.AccountId, driverAccount.SecurityId, driverAccount.PositionTypeCode }))
            {
                ClientMarketData.ViolationRow violationRow = (ClientMarketData.ViolationRow)dataRowView.Row;
                if (violationRow.RestrictionRow.Severity > 0)
                {
                    violationCount++;
                }
            }
            AddAttribute("Violation", violationCount);

            // Add the essential attributes to the element.
            AddAttribute("AccountId", accountRow.AccountId.ToString());

            // Aggregate the tax lot positions and cost.
            decimal taxLotQuantity = 0.0M;
            decimal taxLotCost     = 0.0M;

            foreach (ClientMarketData.TaxLotRow taxLotRow in accountRow.GetTaxLotRows())
            {
                if (taxLotRow.SecurityId == driverAccount.SecurityId &&
                    taxLotRow.PositionTypeCode == driverAccount.PositionTypeCode)
                {
                    taxLotQuantity += taxLotRow.Quantity;
                    taxLotCost     += taxLotRow.Cost * taxLotRow.Quantity;
                }
            }
            AddAttribute("TaxLotQuantity", taxLotQuantity.ToString());
            AddAttribute("TaxLotCost", taxLotCost.ToString());

            // Aggregate the proposed orders positions.
            decimal proposedOrderQuantity = 0.0M;

            foreach (DataRowView dataRowView in
                     appraisalDocument.proposedOrderView.FindRows(new object[] { driverAccount.AccountId, driverAccount.SecurityId,
                                                                                 driverAccount.PositionTypeCode }))
            {
                ClientMarketData.ProposedOrderRow proposedOrderRow = (ClientMarketData.ProposedOrderRow)dataRowView.Row;
                proposedOrderQuantity += proposedOrderRow.Quantity *
                                         proposedOrderRow.TransactionTypeRow.QuantitySign;
            }
            AddAttribute("ProposedOrderQuantity", proposedOrderQuantity.ToString());

            // Aggregate the orders.
            decimal orderQuantity = 0.0M;

            foreach (DataRowView dataRowView in
                     appraisalDocument.orderView.FindRows(new object[] { driverAccount.AccountId, driverAccount.SecurityId,
                                                                         driverAccount.PositionTypeCode }))
            {
                ClientMarketData.OrderRow orderRow = (ClientMarketData.OrderRow)dataRowView.Row;
                orderQuantity += orderRow.Quantity *
                                 orderRow.TransactionTypeRow.QuantitySign;
            }
            AddAttribute("OrderQuantity", orderQuantity.ToString());

            // Aggregate the allocations.
            decimal allocationQuantity = 0.0M;

            foreach (DataRowView dataRowView in
                     appraisalDocument.allocationView.FindRows(new object[] { driverAccount.AccountId, driverAccount.SecurityId,
                                                                              driverAccount.PositionTypeCode }))
            {
                ClientMarketData.AllocationRow allocationRow = (ClientMarketData.AllocationRow)dataRowView.Row;
                allocationQuantity += allocationRow.Quantity *
                                      allocationRow.TransactionTypeRow.QuantitySign;
            }
            AddAttribute("AllocationQuantity", allocationQuantity.ToString());
        }
示例#6
0
        /// <summary>
        /// Fills the OrderForm table with instructions to create, delete or update proposed orders.
        /// </summary>
        /// <param name="accountId">Identifiers the destination account of the proposed order.</param>
        /// <param name="securityId">Identifies the security being trade.</param>
        /// <param name="positionTypeCode">Identifies the long or short position of the trade.</param>
        /// <param name="settlementId"></param>
        /// <param name="proposedQuantity">The signed (relative) quantity of the trade.</param>
        public static void Create(RemoteBatch remoteBatch, RemoteTransaction remoteTransaction,
                                  ClientMarketData.AccountRow accountRow, ClientMarketData.SecurityRow securityRow, int positionTypeCode,
                                  decimal proposedQuantity)
        {
            // If the proposed quantity is to be zero, we'll delete all proposed orders for this position in the parent and
            // descendant accounts.  Otherwise, a command batch will be created to clear any child proposed orders and create or
            // update a proposed order for the parent account.
            if (proposedQuantity == 0.0M)
            {
                ProposedOrder.Delete(remoteBatch, remoteTransaction, accountRow, securityRow, positionTypeCode);
            }
            else
            {
                // The strategy here is to cycle through all the existing proposed orders looking for any that match the account
                // id, security id and position type of the new order.  If none is found, we create a new order. If one is found,
                // we modify it for the new quantity.  Any additional proposed orders are deleted.  This flag lets us know if any
                // existing proposed orders match the position attributes.
                bool firstTime = true;

                // Cycle through each of the proposed orders in the given account looking for a matching position.
                object[] key = new object[] { accountRow.AccountId, securityRow.SecurityId, positionTypeCode };
                foreach (DataRowView dataRowView in ClientMarketData.ProposedOrder.UKProposedOrderAccountIdSecurityIdPositionTypeCode.FindRows(key))
                {
                    // This is used to reference the current proposed order that matches the position criteria.
                    ClientMarketData.ProposedOrderRow parentProposedOrderRow = (ClientMarketData.ProposedOrderRow)dataRowView.Row;

                    // This check is provided for currency-like assets.  There may be many proposed orders for currency
                    // transactions that are used to settle other trades.  The user can also enter currency orders directly into
                    // the appraisal.  Any manual deposits or withdrawls should not impact settlement orders.  This check will skip
                    // any trade that is linked to another order.
                    if (Shadows.Quasar.Common.Relationship.IsChildProposedOrder(parentProposedOrderRow))
                    {
                        continue;
                    }

                    // Recycle the first proposed order that matches the position criteria.  Any additional proposed orders for the
                    // same account, security, position type will be deleted.
                    if (firstTime)
                    {
                        // Any proposed orders found after this one will be deleted.  This variable will also indicate that an
                        // existing proposed order was recycled.  After the loop is run on this position, a new order will be
                        // created if an existing order couldn't be recycled.
                        firstTime = false;

                        // Create the command to update this proposed order.
                        Update(remoteBatch, remoteTransaction, parentProposedOrderRow, proposedQuantity);
                    }
                    else
                    {
                        // Any order that isn't recycled is considered to be redundant.  That is, this order has been superceded by
                        // the recycled order.  Clearing any redundant orders makes the operation more intuitive: the user knows
                        // that the only order on the books is the one they entered.  They don't have to worry about artifacts from
                        // other operations.
                        Delete(remoteBatch, remoteTransaction, parentProposedOrderRow);
                    }
                }

                // This will create a new proposed order if an existing one couldn't be found above for recycling.
                if (firstTime == true)
                {
                    Insert(remoteBatch, remoteTransaction, accountRow, securityRow, positionTypeCode, proposedQuantity);
                }
            }
        }
示例#7
0
        private static void Update(RemoteBatch remoteBatch, RemoteTransaction remoteTransaction,
                                   ClientMarketData.ProposedOrderRow parentProposedOrder, decimal quantityInstruction)
        {
            // These define the assembly and the types within those assemblies that will be used to create the proposed orders on
            // the middle tier.
            RemoteAssembly remoteAssembly    = remoteBatch.Assemblies.Add("Service.Core");
            RemoteType     proposedOrderType = remoteAssembly.Types.Add("Shadows.WebService.Core.ProposedOrder");

            ClientMarketData.AccountRow  accountRow  = parentProposedOrder.AccountRow;
            ClientMarketData.SecurityRow securityRow = parentProposedOrder.SecurityRowByFKSecurityProposedOrderSecurityId;

            // This will turn the signed quantity into an absolute quantity and a transaction code (e.g. -1000 is turned into a
            // SELL of 1000 shares).
            decimal parentQuantity = Math.Abs(quantityInstruction);

            int parentTransactionTypeCode = TransactionType.Calculate(securityRow.SecurityTypeCode,
                                                                      parentProposedOrder.PositionTypeCode, quantityInstruction);

            // The time in force first comes from the user preferences, next, account settings and finally defaults to a day
            // orders.
            int timeInForceCode = !ClientPreferences.IsTimeInForceCodeNull() ? ClientPreferences.TimeInForceCode :
                                  !accountRow.IsTimeInForceCodeNull() ? accountRow.TimeInForceCode : TimeInForce.DAY;

            // The destination blotter comes first from the user preferences, second from the account preferences, and finally uses
            // the auto-routing logic.
            int blotterId = !ClientPreferences.IsBlotterIdNull() ? ClientPreferences.BlotterId :
                            !accountRow.IsBlotterIdNull() ? accountRow.BlotterId :
                            TradingSupport.AutoRoute(securityRow, parentQuantity);

            // Create a command to update the proposed order.
            RemoteMethod updateParent = proposedOrderType.Methods.Add("Update");

            updateParent.Transaction = remoteTransaction;
            updateParent.Parameters.Add("rowVersion", parentProposedOrder.RowVersion);
            updateParent.Parameters.Add("proposedOrderId", parentProposedOrder.ProposedOrderId);
            updateParent.Parameters.Add("accountId", parentProposedOrder.AccountId);
            updateParent.Parameters.Add("securityId", parentProposedOrder.SecurityId);
            updateParent.Parameters.Add("settlementId", parentProposedOrder.SettlementId);
            updateParent.Parameters.Add("blotterId", blotterId);
            updateParent.Parameters.Add("positionTypeCode", parentProposedOrder.PositionTypeCode);
            updateParent.Parameters.Add("transactionTypeCode", parentTransactionTypeCode);
            updateParent.Parameters.Add("timeInForceCode", timeInForceCode);
            updateParent.Parameters.Add("orderTypeCode", OrderType.Market);
            updateParent.Parameters.Add("quantity", parentQuantity);

            foreach (ClientMarketData.ProposedOrderTreeRow proposedOrderTree in
                     parentProposedOrder.GetProposedOrderTreeRowsByFKProposedOrderProposedOrderTreeParentId())
            {
                ClientMarketData.ProposedOrderRow childProposedOrder =
                    proposedOrderTree.ProposedOrderRowByFKProposedOrderProposedOrderTreeChildId;

                // If this is the settlement part of the order, then adjust the quantity.
                if (childProposedOrder.SecurityId == parentProposedOrder.SettlementId)
                {
                    // The settlement security is needed for the calculation of the cash impact of this trade.
                    ClientMarketData.CurrencyRow currencyRow =
                        MarketData.Currency.FindByCurrencyId(childProposedOrder.SettlementId);

                    decimal marketValue = parentQuantity * securityRow.QuantityFactor *
                                          Price.Security(currencyRow, securityRow) * securityRow.PriceFactor *
                                          TransactionType.GetCashSign(parentTransactionTypeCode);

                    decimal childQuantity = Math.Abs(marketValue);

                    int childTransactionTypeCode = TransactionType.Calculate(securityRow.SecurityTypeCode,
                                                                             parentProposedOrder.PositionTypeCode, marketValue);

                    // Create a command to update the proposed order.
                    RemoteMethod updateChild = proposedOrderType.Methods.Add("Update");
                    updateChild.Transaction = remoteTransaction;
                    updateChild.Parameters.Add("rowVersion", childProposedOrder.RowVersion);
                    updateChild.Parameters.Add("proposedOrderId", childProposedOrder.ProposedOrderId);
                    updateChild.Parameters.Add("accountId", childProposedOrder.AccountId);
                    updateChild.Parameters.Add("securityId", childProposedOrder.SecurityId);
                    updateChild.Parameters.Add("settlementId", childProposedOrder.SettlementId);
                    updateChild.Parameters.Add("blotterId", blotterId);
                    updateChild.Parameters.Add("positionTypeCode", parentProposedOrder.PositionTypeCode);
                    updateChild.Parameters.Add("transactionTypeCode", childTransactionTypeCode);
                    updateChild.Parameters.Add("timeInForceCode", timeInForceCode);
                    updateChild.Parameters.Add("orderTypeCode", OrderType.Market);
                    updateChild.Parameters.Add("quantity", childQuantity);
                }
            }
        }