Example #1
0
        /// <summary>
        /// Handles a change to the Price table.
        /// </summary>
        /// <param name="sender">The object that originated the event.</param>
        /// <param name="priceRowChangeEventArgs">The event arguments.</param>
        protected virtual void OnPriceRowChanged(Object sender, DataModel.PriceRowChangeEventArgs priceRowChangeEventArgs)
        {
            // Validate the parameters.
            if (sender == null)
            {
                throw new ArgumentNullException("sender");
            }
            if (priceRowChangeEventArgs == null)
            {
                throw new ArgumentNullException("priceRowChangeEventArgs");
            }

            // We're only interested in adds and changes.
            if (priceRowChangeEventArgs.Action == DataRowAction.Add || priceRowChangeEventArgs.Action == DataRowAction.Change)
            {
                // Select all the WorkingOrderRows that are related to the Securities that are related to the PriceRow that has changed.  We are looking for
                // changes to the price of items displayed in this blotter.
                DataModel.SecurityRow securityRow = priceRowChangeEventArgs.Row.SecurityRowByFK_Security_Price_SecurityId;
                var workingOrderRows = from workingOrderRow in securityRow.GetWorkingOrderRowsByFK_Security_WorkingOrder_SecurityId()
                                       select workingOrderRow;

                // Iterate through all the rows affected by the change to the Price row and update the properties related to the entity table.
                foreach (DataModel.WorkingOrderRow workingOrderRow in workingOrderRows)
                {
                    if (this.blotterIdSet.Contains(workingOrderRow.BlotterId))
                    {
                        // This will copy and commit the changes made to the Price row to the WorkingOrder record.
                        Int32 index = this.BinarySearch(order => order.WorkingOrderId, workingOrderRow.WorkingOrderId);
                        if (index >= 0)
                        {
                            // These factors are used display the market value using the notations provided for price and quantity.
                            Decimal quantityFactor = workingOrderRow.SecurityRowByFK_Security_WorkingOrder_SecurityId.QuantityFactor;
                            Decimal priceFactor    = workingOrderRow.SecurityRowByFK_Security_WorkingOrder_SecurityId.PriceFactor;

                            // This sets the prices and updates any field related to the prices.
                            TType workingOrder = this[index];
                            this.workingOrderCollectionView.EditItem(workingOrder);
                            workingOrder.AskPrice.Price  = priceRowChangeEventArgs.Row.AskPrice;
                            workingOrder.BidPrice.Price  = priceRowChangeEventArgs.Row.BidPrice;
                            workingOrder.LastPrice.Price = priceRowChangeEventArgs.Row.LastPrice;
                            workingOrder.MarketValue     = workingOrder.SourceOrderQuantity * quantityFactor * workingOrder.LastPrice.Price * priceFactor;
                            this.workingOrderCollectionView.CommitEdit();
                        }
                    }
                }
            }
        }
