Beispiel #1
0
        /// <summary>
        /// Creates an XML Element representing a blockOrder in a execution document.
        /// </summary>
        /// <param name="xmlDocument">The destination XML document.</param>
        /// <param name="blockOrderRow">A blockOrder record.</param>
        public BlockOrderElement(XmlDocument xmlDocument, ClientMarketData.BlockOrderRow blockOrderRow) : base("BlockOrder", xmlDocument)
        {
            // Add the attributes of a blockOrder to this record.
            AddAttribute("BlockOrderId", blockOrderRow.BlockOrderId.ToString());

            // If the security exists, add the basic data to the block information.
            ClientMarketData.SecurityRow securityRow = blockOrderRow.SecurityRowByFKSecurityBlockOrderSecurityId;
            AddAttribute("SecurityId", securityRow.SecurityId.ToString());
            AddAttribute("SecuritySymbol", securityRow.Symbol);
            AddAttribute("SecurityName", securityRow.ObjectRow.Name);

            // It's useful to have the transaction type so we know whether to add fees and commissions or subtract
            // them from the net calculations.
            AddAttribute("TransactionTypeCode", blockOrderRow.TransactionTypeCode.ToString());
            AddAttribute("TransactionTypeDescription", blockOrderRow.TransactionTypeRow.Description);

            decimal quantityOrdered = 0.0M;

            foreach (ClientMarketData.OrderRow orderRow in blockOrderRow.GetOrderRows())
            {
                quantityOrdered += orderRow.Quantity;
            }

            AddAttribute("QuantityOrdered", quantityOrdered.ToString());
        }
Beispiel #2
0
        protected void Initialize(ClientMarketData.SecurityRow securityRow)
        {
            // Initialize the base class.
            base.Initialize(securityRow.ObjectRow);

            // Find the default settlement security for equities.
            if (securityRow.SecurityTypeCode == Common.SecurityType.Debt)
            {
                foreach (ClientMarketData.DebtRow debtRow in securityRow.GetDebtRowsByFKSecurityDebtDebtId())
                {
                    this.settlementId = debtRow.SettlementId;
                }
            }

            // Find the default settlement security for equities.
            if (securityRow.SecurityTypeCode == Common.SecurityType.Equity)
            {
                foreach (ClientMarketData.EquityRow equityRow in securityRow.GetEquityRowsByFKSecurityEquityEquityId())
                {
                    this.settlementId = equityRow.SettlementId;
                }
            }

            // Initialize the record from the data model.
            this.securityTypeCode = securityRow.SecurityTypeCode;
            this.quantityFactor   = securityRow.QuantityFactor;
            this.priceFactor      = securityRow.PriceFactor;
            this.symbol           = securityRow.Symbol;
        }
Beispiel #3
0
        internal static Security Make(ClientMarketData.SecurityRow securityRow)
        {
            Security security = new Security();

            security.Initialize(securityRow);
            return(security);
        }
        /// <summary>
        /// Creates an XML Element representing a broker in a execution document.
        /// </summary>
        /// <param name="xmlDocument">The destination XML document.</param>
        /// <param name="blockOrderRow">A broker record.</param>
        public BlockOrderElement(XmlDocument xmlDocument, ClientMarketData.BlockOrderRow blockOrderRow) : base("BlockOrder", xmlDocument)
        {
            // The block order id is occationally useful info at the root element.
            AddAttribute("BlockOrderId", blockOrderRow.BlockOrderId);

            // It's useful to have the transaction type so we know whether to add fees and commissions or subtract
            // them from the net calculations.
            AddAttribute("TransactionTypeCode", blockOrderRow.TransactionTypeCode);

            // Get a shortcut to the security.
            ClientMarketData.SecurityRow securityRow = blockOrderRow.SecurityRowByFKSecurityBlockOrderSecurityId;

            // Add Fixed Income Fundamentals where they exist.
            foreach (ClientMarketData.DebtRow debtRow in securityRow.GetDebtRowsByFKSecurityDebtDebtId())
            {
                // Add the fundamental data for the debt.
                if (!debtRow.IsIssuerIdNull())
                {
                    AddAttribute("IssuerId", debtRow.IssuerId.ToString());
                }
                AddAttribute("DebtTypeCode", debtRow.DebtTypeCode.ToString());
                AddAttribute("Coupon", debtRow.Coupon.ToString());
                AddAttribute("MaturityDate", debtRow.MaturityDate.ToShortDateString());
            }
        }
Beispiel #5
0
        /// <summary>
        /// Initializes a Security.
        /// </summary>
        /// <param name="configurationId">Defines which external fields are used to identify an object.</param>
        /// <param name="securityId">The security identifier.</param>
        /// <returns>A security record, null if the identifier doesn't exist.</returns>
        protected override void Initialize(int securityId)
        {
            // Use the specified configuration to find the internal security identifier.
            ClientMarketData.SecurityRow securityRow = ClientMarketData.Security.FindBySecurityId(securityId);
            if (securityRow == null)
            {
                throw new Exception(String.Format("Security {0} doesn't exist", securityId));
            }

            Initialize(securityRow);
        }
Beispiel #6
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);
                }
            }
        }
        /// <summary>
        /// Notifies the user that a match opportunity exists.
        /// </summary>
        /// <param name="parameter">The thread initialization parameters.</param>
        private void NotifyUser(object parameter)
        {
            // Extract the thread parameters.
            int matchId = (int)parameter;

            // The symbol, title and the bitmap for the corporate logo will be retrieved from the data model in the code below.
            // They will be used to initialize the pop-up dialog after the locks on the data model have been released.
            string symbol = string.Empty;
            string title  = string.Empty;
            Bitmap logo   = null;

            try
            {
                // Lock the tables.
                System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked);
                ClientMarketData.MatchLock.AcquireReaderLock(ClientTimeout.LockWait);
                ClientMarketData.NegotiationLock.AcquireReaderLock(ClientTimeout.LockWait);
                ClientMarketData.OrderTypeLock.AcquireReaderLock(ClientTimeout.LockWait);
                ClientMarketData.SecurityLock.AcquireReaderLock(ClientTimeout.LockWait);
                ClientMarketData.WorkingOrderLock.AcquireReaderLock(ClientTimeout.LockWait);

                // The match record, working order, order type and security records are used to construct the title, symbol and
                // logo used by the notification window.
                ClientMarketData.MatchRow        matchRow        = ClientMarketData.Match.FindByMatchId(matchId);
                ClientMarketData.WorkingOrderRow workingOrderRow = matchRow.WorkingOrderRow;
                ClientMarketData.OrderTypeRow    orderTypeRow    = workingOrderRow.OrderTypeRow;
                ClientMarketData.SecurityRow     securityRow     = workingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId;

                // Get the security symbol.
                symbol = securityRow.Symbol;

                // Create a logo bitmap.
                if (!securityRow.IsLogoNull())
                {
                    MemoryStream memoryStream = new MemoryStream(Convert.FromBase64String(securityRow.Logo));
                    logo = new Bitmap(memoryStream);
                }

                // Construct the title for the notification window.
                title = string.Format("{0} of {1}", orderTypeRow.Description, symbol);
            }
            finally
            {
                // Release the locks.
                if (ClientMarketData.MatchLock.IsReaderLockHeld)
                {
                    ClientMarketData.MatchLock.ReleaseReaderLock();
                }
                if (ClientMarketData.NegotiationLock.IsReaderLockHeld)
                {
                    ClientMarketData.NegotiationLock.ReleaseReaderLock();
                }
                if (ClientMarketData.OrderTypeLock.IsReaderLockHeld)
                {
                    ClientMarketData.OrderTypeLock.ReleaseReaderLock();
                }
                if (ClientMarketData.SecurityLock.IsReaderLockHeld)
                {
                    ClientMarketData.SecurityLock.ReleaseReaderLock();
                }
                if (ClientMarketData.WorkingOrderLock.IsReaderLockHeld)
                {
                    ClientMarketData.WorkingOrderLock.ReleaseReaderLock();
                }
                System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked);
            }

            // The notification window looks and acts like the Microsoft Instant Messaging window.  It will pop up in the lower
            // right hand corner of the screen with a title, the corporate logo and a chance to either accept or decline the
            // opportunity for a match.
            NotificationWindow notificationWindow = new NotificationWindow();

            notificationWindow.MatchId        = matchId;
            notificationWindow.Symbol         = symbol;
            notificationWindow.Message        = title;
            notificationWindow.CompanyLogo    = logo;
            notificationWindow.Accept        += new MatchEventHandler(AcceptNegotiation);
            notificationWindow.Decline       += new MatchEventHandler(DeclineNegotiation);
            notificationWindow.ChangeOptions += new EventHandler(ChangeOptions);
            notificationWindow.Show();
        }
