/// <summary> /// Calculates the quantity of child order for a given position /// </summary> /// <param name="AccountId">The identifier of the account.</param> /// <param name="SecurityId">The identifier of the security.</param> /// <param name="positionTypeCode">The positionTypeCode (long or short).</param> /// <returns>The quantity of the child proposedOrder.</returns> public static decimal CalculateChildProposedQuantity(DataModel.AccountRow accountRow, DataModel.SecurityRow securityRow, int positionTypeCode) { // This is the accumulator for market value. decimal quantity = 0.0M; // Aggregate Proposed Order foreach (DataModel.ProposedOrderRow proposedOrderRow in accountRow.GetProposedOrderRows()) { if (Relationship.IsChildProposedOrder(proposedOrderRow) && proposedOrderRow.SecurityId == securityRow.SecurityId && proposedOrderRow.PositionTypeCode == positionTypeCode) { quantity += proposedOrderRow.Quantity * proposedOrderRow.TransactionTypeRow.QuantitySign; } } // If sub-account are to be included, recurse into the account structures. foreach (DataModel.ObjectTreeRow objectTreeRow in accountRow.ObjectRow.GetObjectTreeRowsByFKObjectObjectTreeParentId()) { foreach (DataModel.AccountRow childAccount in objectTreeRow.ObjectRowByFKObjectObjectTreeChildId.GetAccountRows()) { quantity += CalculateChildProposedQuantity(childAccount, securityRow, positionTypeCode); } } // This is the market value of the given account/security/position combination. return(quantity); }
/// <summary> /// Calculates the market market value of the account and, optinally, all the sub-account. /// </summary> /// <param name="baseCurrency">The identifier of the base currency.</param> /// <param name="accountRow">The identifier of the account.</param> /// <returns>The market value of the account and, optinally, all the sub account in the base currency.</returns> public static decimal Calculate(DataModel.CurrencyRow baseCurrency, DataModel.AccountRow accountRow, MarketValueFlags marketValueFlags) { // This is the accumulator for market value. decimal marketValue = 0.0M; // Add up all the taxLot. if ((marketValueFlags & MarketValueFlags.IncludeTaxLot) != 0) { foreach (DataModel.TaxLotRow taxLotRow in accountRow.GetTaxLotRows()) { marketValue += Calculate(baseCurrency, taxLotRow); } } // Add up all the proposedOrder. if ((marketValueFlags & MarketValueFlags.IncludeProposedOrder) != 0) { foreach (DataModel.ProposedOrderRow proposedOrderRow in accountRow.GetProposedOrderRows()) { marketValue += Calculate(baseCurrency, proposedOrderRow); } } // Add up all the order. if ((marketValueFlags & MarketValueFlags.IncludeOrder) != 0) { foreach (DataModel.OrderRow SetPrice in accountRow.GetOrderRows()) { marketValue += Calculate(baseCurrency, SetPrice); } } // Add up all the allocation. if ((marketValueFlags & MarketValueFlags.IncludeAllocation) != 0) { foreach (DataModel.AllocationRow allocationRow in accountRow.GetAllocationRows()) { marketValue += Calculate(baseCurrency, allocationRow); } } // Add in the market value of the sub-account. if ((marketValueFlags & MarketValueFlags.IncludeChildAccounts) != 0) { foreach (DataModel.ObjectTreeRow objectTreeRow in accountRow.ObjectRow.GetObjectTreeRowsByFKObjectObjectTreeParentId()) { foreach (DataModel.AccountRow childAccount in objectTreeRow.ObjectRowByFKObjectObjectTreeChildId.GetAccountRows()) { marketValue += Calculate(baseCurrency, childAccount, marketValueFlags); } } } // This is the market value of the given account in the base currency. return(marketValue); }
/// <summary> /// Constructs a hierarchical view of the appraisal including the active position and the positionTarget. /// </summary> /// <param name="AccountId"> identifier of the account.</param> /// <remarks> /// Table locks needed: /// Read: Allocation /// Read: Account /// Read: Model /// Read: PositionTarget /// Read: ProposedOrder /// Read: Object /// Read: ObjectTree /// Read: Order /// Read: Scheme /// Read: Security /// Read: TaxLot /// </remarks> public Appraisal(DataModel.AccountRow accountRow, bool includeChildren) { // Clearing out the schema record will exclude any sector information in the outline. this.schemeRow = null; // Recursively build the document outline from the active position. BuildAppraisalSet(accountRow, includeChildren); }
/// <summary> /// Constructs a hierarchical view of the appraisal including the active position and the positionTarget. /// </summary> /// <param name="accountRow">The parent account used to construct the outline.</param> /// <param name="schemeRow">The security classification scheme used to construct the outline.</param> /// <remarks> /// Table locks needed: /// Read: Allocation /// Read: Account /// Read: Model /// Read: PositionTarget /// Read: ProposedOrder /// Read: Object /// Read: ObjectTree /// Read: Order /// Read: Scheme /// Read: Security /// Read: TaxLot /// </remarks> public Appraisal(DataModel.AccountRow accountRow, DataModel.SchemeRow schemeRow, bool includeChildren) { // The scheme record drives the building of the appraisal. this.schemeRow = schemeRow; // Recursively build the document outline from the active position. BuildAppraisalSet(accountRow, includeChildren); }
/// <summary> /// Recursively populate an array of accounts associated with the parent account /// </summary> /// <param name="accountList">The array used to collect account identifiers.</param> /// <param name="parentAccount">The current parent account in the hierachical search.</param> private static void GetAccountList(ArrayList accountList, DataModel.AccountRow parentAccount) { // Populate the array with each of the children account ids and then recurse into those children and collect the // grand-children. This process continues until there are no more children to add to the array. foreach (DataModel.ObjectTreeRow parentObjectTree in parentAccount.ObjectRow.GetObjectTreeRowsByFKObjectObjectTreeParentId()) { foreach (DataModel.AccountRow childAccount in parentObjectTree.ObjectRowByFKObjectObjectTreeChildId.GetAccountRows()) { accountList.Add(childAccount.AccountId); GetAccountList(accountList, childAccount); } } }
/// <summary> /// Constructs a hierarchical view of the appraisal including the active position and the positionTarget. /// </summary> /// <param name="AccountId">The account identifier.</param> /// <param name="ModelId">The model identifier.</param> /// <remarks> /// Table locks needed: /// Read: Allocation /// Read: Account /// Read: Model /// Read: PositionTarget /// Read: ProposedOrder /// Read: Object /// Read: ObjectTree /// Read: Order /// Read: Scheme /// Read: Security /// Read: TaxLot /// </remarks> public Appraisal(DataModel.AccountRow accountRow, DataModel.ModelRow modelRow, bool includeChildren) { // Only the sector that are in this scheme are included in the outline. If no scheme is found, there // won't be any security classification data in the outline. int SchemeId = (modelRow.IsSchemeIdNull()) ? accountRow.SchemeId : modelRow.SchemeId; this.schemeRow = DataModel.Scheme.FindBySchemeId(SchemeId); // Add each of the SecurityIdentified in the model to the document outline. foreach (DataModel.PositionTargetRow positionTargetRows in modelRow.GetPositionTargetRows()) { BuildSecurity(accountRow.AccountId, positionTargetRows.SecurityId, positionTargetRows.PositionTypeCode); } // Recursively build the document outline from the active position. BuildAppraisalSet(accountRow, includeChildren); }
/// <summary> /// Recursively constructs a DataSet containing the outline of the document. /// </summary> /// <param name="accountRow">The current branch of the account hierarchy in the search.</param> /// <remarks> /// Locks needed: /// Read: Account /// Read: Allocation /// Read: Object /// Read: ObjectTree /// Read: Order /// Read: ProposedOrder /// Read: Sector /// Read: TaxLot /// </remarks> protected void BuildAppraisalSet(DataModel.AccountRow accountRow, bool includeChildren) { // Add all the distinct taxLot to the outline. foreach (DataModel.TaxLotRow taxLotRow in accountRow.GetTaxLotRows()) { BuildSecurity(taxLotRow.AccountId, taxLotRow.SecurityId, taxLotRow.PositionTypeCode); } // Add all the distinct proposedOrder to the outline. foreach (DataModel.ProposedOrderRow proposedOrderRow in accountRow.GetProposedOrderRows()) { BuildSecurity(proposedOrderRow.AccountId, proposedOrderRow.SecurityId, proposedOrderRow.PositionTypeCode); } // Add all the distinct order to the outline. foreach (DataModel.OrderRow SetPrice in accountRow.GetOrderRows()) { BuildSecurity(SetPrice.AccountId, SetPrice.SecurityId, SetPrice.PositionTypeCode); } // Add all the distinct allocation to the outline. foreach (DataModel.AllocationRow allocationRow in accountRow.GetAllocationRows()) { BuildSecurity(allocationRow.AccountId, allocationRow.SecurityId, allocationRow.PositionTypeCode); } // Now, if requested, recurse down into all the subaccount and add their distinct characteristics to the outline. if (includeChildren) { foreach (DataModel.ObjectTreeRow objectTreeRow in accountRow.ObjectRow.GetObjectTreeRowsByFKObjectObjectTreeParentId()) { foreach (DataModel.AccountRow childAccount in objectTreeRow.ObjectRowByFKObjectObjectTreeChildId.GetAccountRows()) { BuildAppraisalSet(childAccount, includeChildren); } } } }
/// <summary> /// Get an array of accounts associated with the parent account /// </summary> /// <param name="accountId">The parent account id.</param> /// <returns>An array containing all the included identifiers in the given parent account's hierarchy.</returns> public static int[] GetAccountList(int accountId) { // Get the account record from the database. DataModel.AccountRow accountRow = DataModel.Account.FindByAccountId(accountId); if (accountRow == null) { throw new Exception(String.Format("Account {0} has been deleted", accountId)); } // This array is used to collect all the child account identifiers. The parent account is always part of the // hierarchy, so include it here as the seed for this recursive action. ArrayList accountList = new ArrayList(); accountList.Add(accountId); // Recursively search the object hierarchy looking for children of this account. GetAccountList(accountList, accountRow); // Copy the list into an array. int[] accountArray = new int[accountList.Count]; accountList.CopyTo(accountArray); return(accountArray); }
/// <summary> /// Calculates the market value of a sector in an account. /// </summary> /// <param name="baseCurrency">The base currency for the market value calculation.</param> /// <param name="accountRow">The identifier of the account.</param> /// <param name="SecurityId">The identifier of the security.</param> /// <param name="marketValueFlags">These flags direct what elements are included and whether to include /// children.</param> /// <returns>The market value of the position.</returns> public static decimal Calculate(DataModel.CurrencyRow baseCurrency, DataModel.AccountRow accountRow, DataModel.SectorRow sectorRow, MarketValueFlags marketValueFlags) { // This is the accumulator for market value. decimal marketValue = 0.0M; // Aggregate the market value of sub-sector. foreach (DataModel.ObjectTreeRow objectTreeRow in sectorRow.ObjectRow.GetObjectTreeRowsByFKObjectObjectTreeParentId()) { foreach (DataModel.SectorRow childSector in objectTreeRow.ObjectRowByFKObjectObjectTreeChildId.GetSectorRows()) { marketValue += Calculate(baseCurrency, accountRow, childSector, marketValueFlags); } } // Aggregate the market value of all security belonging to this sector. foreach (DataModel.ObjectTreeRow objectTreeRow in sectorRow.ObjectRow.GetObjectTreeRowsByFKObjectObjectTreeParentId()) { foreach (DataModel.SecurityRow childSecurity in objectTreeRow.ObjectRowByFKObjectObjectTreeChildId.GetSecurityRows()) { // Aggregate the Long Position in this security in this account. marketValue += Calculate(baseCurrency, accountRow, childSecurity, PositionType.Long, marketValueFlags); // Aggregate the Short Position in this security in this account. marketValue += Calculate(baseCurrency, accountRow, childSecurity, PositionType.Short, marketValueFlags); } } // This is the market value of the given account/sector combination. return(marketValue); }
/// <summary> /// Calculates the market value of a position. /// </summary> /// <param name="baseCurrency">The base currency for the market value calculation.</param> /// <param name="accountRow">The identifier of the account.</param> /// <param name="SecurityId">The identifier of the security.</param> /// <param name="PositionTypeCode">The PositionTypeCode (long or short).</param> /// <param name="marketValueFlags">These flags direct what elements are included and whether to include /// children.</param> /// <returns></returns> public static decimal Calculate(DataModel.CurrencyRow baseCurrency, DataModel.AccountRow accountRow, DataModel.SecurityRow securityRow, int PositionTypeCode, MarketValueFlags marketValueFlags) { // This is the accumulator for market value. decimal marketValue = 0.0M; // Aggregate Tax Lots if ((marketValueFlags & MarketValueFlags.IncludeTaxLot) != 0) { foreach (DataModel.TaxLotRow taxLotRow in accountRow.GetTaxLotRows()) { if (taxLotRow.SecurityId == securityRow.SecurityId && taxLotRow.PositionTypeCode == PositionTypeCode) { marketValue += Calculate(baseCurrency, taxLotRow); } } } // Aggregate Proposed Order if ((marketValueFlags & MarketValueFlags.IncludeProposedOrder) != 0) { foreach (DataModel.ProposedOrderRow proposedOrderRow in accountRow.GetProposedOrderRows()) { if (proposedOrderRow.SecurityId == securityRow.SecurityId && proposedOrderRow.PositionTypeCode == PositionTypeCode) { marketValue += Calculate(baseCurrency, proposedOrderRow); } } } // Aggregate Order if ((marketValueFlags & MarketValueFlags.IncludeOrder) != 0) { foreach (DataModel.OrderRow SetPrice in accountRow.GetOrderRows()) { if (SetPrice.SecurityId == securityRow.SecurityId && SetPrice.PositionTypeCode == PositionTypeCode) { marketValue += Calculate(baseCurrency, SetPrice); } } } // Aggregate Allocation if ((marketValueFlags & MarketValueFlags.IncludeAllocation) != 0) { foreach (DataModel.AllocationRow allocationRow in accountRow.GetAllocationRows()) { if (allocationRow.SecurityId == securityRow.SecurityId && allocationRow.PositionTypeCode == PositionTypeCode) { marketValue += Calculate(baseCurrency, allocationRow); } } } // If sub-account are to be included, recurse into the account structures. if ((marketValueFlags & MarketValueFlags.IncludeChildAccounts) != 0) { foreach (DataModel.ObjectTreeRow objectTreeRow in accountRow.ObjectRow.GetObjectTreeRowsByFKObjectObjectTreeParentId()) { foreach (DataModel.AccountRow childAccount in objectTreeRow.ObjectRowByFKObjectObjectTreeChildId.GetAccountRows()) { marketValue += Calculate(baseCurrency, childAccount, securityRow, PositionTypeCode, marketValueFlags); } } } // This is the market value of the given account/security/position combination. return(marketValue); }
/// <summary> /// Calculates the number of shares in a given position. /// </summary> /// <param name="baseCurrency">The base currency for the market value calculation.</param> /// <param name="AccountId">The identifier of the account.</param> /// <param name="SecurityId">The identifier of the security.</param> /// <param name="positionTypeCode">The PositionTypeCode (long or short).</param> /// <param name="quantityFlags">These flags direct what elements are included and whether to include /// children.</param> /// <returns></returns> public static decimal Calculate(DataModel.AccountRow accountRow, DataModel.SecurityRow securityRow, int positionTypeCode, MarketValueFlags quantityFlags) { // This is the accumulator for market value. decimal quantity = 0.0M; // This key is used to find records that match the given position. object[] key = new object[] { accountRow.AccountId, securityRow.SecurityId, positionTypeCode }; // Aggregate Tax Lots if ((quantityFlags & MarketValueFlags.IncludeTaxLot) != 0) { foreach (DataRowView dataRowView in DataModel.TaxLot.UKTaxLotAccountIdSecurityIdPositionTypeCode.FindRows(key)) { quantity += ((DataModel.TaxLotRow)dataRowView.Row).Quantity; } } // Aggregate Proposed Order if ((quantityFlags & MarketValueFlags.IncludeProposedOrder) != 0) { foreach (DataRowView dataRowView in DataModel.ProposedOrder.UKProposedOrderAccountIdSecurityIdPositionTypeCode.FindRows(key)) { DataModel.ProposedOrderRow proposedProposedOrderRow = (DataModel.ProposedOrderRow)dataRowView.Row; quantity += proposedProposedOrderRow.Quantity * proposedProposedOrderRow.TransactionTypeRow.QuantitySign; } } // Aggregate Order if ((quantityFlags & MarketValueFlags.IncludeOrder) != 0) { foreach (DataRowView dataRowView in DataModel.Order.UKOrderAccountIdSecurityIdPositionTypeCode.FindRows(key)) { DataModel.OrderRow orderRow = (DataModel.OrderRow)dataRowView.Row; quantity += orderRow.Quantity * orderRow.TransactionTypeRow.QuantitySign; } } // Aggregate Allocation if ((quantityFlags & MarketValueFlags.IncludeAllocation) != 0) { foreach (DataRowView dataRowView in DataModel.Allocation.UKAllocationAccountIdSecurityIdPositionTypeCode.FindRows(key)) { DataModel.AllocationRow allocationRow = (DataModel.AllocationRow)dataRowView.Row; quantity += allocationRow.Quantity * allocationRow.TransactionTypeRow.QuantitySign; } } // If sub-account are to be included, recurse into the account structures. if ((quantityFlags & MarketValueFlags.IncludeChildAccounts) != 0) { foreach (DataModel.ObjectTreeRow objectTreeRow in accountRow.ObjectRow.GetObjectTreeRowsByFKObjectObjectTreeParentId()) { foreach (DataModel.AccountRow childAccount in objectTreeRow.ObjectRowByFKObjectObjectTreeChildId.GetAccountRows()) { quantity += Calculate(childAccount, securityRow, positionTypeCode, quantityFlags); } } } // This is the market value of the given account/security/position combination. return(quantity); }