Example #2
0
        /// <summary>
        /// Copies the outline of a security position from the data model into the AppraisalSet.
        /// </summary>
        /// <param name="AccountId">AccountId of the position to search through.</param>
        /// <param name="SecurityId">SecurityId of the position to search through.</param>
        /// <param name="PositionTypeCode">Position Type Code of the position to search through.</param>
        /// <remarks>
        /// Table locks needed:
        ///		Read:	Security
        /// </remarks>
        protected void BuildSecurity(int AccountId, int SecurityId, int PositionTypeCode)
        {
            // See if the given security exists already in the table of security.  If this is the first time we've
            // encountered this security, we need to add it to the driver tables and then recursively search the hierarchy
            // and add every parent sector all the way up to the security classification scheme.  If we've run across it
            // already, we don't need to do anything related to the security.
            AppraisalSet.SecurityRow driverSecurity = this.Security.FindBySecurityId(SecurityId);
            if (driverSecurity == null)
            {
                // The AppraisalSet structure mirrors the structure of the MarketData.  We have a common 'object' table that
                // all object can use to navigate the tree structure.  When adding a new element to the data structure,
                // we need to add the object first to maintain integrity, then the security can be added.
                AppraisalSet.ObjectRow objectRow = this.Object.AddObjectRow(SecurityId);
                driverSecurity = this.Security.AddSecurityRow(objectRow);

                // Recursively search the hierarchy all the way up to the security classification scheme.  This will add
                // any elements of the hierarchy that are not already part of the outline.  Note that we first check to
                // see if the security belongs to the given security scheme before building the links.  This saves us from
                // having unused fragments of other security scheme in the outline.  This is useful when checking for
                // unclassified security.
                DataModel.SecurityRow securityRow = DataModel.Security.FindBySecurityId(SecurityId);
                if (IsObjectInScheme(securityRow.ObjectRow))
                {
                    BuildSector(securityRow.ObjectRow);
                    BuildScheme(securityRow.ObjectRow);
                }
            }

            // At this point, we know that the security and all the sector have been added to the outline.  Check to see
            // if the position -- that is, the combination of security and whether we own it or have borrowed it -- exist
            // in the outline.  Add the combination if it doesn't.
            AppraisalSet.PositionRow positionRow = this.Position.FindBySecurityIdPositionTypeCode(SecurityId, PositionTypeCode);
            if (positionRow == null)
            {
                positionRow = this.Position.AddPositionRow(driverSecurity, PositionTypeCode);
            }

            // Finally, at the bottom of the list, is the account level information.  This operation insures that only distinct account/position combinations
            // appear in the document.  This is very useful if the same account were to appear in different groups.
            AppraisalSet.AccountRow driverAccount = this.Account.FindByAccountIdSecurityIdPositionTypeCode(AccountId, SecurityId, PositionTypeCode);
            if (driverAccount == null)
            {
                driverAccount = this.Account.AddAccountRow(AccountId, SecurityId, PositionTypeCode);
            }
        }
Example #3
0
        /// <summary>
        /// Handles a change to the DestinationOrder table.
        /// </summary>
        /// <param name="sender">The object that originated the event.</param>
        /// <param name="e">The event data.</param>
        static void OnDestinationOrderRowChanged(object sender, DataModel.DestinationOrderRowChangeEventArgs e)
        {
            // This will turn new DestinationOrder records into orders that can be sent to a destination for execution.
            if (e.Action == DataRowAction.Add)
            {
                // The current transaction is going to be needed to lock records.
                DataModelTransaction dataModelTransaction = DataModel.CurrentTransaction;

                // Create a new message for the order we're going to build from the DestinationOrder.
                Message message = new Message();

                // The market execution engine will need to know the source firm so it knows how to route the order back.
                OrganizationPrincipal organizationPrincipal = Thread.CurrentPrincipal as OrganizationPrincipal;
                message.SenderCompID = organizationPrincipal.Organization;

                // Copy the basic properties of the DestinationOrder into the message.
                DataModel.DestinationOrderRow destinationOrderRow = e.Row;
                message.ClOrdID         = destinationOrderRow.DestinationOrderId.ToString();
                message.OrderQty        = destinationOrderRow.OrderedQuantity;
                message.OrdType         = destinationOrderRow.OrderTypeCode;
                message.SideCode        = destinationOrderRow.SideCode;
                message.TimeInForceCode = destinationOrderRow.TimeInForceCode;

                // Get the symbol to use as a security identifier.
                DataModel.SecurityRow securityRow = destinationOrderRow.SecurityRowByFK_Security_DestinationOrder_SecurityId;
                securityRow.AcquireReaderLock(dataModelTransaction.TransactionId, DataModel.LockTimeout);
                dataModelTransaction.AddLock(securityRow);
                if (securityRow.RowState == DataRowState.Detached)
                {
                    throw new FaultException <RecordNotFoundFault>(new RecordNotFoundFault("Security", new Object[] { destinationOrderRow.SecurityId }));
                }
                message.Symbol = securityRow.Symbol;

                // This will put the new order in a queue.  The DestinatonThread will pull it out, batch it up and send it to the destination to be executed.
                lock (MarketEngine.syncRoot)
                {
                    MarketEngine.messageQueue.Enqueue(message);
                    if (messageQueue.Count == 1)
                    {
                        MarketEngine.orderEvent.Set();
                    }
                }
            }
        }