Beispiel #8
0
        internal static Position Make(int accountId, int securityId, int positionTypeCode)
        {
            Position position = new Position();

            ClientMarketData.AccountRow accountRow =
                ClientMarketData.Account.FindByAccountId(accountId);
            if (accountRow == null)
            {
                throw new Exception(string.Format("Account {0} doesn't exist", accountId));
            }

            ClientMarketData.SecurityRow securityRow =
                ClientMarketData.Security.FindBySecurityId(securityId);
            if (securityRow == null)
            {
                throw new Exception(string.Format("Security {0} doesn't exist", securityId));
            }

            // Look up the position record.
            ClientMarketData.PositionRow positionRow =
                ClientMarketData.Position.FindByAccountIdSecurityIdPositionTypeCode(accountId, securityId, positionTypeCode);

            // We can always create a position.  There may be no information associated with it, but it can be created just the
            // same.
            position.account      = Account.Make(accountId);
            position.security     = Security.Make(securityId);
            position.positionType = (PositionType)positionTypeCode;

            // If we have a record for the price/currency combination, then update it with the new price.
            if (positionRow != null)
            {
                if (!positionRow.IsUserData0Null())
                {
                    position.userData0 = positionRow.UserData0;
                }
                if (!positionRow.IsUserData1Null())
                {
                    position.userData1 = positionRow.UserData1;
                }
                if (!positionRow.IsUserData2Null())
                {
                    position.userData2 = positionRow.UserData2;
                }
                if (!positionRow.IsUserData3Null())
                {
                    position.userData3 = positionRow.UserData3;
                }
                if (!positionRow.IsUserData4Null())
                {
                    position.userData4 = positionRow.UserData4;
                }
                if (!positionRow.IsUserData5Null())
                {
                    position.userData5 = positionRow.UserData5;
                }
                if (!positionRow.IsUserData6Null())
                {
                    position.userData6 = positionRow.UserData6;
                }
                if (!positionRow.IsUserData7Null())
                {
                    position.userData7 = positionRow.UserData7;
                }
            }

            return(position);
        }
Beispiel #9
0
        public decimal GetMarketValue(Security security, int positionType)
        {
            try
            {
                // Lock the tables
                Debug.Assert(!ClientMarketData.AreLocksHeld);
                ClientMarketData.AccountLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.AllocationLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.CurrencyLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.DebtLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.EquityLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.ObjectLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.ObjectTreeLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.OrderLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.PriceLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.ProposedOrderLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.SectorLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.SecurityLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.TaxLotLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.TransactionTypeLock.AcquireReaderLock(CommonTimeout.LockWait);

                ClientMarketData.AccountRow  accountRow  = ClientMarketData.Account.FindByAccountId(this.AccountId);
                ClientMarketData.SecurityRow securityRow = ClientMarketData.Security.FindBySecurityId(security.SecurityId);
                return(Common.MarketValue.Calculate(accountRow.CurrencyRow, accountRow, securityRow, positionType,
                                                    MarketValueFlags.EntirePosition | MarketValueFlags.IncludeChildAccounts));
            }
            finally
            {
                // Release the table locks.
                if (ClientMarketData.AccountLock.IsReaderLockHeld)
                {
                    ClientMarketData.AccountLock.ReleaseReaderLock();
                }
                if (ClientMarketData.AllocationLock.IsReaderLockHeld)
                {
                    ClientMarketData.AllocationLock.ReleaseReaderLock();
                }
                if (ClientMarketData.CurrencyLock.IsReaderLockHeld)
                {
                    ClientMarketData.CurrencyLock.ReleaseReaderLock();
                }
                if (ClientMarketData.DebtLock.IsReaderLockHeld)
                {
                    ClientMarketData.DebtLock.ReleaseReaderLock();
                }
                if (ClientMarketData.EquityLock.IsReaderLockHeld)
                {
                    ClientMarketData.EquityLock.ReleaseReaderLock();
                }
                if (ClientMarketData.ObjectLock.IsReaderLockHeld)
                {
                    ClientMarketData.ObjectLock.ReleaseReaderLock();
                }
                if (ClientMarketData.ObjectTreeLock.IsReaderLockHeld)
                {
                    ClientMarketData.ObjectTreeLock.ReleaseReaderLock();
                }
                if (ClientMarketData.OrderLock.IsReaderLockHeld)
                {
                    ClientMarketData.OrderLock.ReleaseReaderLock();
                }
                if (ClientMarketData.PriceLock.IsReaderLockHeld)
                {
                    ClientMarketData.PriceLock.ReleaseReaderLock();
                }
                if (ClientMarketData.ProposedOrderLock.IsReaderLockHeld)
                {
                    ClientMarketData.ProposedOrderLock.ReleaseReaderLock();
                }
                if (ClientMarketData.SectorLock.IsReaderLockHeld)
                {
                    ClientMarketData.SectorLock.ReleaseReaderLock();
                }
                if (ClientMarketData.SecurityLock.IsReaderLockHeld)
                {
                    ClientMarketData.SecurityLock.ReleaseReaderLock();
                }
                if (ClientMarketData.TaxLotLock.IsReaderLockHeld)
                {
                    ClientMarketData.TaxLotLock.ReleaseReaderLock();
                }
                if (ClientMarketData.TransactionTypeLock.IsReaderLockHeld)
                {
                    ClientMarketData.TransactionTypeLock.ReleaseReaderLock();
                }
                Debug.Assert(!ClientMarketData.AreLocksHeld);
            }
        }
Beispiel #10
0
 /// <summary>
 /// Indicates if a given security is part of the document's security classification scheme.
 /// </summary>
 /// <param name="securityRow">A security to be tested.</param>
 /// <returns>True if the security belongs to the document's classification scheme.</returns>
 /// <remarks>
 /// Table locks needed:
 ///		Read:	ObjectTree
 ///		Read:	Objects
 /// </remarks>
 private bool IsSecurityInSector(ClientMarketData.SectorRow sectorRow, ClientMarketData.SecurityRow securityRow)
 {
     // Call the generic method to determine the relationship between the sector and the security.
     return(Shadows.Quasar.Common.Object.IsParent(sectorRow.ObjectRow, securityRow.ObjectRow));
 }
