Beispiel #1
0
        /// <summary>
        /// Creates a temporary model based on the current sector 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 sector weights of the account.</returns>
        private static ModelBatch CreateSectorSelfModel(ClientMarketData.AccountRow accountRow, ClientMarketData.SchemeRow schemeRow)
        {
            // This command batch will create a temporary model and populate it with the current position level percentages as the
            // target values.
            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 model.
            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.Sector);
            insertModel.Parameters.Add("name", "Untitled");
            insertModel.Parameters.Add("schemeId", schemeRow.SchemeId);
            insertModel.Parameters.Add("algorithmId", Algorithm.SectorMergeRebalancer);
            insertModel.Parameters.Add("temporary", true);

            // The 'Self Sector' uses the market value of all the account and sub-account.
            decimal accountMarketValue = MarketValue.Calculate(accountRow.CurrencyRow, accountRow,
                                                               MarketValueFlags.EntirePosition | MarketValueFlags.IncludeChildAccounts);

            // No need to construct a model if the account market value is zero.
            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 industry classification sectors.
                Common.Appraisal appraisal = new Common.Appraisal(accountRow, schemeRow, true);

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

                // Now that we have an outline to follow, we are going to run through each of the sectors, calculate the market
                // value, and create an entry in the temporary model for that sector and it's current weight of the overall market
                // value.
                foreach (AppraisalSet.SchemeRow driverScheme in appraisal.Scheme)
                {
                    foreach (AppraisalSet.ObjectTreeRow driverTree in
                             driverScheme.ObjectRow.GetObjectTreeRowsByFKObjectObjectTreeParentId())
                    {
                        foreach (AppraisalSet.SectorRow driverSector in
                                 driverTree.ObjectRowByFKObjectObjectTreeChildId.GetSectorRows())
                        {
                            // This sector is the destination for the market value calculation.
                            ClientMarketData.SectorRow sectorRow = ClientMarketData.Sector.FindBySectorId(driverSector.SectorId);

                            // Calculate the market value of all the securities held by all the accounts in the current sector.
                            decimal sectorMarketValue = MarketValue.Calculate(accountRow.CurrencyRow, accountRow, sectorRow,
                                                                              MarketValueFlags.EntirePosition | MarketValueFlags.IncludeChildAccounts);

                            // Add the position level target to the model.
                            RemoteMethod insertSector = sectorTargetType.Methods.Add("Insert");
                            insertSector.Parameters.Add("modelId", insertModel.Parameters["modelId"]);
                            insertSector.Parameters.Add("sectorId", sectorRow.SectorId);
                            insertSector.Parameters.Add("percent", sectorMarketValue / accountMarketValue);
                        }
                    }
                }
            }

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

            // This batch will create a temporary model based on the sector totals of the original account.
            return(modelBatch);
        }
Beispiel #2
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 #3
0
        /// <summary>
        /// Constructs an AppraisalDocument.
        /// </summary>
        /// <param name="accountRow">A record containing the account or fund data.</param>
        /// <param name="modelRow">A record containing the model that is superimposed on the appraisal data for
        /// rebalancing.</param>
        public AppraisalDocument(ClientMarketData.AccountRow accountRow, ClientMarketData.ModelRow modelRow)
        {
            // Create a view of the proposed orders that makes it easy to aggregate by position.
            this.proposedOrderView      = new DataView(ClientMarketData.ProposedOrder);
            this.proposedOrderView.Sort = "[AccountId], [SecurityId], [PositionTypeCode]";

            // Create a view of the orders that makes it easy to aggregate by position.
            this.orderView      = new DataView(ClientMarketData.Order);
            this.orderView.Sort = "[AccountId], [SecurityId], [PositionTypeCode]";

            // Create a view of the allocations that makes it easy to aggregate by position.
            this.allocationView      = new DataView(ClientMarketData.Allocation);
            this.allocationView.Sort = "[AccountId], [SecurityId], [PositionTypeCode]";

            // This makes the account and model avaiable to the recursive methods.
            this.accountRow = accountRow;
            this.modelRow   = modelRow;

            // Create the root element and add it to the document.
            AppraisalElement rootElement = new AppraisalElement(this);

            this.AppendChild(rootElement);

            // Create and populate the DataSet that represents the outline of the appraisal.  This function creates a
            // set of linked structures that contains only the sectors, securities and positions that will appear in
            // this document. This driver is built from the bottom up, meaning that we start with the tax lots,
            // proposed orders, orders and allocations associated with the given account and build the driver up to
            // the topmost security classification scheme.  The alternative -- starting with the classification scheme
            // and building down until we join with the tax lots, etc, -- turned out to be six times slower.
            this.appraisal = new Common.Appraisal(accountRow, modelRow, true);

            // This sector is a catch-all heading for securities not mapped to the given hierarchy.  If everything is
            // mapped, then this sector won't appear in the document.
            SectorElement unclassifiedSector = null;

            // Now that the driver is built, we can begin constructing the document.  The first section is the
            // 'Unclassified' sector.  This section catches all securities that aren't explicitly mapped to the
            // hierarchy.  This is important because classification schemes are not guaranteed to map every security.
            // Without this section, those unmapped securities wouldn't appear on the appraisal and wouldn't be
            // included in the NAV calculation.  That is very bad.  Note also that we skip over the classification
            // scheme record during the check.  We know that the security classification scheme is at the top of the
            // hierarchy and won't have any parents.  Every other record that doesn't have a parent in the hierarchy
            // is 'Unclassified'.
            foreach (AppraisalSet.SecurityRow parentSecurity in this.appraisal.Security)
            {
                if (parentSecurity.ObjectRow.GetObjectTreeRowsByFKObjectObjectTreeChildId().Length == 0)
                {
                    // If the document doesn't have an 'Unclassified' sector yet, then add the sector heading.  All
                    // secutiries that are not mapped to the given hierarchy will appear under this catch-all header.
                    if (unclassifiedSector == null)
                    {
                        rootElement.InsertBySortOrder(unclassifiedSector = new SectorElement(this));
                    }

                    // Attach the each of the unclassified securities to the unclassified sector heading.
                    BuildDocument(unclassifiedSector, parentSecurity.ObjectRow);
                }
            }

            // The report is built recursively.  The 'AppraisalSet', constructed above, represents an 'inner join' of the
            // hierarchy information to the active position information.  We'll begin traversing the 'AppraisalSet' from
            // the top level security: a single node representing the classification scheme.
            foreach (AppraisalSet.SchemeRow schemeRow in this.appraisal.Scheme)
            {
                foreach (AppraisalSet.ObjectTreeRow objectTreeRow in schemeRow.ObjectRow.GetObjectTreeRowsByFKObjectObjectTreeParentId())
                {
                    BuildDocument(rootElement, objectTreeRow.ObjectRowByFKObjectObjectTreeChildId);
                }
            }
        }