Example #4
0
        public static int GetDefaultSettlementId(DataModel.SecurityRow securityRow)
        {
            // A settlement price is required to find the price of a security.  For many issues, the default can be found from
            // the defaults.  Others, such as currency transaction and exotic deals require an explicit settlement currency to
            // determine the price.
            foreach (DataModel.CurrencyRow currencyRow in securityRow.GetCurrencyRows())
            {
                return(currencyRow.CurrencyId);
            }
            foreach (DataModel.DebtRow debtRow in securityRow.GetDebtRowsByFKSecurityDebtDebtId())
            {
                return(debtRow.SettlementId);
            }
            foreach (DataModel.EquityRow equityRow in securityRow.GetEquityRowsByFKSecurityEquityEquityId())
            {
                return(equityRow.SettlementId);
            }

            // Failure to find a settlement currency is a serious matter.
            throw new Exception(String.Format("Security {0} has no settlement currecy.", securityRow.SecurityId));
        }
Example #5
0
        public static int GetDefaultSettlementId(int SecurityId)
        {
            try
            {
                // Lock the tables.
                Debug.Assert(!DataModel.IsLocked);
                DataModel.DebtLock.AcquireReaderLock(Timeout.Infinite);
                DataModel.EquityLock.AcquireReaderLock(Timeout.Infinite);
                DataModel.SecurityLock.AcquireReaderLock(Timeout.Infinite);

                // Make sure the security exists.  We need it to find the default settlement security.
                DataModel.SecurityRow securityRow = DataModel.Security.FindBySecurityId(SecurityId);
                if (securityRow == null)
                {
                    throw new Exception(String.Format("Security {0} doesn't exist", SecurityId));
                }

                // This version of the method assumes that the locks have been aquired.
                return(GetDefaultSettlementId(securityRow));
            }
            finally
            {
                // Release the table locks.
                if (DataModel.DebtLock.IsReaderLockHeld)
                {
                    DataModel.DebtLock.ReleaseReaderLock();
                }
                if (DataModel.EquityLock.IsReaderLockHeld)
                {
                    DataModel.EquityLock.ReleaseReaderLock();
                }
                if (DataModel.SecurityLock.IsReaderLockHeld)
                {
                    DataModel.SecurityLock.ReleaseReaderLock();
                }
                Debug.Assert(!DataModel.IsLocked);
            }
        }
Example #6
0
        public static int AutoRoute(DataModel.SecurityRow securityRow, decimal quantity)
        {
            // Use a blotter route for the security if it exists.
            foreach (DataModel.BlotterMapRow blotterMapRow in securityRow.GetBlotterMapRows())
            {
                if (blotterMapRow.MinimumQuantity <= quantity && (blotterMapRow.IsMaximumQuantityNull() ||
                                                                  quantity <= blotterMapRow.MaximumQuantity))
                {
                    return(blotterMapRow.BlotterId);
                }
            }

            // Return the default blotter.
            foreach (DataModel.BlotterRow blotterRow in DataModel.Blotter)
            {
                if (blotterRow.DefaultBlotter)
                {
                    return(blotterRow.BlotterId);
                }
            }

            throw new Exception("Default Blotter is not set.");
        }
Example #7
0
        /// <summary>
        /// Calculates the price of a security.
        /// </summary>
        /// <param name="baseCurrency">The demonimation of the price.</param>
        /// <param name="securityRow">The security to be priced.</param>
        /// <returns>The price of the security in the requested denomination.</returns>
        public static decimal Security(DataModel.CurrencyRow baseCurrency, DataModel.SecurityRow securityRow)
        {
            // Calculate the price of a Currency.
            foreach (DataModel.CurrencyRow currencyRow in securityRow.GetCurrencyRows())
            {
                return(Price.Currency(baseCurrency, currencyRow));
            }

            // Calculate the price of a Debt.
            foreach (DataModel.DebtRow debtRow in securityRow.GetDebtRowsByFKSecurityDebtDebtId())
            {
                return(Price.Debt(baseCurrency, debtRow));
            }

            // Calculate the price of an Equity.
            foreach (DataModel.EquityRow equityRow in securityRow.GetEquityRowsByFKSecurityEquityEquityId())
            {
                return(Price.Equity(baseCurrency, equityRow));
            }

            // If the security isn't one of the major securityType, then it can't be priced.
            return(0.0M);
        }