Beispiel #11
0
        /// <summary>
        /// Creates a command in a RemoteBatch structure to insert a proposed order.
        /// </summary>
        /// <param name="remoteBatch"></param>
        /// <param name="remoteTransaction"></param>
        /// <param name="accountRow"></param>
        /// <param name="securityRow"></param>
        /// <param name="positionTypeCode"></param>
        /// <param name="quantityInstruction"></param>
        private static void Insert(RemoteBatch remoteBatch, RemoteTransaction remoteTransaction,
                                   ClientMarketData.AccountRow accountRow, ClientMarketData.SecurityRow securityRow, int positionTypeCode,
                                   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");
            RemoteType     proposedOrderTreeType = remoteAssembly.Types.Add("Shadows.WebService.Core.ProposedOrderTree");

            // Find the default settlement for this order.
            int settlementId = Shadows.Quasar.Common.Security.GetDefaultSettlementId(securityRow);

            // As a convention between the rebalancing section and the order generation, the parentQuantity passed into this method
            // is a signed value where the negative values are treated as 'Sell' instructions and the positive values meaning
            // 'Buy'. This will adjust the parentQuantity so the trading methods can deal with an unsigned value, which is more
            // natural for trading.
            decimal parentQuantity = Math.Abs(quantityInstruction);

            // This will turn the signed parentQuantity into an absolute parentQuantity and a transaction code (e.g. -1000 is
            // turned into a SELL of 1000 shares).
            int parentTransactionTypeCode = TransactionType.Calculate(securityRow.SecurityTypeCode, 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 parentBlotterId = ClientPreferences.IsBlotterIdNull() ? (accountRow.IsBlotterIdNull() ?
                                                                         TradingSupport.AutoRoute(securityRow, parentQuantity) : accountRow.BlotterId) : ClientPreferences.BlotterId;

            // Create a command to delete the relationship between the parent and child.
            RemoteMethod insertParent = proposedOrderType.Methods.Add("Insert");

            insertParent.Transaction = remoteTransaction;
            insertParent.Parameters.Add("proposedOrderId", DataType.Int, Direction.ReturnValue);
            insertParent.Parameters.Add("blotterId", parentBlotterId);
            insertParent.Parameters.Add("accountId", accountRow.AccountId);
            insertParent.Parameters.Add("securityId", securityRow.SecurityId);
            insertParent.Parameters.Add("settlementId", settlementId);
            insertParent.Parameters.Add("positionTypeCode", positionTypeCode);
            insertParent.Parameters.Add("transactionTypeCode", parentTransactionTypeCode);
            insertParent.Parameters.Add("timeInForceCode", timeInForceCode);
            insertParent.Parameters.Add("orderTypeCode", OrderType.Market);
            insertParent.Parameters.Add("quantity", parentQuantity);

            // Now it's time to create an order for the settlement currency.
            if (securityRow.SecurityTypeCode == SecurityType.Equity || securityRow.SecurityTypeCode == SecurityType.Debt)
            {
                // The underlying currency is needed for the market value calculations.
                ClientMarketData.CurrencyRow currencyRow = MarketData.Currency.FindByCurrencyId(settlementId);

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

                // The stragegy for handling the settlement currency changes is to calculate the old market value, calculate the
                // new market value, and add the difference to the running total for the settlement currency of this security. The
                // new market value is the impact of the trade that was just entered.
                int childTransactionTypeCode = TransactionType.Calculate(securityRow.SecurityTypeCode, positionTypeCode,
                                                                         marketValue);
                decimal childQuantity = Math.Abs(marketValue);

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

                // Fill in the rest of the fields and the defaulted fields for this order. Create a command to delete the
                // relationship between the parent and child.
                RemoteMethod insertChild = proposedOrderType.Methods.Add("Insert");
                insertChild.Transaction = remoteTransaction;
                insertChild.Parameters.Add("proposedOrderId", DataType.Int, Direction.ReturnValue);
                insertChild.Parameters.Add("blotterId", childBlotterId);
                insertChild.Parameters.Add("accountId", accountRow.AccountId);
                insertChild.Parameters.Add("securityId", settlementId);
                insertChild.Parameters.Add("settlementId", settlementId);
                insertChild.Parameters.Add("transactionTypeCode", childTransactionTypeCode);
                insertChild.Parameters.Add("positionTypeCode", positionTypeCode);
                insertChild.Parameters.Add("timeInForceCode", timeInForceCode);
                insertChild.Parameters.Add("orderTypeCode", OrderType.Market);
                insertChild.Parameters.Add("quantity", childQuantity);

                RemoteMethod insertRelation = proposedOrderTreeType.Methods.Add("Insert");
                insertRelation.Transaction = remoteTransaction;
                insertRelation.Parameters.Add("parentId", insertParent.Parameters["proposedOrderId"]);
                insertRelation.Parameters.Add("childId", insertChild.Parameters["proposedOrderId"]);
            }
        }
        /// <summary>
        /// Initialize the data used in this application.
        /// </summary>
        private void InitializeData(object parameter)
        {
            string           title            = string.Empty;
            string           symbol           = string.Empty;
            string           name             = string.Empty;
            Bitmap           logo             = null;
            decimal          leavesQuantity   = 0.0m;
            decimal          minimumQuantity  = 0.0m;
            NegotiationState negotiationState = NegotiationState.None;

            try
            {
                // Lock the tables.
                System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked);
                ClientMarketData.MatchLock.AcquireReaderLock(ClientTimeout.LockWait);
                ClientMarketData.NegotiationLock.AcquireReaderLock(ClientTimeout.LockWait);
                ClientMarketData.ObjectLock.AcquireReaderLock(ClientTimeout.LockWait);
                ClientMarketData.OrderTypeLock.AcquireReaderLock(ClientTimeout.LockWait);
                ClientMarketData.SecurityLock.AcquireReaderLock(ClientTimeout.LockWait);
                ClientMarketData.WorkingOrderLock.AcquireReaderLock(ClientTimeout.LockWait);

                // Find the Match record.
                ClientMarketData.MatchRow        matchRow        = ClientMarketData.Match.FindByMatchId(this.matchId);
                ClientMarketData.WorkingOrderRow workingOrderRow = matchRow.WorkingOrderRow;
                ClientMarketData.OrderTypeRow    orderTypeRow    = workingOrderRow.OrderTypeRow;
                ClientMarketData.SecurityRow     securityRow     = workingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId;

                symbol          = securityRow.Symbol;
                name            = securityRow.ObjectRow.Name;
                minimumQuantity = securityRow.MinimumQuantity;
                if (!securityRow.IsLogoNull())
                {
                    MemoryStream memoryStream = new MemoryStream(Convert.FromBase64String(securityRow.Logo));
                    logo = new Bitmap(memoryStream);
                }
                title          = string.Format("{0} of {1}", orderTypeRow.Description, symbol);
                leavesQuantity = workingOrderRow.SubmittedQuantity;
                foreach (ClientMarketData.DestinationOrderRow destinationOrderRow in workingOrderRow.GetDestinationOrderRows())
                {
                    foreach (ClientMarketData.ExecutionRow executionRow in destinationOrderRow.GetExecutionRows())
                    {
                        leavesQuantity -= executionRow.ExecutionQuantity;
                    }
                }
            }
            finally
            {
                // Release the locks.
                if (ClientMarketData.MatchLock.IsReaderLockHeld)
                {
                    ClientMarketData.MatchLock.ReleaseReaderLock();
                }
                if (ClientMarketData.NegotiationLock.IsReaderLockHeld)
                {
                    ClientMarketData.NegotiationLock.ReleaseReaderLock();
                }
                if (ClientMarketData.ObjectLock.IsReaderLockHeld)
                {
                    ClientMarketData.ObjectLock.ReleaseReaderLock();
                }
                if (ClientMarketData.OrderTypeLock.IsReaderLockHeld)
                {
                    ClientMarketData.OrderTypeLock.ReleaseReaderLock();
                }
                if (ClientMarketData.SecurityLock.IsReaderLockHeld)
                {
                    ClientMarketData.SecurityLock.ReleaseReaderLock();
                }
                if (ClientMarketData.WorkingOrderLock.IsReaderLockHeld)
                {
                    ClientMarketData.WorkingOrderLock.ReleaseReaderLock();
                }
                System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked);
            }

            Invoke(new SetDialogAttributesDelegate(SetDialogAttributes), new object[] { title, symbol, name, logo, leavesQuantity, negotiationState });
        }
Beispiel #13
0
        /// <summary>
        /// Creates an Equity Element for an Appriasal Document.
        /// </summary>
        /// <param name="appraisalDocument">The parent Xml Document.</param>
        /// <param name="equityRow">An equity record from the data model.</param>
        /// <param name="PositionTypeCode">Whether a short or long position.</param>
        public EquityElement(AppraisalDocument appraisalDocument, ClientMarketData.EquityRow equityRow,
                             AppraisalSet.PositionRow positionRow) : base("Equity", appraisalDocument)
        {
            // These records are used to access information held in the ancestors.
            ClientMarketData.SecurityRow securityRow = equityRow.SecurityRowByFKSecurityEquityEquityId;
            ClientMarketData.ObjectRow   objectRow   = securityRow.ObjectRow;

            // Add the essential attributes for this element.
            AddAttribute("SecurityId", equityRow.EquityId.ToString());
            AddAttribute("PositionTypeCode", positionRow.PositionTypeCode.ToString());
            AddAttribute("Name", objectRow.Name.ToString());
            AddAttribute("PriceFactor", securityRow.PriceFactor.ToString());
            AddAttribute("QuantityFactor", securityRow.QuantityFactor.ToString());

            // Find the price based on the default currency found in the equity record.  If the security master doesn't
            // have a price for this security, provide dummy values to insure a market value can be calculated.  Zero is a
            // perfectly reasonable interpretation of a missing price.
            ClientMarketData.PriceRow securityPrice = ClientMarketData.Price.FindBySecurityIdCurrencyId(
                securityRow.SecurityId, equityRow.SettlementId);
            if (securityPrice == null)
            {
                AddAttribute("Price", "0.0");
            }
            else
            {
                if (ClientPreferences.Pricing == Pricing.Close)
                {
                    AddAttribute("Price", securityPrice.ClosePrice.ToString());
                }
                if (ClientPreferences.Pricing == Pricing.Last)
                {
                    AddAttribute("Price", securityPrice.LastPrice.ToString());
                }
            }

            // Find the crossing price.  This is used to convert any local price into the account's base currency. Provide
            // defaults if the crossing price can be found.  While this will lead to wrong values, they will be obvious on
            // the appraisal.
            ClientMarketData.PriceRow currencyPrice = ClientMarketData.Price.FindBySecurityIdCurrencyId(
                equityRow.SettlementId, appraisalDocument.AccountRow.CurrencyRow.CurrencyId);
            if (currencyPrice == null)
            {
                AddAttribute("CloseCrossPrice", "0.0");
                AddAttribute("LastCrossPrice", "0.0");
            }
            else
            {
                AddAttribute("CloseCrossPrice", currencyPrice.ClosePrice.ToString());
                AddAttribute("LastCrossPrice", currencyPrice.LastPrice.ToString());
            }

            // Add a target percentage if one is associated with this security.
            ClientMarketData.PositionTargetRow positionTargetRow =
                ClientMarketData.PositionTarget.FindByModelIdSecurityIdPositionTypeCode(
                    appraisalDocument.ModelRow.ModelId, equityRow.EquityId, positionRow.PositionTypeCode);
            if (positionTargetRow != null)
            {
                AddAttribute("ModelPercent", positionTargetRow.Percent.ToString());
            }

            // If there is a position record associated with this, er..  position, then add the externally supplied data
            // to the record.  Since the tax lots are always aggregated as we need them into a position, there's no static
            // table that keeps position data.  This information is generally from an outside system that is related to
            // the position, such as risk metrics or quantitative calculations.
            ClientMarketData.PositionRow position = ClientMarketData.Position.FindByAccountIdSecurityIdPositionTypeCode(
                appraisalDocument.AccountRow.AccountId, positionRow.SecurityId, positionRow.PositionTypeCode);
            if (position != null)
            {
                if (!position.IsUserData0Null())
                {
                    AddAttribute("UserData0", position.UserData0.ToString());
                }
                if (!position.IsUserData1Null())
                {
                    AddAttribute("UserData1", position.UserData1.ToString());
                }
                if (!position.IsUserData2Null())
                {
                    AddAttribute("UserData2", position.UserData2.ToString());
                }
                if (!position.IsUserData3Null())
                {
                    AddAttribute("UserData3", position.UserData3.ToString());
                }
                if (!position.IsUserData4Null())
                {
                    AddAttribute("UserData4", position.UserData4.ToString());
                }
                if (!position.IsUserData5Null())
                {
                    AddAttribute("UserData5", position.UserData5.ToString());
                }
                if (!position.IsUserData6Null())
                {
                    AddAttribute("UserData6", position.UserData6.ToString());
                }
                if (!position.IsUserData7Null())
                {
                    AddAttribute("UserData7", position.UserData7.ToString());
                }
            }

            // Add the account level aggregates for this security/position type pair.
            foreach (AppraisalSet.AccountRow accountRow in positionRow.GetAccountRows())
            {
                this.AppendChild(new AccountElement(appraisalDocument, accountRow));
            }
        }
