public Computations CreateComputations(GlobeModel root, GlobeTraverser traverser)
        {
            var computations = new Computations();

            computations.BaseActiveFormula = this.CreateBaseActiveFormula();
            var portfolioAdjustmentTotal            = computations.PortfolioAdjustmentTotal = root.PortfolioAdjustment;
            var baseWherePortfoioAdjustmentSetTotal = computations.BaseWherePortfoioAdjustmentSetTotal = this.CreateBaseWherePortfoioAdjustmentSetTotal(traverser, root);

            computations.BaseLessOverlayFormula = this.CreateBaseLessOverlayFormula(
                this.CreateRescaledBaseFormula(
                    computations.BaseWherePortfoioAdjustmentSetTotal,
                    computations.PortfolioAdjustmentTotal
                    )
                );

            computations.CashBase         = this.CreateBaseForCash(this.CreateBaseForCashFormula(root));
            computations.CashRescaledBase = this.CreateRescaledBaseForCash(this.CreateRescaledBaseForCashFormula(computations.CashBase, baseWherePortfoioAdjustmentSetTotal, portfolioAdjustmentTotal));

            computations.BaseLessOverlayPositiveTotal = this.CreateBaseLessOverlayPositiveTotalExpression(root, traverser, computations.BaseLessOverlayFormula, computations.CashRescaledBase);
            computations.BaseLessOverlayTotal         = this.CreateBaseLessOverlayTotalExpression(root, traverser, computations.BaseLessOverlayFormula, computations.CashRescaledBase);
            computations.PortfolioScaledFormula       = this.CreatePortfolioScaledFormula(computations.BaseLessOverlayFormula, computations.BaseLessOverlayPositiveTotal, computations.BaseLessOverlayTotal);
            computations.CashPortfolioScaled          = this.CreateScaledCash(this.CreateCashScaledFormula(computations.CashRescaledBase, computations.BaseLessOverlayPositiveTotal, computations.BaseLessOverlayTotal));
            computations.TrueExposureFormula          = this.CreateTrueExposureFormula();
            computations.TrueActiveFormula            = this.CreateTrueActiveFormula();

            return(computations);
        }
        public BasketRegionModel CreateBasketRegionModel(
            ManagingBaskets.RegionBasket basket,
            IEnumerable <CountryModel> countries,
            Computations computations,
            EditableExpression baseExpression,
            EditableExpression portfolioAdjustmentExpression
            )
        {
            var result = new BasketRegionModel(
                basket,
                new SumExpression(
                    ValueNames.Benchmark,
                    countries.Select(x => x.Benchmark),
                    this.defaultValues.DefaultBenchmark,
                    this.commonParts.ValidateWhatever
                    ),
                baseExpression,
                self => new ModelFormulaExpression <IModel, Decimal?>(
                    ValueNames.BaseActive,
                    self,
                    computations.BaseActiveFormula,
                    this.commonParts.NullableDecimalValueAdapter,
                    this.commonParts.ValidateWhatever
                    ),
                new SumExpression(
                    ValueNames.Overlay,
                    countries.Select(x => x.Overlay),
                    this.defaultValues.DefaultOverlay,
                    this.commonParts.ValidateWhatever
                    ),
                portfolioAdjustmentExpression,
                self => new ModelFormulaExpression <IModel, Decimal?>(
                    ValueNames.PortfolioScaled,
                    self,
                    computations.PortfolioScaledFormula,
                    this.commonParts.NullableDecimalValueAdapter,
                    this.commonParts.ValidateWhatever
                    ),
                self => new ModelFormulaExpression <IModel, Decimal?>(
                    ValueNames.TrueExposure,
                    self,
                    computations.TrueExposureFormula,
                    this.commonParts.NullableDecimalValueAdapter,
                    this.commonParts.ValidateWhatever
                    ),
                self => new ModelFormulaExpression <IModel, Decimal?>(
                    ValueNames.TrueActive,
                    self,
                    computations.TrueActiveFormula,
                    this.commonParts.NullableDecimalValueAdapter,
                    this.commonParts.ValidateWhatever
                    ),
                countries
                );

            return(result);
        }
        public BasketCountryModel CreateBasketCountryModel(
            ManagingBaskets.CountryBasket basket,
            Computations computations,
            EditableExpression baseExpression,
            EditableExpression portfolioAdjustmentExpression
            )
        {
            var result = new BasketCountryModel(
                basket,
                new UnchangableExpression <Decimal>(
                    ValueNames.Benchmark,
                    this.defaultValues.DefaultBenchmark,
                    this.commonParts.DecimalValueAdapter,
                    this.commonParts.ValidateWhatever
                    ),
                baseExpression,
                self => new ModelFormulaExpression <IModel, Decimal?>(
                    ValueNames.BaseActive,
                    self,
                    computations.BaseActiveFormula,
                    this.commonParts.NullableDecimalValueAdapter,
                    this.commonParts.ValidateWhatever
                    ),
                new UnchangableExpression <Decimal>(
                    ValueNames.Overlay,
                    this.defaultValues.DefaultOverlay,
                    this.commonParts.DecimalValueAdapter,
                    this.commonParts.ValidateWhatever
                    ),
                portfolioAdjustmentExpression,
                self => new ModelFormulaExpression <IModel, Decimal?>(
                    ValueNames.PortfolioScaled,
                    self,
                    computations.PortfolioScaledFormula,
                    this.commonParts.NullableDecimalValueAdapter,
                    this.commonParts.ValidateWhatever
                    ),
                self => new ModelFormulaExpression <IModel, Decimal?>(
                    ValueNames.TrueExposure,
                    self,
                    computations.TrueExposureFormula,
                    this.commonParts.NullableDecimalValueAdapter,
                    this.commonParts.ValidateWhatever
                    ),
                self => new ModelFormulaExpression <IModel, Decimal?>(
                    ValueNames.TrueActive,
                    self,
                    computations.TrueActiveFormula,
                    this.commonParts.NullableDecimalValueAdapter,
                    this.commonParts.ValidateWhatever
                    ),
                this.commonParts
                );

            return(result);
        }
        protected void RegisterMissingCountriesIfAny(ManagingBpt.RootModel result, Computations computations, CountryRepository countryRepository, TargetingType targetingType, SecurityRepository securityRepository, PortfolioRepository portfolioRepository, ManagingPst.PortfolioSecurityTargetRepository portfolioSecurityTargetRepository, IEnumerable <BenchmarkSumByIsoInfo> benchmarks)
        {
            // figuring out missing ISO country codes (if any) from benchmarks and overlays
            var missingCountriesIsoCodes = this.countriesDetector.FindMissingCountries(
                targetingType.Taxonomy,
                benchmarks,
                result.Factors.Items.Where(x => x.OverlayFactor.EditedValue.HasValue).Select(x => x.BottomUpPortfolio.Name),
                portfolioSecurityTargetRepository,
                portfolioRepository,
                securityRepository
                );

            if (missingCountriesIsoCodes.Any())
            {
                List <string> clearedMissingCountriesIsoCode;
                var           traverser  = new GlobeTraverser();
                var           otherModel = traverser.TraverseGlobe(result.Globe).Where(m => m.TryAsOther() != null).FirstOrDefault();
                if (otherModel != null)
                {
                    clearedMissingCountriesIsoCode = new List <string>();
                    var codesInModel = otherModel.TryAsOther().UnsavedBasketCountries.Select(b => b.Country.IsoCode).Union(otherModel.TryAsOther().BasketCountries.Select(b => b.Basket.Country.IsoCode));
                    clearedMissingCountriesIsoCode.AddRange(codesInModel.Except(missingCountriesIsoCodes));
                }
                else
                {
                    clearedMissingCountriesIsoCode = new List <string>(missingCountriesIsoCodes);
                }

                if (clearedMissingCountriesIsoCode.Any())
                {
                    // there are some missing ISO country codes
                    // we need to resolve them to countries
                    // and put these countries to the taxonomy
                    var missingCountries = clearedMissingCountriesIsoCode.Select(x => countryRepository.GetCountry(x));
                    this.RegisterMissingCountries(result, missingCountries, computations);
                }
            }
        }
        public CashModel CreateCash(Computations computations)
        {
            var result = new CashModel(
                computations.CashBase,
                computations.CashPortfolioScaled,

/*
 * Add a Cash amount to the True Exposure column.
 * a.       Formula:  True Exposure Cash = Portfolio Scaled Cash
 * b.      Include Cash Amount in the Total row of the True Exposure column.
 */
                computations.CashPortfolioScaled,

/*
 * Add a Cash amount to the True Active column.
 * a.       Formula:  True Active Cash = Portfolio Scaled Cash – Benchmark Cash (Benchmark Cash should = 0).
 * b.      Include Cash Amount in the Total row of the True Exposure column.
 */
                computations.CashPortfolioScaled
                );

            return(result);
        }
        protected IRegionModelResident DeserializeRegionModelResidentOnceResolved(BasketRepository basketRepository, JsonReader reader, Computations computations)
        {
            IRegionModelResident result;
            var discriminator = reader.ReadAsString(JsonNames.Discriminator);

            if (discriminator == JsonNames.BasketRegion)
            {
                result = this.DeserializeBasketRegionModel(basketRepository, reader, computations);
            }
            else if (discriminator == JsonNames.BasketCountry)
            {
                result = this.DeserializeBasketCountryModel(basketRepository, reader, computations);
            }
            else if (discriminator == JsonNames.Region)
            {
                result = this.DeserializeRegionModel(basketRepository, reader, computations);
            }
            else
            {
                throw new ApplicationException("Unexpected discriminator \"" + discriminator + "\".");
            }

            return(result);
        }
        protected IGlobeResident DeserializeBreakdownResidentModelOnceResolver(BasketRepository basketRepository, JsonReader reader, Computations computations)
        {
            IGlobeResident resident;
            var            discriminator = reader.ReadAsString(JsonNames.Discriminator);

            if (discriminator == JsonNames.BasketRegion)
            {
                resident = this.DeserializeBasketRegionModel(basketRepository, reader, computations);
            }
            else if (discriminator == JsonNames.Region)
            {
                resident = this.DeserializeRegionModel(basketRepository, reader, computations);
            }
            else if (discriminator == JsonNames.Other)
            {
                resident = this.DeserializeOtherModel(basketRepository, reader, computations);
            }
            else
            {
                throw new ApplicationException("Unexpected discriminator \"" + discriminator + "\".");
            }
            return(resident);
        }
        protected OtherModel DeserializeOtherModel(BasketRepository basketRepository, JsonReader reader, Computations computations)
        {
            var basketCountries        = new List <BasketCountryModel>();
            var unsavedBasketCountries = new List <UnsavedBasketCountryModel>();


            reader.ReadArray(JsonNames.BasketCountries, delegate
            {
                reader.ReadAsString(JsonNames.Discriminator);
                var basketCountry = this.DeserializeBasketCountryModel(basketRepository, reader, computations);
                basketCountries.Add(basketCountry);
            });

            reader.ReadArray(JsonNames.UnsavedBasketCountries, delegate
            {
                reader.ReadAsString(JsonNames.Discriminator);
                var unsavedBasketCountry = this.DeserializeUnsavedBasketCountryModel(reader, computations);
                unsavedBasketCountries.Add(unsavedBasketCountry);
            });

            var result = this.modelBuilder.CreateOtherModel(
                basketCountries,
                unsavedBasketCountries
                );

            return(result);
        }
        protected RegionModel DeserializeRegionModel(BasketRepository basketRepository, JsonReader reader, Computations computations)
        {
            var name = reader.ReadAsString("name");

            var residents = new List <IRegionModelResident>();

            reader.ReadArray(JsonNames.Residents, delegate
            {
                var resident = this.DeserializeRegionModelResidentOnceResolved(basketRepository, reader, computations);
                residents.Add(resident);
            });

            var result = this.modelBuilder.CreateRegionModel(
                name,
                computations.BaseActiveFormula,
                residents
                );

            return(result);
        }
        protected UnsavedBasketCountryModel DeserializeUnsavedBasketCountryModel(JsonReader reader, Computations computations)
        {
            //var basketId = reader.ReadAsInt32(JsonNames.BasketId);

            var country = reader.Read(JsonNames.Country, delegate
            {
                return(this.DeserializeCountry(reader));
            });

            //var basket = basketRepository.GetBasket(basketId).AsCountryBasket();
            var result = this.modelBuilder.CreateUnsavedBasketModel(
                country,
                computations,
                this.modelBuilder.CreateBaseExpression(),
                this.modelBuilder.CreatePortfolioAdjustmentExpression()
                );

            reader.Read(JsonNames.Benchmark, delegate
            {
                this.expressionDeserializer.PopulateUnchangeableExpression(reader, result.Benchmark);
            });

            reader.Read(JsonNames.Base, delegate
            {
                this.expressionDeserializer.PopulateEditableExpression(reader, result.Base);
            });

            reader.Read(JsonNames.Overlay, delegate
            {
                this.expressionDeserializer.PopulateUnchangeableExpression(reader, result.Overlay);
            });

            reader.Read(JsonNames.PortfolioAdjustment, delegate
            {
                this.expressionDeserializer.PopulateEditableExpression(reader, result.PortfolioAdjustment);
            });

            return(result);
        }
        protected BasketRegionModel DeserializeBasketRegionModel(BasketRepository basketRepository, JsonReader reader, Computations computations)
        {
            var basketId = reader.ReadAsInt32(JsonNames.BasketId);
            var basket   = basketRepository.GetBasket(basketId).AsRegionBasket();

            var baseExpression = this.modelBuilder.CreateBaseExpression();

            reader.Read(JsonNames.Base, delegate
            {
                this.expressionDeserializer.PopulateEditableExpression(reader, baseExpression);
            });

            var portfolioAdjustmentExpression = this.modelBuilder.CreatePortfolioAdjustmentExpression();

            reader.Read(JsonNames.PortfolioAdjustment, delegate
            {
                this.expressionDeserializer.PopulateEditableExpression(reader, portfolioAdjustmentExpression);
            });

            var countries = reader.ReadArray(JsonNames.Countries, delegate
            {
                return(this.DeserializeCountryModel(reader));
            });

            var result = this.modelBuilder.CreateBasketRegionModel(
                basket,
                countries,
                computations,
                baseExpression,
                portfolioAdjustmentExpression
                );

            return(result);
        }
        public void RegisterMissingCountries(RootModel root, IEnumerable <Country> missingCountries, Computations computations)
        {
            if (!missingCountries.Any())
            {
                return;                                 // hey! there's nothing to do
            }
            var other = this.ClaimOtherModel(root);

            foreach (var country in missingCountries)
            {
                var baseExpression = this.modelBuilder.CreateBaseExpression();
                var portfolioAdjustmentExpression = this.modelBuilder.CreatePortfolioAdjustmentExpression();
                var unsavedBasketCountry          = this.modelBuilder.CreateUnsavedBasketModel(
                    country,
                    computations,
                    baseExpression,
                    portfolioAdjustmentExpression
                    );
                other.UnsavedBasketCountries.Add(unsavedBasketCountry);
            }
        }