Example #8
0
        /// <summary>
        /// Create an debt working order.
        /// </summary>
        void CreateDebt()
        {
            // All orders get a unique identifier.
            Guid workingOrderId = Guid.NewGuid();

            // These records provide the starting point for generating the orders.
            DataModel.BlotterRow blotterRow      = DataModel.Blotter.BlotterKey.Find(generatorInfo.BlotterId);
            DataModel.UserRow    userRow         = DataModel.User.UserKey.Find(generatorInfo.UserId);
            DataModel.CountryRow unitedStatesRow = DataModel.Country.CountryKeyExternalId0.Find("US");
            DataModel.StatusRow  statusRow       = DataModel.Status.StatusKey.Find(StatusCode.New);

            // Generate the settlement currency
            DataModel.EntityRow   usdEntityRow          = DataModel.Entity.EntityKeyExternalId0.Find("USD");
            DataModel.SecurityRow settlementCurrencyRow = DataModel.Security.SecurityKey.Find(usdEntityRow.EntityId);

            // The orders are an even mix of Buys and Sells.  Most positions are long.
            Boolean  isBuy    = random.Next(2) == 0;
            Boolean  isLong   = random.Next(4) != 0;
            SideCode sideCode = isBuy && isLong ? SideCode.Buy : !isBuy && isLong ? SideCode.Sell : isBuy && !isLong ? SideCode.BuyCover : SideCode.SellShort;

            DataModel.SideRow sideRow = DataModel.Side.SideKey.Find(sideCode);

            // Find a random debt position that is unique to this blotter.
            DataModel.SecurityRow securityRow = null;
            while (securityRow == null)
            {
                // Select a random debt instrument for the next order.
                DataModel.DebtRow debtRow = DataModel.Debt[random.Next(DataModel.Debt.Count - 1)];

                // Only generate orders for positions that are unique to this blotter.
                Position position = new Position(debtRow.DebtId, sideCode);
                if (!positionSet.Contains(position))
                {
                    securityRow = debtRow.SecurityRowByFK_Security_Debt_DebtId;
                    positionSet.Add(position);
                }
            }

            // These orders will not match by default.  We need to turn them on manually.
            DataModel.CrossingRow crossingRow = DataModel.Crossing.CrossingKey.Find(CrossingCode.NeverMatch);

            // Select a random Time In Force for this order.  Most orders are Day orders but occationally we'll generate a GTC just to keep it interesting.
            TimeInForceCode timeInForce = random.Next(4) == 0 ? TimeInForceCode.GoodTillCancel : TimeInForceCode.Day;

            DataModel.TimeInForceRow timeInForceRow = DataModel.TimeInForce.TimeInForceKey.Find(timeInForce);

            // Generate the trade and settlement dates based on the current time and make sure it doesn't fall on a weekend.
            DateTime tradeDate      = DateTime.Now;
            DateTime settlementDate = DateTime.Now;
            TimeSpan oneDay         = TimeSpan.FromDays(1.0);

            for (Int32 dayIndex = 0; dayIndex < 3; dayIndex++)
            {
                settlementDate += oneDay;
                if (settlementDate.DayOfWeek == DayOfWeek.Saturday)
                {
                    settlementDate += oneDay;
                }
                if (settlementDate.DayOfWeek == DayOfWeek.Sunday)
                {
                    settlementDate += oneDay;
                }
            }

            // This will generate random matching preferences for the orders for demonstrating the matching box capabilities.
            Boolean isBrokerMatch      = random.Next(20) == 0;
            Boolean isHedgeMatch       = random.Next(15) == 0;
            Boolean isInstitutionMatch = true;

            // This randomizes the random matching patterns.  Every now and then, don't match with anyone.
            if (random.Next(5) == 0)
            {
                isBrokerMatch      = false;
                isHedgeMatch       = false;
                isInstitutionMatch = false;
            }

            //  <transaction>
            XElement elementTransaction = new XElement("transaction");

            this.xDocument.Root.Add(elementTransaction);

            //    <method name="StoreWorkingOrder">
            XElement elementWorkingOrder = new XElement("method", new XAttribute("name", "StoreWorkingOrder"));

            elementTransaction.Add(elementWorkingOrder);

            //      <parameter name="blotterKey" value="EMERGING MARKETS BLOTTER" />
            elementWorkingOrder.Add(
                new XElement("parameter",
                             new XAttribute("name", "blotterKey"),
                             new XAttribute("value", blotterRow.EntityRow.ExternalId0)));

            //      <parameter name="configurationId" value="US TICKER" />
            elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "configurationId"), new XAttribute("value", "CUSIP")));

            //      <parameter name="createdTime" value="5/6/2012 5:27:56 PM" />
            elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "createdTime"), new XAttribute("value", DateTime.Now.ToString("G"))));

            //      <parameter name="crossingKey" value="NEVER MATCH" />
            elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "crossingKey"), new XAttribute("value", crossingRow.ExternalId0)));

            //      <parameter name="externalId0" value="{bab88942-5c4e-440a-a352-c8e9b00fec12}" />
            elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "externalId0"), new XAttribute("value", workingOrderId.ToString("B"))));

            //      <parameter name="isBrokerMatch" value="false" />
            elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "isBrokerMatch"), new XAttribute("value", isBrokerMatch)));

            //      <parameter name="isHedgeMatch" value="false" />
            elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "isHedgeMatch"), new XAttribute("value", isHedgeMatch)));

            //      <parameter name="isInstitutionMatch" value="true" />
            elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "isInstitutionMatch"), new XAttribute("value", isInstitutionMatch)));

            //      <parameter name="modifiedTime" value="5/6/2012 5:27:56 PM" />
            elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "modifiedTime"), new XAttribute("value", DateTime.Now.ToString("G"))));

            //      <parameter name="orderTypeKey" value="MKT" />
            elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "orderTypeKey"), new XAttribute("value", "MKT")));

            //      <parameter name="securityKeyBySecurityId" value="ODP" />
            elementWorkingOrder.Add(
                new XElement("parameter",
                             new XAttribute("name", "securityKeyBySecurityId"),
                             new XAttribute("value", securityRow.EntityRow.ExternalId4)));

            //      <parameter name="securityKeyBySettlementId" value="USD" />
            elementWorkingOrder.Add(
                new XElement("parameter",
                             new XAttribute("name", "securityKeyBySettlementId"),
                             new XAttribute("value", settlementCurrencyRow.EntityRow.ExternalId0)));

            //      <parameter name="settlementDate" value="5/9/2012 5:27:56 PM" />
            elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "settlementDate"), new XAttribute("value", settlementDate.ToString("G"))));

            //      <parameter name="sideKey" value="SELL" />
            elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "sideKey"), new XAttribute("value", sideRow.ExternalId0)));

            //      <parameter name="statusKey" value="NEW" />
            elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "statusKey"), new XAttribute("value", statusRow.ExternalId0)));

            //      <parameter name="timeInForceKey" value="DAY" />
            elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "timeInForceKey"), new XAttribute("value", timeInForceRow.ExternalId0)));

            //      <parameter name="tradeDate" value="5/6/2012 5:27:56 PM" />
            elementWorkingOrder.Add(new XElement("parameter", new XAttribute("name", "tradeDate"), new XAttribute("value", tradeDate.ToString("G"))));

            //      <parameter name="userKeyByCreatedUserId" value="DEV KAPOOR" />
            elementWorkingOrder.Add(
                new XElement("parameter",
                             new XAttribute("name", "userKeyByCreatedUserId"),
                             new XAttribute("value", userRow.EntityRow.ExternalId0)));

            //      <parameter name="userKeyByModifiedUserId" value="DEV KAPOOR" />
            elementWorkingOrder.Add(
                new XElement("parameter",
                             new XAttribute("name", "userKeyByModifiedUserId"),
                             new XAttribute("value", userRow.EntityRow.ExternalId0)));

            // This will generate between one and three source orders for the working order.  Source orders are a blocking concept.  You can get several orders for
            // the same security on the same side for the same price.  When this happens, it is much more efficient to block them as a single order and execute them
            // as a single order and allocate them back to the original orders when the order is done.
            Int32 sourceOrderCount = random.Next(1, 3);

            for (Int32 sourceOrderIndex = 0; sourceOrderIndex < sourceOrderCount; sourceOrderIndex++)
            {
                // This creates a unique identifier for the source order.
                Guid sourceOrderId = Guid.NewGuid();

                // This generates a random quantity for the order between 100 and 10,000 shares.
                Decimal orderedQuantity = Convert.ToDecimal(random.Next(1, 100)) * 100.0M;

                //    <method name="StoreSourceOrder">
                XElement elementSourceOrder = new XElement("method", new XAttribute("name", "StoreSourceOrder"));
                elementTransaction.Add(elementSourceOrder);

                //      <parameter name="configurationId" value="US TICKER" />
                elementSourceOrder.Add(new XElement("parameter", new XAttribute("name", "configurationId"), new XAttribute("value", "CUSIP")));

                //      <parameter name="createdTime" value="2012-05-06T17:27:56.2658093-04:00" />
                elementSourceOrder.Add(new XElement("parameter", new XAttribute("name", "createdTime"), new XAttribute("value", DateTime.Now)));

                //      <parameter name="externalId0" value="{3c69e0a0-3316-4499-a7b1-6dda5a058837}" />
                elementSourceOrder.Add(new XElement("parameter", new XAttribute("name", "externalId0"), new XAttribute("value", sourceOrderId.ToString("B"))));

                //      <parameter name="modifiedTime" value="5/6/2012 5:27:56 PM" />
                elementSourceOrder.Add(new XElement("parameter", new XAttribute("name", "modifiedTime"), new XAttribute("value", DateTime.Now.ToString("G"))));

                //      <parameter name="orderedQuantity" value="4300.0" />
                elementSourceOrder.Add(new XElement("parameter", new XAttribute("name", "orderedQuantity"), new XAttribute("value", orderedQuantity)));

                //      <parameter name="orderTypeKey" value="MKT" />
                elementSourceOrder.Add(new XElement("parameter", new XAttribute("name", "orderTypeKey"), new XAttribute("value", "MKT")));

                //      <parameter name="securityKeyBySecurityId" value="ODP" />
                elementSourceOrder.Add(
                    new XElement("parameter",
                                 new XAttribute("name", "securityKeyBySecurityId"),
                                 new XAttribute("value", securityRow.EntityRow.ExternalId4)));

                //      <parameter name="securityKeyBySettlementId" value="USD" />
                elementSourceOrder.Add(
                    new XElement("parameter",
                                 new XAttribute("name", "securityKeyBySettlementId"),
                                 new XAttribute("value", settlementCurrencyRow.EntityRow.ExternalId0)));

                //      <parameter name="settlementDate" value="2012-05-09T17:27:56.2528086-04:00" />
                elementSourceOrder.Add(new XElement("parameter", new XAttribute("name", "settlementDate"), new XAttribute("value", settlementDate)));

                //      <parameter name="sideKey" value="SELL" />
                elementSourceOrder.Add(new XElement("parameter", new XAttribute("name", "sideKey"), new XAttribute("value", sideRow.ExternalId0)));

                //      <parameter name="statusKey" value="NEW" />
                elementSourceOrder.Add(new XElement("parameter", new XAttribute("name", "statusKey"), new XAttribute("value", statusRow.ExternalId0)));

                //      <parameter name="timeInForceKey" value="DAY" />
                elementSourceOrder.Add(
                    new XElement("parameter",
                                 new XAttribute("name", "timeInForceKey"),
                                 new XAttribute("value", timeInForceRow.ExternalId0)));

                //      <parameter name="tradeDate" value="5/6/2012 5:27:56 PM" />
                elementSourceOrder.Add(new XElement("parameter", new XAttribute("name", "tradeDate"), new XAttribute("value", tradeDate.ToString("G"))));

                //      <parameter name="userKeyByCreatedUserId" value="DEV KAPOOR" />
                elementSourceOrder.Add(
                    new XElement("parameter",
                                 new XAttribute("name", "userKeyByCreatedUserId"),
                                 new XAttribute("value", userRow.EntityRow.ExternalId0)));

                //      <parameter name="userKeyByModifiedUserId" value="DEV KAPOOR" />
                elementSourceOrder.Add(
                    new XElement("parameter",
                                 new XAttribute("name", "userKeyByModifiedUserId"),
                                 new XAttribute("value", userRow.EntityRow.ExternalId0)));

                //      <parameter name="workingOrderKey" value="{bab88942-5c4e-440a-a352-c8e9b00fec12}" />
                elementSourceOrder.Add(
                    new XElement("parameter",
                                 new XAttribute("name", "workingOrderKey"),
                                 new XAttribute("value", workingOrderId.ToString("B"))));
            }
        }