Beispiel #14
0
        /// <summary>
        /// Creates a Currency Element for an Appraisal Document.
        /// </summary>
        /// <param name="appraisalDocument">The parent Xml Document.</param>
        /// <param name="currencyRow">A currency record in the data model.</param>
        /// <param name="PositionTypeCode">Whether a short or long position.</param>
        public CurrencyElement(AppraisalDocument appraisalDocument, ClientMarketData.CurrencyRow currencyRow,
                               AppraisalSet.PositionRow positionRow) : base("Currency", appraisalDocument)
        {
            // These records are used to access information held in the ancestors.
            ClientMarketData.SecurityRow securityRow = currencyRow.SecurityRow;
            ClientMarketData.ObjectRow   objectRow   = securityRow.ObjectRow;

            // Add the essential attributes for this element.
            AddAttribute("SecurityId", currencyRow.CurrencyId.ToString());
            AddAttribute("PositionTypeCode", positionRow.PositionTypeCode.ToString());
            AddAttribute("Name", objectRow.Name.ToString());

            // Add the price info.
            ClientMarketData.PriceRow priceRow =
                ClientMarketData.Price.FindBySecurityIdCurrencyId(securityRow.SecurityId,
                                                                  appraisalDocument.AccountRow.CurrencyRow.CurrencyId);
            if (priceRow == null)
            {
                AddAttribute("Price", "0.0");
            }
            else
            {
                if (ClientPreferences.Pricing == Pricing.Close)
                {
                    AddAttribute("Price", priceRow.ClosePrice.ToString());
                }
                if (ClientPreferences.Pricing == Pricing.Last)
                {
                    AddAttribute("Price", priceRow.LastPrice.ToString());
                }
            }

            // Add a target percentage if one is associated with this security.
            ClientMarketData.PositionTargetRow positionTargetRow =
                ClientMarketData.PositionTarget.FindByModelIdSecurityIdPositionTypeCode(
                    appraisalDocument.ModelRow.ModelId, currencyRow.CurrencyId, positionRow.PositionTypeCode);
            if (positionTargetRow != null)
            {
                AddAttribute("ModelPercent", positionTargetRow.Percent.ToString());
            }

            // If there is a position record associated with this, er..  position, then add the externally supplied data
            // to the record.  Since the tax lots are always aggregated as we need them into a position, there's no static
            // table that keeps position data.  This information is generally from an outside system that is related to
            // the position, such as risk metrics or quantitative calculations.
            ClientMarketData.PositionRow position = ClientMarketData.Position.FindByAccountIdSecurityIdPositionTypeCode(
                appraisalDocument.AccountRow.AccountId, positionRow.SecurityId, positionRow.PositionTypeCode);
            if (position != null)
            {
                if (!position.IsUserData0Null())
                {
                    AddAttribute("UserData0", position.UserData0.ToString());
                }
                if (!position.IsUserData1Null())
                {
                    AddAttribute("UserData1", position.UserData1.ToString());
                }
                if (!position.IsUserData2Null())
                {
                    AddAttribute("UserData2", position.UserData2.ToString());
                }
                if (!position.IsUserData3Null())
                {
                    AddAttribute("UserData3", position.UserData3.ToString());
                }
                if (!position.IsUserData4Null())
                {
                    AddAttribute("UserData4", position.UserData4.ToString());
                }
                if (!position.IsUserData5Null())
                {
                    AddAttribute("UserData5", position.UserData5.ToString());
                }
                if (!position.IsUserData6Null())
                {
                    AddAttribute("UserData6", position.UserData6.ToString());
                }
                if (!position.IsUserData7Null())
                {
                    AddAttribute("UserData7", position.UserData7.ToString());
                }
            }

            // Append the account level aggregates to this security/position type element.
            foreach (AppraisalSet.AccountRow accountRow in positionRow.GetAccountRows())
            {
                this.AppendChild(new AccountElement(appraisalDocument, accountRow));
            }
        }
Beispiel #15
0
        public void CalculateFields()
        {
            // The block order document has an operation that displays distinct values when the occur.  For instance, if
            // all the orders in the block have the same time in force, then that time in force will appear in the
            // document at the block level.  However, if any one of the elements is different from the others, the same
            // column would be blanked out to show that there is more than one value associated with this attribute of the
            // block.  The first order is used as a seed for this operation.  If any element in the block doesn't share
            // the first order's attribute, then that attribute is left blank.
            decimal       quantityOrdered = 0.0M;
            OrdersElement firstOrder      = (OrdersElement)this.SelectSingleNode(".//Order");

            if (firstOrder != null)
            {
                // Aggregates by Orders.
                int     orders                 = 0;
                int     securityIdSum          = 0;
                int     accountIdSum           = 0;
                int     transactionTypeCodeSum = 0;
                int     timeInForceCodeSum     = 0;
                int     orderTypeCodeSum       = 0;
                decimal price1Sum              = 0.0M;
                decimal price2Sum              = 0.0M;

                foreach (OrdersElement ordersElement in this.SelectNodes("Order"))
                {
                    orders++;
                    securityIdSum          += ordersElement.OrderRow.SecurityId;
                    accountIdSum           += ordersElement.OrderRow.AccountId;
                    transactionTypeCodeSum += ordersElement.OrderRow.TransactionTypeCode;
                    timeInForceCodeSum     += ordersElement.OrderRow.TimeInForceCode;
                    orderTypeCodeSum       += ordersElement.OrderRow.OrderTypeCode;
                    price1Sum       += ordersElement.OrderRow.IsPrice1Null() ? 0.0M : ordersElement.OrderRow.Price1;
                    price2Sum       += ordersElement.OrderRow.IsPrice2Null() ? 0.0M : ordersElement.OrderRow.Price2;
                    quantityOrdered += ordersElement.OrderRow.Quantity;
                }

                if (securityIdSum == firstOrder.OrderRow.SecurityId * orders)
                {
                    AddAttribute("SecurityId", firstOrder.OrderRow.SecurityId);

                    ClientMarketData.SecurityRow securityRow = firstOrder.OrderRow.SecurityRowByFKSecurityOrderSecurityId;
                    AddAttribute("SecurityName", securityRow.ObjectRow.Name);
                    AddAttribute("SecuritySymbol", securityRow.Symbol);

                    ClientMarketData.PriceRow priceRow = ClientMarketData.Price.FindBySecurityIdCurrencyId(
                        firstOrder.OrderRow.SecurityId, firstOrder.OrderRow.SettlementId);
                    if (priceRow != null)
                    {
                        AddAttribute("LastPrice", priceRow.LastPrice);
                        AddAttribute("BidPrice", priceRow.BidPrice);
                        AddAttribute("BidSize", priceRow.BidSize);
                        AddAttribute("AskPrice", priceRow.AskPrice);
                        AddAttribute("AskSize", priceRow.AskSize);
                    }

                    // Add Fixed Income Fundamentals where they exist.
                    foreach (ClientMarketData.DebtRow debtRow in securityRow.GetDebtRowsByFKSecurityDebtDebtId())
                    {
                        if (!debtRow.IsIssuerIdNull())
                        {
                            AddAttribute("IssuerId", debtRow.IssuerId);
                        }
                        AddAttribute("DebtTypeCode", debtRow.DebtTypeCode);
                        AddAttribute("Coupon", debtRow.Coupon);
                        AddAttribute("MaturityDate", debtRow.MaturityDate.ToShortDateString());
                    }
                }

                if (accountIdSum == firstOrder.OrderRow.AccountId * orders)
                {
                    AddAttribute("AccountId", firstOrder.OrderRow.AccountId);

                    ClientMarketData.AccountRow accountRow = firstOrder.OrderRow.AccountRow;
                    AddAttribute("AccountName", accountRow.ObjectRow.Name);
                }

                if (transactionTypeCodeSum == firstOrder.OrderRow.TransactionTypeCode * orders)
                {
                    AddAttribute("TransactionTypeCode", firstOrder.OrderRow.TransactionTypeCode);
                    AddAttribute("TransactionTypeName", firstOrder.OrderRow.TransactionTypeRow.Mnemonic);
                }

                if (timeInForceCodeSum == firstOrder.OrderRow.TimeInForceCode * orders)
                {
                    AddAttribute("TimeInForceCode", firstOrder.OrderRow.TimeInForceCode);
                    AddAttribute("TimeInForceName", firstOrder.OrderRow.TimeInForceRow.Mnemonic);
                }

                if (orderTypeCodeSum == firstOrder.OrderRow.OrderTypeCode * orders)
                {
                    AddAttribute("OrderTypeCode", firstOrder.OrderRow.OrderTypeCode);
                    AddAttribute("OrderTypeName", firstOrder.OrderRow.OrderTypeRow.Mnemonic);
                }

                if (!firstOrder.OrderRow.IsPrice1Null() && price1Sum == firstOrder.OrderRow.Price1 * orders)
                {
                    AddAttribute("Price1", firstOrder.OrderRow.Price1);
                }

                if (!firstOrder.OrderRow.IsPrice2Null() && price2Sum == firstOrder.OrderRow.Price2 * orders)
                {
                    AddAttribute("Price2", firstOrder.OrderRow.Price2);
                }

                // HACK - Trade and Settlement are defaulted.  These should be distinct elements from the executions.
                AddAttribute("TradeDate", DateTime.Now.ToShortDateString());
                AddAttribute("SettlementDate", DateTime.Now.ToShortDateString());
            }

            AddAttribute("QuantityOrdered", quantityOrdered);

            // Aggregate Placements
            decimal           quantityPlaced = 0.0M;
            PlacementsElement firstPlacement = (PlacementsElement)this.SelectSingleNode(".//Placement");

            if (firstPlacement != null)
            {
                // Aggregates by Placements.
                int placements  = 0;
                int brokerIdSum = 0;

                foreach (PlacementsElement placementsElement in this.SelectNodes("Placement"))
                {
                    placements++;
                    brokerIdSum    += placementsElement.PlacementRow.BrokerId;
                    quantityPlaced += placementsElement.PlacementRow.Quantity;
                }

                if (brokerIdSum == firstPlacement.PlacementRow.BrokerId * placements)
                {
                    AddAttribute("PlacementBrokerId", firstPlacement.PlacementRow.BrokerId);
                    AddAttribute("PlacementBrokerSymbol", firstPlacement.PlacementRow.BrokerRow.Symbol);
                }
            }

            AddAttribute("QuantityPlaced", quantityPlaced);

            // Aggregate Execution
            decimal          quantityExecuted = 0.0M;
            ExecutionElement firstExecution   = (ExecutionElement)this.SelectSingleNode(".//Execution");

            if (firstExecution != null)
            {
                // Aggregates by Execution.
                int placements  = 0;
                int brokerIdSum = 0;

                foreach (ExecutionElement placementsElement in this.SelectNodes("Execution"))
                {
                    placements++;
                    brokerIdSum      += placementsElement.ExecutionRow.BrokerId;
                    quantityExecuted += placementsElement.ExecutionRow.Quantity;
                }

                if (brokerIdSum == firstExecution.ExecutionRow.BrokerId * placements)
                {
                    AddAttribute("PlacementBrokerId", firstExecution.ExecutionRow.BrokerId);
                    AddAttribute("PlacementBrokerSymbol", firstExecution.ExecutionRow.BrokerRow.Symbol);
                }
            }

            AddAttribute("QuantityExecuted", quantityExecuted);
        }
