Пример #1
0
        public PortfolioWork Adjust(PortfolioWork portfolio)
        {
            var port = portfolio.Portfolio;
            var ret  = portfolio.ReturnData;
            var pl   = 0M.AsMoney();

            foreach (var invest in port.ComputedInvestments())
            {
                var investmentPercentage = invest.Value;
                if (investmentPercentage > 1)
                {
                    investmentPercentage *= .01M;
                }
                var weightedReturn = (decimal)ret.NameToPercentageReturn[invest.Key] * investmentPercentage;
                var amt            = port.InvestmentAmount.GetClone();

                //Perhaps the best way to handle this is to note if you have 0 or less invested, then the performance ultimately should be 0.
                if (port.InvestmentAmount <= 0)
                {
                    amt = 0M.AsMoney();
                }
                var investmentReturn = weightedReturn * amt;
                pl += investmentReturn;
                portfolio.Returns.Returns.Add(invest.Key, investmentReturn);
            }
            portfolio.Returns.MonthProfitOrLoss = pl;

            port.InvestmentAmount += pl;

            return(portfolio);
        }
Пример #2
0
 public void Init(PortfolioWork portfolio)
 {
     if (!portfolio.ReturnData.NameToCape.ContainsKey(from))
     {
         throw new Exception($"Unable to find '{from}' in DisplayNameOfCapeMeasureToHeader.  Given current configuration would allow from to be: '{string.Join("','", portfolio.ReturnData.NameToCape.Keys)}'.");
     }
 }
Пример #3
0
        public PortfolioWork Adjust(PortfolioWork portfolio)
        {
            var maxCapeToDoNothing   = maxCapeBeforeAdjustment;
            var percentageAdjustment = percentageAdjusted;
            var amountOfAdditionalCapePerAdjustment = additionalAdjustmentPerCapeExcess;
            var cape = portfolio.ReturnData.NameToCape[from];

            if (cape == null || !cape.HasValue)
            {
                return(portfolio);
            }
            if (cape <= maxCapeToDoNothing)
            {
                return(portfolio);
            }

            var equity = portfolio.Portfolio.ComputedInvestments()[from];

            if (equity <= 0)
            {
                return(portfolio);            //no equity to remove...
            }
            var capeOverage      = cape - maxCapeToDoNothing;
            var actualAdjustment = (decimal)(capeOverage / amountOfAdditionalCapePerAdjustment) * percentageAdjustment;

            if (equity < actualAdjustment)
            {
                actualAdjustment = equity;
            }

            portfolio.Portfolio.TemporaryInvestmentAdjustments.Upsert(from, -1 * actualAdjustment);
            portfolio.Portfolio.TemporaryInvestmentAdjustments.Upsert(to, actualAdjustment);

            return(portfolio);
        }
Пример #4
0
        public Outcome CalculateMonthReturn(PortfolioWork portfolio)
        {
            var outcome = new Outcome
            {
                PreviousPortfolio      = portfolio.CopyOfPortfolio(),
                NewPortfolio           = adjuster.UpdatePortfolio(portfolio).CopyOfPortfolio(),
                PeriodNumber           = portfolio.MonthProcessed,
                ReturnDataDate         = new DateTime((int)portfolio.ReturnData.Year, (int)portfolio.ReturnData.Month, 1),
                Returns                = portfolio.Returns,
                TotalIncomeAndExpenses = portfolio.TotalIncomeAndExpenses,
            };


            return(outcome);
        }
Пример #5
0
        public PortfolioWork Adjust(PortfolioWork portfolio)
        {
            foreach (var item in Offsets)
            {
                if (item.StartMonth > portfolio.MonthProcessed)
                {
                    continue;
                }
                if (item.EndMonth != null && item.EndMonth < portfolio.MonthProcessed)
                {
                    continue;
                }

                portfolio.TotalIncomeAndExpenses     += item.OffsetAmount;
                portfolio.Portfolio.InvestmentAmount += item.OffsetAmount;
            }

            return(portfolio);
        }
Пример #6
0
 public PortfolioWork Adjust(PortfolioWork portfolio)
 {
     return(portfolio);
 }
Пример #7
0
 public void Init(PortfolioWork portfolio)
 {
 }
Пример #8
0
        public PortfolioWork Adjust(PortfolioWork portfolio)
        {
            if (callCount++ > 20)
            {
                return(portfolio);
            }
            var reprocess = false;

            if (max != null)
            {
                foreach (var item in max)
                {
                    var currentVal = portfolio.Portfolio.Investments[item.Key];
                    var maxVal     = item.Value;
                    if (currentVal > maxVal)
                    {
                        var overage = currentVal - maxVal;
                        reprocess = true;
                        portfolio.Portfolio.Investments[item.Key] = maxVal;
                        var portList = portfolio.Portfolio.Investments.GetClone().Where(a => a.Key != item.Key).ToList();

                        //Warning: This could end up with rounding errors in the 10th decimal place--probably doesn't matter.
                        foreach (var otherInvestments in portList)
                        {
                            portfolio.Portfolio.Investments[otherInvestments.Key] = otherInvestments.Value + (decimal)(overage / portList.Count());
                        }
                    }
                }
            }

            //TODO: This can be defeated by Temporary changes like CAPE adjustments.
            if (min != null)
            {
                foreach (var item in min)
                {
                    var currentVal = portfolio.Portfolio.Investments[item.Key];
                    var minVal     = item.Value;
                    if (currentVal < minVal)
                    {
                        var underage = minVal - currentVal;
                        reprocess = true;
                        portfolio.Portfolio.Investments[item.Key] = minVal;
                        var portList = portfolio.Portfolio.Investments.GetClone().Where(a => a.Key != item.Key).ToList();

                        var additionalOffset = 0M;
                        do
                        {
                            var newOffset = additionalOffset;
                            additionalOffset = 0M;
                            //Warning: This could end up with rounding errors in the 10th decimal place--probably doesn't matter.
                            foreach (var otherInvestments in portList)
                            {
                                var valueAdjustment = otherInvestments.Value - (decimal)((underage + newOffset) / portList.Count());
                                if (min.ContainsKey(otherInvestments.Key))
                                {
                                    if (min[otherInvestments.Key] > valueAdjustment)
                                    {
                                        additionalOffset += min[otherInvestments.Key] - valueAdjustment;
                                        valueAdjustment   = min[otherInvestments.Key];
                                    }
                                }
                                portfolio.Portfolio.Investments[otherInvestments.Key] = valueAdjustment;
                            }
                            if (additionalOffset != 0)
                            {
                                portList = portList.Where(a => portfolio.Portfolio.Investments[a.Key] != min.GetValueOrDefault(a.Key)).ToList();
                            }
                            underage = 0;
                        } while (additionalOffset != 0);
                    }
                }
            }

            if (reprocess)
            {
                return(Adjust(portfolio));
            }

            return(portfolio);
        }
Пример #9
0
 public void Init(PortfolioWork portfolio)
 {
     callCount = 0;
 }