Example #9
0
        /// <summary>
        /// Calculates the market value of a position.
        /// </summary>
        /// <param name="baseCurrency">The base currency for the market value calculation.</param>
        /// <param name="accountRow">The identifier of the account.</param>
        /// <param name="SecurityId">The identifier of the security.</param>
        /// <param name="PositionTypeCode">The PositionTypeCode (long or short).</param>
        /// <param name="marketValueFlags">These flags direct what elements are included and whether to include
        /// children.</param>
        /// <returns></returns>
        public static decimal Calculate(DataModel.CurrencyRow baseCurrency, DataModel.AccountRow accountRow,
                                        DataModel.SecurityRow securityRow, int PositionTypeCode, MarketValueFlags marketValueFlags)
        {
            // This is the accumulator for market value.
            decimal marketValue = 0.0M;

            // Aggregate Tax Lots
            if ((marketValueFlags & MarketValueFlags.IncludeTaxLot) != 0)
            {
                foreach (DataModel.TaxLotRow taxLotRow in accountRow.GetTaxLotRows())
                {
                    if (taxLotRow.SecurityId == securityRow.SecurityId &&
                        taxLotRow.PositionTypeCode == PositionTypeCode)
                    {
                        marketValue += Calculate(baseCurrency, taxLotRow);
                    }
                }
            }

            // Aggregate Proposed Order
            if ((marketValueFlags & MarketValueFlags.IncludeProposedOrder) != 0)
            {
                foreach (DataModel.ProposedOrderRow proposedOrderRow in accountRow.GetProposedOrderRows())
                {
                    if (proposedOrderRow.SecurityId == securityRow.SecurityId &&
                        proposedOrderRow.PositionTypeCode == PositionTypeCode)
                    {
                        marketValue += Calculate(baseCurrency, proposedOrderRow);
                    }
                }
            }

            // Aggregate Order
            if ((marketValueFlags & MarketValueFlags.IncludeOrder) != 0)
            {
                foreach (DataModel.OrderRow SetPrice in accountRow.GetOrderRows())
                {
                    if (SetPrice.SecurityId == securityRow.SecurityId &&
                        SetPrice.PositionTypeCode == PositionTypeCode)
                    {
                        marketValue += Calculate(baseCurrency, SetPrice);
                    }
                }
            }

            // Aggregate Allocation
            if ((marketValueFlags & MarketValueFlags.IncludeAllocation) != 0)
            {
                foreach (DataModel.AllocationRow allocationRow in accountRow.GetAllocationRows())
                {
                    if (allocationRow.SecurityId == securityRow.SecurityId &&
                        allocationRow.PositionTypeCode == PositionTypeCode)
                    {
                        marketValue += Calculate(baseCurrency, allocationRow);
                    }
                }
            }

            // If sub-account are to be included, recurse into the account structures.
            if ((marketValueFlags & MarketValueFlags.IncludeChildAccounts) != 0)
            {
                foreach (DataModel.ObjectTreeRow objectTreeRow in
                         accountRow.ObjectRow.GetObjectTreeRowsByFKObjectObjectTreeParentId())
                {
                    foreach (DataModel.AccountRow childAccount in
                             objectTreeRow.ObjectRowByFKObjectObjectTreeChildId.GetAccountRows())
                    {
                        marketValue += Calculate(baseCurrency, childAccount, securityRow,
                                                 PositionTypeCode, marketValueFlags);
                    }
                }
            }

            // This is the market value of the given account/security/position combination.
            return(marketValue);
        }