Beispiel #16
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);
                }
            }
        }
Beispiel #17
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);
                }
            }
        }
Beispiel #18
0
        /// <summary>
        /// Creates an XML Element representing a placment in the order document.
        /// </summary>
        /// <param name="xmlDocument">The destination XML document.</param>
        /// <param name="orderRow">A order record.</param>
        public LocalOrderElement(XmlDocument xmlDocument, LocalOrderSet.OrderRow orderRow) :
            base("LocalOrder", xmlDocument)
        {
            // Add the attributes of a order to this record.
            AddAttribute("OrderId", orderRow.OrderId.ToString());

            // Account field
            if (!orderRow.IsAccountIdNull())
            {
                AddAttribute("AccountId", orderRow.AccountId.ToString());

                ClientMarketData.AccountRow accountRow = ClientMarketData.Account.FindByAccountId(orderRow.AccountId);
                if (accountRow != null)
                {
                    AddAttribute("AccountId", accountRow.AccountId.ToString());
                    AddAttribute("AccountName", accountRow.ObjectRow.Name);
                    AddAttribute("AccountMnemonic", accountRow.Mnemonic);
                }
            }

            // Security field
            if (!orderRow.IsSecurityIdNull())
            {
                AddAttribute("SecurityId", orderRow.SecurityId.ToString());

                ClientMarketData.SecurityRow securityRow = ClientMarketData.Security.FindBySecurityId(orderRow.SecurityId);
                if (securityRow != null)
                {
                    AddAttribute("SecurityId", securityRow.SecurityId.ToString());
                    AddAttribute("SecurityName", securityRow.ObjectRow.Name);
                    AddAttribute("SecuritySymbol", securityRow.Symbol);
                }
            }

            // Broker field
            if (!orderRow.IsBrokerIdNull())
            {
                AddAttribute("BrokerId", orderRow.BrokerId.ToString());

                ClientMarketData.BrokerRow brokerRow = ClientMarketData.Broker.FindByBrokerId(orderRow.BrokerId);
                if (brokerRow != null)
                {
                    AddAttribute("BrokerId", brokerRow.BrokerId.ToString());
                    AddAttribute("BrokerName", brokerRow.ObjectRow.Name);
                    AddAttribute("BrokerSymbol", brokerRow.Symbol);
                    if (!brokerRow.IsPhoneNull())
                    {
                        AddAttribute("BrokerPhone", brokerRow.Phone);
                    }
                }
            }

            // TransactionType field
            if (!orderRow.IsTransactionTypeCodeNull())
            {
                AddAttribute("TransactionTypeCode", orderRow.TransactionTypeCode.ToString());

                ClientMarketData.TransactionTypeRow transactionTypeRow = ClientMarketData.TransactionType.FindByTransactionTypeCode(orderRow.TransactionTypeCode);
                if (transactionTypeRow != null)
                {
                    AddAttribute("TransactionTypeMnemonic", transactionTypeRow.Mnemonic);
                }
            }

            // TimeInForce field
            if (!orderRow.IsTimeInForceCodeNull())
            {
                AddAttribute("TimeInForceCode", orderRow.TimeInForceCode.ToString());

                ClientMarketData.TimeInForceRow timeInForceRow = ClientMarketData.TimeInForce.FindByTimeInForceCode(orderRow.TimeInForceCode);
                if (timeInForceRow != null)
                {
                    AddAttribute("TimeInForceMnemonic", timeInForceRow.Mnemonic);
                }
            }

            // OrderType field
            if (!orderRow.IsOrderTypeCodeNull())
            {
                AddAttribute("OrderTypeCode", orderRow.OrderTypeCode.ToString());

                ClientMarketData.OrderTypeRow orderTypeRow = ClientMarketData.OrderType.FindByOrderTypeCode(orderRow.OrderTypeCode);
                if (orderTypeRow != null)
                {
                    AddAttribute("OrderTypeMnemonic", orderTypeRow.Mnemonic);
                }
            }

            if (!orderRow.IsQuantityNull())
            {
                AddAttribute("Quantity", orderRow.Quantity.ToString());
            }
            if (!orderRow.IsPrice1Null())
            {
                AddAttribute("Price1", orderRow.Price1.ToString());
            }
            if (!orderRow.IsPrice2Null())
            {
                AddAttribute("Price2", orderRow.Price2.ToString());
            }
        }
Beispiel #19
0
        /// <summary>
        /// Creates a denormalized order record from a local record.
        /// </summary>
        /// <param name="localOrder">A local order record.</param>
        /// <returns>A order record that is independant of the global data set for all the anscillary data.</returns>
        public static OrderSet.OrderRow Create(LocalOrderSet.OrderRow localOrder)
        {
            // Create a new, empty order record.
            OrderSet.OrderRow orderRow = orderSet.Order.NewOrderRow();

            // This new record is a copy of a local record and uses the local system of identifiers.
            orderRow.IsLocal = true;

            // Copy each field that has an analog in the local record set into the new record.
            foreach (DataColumn dataColumn in localOrder.Table.Columns)
            {
                orderRow[dataColumn.ColumnName] = localOrder[dataColumn];
            }

            // AccountId cross-referenced data is filled in here.
            if (!localOrder.IsAccountIdNull())
            {
                ClientMarketData.AccountRow accountRow = ClientMarketData.Account.FindByAccountId(orderRow.AccountId);
                if (accountRow != null)
                {
                    orderRow.AccountMnemonic = accountRow.Mnemonic;
                    orderRow.AccountName     = accountRow.ObjectRow.Name;
                }
            }

            // SecurityId cross-referenced data is filled in here.
            if (!localOrder.IsSecurityIdNull())
            {
                ClientMarketData.SecurityRow securityRow = ClientMarketData.Security.FindBySecurityId(orderRow.SecurityId);
                if (securityRow != null)
                {
                    orderRow.SecuritySymbol = securityRow.Symbol;
                    orderRow.SecurityName   = securityRow.ObjectRow.Name;
                }
            }

            // CurrencyId cross-referenced data is filled in here.
            if (!localOrder.IsSettlementIdNull())
            {
                ClientMarketData.CurrencyRow currencyRow = ClientMarketData.Currency.FindByCurrencyId(orderRow.SettlementId);
                if (currencyRow != null)
                {
                    orderRow.SettlementSymbol = currencyRow.SecurityRow.Symbol;
                    orderRow.SettlementName   = currencyRow.SecurityRow.ObjectRow.Name;
                }
            }

            // BrokerId cross-referenced data is filled in here.
            if (!localOrder.IsBrokerIdNull())
            {
                ClientMarketData.BrokerRow brokerRow = ClientMarketData.Broker.FindByBrokerId(orderRow.BrokerId);
                if (brokerRow != null)
                {
                    orderRow.BrokerSymbol = brokerRow.Symbol;
                    orderRow.BrokerName   = brokerRow.ObjectRow.Name;
                }
            }

            // TransactionType cross-referenced data is filled in here.
            if (!localOrder.IsTransactionTypeCodeNull())
            {
                ClientMarketData.TransactionTypeRow transactionTypeRow = ClientMarketData.TransactionType.FindByTransactionTypeCode(orderRow.TransactionTypeCode);
                if (transactionTypeRow != null)
                {
                    orderRow.TransactionTypeMnemonic = transactionTypeRow.Mnemonic;
                }
            }

            // TimeInForce cross-referenced data is filled in here.
            if (!localOrder.IsTimeInForceCodeNull())
            {
                ClientMarketData.TimeInForceRow timeInForceRow = ClientMarketData.TimeInForce.FindByTimeInForceCode(orderRow.TimeInForceCode);
                if (timeInForceRow != null)
                {
                    orderRow.TimeInForceMnemonic = timeInForceRow.Mnemonic;
                }
            }

            // TimeInForce cross-referenced data is filled in here.
            if (!localOrder.IsOrderTypeCodeNull())
            {
                ClientMarketData.OrderTypeRow orderTypeRow = ClientMarketData.OrderType.FindByOrderTypeCode(orderRow.OrderTypeCode);
                if (orderTypeRow != null)
                {
                    orderRow.OrderTypeMnemonic = orderTypeRow.Mnemonic;
                }
            }

            // This is a complete record of the order, including the referenced data.
            return(orderRow);
        }
Beispiel #20
0
        /// <summary>
        /// Recursively rebalances an account and all it's children.
        /// </summary>
        /// <param name="accountRow">The parent account to be rebalanced.</param>
        private static void RecurseAccounts(RemoteBatch remoteBatch, RemoteTransaction remoteTransaction,
                                            AppraisalSet appraisalSet, ClientMarketData.AccountRow accountRow, ClientMarketData.ModelRow modelRow)
        {
            // The base currency of the account is used to cacluate market values.
            ClientMarketData.CurrencyRow currencyRow = ClientMarketData.Currency.FindByCurrencyId(accountRow.CurrencyId);

            // Calculate the total market value for the appraisal.  This will be the denominator in all calculations involving
            // portfolio percentages.
            decimal accountMarketValue = MarketValue.Calculate(currencyRow, accountRow, MarketValueFlags.EntirePosition);

            // Cycle through all the positions of the appraisal using the current account and calculate the size and direction of
            // the trade needed to bring it to the model's target percent.
            foreach (AppraisalSet.SecurityRow driverSecurity in appraisalSet.Security)
            {
                // We need to reference the security row in the ClientMarketData to price this item.
                ClientMarketData.SecurityRow securityRow = ClientMarketData.Security.FindBySecurityId(driverSecurity.SecurityId);

                // In this rebalancing operation, the cash balance is dependant on the securities bought and sold. The assumption
                // is made that we won't implicitly add or remove cash to accomplish the reblancing operation. When stocks are
                // bought or sold below, they will impact the underlying currency.  A cash target can be reached by setting all the
                // other percentages up properly.  As long as the total percentage in a model is 100%, the proper cash target will
                // be calculated.  We don't have to do anything with this asset type.
                if (securityRow.SecurityTypeCode == SecurityType.Currency)
                {
                    continue;
                }

                // This section will calculate the difference in between the actual and target market values for each
                // position and create orders that will bring the account to the targeted percentages.
                foreach (AppraisalSet.PositionRow driverPosition in driverSecurity.GetPositionRows())
                {
                    // Calculate the proposed quantity needed to bring this asset/account combination to the percentage given by
                    // the model.  First, find the target percent.  If it's not there, we assume a target of zero (meaning sell all
                    // holdings).
                    ClientMarketData.PositionTargetRow positionTargetRow =
                        ClientMarketData.PositionTarget.FindByModelIdSecurityIdPositionTypeCode(modelRow.ModelId,
                                                                                                securityRow.SecurityId, driverPosition.PositionTypeCode);
                    decimal targetPositionPercent = positionTargetRow == null ? 0.0M : positionTargetRow.Percent;

                    // The market value of this trade will be the target market value less the current market value of
                    // this position (without including the existing proposed orders in the current market value
                    // calculation).
                    decimal targetPositionMarketValue = targetPositionPercent * accountMarketValue;
                    decimal actualPositionMarketValue = MarketValue.Calculate(currencyRow, accountRow, securityRow,
                                                                              driverPosition.PositionTypeCode, MarketValueFlags.ExcludeProposedOrder);
                    decimal proposedMarketValue = targetPositionMarketValue - actualPositionMarketValue;

                    // Calculate the quantity needed to hit the target market value and round it according to the model. Note that
                    // the market values and prices are all denominated in the currency of the parent account. Also note the
                    // quantityFactor is needed for the proper quantity calculation.
                    decimal price            = Price.Security(currencyRow, securityRow);
                    decimal proposedQuantity = price == 0.0M ? 0.0M : proposedMarketValue / (price * securityRow.QuantityFactor);

                    // If we have an equity, round to the model's lot size.  Common values are 100 and 1.
                    if (securityRow.SecurityTypeCode == SecurityType.Equity)
                    {
                        proposedQuantity = Math.Round(proposedQuantity / modelRow.EquityRounding, 0) * modelRow.EquityRounding;
                    }

                    // A debt generally needs to be rounded to face.
                    if (securityRow.SecurityTypeCode == SecurityType.Debt)
                    {
                        proposedQuantity = Math.Round(proposedQuantity / modelRow.DebtRounding, 0) * modelRow.DebtRounding;
                    }

                    // Have the Order Form Builder object construct an order based on the new proposed quantity.  This method will
                    // fill in the defaults needed for a complete Proposed Order.  It will also create an deposit or widthdrawal
                    // from an account to cover the transaction.
                    ProposedOrder.Create(remoteBatch, remoteTransaction, accountRow, securityRow, driverPosition.PositionTypeCode,
                                         proposedQuantity);
                }
            }

            // Now that we've rebalanced the parent account, cycle through all the children accounts and rebalance them.
            foreach (ClientMarketData.ObjectTreeRow objectTreeRow in
                     accountRow.ObjectRow.GetObjectTreeRowsByFKObjectObjectTreeParentId())
            {
                foreach (ClientMarketData.AccountRow childAccount in
                         objectTreeRow.ObjectRowByFKObjectObjectTreeChildId.GetAccountRows())
                {
                    Security.RecurseAccounts(remoteBatch, remoteTransaction, appraisalSet, childAccount, modelRow);
                }
            }
        }
Beispiel #21
0
        /// <summary>
        /// Method called to retrieve the securityId for the security selected in the match viewere.
        /// </summary>
        /// <param name="parameter"></param>
        private void InitializeData(object parameter)
        {
            int id = Int32.MinValue;

            try
            {
                // Lock the tables.
                System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked);
                ClientMarketData.MatchLock.AcquireReaderLock(ClientTimeout.LockWait);
                ClientMarketData.NegotiationLock.AcquireReaderLock(ClientTimeout.LockWait);
                ClientMarketData.OrderTypeLock.AcquireReaderLock(ClientTimeout.LockWait);
                ClientMarketData.SecurityLock.AcquireReaderLock(ClientTimeout.LockWait);
                ClientMarketData.WorkingOrderLock.AcquireReaderLock(ClientTimeout.LockWait);

                // Find the Match record.
                ClientMarketData.MatchRow        matchRow        = ClientMarketData.Match.FindByMatchId(this.matchId);
                ClientMarketData.WorkingOrderRow workingOrderRow = matchRow.WorkingOrderRow;
                ClientMarketData.OrderTypeRow    orderTypeRow    = workingOrderRow.OrderTypeRow;
                ClientMarketData.SecurityRow     securityRow     = workingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId;

                if (securityRow != null)
                {
                    id = securityRow.SecurityId;
                }
            }
            catch (Exception e)
            {
                // Write the error and stack trace out to the debug listener
                EventLog.Error("{0}, {1}", e.Message, e.StackTrace);
            }
            finally
            {
                // Release the locks.
                if (ClientMarketData.MatchLock.IsReaderLockHeld)
                {
                    ClientMarketData.MatchLock.ReleaseReaderLock();
                }
                if (ClientMarketData.NegotiationLock.IsReaderLockHeld)
                {
                    ClientMarketData.NegotiationLock.ReleaseReaderLock();
                }
                if (ClientMarketData.OrderTypeLock.IsReaderLockHeld)
                {
                    ClientMarketData.OrderTypeLock.ReleaseReaderLock();
                }
                if (ClientMarketData.SecurityLock.IsReaderLockHeld)
                {
                    ClientMarketData.SecurityLock.ReleaseReaderLock();
                }
                if (ClientMarketData.WorkingOrderLock.IsReaderLockHeld)
                {
                    ClientMarketData.WorkingOrderLock.ReleaseReaderLock();
                }
                System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked);
            }

            if (id != Int32.MinValue)
            {
                this.Open(id);
            }
        }