Example #10
0
        /// <summary>
        /// Calculates the number of shares in a given position.
        /// </summary>
        /// <param name="baseCurrency">The base currency for the market value calculation.</param>
        /// <param name="AccountId">The identifier of the account.</param>
        /// <param name="SecurityId">The identifier of the security.</param>
        /// <param name="positionTypeCode">The PositionTypeCode (long or short).</param>
        /// <param name="quantityFlags">These flags direct what elements are included and whether to include
        /// children.</param>
        /// <returns></returns>
        public static decimal Calculate(DataModel.AccountRow accountRow, DataModel.SecurityRow securityRow,
                                        int positionTypeCode, MarketValueFlags quantityFlags)
        {
            // This is the accumulator for market value.
            decimal quantity = 0.0M;

            // This key is used to find records that match the given position.
            object[] key = new object[] { accountRow.AccountId, securityRow.SecurityId, positionTypeCode };

            // Aggregate Tax Lots
            if ((quantityFlags & MarketValueFlags.IncludeTaxLot) != 0)
            {
                foreach (DataRowView dataRowView in DataModel.TaxLot.UKTaxLotAccountIdSecurityIdPositionTypeCode.FindRows(key))
                {
                    quantity += ((DataModel.TaxLotRow)dataRowView.Row).Quantity;
                }
            }

            // Aggregate Proposed Order
            if ((quantityFlags & MarketValueFlags.IncludeProposedOrder) != 0)
            {
                foreach (DataRowView dataRowView in DataModel.ProposedOrder.UKProposedOrderAccountIdSecurityIdPositionTypeCode.FindRows(key))
                {
                    DataModel.ProposedOrderRow proposedProposedOrderRow = (DataModel.ProposedOrderRow)dataRowView.Row;
                    quantity += proposedProposedOrderRow.Quantity * proposedProposedOrderRow.TransactionTypeRow.QuantitySign;
                }
            }

            // Aggregate Order
            if ((quantityFlags & MarketValueFlags.IncludeOrder) != 0)
            {
                foreach (DataRowView dataRowView in DataModel.Order.UKOrderAccountIdSecurityIdPositionTypeCode.FindRows(key))
                {
                    DataModel.OrderRow orderRow = (DataModel.OrderRow)dataRowView.Row;
                    quantity += orderRow.Quantity * orderRow.TransactionTypeRow.QuantitySign;
                }
            }

            // Aggregate Allocation
            if ((quantityFlags & MarketValueFlags.IncludeAllocation) != 0)
            {
                foreach (DataRowView dataRowView in DataModel.Allocation.UKAllocationAccountIdSecurityIdPositionTypeCode.FindRows(key))
                {
                    DataModel.AllocationRow allocationRow = (DataModel.AllocationRow)dataRowView.Row;
                    quantity += allocationRow.Quantity * allocationRow.TransactionTypeRow.QuantitySign;
                }
            }

            // If sub-account are to be included, recurse into the account structures.
            if ((quantityFlags & MarketValueFlags.IncludeChildAccounts) != 0)
            {
                foreach (DataModel.ObjectTreeRow objectTreeRow in
                         accountRow.ObjectRow.GetObjectTreeRowsByFKObjectObjectTreeParentId())
                {
                    foreach (DataModel.AccountRow childAccount in
                             objectTreeRow.ObjectRowByFKObjectObjectTreeChildId.GetAccountRows())
                    {
                        quantity += Calculate(childAccount, securityRow, positionTypeCode, quantityFlags);
                    }
                }
            }

            // This is the market value of the given account/security/position combination.
            return(quantity);
        }