Beispiel #22
0
        /// <summary>
        /// Creates a temporary model based on the current position level targets.
        /// </summary>
        /// <param name="accountRow">An account used as a basis for the targets.</param>
        /// <param name="schemeRow">The scheme used to select sector targets.</param>
        /// <returns>A batch of commands that will create a model containing the current position weights of the account.</returns>
        private static ModelBatch CreatePositionSelfModel(ClientMarketData.AccountRow accountRow, ClientMarketData.SchemeRow schemeRow)
        {
            // Create the batch and fill it in with the assembly and type needed for this function.
            ModelBatch        modelBatch        = new ModelBatch();
            RemoteTransaction remoteTransaction = modelBatch.Transactions.Add();
            RemoteAssembly    remoteAssembly    = modelBatch.Assemblies.Add("Service.Core");
            RemoteType        remoteType        = remoteAssembly.Types.Add("Shadows.WebService.Core.Model");

            // Create the temporary, position model based on the scheme used by the original account.
            RemoteMethod insertModel = remoteType.Methods.Add("Insert");

            insertModel.Parameters.Add("modelId", DataType.Int, Direction.ReturnValue);
            insertModel.Parameters.Add("rowVersion", DataType.Long, Direction.Output);
            insertModel.Parameters.Add("modelTypeCode", ModelType.Security);
            insertModel.Parameters.Add("name", "Untitled");
            insertModel.Parameters.Add("schemeId", schemeRow.SchemeId);
            insertModel.Parameters.Add("algorithmId", Algorithm.SecurityRebalancer);
            insertModel.Parameters.Add("temporary", true);

            // The 'Self Security' model uses the market value of all the positions, regardless of account or sub-account, when
            // calculating the denominator for the percentages.
            decimal accountMarketValue = MarketValue.Calculate(accountRow.CurrencyRow, accountRow,
                                                               MarketValueFlags.EntirePosition | MarketValueFlags.IncludeChildAccounts);

            // If the account market value is zero, we can't do much more to create a model.
            if (accountMarketValue != 0.0M)
            {
                // Create a new outline for the model to follow.  This will collect the tax lots, proposed orders orders and
                // allocations into positions that can be used for calculating percentages.
                Common.Appraisal appraisal = new Common.Appraisal(accountRow, true);

                // Run through each of the positions, starting with the security.
                foreach (AppraisalSet.SecurityRow driverSecurity in appraisal.Security)
                {
                    // This is a position is the destination for the market value calculation.
                    ClientMarketData.SecurityRow securityRow =
                        ClientMarketData.Security.FindBySecurityId(driverSecurity.SecurityId);

                    // The object Type for this operation.
                    RemoteType positionTargetType = remoteAssembly.Types.Add("Shadows.WebService.Core.PositionTarget");

                    // Run through each of the positions in the appraisal calculating the market value of each position. The ratio
                    // of this market value to the account's market value is the model percentage.
                    foreach (AppraisalSet.PositionRow positionRow in driverSecurity.GetPositionRows())
                    {
                        // Calculate the market value of the given position.
                        decimal securityMarketValue = MarketValue.Calculate(accountRow.CurrencyRow, accountRow,
                                                                            securityRow, positionRow.PositionTypeCode,
                                                                            MarketValueFlags.EntirePosition | MarketValueFlags.EntirePosition);

                        // Add the position level target to the model.
                        RemoteMethod insertPosition = positionTargetType.Methods.Add("Insert");
                        insertPosition.Parameters.Add("modelId", insertModel.Parameters["modelId"]);
                        insertPosition.Parameters.Add("securityId", securityRow.SecurityId);
                        insertPosition.Parameters.Add("positionTypeCode", positionRow.PositionTypeCode);
                        insertPosition.Parameters.Add("percent", securityMarketValue / accountMarketValue);
                    }
                }
            }

            // Save the reference to the 'modelId' return parameter.
            modelBatch.ModelIdParameter = insertModel.Parameters["modelId"];

            // This batch will create a temporary model based on the position totals of the original account.
            return(modelBatch);
        }
Beispiel #23
0
        /// <summary>
        /// Recursively calculates proposed orders for a sector.
        /// </summary>
        /// <param name="sector">Gives the current sector (sector) for the calculation.</param>
        private static void RecurseSectors(RemoteBatch remoteBatch, RemoteTransaction remoteTransaction,
                                           ClientMarketData.CurrencyRow currencyRow, ClientMarketData.ModelRow modelRow, AppraisalSet.ObjectRow driverObject,
                                           decimal actualSectorMarketValue, decimal targetSectorMarketValue)
        {
            // Run through each of the positions in the sector and calculate the current percentage of the position within
            // the sector.  We're going to keep this percentage as we rebalance to the new sector market value.
            foreach (AppraisalSet.SecurityRow driverSecurity in driverObject.GetSecurityRows())
            {
                foreach (AppraisalSet.PositionRow driverPosition in driverSecurity.GetPositionRows())
                {
                    // We need to know what kind of security we're dealing with when calculating market values and quantities
                    // below.
                    ClientMarketData.SecurityRow securityRow =
                        ClientMarketData.Security.FindBySecurityId(driverSecurity.SecurityId);

                    // In this rebalancing operation, the cash balance is dependant on the securities bought and sold.  When
                    // stocks are bought or sold below, they will impact the underlying currency.  We can not balance to a
                    // currency target directly.
                    if (securityRow.SecurityTypeCode == SecurityType.Currency)
                    {
                        continue;
                    }

                    // Calculate the proposed orders for each account.  The fraction of the security within the sector will
                    // stay the same, even though the sector may increase or decrease with respect to the total market value.
                    foreach (AppraisalSet.AccountRow driverAccount in driverPosition.GetAccountRows())
                    {
                        // The underlying currency is needed for the market value calculations.
                        ClientMarketData.AccountRow accountRow = ClientMarketData.Account.FindByAccountId(driverAccount.AccountId);

                        // Sector rebalancing keeps the percentage of a security within the sector constant.  Only the overall
                        // percentage of the sector with respect to the NAV changes.  To accomplish this, we first calculate
                        // the percentage of the security within the sector before we rebalance the sector.
                        decimal actualPositionMarketValue = MarketValue.Calculate(currencyRow,
                                                                                  accountRow, securityRow, driverPosition.PositionTypeCode,
                                                                                  MarketValueFlags.EntirePosition);

                        // Calculate the target market value as a percentage of the entire sector (use zero if the sector has
                        // no market value to prevent divide by zero errors).
                        decimal targetPositionMarketValue = (actualSectorMarketValue == 0) ? 0.0M :
                                                            actualPositionMarketValue * targetSectorMarketValue / actualSectorMarketValue;

                        // The target proposed orders market value keeps the percentage of the position constant while
                        // changing the overall sector percentage.
                        decimal proposedMarketValue = targetPositionMarketValue - MarketValue.Calculate(currencyRow,
                                                                                                        accountRow, securityRow, driverPosition.PositionTypeCode,
                                                                                                        MarketValueFlags.ExcludeProposedOrder);

                        // Calculate the quantity needed to hit the target market value and round it according to the
                        // model.  Note that the market values and prices are all denominated in the currency of the
                        // parent account.  Also note the quantityFactor is needed for the proper quantity calculation.
                        decimal proposedQuantity = proposedMarketValue / (Price.Security(currencyRow, securityRow) *
                                                                          securityRow.PriceFactor * securityRow.QuantityFactor);

                        // If we have an equity, round to the model's lot size.
                        if (securityRow.SecurityTypeCode == SecurityType.Equity)
                        {
                            proposedQuantity = Math.Round(proposedQuantity / modelRow.EquityRounding, 0) *
                                               modelRow.EquityRounding;
                        }

                        // A debt generally needs to be rounded to face.
                        if (securityRow.SecurityTypeCode == SecurityType.Debt)
                        {
                            proposedQuantity = Math.Round(proposedQuantity / modelRow.DebtRounding, 0) *
                                               modelRow.DebtRounding;
                        }

                        // Have the Order Form Builder object construct an order based on the quantity we've calcuated from
                        // the market value.  This method will fill in the defaults needed for a complete proposed order.
                        ProposedOrder.Create(remoteBatch, remoteTransaction, accountRow, securityRow,
                                             driverAccount.PositionTypeCode, proposedQuantity);
                    }
                }
            }

            // Recurse into each of the sub-sectors.  This allows us to rebalance with any number of levels to the
            // hierarchy.  Eventually, we will run across a sector with security positions in it and end up doing some
            // real work.
            foreach (AppraisalSet.ObjectTreeRow driverTree in
                     driverObject.GetObjectTreeRowsByFKObjectObjectTreeParentId())
            {
                SectorMerge.RecurseSectors(remoteBatch, remoteTransaction, currencyRow, modelRow,
                                           driverTree.ObjectRowByFKObjectObjectTreeChildId, actualSectorMarketValue,
                                           targetSectorMarketValue);
            }
        }
Beispiel #24
0
        /// <summary>
        /// Recursively calculates proposed orders for a sector.
        /// </summary>
        /// <param name="sector">Gives the current sector (sector) for the calculation.</param>
        private static void RecurseSectors(RemoteBatch remoteBatch, RemoteTransaction remoteTransaction, ClientMarketData.ModelRow modelRow,
                                           AppraisalSet.SectorRow driverSector, decimal actualSectorMarketValue, decimal targetSectorMarketValue)
        {
            // The main idea here is to keep the ratio of the security to the sector constant, while changing the market
            // value of the sector.  Scan each of the securities belonging to this sector.
            foreach (AppraisalSet.ObjectTreeRow objectTreeRow in
                     driverSector.ObjectRow.GetObjectTreeRowsByFKObjectObjectTreeParentId())
            {
                // Cycle through each of the securities in the sector.  We're going to keep the ratio of the security the
                // same as we target a different sector total.
                foreach (AppraisalSet.SecurityRow driverSecurity in
                         objectTreeRow.ObjectRowByFKObjectObjectTreeChildId.GetSecurityRows())
                {
                    foreach (AppraisalSet.PositionRow driverPosition in driverSecurity.GetPositionRows())
                    {
                        // We need to reference the security record for calculating proposed orders and the market value
                        // of the trade.
                        ClientMarketData.SecurityRow securityRow =
                            ClientMarketData.Security.FindBySecurityId(driverSecurity.SecurityId);

                        // In this rebalancing operation, the cash balance is dependant on the securities bought and
                        // sold.  When stocks are bought or sold below, they will impact the underlying currency.  A cash
                        // target can be reached by setting all the other percentages up properly.  As long as the total
                        // percentage in a model is 100%, the proper cash target will be calculated.  We don't have to do
                        // anything with this asset type.
                        if (securityRow.SecurityTypeCode == SecurityType.Currency)
                        {
                            continue;
                        }

                        // The ratio of the security within the sector will stay constant, even though the sector may
                        // increase or decrease with the target in the model.  Note that there's only one account in the
                        // 'Accounts' table of the driver because this is a 'Wrap' operation.
                        foreach (AppraisalSet.AccountRow driverAccount in driverPosition.GetAccountRows())
                        {
                            // Find the account associated with the driver record.
                            ClientMarketData.AccountRow accountRow =
                                ClientMarketData.Account.FindByAccountId(driverAccount.AccountId);

                            // The market value of all the securities are normalized to the base currency of the account
                            // so they can be aggregated.
                            ClientMarketData.CurrencyRow currencyRow =
                                ClientMarketData.Currency.FindByCurrencyId(accountRow.CurrencyId);

                            // Sector rebalancing keeps the percentage of a security within the sector constant.  Only the
                            // overall percentage of the sector with respect to the NAV changes.  The first step in this
                            // rebalancing operation is to calculate the market value of the given position.
                            decimal actualPositionMarketValue = MarketValue.Calculate(currencyRow, accountRow,
                                                                                      securityRow, driverPosition.PositionTypeCode, MarketValueFlags.EntirePosition);

                            // The target market value operation keeps the percentage of the position constant while
                            // changing the overall sector percentage.
                            decimal targetPositionMarketValue = (actualSectorMarketValue == 0) ? 0.0M :
                                                                actualPositionMarketValue * targetSectorMarketValue / actualSectorMarketValue;

                            // Calculate the market value of an order that will achieve the target.  Note that we're not
                            // including the existing proposed orders in the market value, but we did include them when
                            // calculating the account's market value.  This allows us to put in what-if orders that will
                            // impact the market value before we do the rebalancing.
                            decimal proposedMarketValue = targetPositionMarketValue - MarketValue.Calculate(currencyRow,
                                                                                                            accountRow, securityRow, driverPosition.PositionTypeCode,
                                                                                                            MarketValueFlags.ExcludeProposedOrder);

                            // Calculate the quantity needed to hit the target market value and round it according to the
                            // model.  Note that the market values and prices are all denominated in the currency of the
                            // parent account.  Also note the quantityFactor is needed for the proper quantity
                            // calculation.
                            decimal proposedQuantity = proposedMarketValue /
                                                       (Price.Security(currencyRow, securityRow) * securityRow.QuantityFactor);

                            // If we have an equity, round to the model's lot size.
                            if (securityRow.SecurityTypeCode == SecurityType.Equity)
                            {
                                proposedQuantity = Math.Round(proposedQuantity / modelRow.EquityRounding, 0) *
                                                   modelRow.EquityRounding;
                            }

                            // A debt generally needs to be rounded to face.
                            if (securityRow.SecurityTypeCode == SecurityType.Debt)
                            {
                                proposedQuantity = Math.Round(proposedQuantity / modelRow.DebtRounding, 0) *
                                                   modelRow.DebtRounding;
                            }

                            // Have the OrderForm object construct an order based on the quantity we've calcuated
                            // from the market value.  This will fill in the defaults for the order and translate the
                            // signed quantities into transaction codes.
                            ProposedOrder.Create(remoteBatch, remoteTransaction, accountRow, securityRow,
                                                 driverAccount.PositionTypeCode, proposedQuantity);
                        }
                    }
                }

                // Recurse into each of the sub-sectors.  This allows us to rebalance with any number of levels to the
                // hierarchy.  Eventually, we will run across a sector with security positions in it and end up doing some
                // real work.
                foreach (AppraisalSet.SectorRow childSector in objectTreeRow.ObjectRowByFKObjectObjectTreeChildId.GetSectorRows())
                {
                    SectorWrap.RecurseSectors(remoteBatch, remoteTransaction, modelRow, childSector, actualSectorMarketValue, targetSectorMarketValue);
                }
            }
        }
Beispiel #25
0
        /// <summary>
        /// Opens the document for the given object and it's argument.
        /// </summary>
        /// <param name="matchId">The primary identifier of the object to open.</param>
        /// <param name="argument">Options that can be used to further specify the document's properties.</param>
        public void OpenMatchCommand(object parameter)
        {
            // Extract the command argument.
            int matchId = (int)parameter;

            // This will force an empty placement and placement document to appear until we get some data.  It's the same
            // as forcing a drawing of the headers only.
            this.matchId = matchId;

            try
            {
                // Lock the tables
                System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked);
                ClientMarketData.EquityLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.MatchLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.ObjectLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.PriceLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.SecurityLock.AcquireReaderLock(CommonTimeout.LockWait);
                ClientMarketData.WorkingOrderLock.AcquireReaderLock(CommonTimeout.LockWait);

                // Install the event handlers.  The ClientMarketData component will advise us when the data has changed.
                ClientMarketData.MatchRow matchRow = ClientMarketData.Match.FindByMatchId(matchId);
                if (matchRow == null)
                {
                    return;
                }
                ClientMarketData.SecurityRow securityRow = matchRow.WorkingOrderRow.SecurityRowBySecurityWorkingOrderSecurityId;
                ClientMarketData.EquityRow   equityRow   = ClientMarketData.Equity.FindByEquityId(securityRow.SecurityId);
                if (equityRow == null)
                {
                    return;
                }
                string securityName = securityRow.ObjectRow.Name;
                ClientMarketData.PriceRow priceRow = ClientMarketData.Price.FindBySecurityId(securityRow.SecurityId);
                decimal price = priceRow.LastPrice;
                Invoke(displayDelegate, new object[] { securityName, price });
            }
            finally
            {
                if (ClientMarketData.EquityLock.IsReaderLockHeld)
                {
                    ClientMarketData.EquityLock.ReleaseReaderLock();
                }
                if (ClientMarketData.MatchLock.IsReaderLockHeld)
                {
                    ClientMarketData.MatchLock.ReleaseReaderLock();
                }
                if (ClientMarketData.ObjectLock.IsReaderLockHeld)
                {
                    ClientMarketData.ObjectLock.ReleaseReaderLock();
                }
                if (ClientMarketData.PriceLock.IsReaderLockHeld)
                {
                    ClientMarketData.PriceLock.ReleaseReaderLock();
                }
                if (ClientMarketData.SecurityLock.IsReaderLockHeld)
                {
                    ClientMarketData.SecurityLock.ReleaseReaderLock();
                }
                if (ClientMarketData.WorkingOrderLock.IsReaderLockHeld)
                {
                    ClientMarketData.WorkingOrderLock.ReleaseReaderLock();
                }
                System.Diagnostics.Debug.Assert(!ClientMarketData.IsLocked);
            }
        }