Example #11
0
        /// <summary>
        /// Calculates the quantity of child order for a given position
        /// </summary>
        /// <param name="AccountId">The identifier of the account.</param>
        /// <param name="SecurityId">The identifier of the security.</param>
        /// <param name="positionTypeCode">The positionTypeCode (long or short).</param>
        /// <returns>The quantity of the child proposedOrder.</returns>
        public static decimal CalculateChildProposedQuantity(DataModel.AccountRow accountRow, DataModel.SecurityRow securityRow,
                                                             int positionTypeCode)
        {
            // This is the accumulator for market value.
            decimal quantity = 0.0M;

            // Aggregate Proposed Order
            foreach (DataModel.ProposedOrderRow proposedOrderRow in accountRow.GetProposedOrderRows())
            {
                if (Relationship.IsChildProposedOrder(proposedOrderRow) &&
                    proposedOrderRow.SecurityId == securityRow.SecurityId &&
                    proposedOrderRow.PositionTypeCode == positionTypeCode)
                {
                    quantity += proposedOrderRow.Quantity * proposedOrderRow.TransactionTypeRow.QuantitySign;
                }
            }

            // If sub-account are to be included, recurse into the account structures.
            foreach (DataModel.ObjectTreeRow objectTreeRow in
                     accountRow.ObjectRow.GetObjectTreeRowsByFKObjectObjectTreeParentId())
            {
                foreach (DataModel.AccountRow childAccount in
                         objectTreeRow.ObjectRowByFKObjectObjectTreeChildId.GetAccountRows())
                {
                    quantity += CalculateChildProposedQuantity(childAccount, securityRow, positionTypeCode);
                }
            }

            // This is the market value of the given account/security/position combination.
            return(quantity);
        }
Example #12
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();
                    }
                }
            }
        }