init
This commit is contained in:
42
MarketDataLib/ValueAtRisk/BinItem.cs
Normal file
42
MarketDataLib/ValueAtRisk/BinItem.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace MarketData.ValueAtRisk
|
||||
{
|
||||
public class BinItem<T>
|
||||
{
|
||||
private double binValue;
|
||||
private long binCount;
|
||||
private T binObject;
|
||||
|
||||
public BinItem(double binValue)
|
||||
{
|
||||
this.binCount=0;
|
||||
this.binValue = binValue;
|
||||
this.binObject=default(T);
|
||||
}
|
||||
public BinItem(double binValue,T binObject)
|
||||
{
|
||||
this.binCount=0;
|
||||
this.binValue = binValue;
|
||||
this.binObject=binObject;
|
||||
}
|
||||
public double BinValue
|
||||
{
|
||||
get { return binValue; }
|
||||
set { binValue = value; }
|
||||
}
|
||||
public long BinCount
|
||||
{
|
||||
get { return binCount; }
|
||||
set { binCount = value; }
|
||||
}
|
||||
public T BinObject
|
||||
{
|
||||
get{return binObject;}
|
||||
set{binObject=value;}
|
||||
}
|
||||
}
|
||||
}
|
||||
147
MarketDataLib/ValueAtRisk/BinManager.cs
Normal file
147
MarketDataLib/ValueAtRisk/BinManager.cs
Normal file
@@ -0,0 +1,147 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace MarketData.ValueAtRisk
|
||||
{
|
||||
public class BinResult<T>
|
||||
{
|
||||
public double Value{get;private set;}
|
||||
public T Item{get;private set;}
|
||||
public BinResult()
|
||||
{
|
||||
}
|
||||
public BinResult(double value,T item)
|
||||
{
|
||||
this.Value=value;
|
||||
this.Item=item;
|
||||
}
|
||||
}
|
||||
public class BinManager<T>
|
||||
{
|
||||
private List<BinItem<T>> binItems;
|
||||
private long binCount;
|
||||
private long samples;
|
||||
|
||||
public BinManager(long binCount=100)
|
||||
{
|
||||
this.binCount = binCount;
|
||||
InitializeBins();
|
||||
}
|
||||
private void InitializeBins()
|
||||
{
|
||||
this.binItems = new List<BinItem<T>>();
|
||||
this.samples=0;
|
||||
}
|
||||
public BinResult<T> GetVaRReturn(double[] values,List<T> items,double percentile)
|
||||
{
|
||||
double minValue = float.NaN;
|
||||
double maxValue = float.NaN;
|
||||
double binSize = double.NaN;
|
||||
T item=default(T);
|
||||
|
||||
InitializeBins();
|
||||
GetMinMax(ref minValue,ref maxValue,values);
|
||||
binSize=(maxValue-minValue)/(double)binCount;
|
||||
for (double value = minValue; value < maxValue; value += binSize)
|
||||
{
|
||||
binItems.Add(new BinItem<T>(value));
|
||||
}
|
||||
for (int index = 0; index < values.Length; index++)
|
||||
{
|
||||
AddValueToBin(values[index]);
|
||||
AddObjectToBin(values[index],items[index]);
|
||||
}
|
||||
double samplesAtRank = samples-(samples * (percentile/100.00));
|
||||
if (samplesAtRank < 1) samplesAtRank = 1;
|
||||
long samplesInRank = 0;
|
||||
double percentVaR = 0;
|
||||
for (int index = 0; index < binItems.Count; index++)
|
||||
{
|
||||
BinItem<T> binItem = binItems[index];
|
||||
samplesInRank += binItem.BinCount;
|
||||
percentVaR = binItem.BinValue;
|
||||
item=binItem.BinObject;
|
||||
if (samplesInRank > samplesAtRank) break;
|
||||
}
|
||||
return new BinResult<T>(percentVaR,item);
|
||||
}
|
||||
public double GetVaRReturn(double[] values,double percentile)
|
||||
{
|
||||
double minValue = float.NaN;
|
||||
double maxValue = float.NaN;
|
||||
double binSize = double.NaN;
|
||||
|
||||
InitializeBins();
|
||||
GetMinMax(ref minValue,ref maxValue,values);
|
||||
binSize=(maxValue-minValue)/(double)binCount;
|
||||
for (double value = minValue; value < maxValue; value += binSize)
|
||||
{
|
||||
binItems.Add(new BinItem<T>(value));
|
||||
}
|
||||
for (int index = 0; index < values.Length; index++)
|
||||
{
|
||||
AddValueToBin(values[index]);
|
||||
}
|
||||
double samplesAtRank = samples-(samples * (percentile/100.00));
|
||||
if (samplesAtRank < 1) samplesAtRank = 1;
|
||||
long samplesInRank = 0;
|
||||
double percentVaR = 0;
|
||||
for (int index = 0; index < binItems.Count; index++)
|
||||
{
|
||||
BinItem<T> binItem = binItems[index];
|
||||
samplesInRank += binItem.BinCount;
|
||||
percentVaR = binItem.BinValue;
|
||||
if (samplesInRank > samplesAtRank) break;
|
||||
}
|
||||
return percentVaR;
|
||||
}
|
||||
private static void GetMinMax(ref double minValue,ref double maxValue,double[] values)
|
||||
{
|
||||
for (int index = 0; index < values.Length; index++)
|
||||
{
|
||||
double value = values[index];
|
||||
if (0 == index)
|
||||
{
|
||||
minValue = maxValue = value;
|
||||
continue;
|
||||
}
|
||||
if (value > maxValue) maxValue = value;
|
||||
if (value < minValue) minValue = value;
|
||||
}
|
||||
}
|
||||
private void AddValueToBin(double value)
|
||||
{
|
||||
bool added = false;
|
||||
samples++;
|
||||
for (int index = 0; index < binItems.Count; index++)
|
||||
{
|
||||
BinItem<T> binItem = binItems[index];
|
||||
if (value <= binItem.BinValue)
|
||||
{
|
||||
binItem.BinCount++;
|
||||
added = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (false == added && binItems.Count>0) binItems[binItems.Count - 1].BinCount++;
|
||||
}
|
||||
private void AddObjectToBin(double value,T item)
|
||||
{
|
||||
bool added = false;
|
||||
// samples++;
|
||||
for (int index = 0; index < binItems.Count; index++)
|
||||
{
|
||||
BinItem<T> binItem = binItems[index];
|
||||
if (value <= binItem.BinValue)
|
||||
{
|
||||
binItem.BinObject=item;
|
||||
added = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (false == added && binItems.Count>0) binItems[binItems.Count - 1].BinObject=item;
|
||||
}
|
||||
}
|
||||
}
|
||||
91
MarketDataLib/ValueAtRisk/HVaR.cs
Normal file
91
MarketDataLib/ValueAtRisk/HVaR.cs
Normal file
@@ -0,0 +1,91 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using MarketData.DataAccess;
|
||||
using MarketData.Utils;
|
||||
|
||||
namespace MarketData.ValueAtRisk
|
||||
{
|
||||
public class HistoricalVaR
|
||||
{
|
||||
private int returnDays = 1;
|
||||
|
||||
private HistoricalVaR()
|
||||
{
|
||||
}
|
||||
public static VaRResult GetVaR(PortfolioHoldings portfolioHoldings, double percentile,int returnDays=1)
|
||||
{
|
||||
VaRResult varResult=new VaRResult();
|
||||
if (null == portfolioHoldings || 0 == portfolioHoldings.Count)
|
||||
{
|
||||
varResult.Success=false;
|
||||
return varResult;
|
||||
}
|
||||
// This ensures that the pricing information for each holding is symmetric.
|
||||
// The piece of code that checks for jagged pricing should be handled differently. For example, we should be able to continue the VaR analysis and simply account for no exposure to the
|
||||
// given symbol in the event of a lack of pricing data. This would handle the current issue with securities that have been trading for less than the number of observation days.
|
||||
if (portfolioHoldings.Count > 1)
|
||||
{
|
||||
int priceCount=-1;
|
||||
for (int index = 1; index < portfolioHoldings.Count; index++)
|
||||
{
|
||||
if(portfolioHoldings[index].Prices.Count>priceCount)priceCount=portfolioHoldings[index].Prices.Count;
|
||||
}
|
||||
for (int index = 1; index < portfolioHoldings.Count; index++)
|
||||
{
|
||||
if (portfolioHoldings[index].Prices.Count != priceCount)
|
||||
{
|
||||
varResult.Success=false;
|
||||
varResult.Message=String.Format("Insufficient price history for {0}. {1}/{2}",portfolioHoldings[index].Symbol,portfolioHoldings[index].Prices.Count,priceCount);
|
||||
return varResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Calculate total market value and then calculate the weightings of each holding
|
||||
double marketValue = portfolioHoldings.GetMarketValue();
|
||||
for (int index = 0; index < portfolioHoldings.Count; index++)
|
||||
{
|
||||
PortfolioHolding portfolioHolding = portfolioHoldings[index];
|
||||
portfolioHolding.Weight = portfolioHolding.MarketValue / marketValue;
|
||||
}
|
||||
// Calculate the weighted returns for the observation period
|
||||
portfolioHoldings.SetReturnDays(returnDays);
|
||||
int numReturns=portfolioHoldings[0].Returns.Length;
|
||||
WeightedReturnsWithContribution weightedReturnsWithContrbution=new WeightedReturnsWithContribution();
|
||||
for (int index = 0; index < numReturns; index++)
|
||||
{
|
||||
for (int portfolioIndex = 0; portfolioIndex < portfolioHoldings.Count; portfolioIndex++)
|
||||
{
|
||||
PortfolioHolding portfolioHolding = portfolioHoldings[portfolioIndex];
|
||||
WeightedReturn weightedReturn=new WeightedReturn(portfolioHolding.Symbol,portfolioHolding.Prices[index].Date,portfolioHolding.Returns[index] * portfolioHolding.Weight);
|
||||
weightedReturnsWithContrbution.Add(index,weightedReturn);
|
||||
}
|
||||
}
|
||||
double[] weightedReturns=weightedReturnsWithContrbution.GetWeightedReturns();
|
||||
List<Contributions> contributionsList=weightedReturnsWithContrbution.GetContributions();
|
||||
// Organize the weighted returns into bins so we can access the nth percentile rank
|
||||
// The VaR nth percentile VaR is simply the weighted return at the given rank (i.e.) 90%, 95%, 99% within the bin
|
||||
// The VaR result will be a negative percent and negative amount to show that this is a loss. We display this as a positive number so we need to take the absolute value of the result
|
||||
// ** To Do ** bring out the contributors to VaR at the given rank.
|
||||
BinManager<Contributions> binManager = new BinManager<Contributions>();
|
||||
BinResult<Contributions> binResult=binManager.GetVaRReturn(weightedReturns,contributionsList,percentile);
|
||||
Contributions contributions=binResult.Item;
|
||||
if(null==contributions){varResult.Success=false;return varResult;}
|
||||
Dictionary<String,PortfolioHolding> portfolioHoldingsBySymbol=new Dictionary<String,PortfolioHolding>();
|
||||
foreach(PortfolioHolding portfolioHolding in portfolioHoldings){if(!portfolioHoldingsBySymbol.ContainsKey(portfolioHolding.Symbol))portfolioHoldingsBySymbol.Add(portfolioHolding.Symbol,portfolioHolding);}
|
||||
foreach(Contribution contribution in contributions)
|
||||
{
|
||||
if(!portfolioHoldingsBySymbol.ContainsKey(contribution.Symbol))continue;
|
||||
portfolioHoldingsBySymbol[contribution.Symbol].Contribution=contribution.ContributionValue;
|
||||
portfolioHoldingsBySymbol[contribution.Symbol].ContributionDate=contribution.AnalysisDate;
|
||||
}
|
||||
return new VaRResult(binResult.Value, portfolioHoldings.GetMarketValue() * binResult.Value);
|
||||
}
|
||||
public int ReturnDays
|
||||
{
|
||||
get { return returnDays; }
|
||||
set { returnDays = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
163
MarketDataLib/ValueAtRisk/PortfolioHoldings.cs
Normal file
163
MarketDataLib/ValueAtRisk/PortfolioHoldings.cs
Normal file
@@ -0,0 +1,163 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using MarketData.DataAccess;
|
||||
using MarketData.MarketDataModel;
|
||||
|
||||
namespace MarketData.ValueAtRisk
|
||||
{
|
||||
public class PortfolioHoldings : List<PortfolioHolding>
|
||||
{
|
||||
public PortfolioHoldings()
|
||||
{
|
||||
}
|
||||
public void SetReturnDays(int days)
|
||||
{
|
||||
for (int index = 0; index < Count; index++)
|
||||
{
|
||||
PortfolioHolding portfolioHolding = this[index];
|
||||
portfolioHolding.SetReturnDays(days);
|
||||
}
|
||||
}
|
||||
public double GetMarketValue()
|
||||
{
|
||||
return (from portfolioHolding in this select portfolioHolding.MarketValue).Sum();
|
||||
}
|
||||
public void UpdateDayCount(int dayCount)
|
||||
{
|
||||
for (int index = 0; index < Count; index++)
|
||||
{
|
||||
PortfolioHolding portfolioHolding = this[index];
|
||||
portfolioHolding.Prices = PricingDA.GetPrices(portfolioHolding.Symbol, portfolioHolding.AsOf, dayCount + 1);
|
||||
portfolioHolding.MarketValue = portfolioHolding.Prices[0].Close * portfolioHolding.Shares;
|
||||
}
|
||||
double totalMarketValue = (from portfolioHolding in this select portfolioHolding.MarketValue).Sum();
|
||||
ForEach(portfolioHolding => new Action(delegate() { portfolioHolding.Weight = portfolioHolding.MarketValue / totalMarketValue; }).Invoke());
|
||||
}
|
||||
public static PortfolioHoldings GetPortfolioHoldings(PortfolioTrades portfolioTrades,int dayCount,DateTime startDate)
|
||||
{
|
||||
if (null == portfolioTrades || 0 == portfolioTrades.Count) return null;
|
||||
PortfolioHoldings portfolioHoldings = new PortfolioHoldings();
|
||||
List<String> symbols = (from portfolioTrade in portfolioTrades select portfolioTrade.Symbol).Distinct().ToList();
|
||||
for (int index = 0; index < symbols.Count; index++)
|
||||
{
|
||||
String symbol = symbols[index];
|
||||
List<PortfolioTrade> trades = (from portfolioTrade in portfolioTrades where portfolioTrade.Symbol.Equals(symbol) select portfolioTrade).ToList();
|
||||
double totalShares = (from portfolioTrade in trades select portfolioTrade.Shares).Sum();
|
||||
double totalExposure=(from portfolioTrade in trades select portfolioTrade.Shares*portfolioTrade.Price).Sum();
|
||||
PortfolioHolding portfolioHolding = new PortfolioHolding();
|
||||
portfolioHolding.Symbol = symbol;
|
||||
portfolioHolding.Shares = totalShares;
|
||||
portfolioHolding.Prices = PricingDA.GetPrices(symbol, startDate, dayCount + 1);
|
||||
portfolioHolding.Weight = 0;
|
||||
if (null != portfolioHolding.Prices && 0 != portfolioHolding.Prices.Count) portfolioHolding.MarketValue = portfolioHolding.Prices[0].Close * totalShares;
|
||||
else portfolioHolding.MarketValue = 0.00;
|
||||
portfolioHolding.Exposure=totalExposure;
|
||||
portfolioHolding.AsOf = startDate;
|
||||
portfolioHoldings.Add(portfolioHolding);
|
||||
}
|
||||
double totalMarketValue = (from portfolioHolding in portfolioHoldings select portfolioHolding.MarketValue).Sum();
|
||||
double totalPortfolioExposure = (from portfolioHolding in portfolioHoldings select portfolioHolding.Exposure).Sum();
|
||||
if(0.00!=totalMarketValue)portfolioHoldings.ForEach(portfolioHolding => new Action(delegate() { portfolioHolding.Weight = portfolioHolding.MarketValue / totalMarketValue;}).Invoke());
|
||||
if (0.00 != totalPortfolioExposure) portfolioHoldings.ForEach(portfolioHolding => new Action(delegate() { portfolioHolding.WeightExp = portfolioHolding.Exposure / totalPortfolioExposure; }).Invoke());
|
||||
return portfolioHoldings;
|
||||
}
|
||||
}
|
||||
// Weight : This is the market value based weight
|
||||
// WeightExp : This is the exposure based weight
|
||||
public class PortfolioHolding
|
||||
{
|
||||
private String symbol;
|
||||
private DateTime asOf;
|
||||
private double shares;
|
||||
private double weight;
|
||||
private double weightExp;
|
||||
private double marketValue;
|
||||
private double exposure;
|
||||
private int returnDays = 1;
|
||||
private Prices prices;
|
||||
private double[] returns = null;
|
||||
private double contribution; // This is used in the VaR analysis and is populated with the contribution to VaR at the time of the analysis
|
||||
private DateTime contributionDate; // This is used in the VaR analysis and is populated with the contribution to VaR at the time of the analysis
|
||||
|
||||
public PortfolioHolding()
|
||||
{
|
||||
}
|
||||
public PortfolioHolding(PortfolioHolding portfolioHolding)
|
||||
{
|
||||
prices = portfolioHolding.prices;
|
||||
shares=portfolioHolding.shares;
|
||||
symbol = portfolioHolding.symbol;
|
||||
weight = portfolioHolding.weight;
|
||||
marketValue = portfolioHolding.marketValue;
|
||||
weightExp = portfolioHolding.weightExp;
|
||||
exposure=portfolioHolding.exposure;
|
||||
returnDays = portfolioHolding.returnDays;
|
||||
returns = portfolioHolding.returns;
|
||||
asOf = portfolioHolding.AsOf;
|
||||
contribution=portfolioHolding.contribution;
|
||||
contributionDate=portfolioHolding.contributionDate;
|
||||
}
|
||||
public String Symbol
|
||||
{
|
||||
get { return symbol; }
|
||||
set { symbol = value; }
|
||||
}
|
||||
public DateTime AsOf
|
||||
{
|
||||
get { return asOf; }
|
||||
set { asOf = value; }
|
||||
}
|
||||
public double Shares
|
||||
{
|
||||
get { return shares; }
|
||||
set { shares = value; }
|
||||
}
|
||||
public double Contribution
|
||||
{
|
||||
get{return contribution;}
|
||||
set{contribution=value;}
|
||||
}
|
||||
public DateTime ContributionDate
|
||||
{
|
||||
get{return contributionDate;}
|
||||
set{contributionDate=value;}
|
||||
}
|
||||
public void SetReturnDays(int days)
|
||||
{
|
||||
if (returnDays == days) return;
|
||||
returnDays = days;
|
||||
returns = prices.GetReturnsAsDoubleArray(returnDays);
|
||||
}
|
||||
public Prices Prices
|
||||
{
|
||||
get { return prices; }
|
||||
set { prices = value; returns = prices.GetReturnsAsDoubleArray(returnDays); }
|
||||
}
|
||||
public double Weight
|
||||
{
|
||||
get { return weight; }
|
||||
set { weight = value; }
|
||||
}
|
||||
public double WeightExp
|
||||
{
|
||||
get { return weightExp; }
|
||||
set { weightExp = value; }
|
||||
}
|
||||
public double[] Returns
|
||||
{
|
||||
get { return returns; }
|
||||
}
|
||||
public double MarketValue
|
||||
{
|
||||
get { return marketValue; }
|
||||
set { marketValue = value; }
|
||||
}
|
||||
public double Exposure
|
||||
{
|
||||
get{return exposure;}
|
||||
set{exposure=value;}
|
||||
}
|
||||
}
|
||||
}
|
||||
46
MarketDataLib/ValueAtRisk/VaRResult.cs
Normal file
46
MarketDataLib/ValueAtRisk/VaRResult.cs
Normal file
@@ -0,0 +1,46 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using MarketData.DataAccess;
|
||||
using MarketData.Utils;
|
||||
|
||||
namespace MarketData.ValueAtRisk
|
||||
{
|
||||
public class VaRResult
|
||||
{
|
||||
private double varPercent;
|
||||
private double varExpectedLoss;
|
||||
public VaRResult()
|
||||
{
|
||||
VaRPercent = 0;
|
||||
VaRExpectedLoss = 0;
|
||||
Success=true;
|
||||
}
|
||||
public VaRResult(VaRResult varResult)
|
||||
{
|
||||
VaRPercent = varResult.VaRPercent;
|
||||
VaRExpectedLoss = varResult.VaRExpectedLoss;
|
||||
Success=varResult.Success;
|
||||
Message=varResult.Message;
|
||||
}
|
||||
public VaRResult(double varPercent, double expectedLoss)
|
||||
{
|
||||
this.VaRPercent = varPercent;
|
||||
this.VaRExpectedLoss = expectedLoss;
|
||||
this.Success=true;
|
||||
}
|
||||
public double VaRPercent
|
||||
{
|
||||
get { return varPercent; }
|
||||
set { varPercent = value; }
|
||||
}
|
||||
public double VaRExpectedLoss
|
||||
{
|
||||
get { return varExpectedLoss; }
|
||||
set { varExpectedLoss = value; }
|
||||
}
|
||||
public bool Success{get;set;}
|
||||
public String Message{get;set;}
|
||||
}
|
||||
}
|
||||
116
MarketDataLib/ValueAtRisk/WeightedReturnsWithContributions.cs
Normal file
116
MarketDataLib/ValueAtRisk/WeightedReturnsWithContributions.cs
Normal file
@@ -0,0 +1,116 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MarketData.ValueAtRisk
|
||||
{
|
||||
// *****************************************************************************************************************************************************
|
||||
public class Contribution
|
||||
{
|
||||
public String Symbol{get;set;}
|
||||
public DateTime AnalysisDate{get;set;}
|
||||
public double ContributionValue{get;set;}
|
||||
public Contribution()
|
||||
{
|
||||
}
|
||||
public Contribution(String symbol,DateTime analysisDate,double contribution)
|
||||
{
|
||||
this.Symbol=symbol;
|
||||
this.ContributionValue=contribution;
|
||||
this.AnalysisDate=analysisDate;
|
||||
}
|
||||
}
|
||||
public class Contributions : List<Contribution>
|
||||
{
|
||||
public Contributions()
|
||||
{
|
||||
}
|
||||
public Contributions(List<Contribution> contributions)
|
||||
{
|
||||
foreach(Contribution contribution in contributions)Add(contribution);
|
||||
}
|
||||
}
|
||||
public class ContributionSorter : IComparer<Contribution>
|
||||
{
|
||||
public int Compare(Contribution c1,Contribution c2)
|
||||
{
|
||||
return c1.ContributionValue.CompareTo(c2.ContributionValue);
|
||||
}
|
||||
}
|
||||
// *****************************************************************************************************************************************************
|
||||
public class WeightedReturn
|
||||
{
|
||||
public String Symbol{get;set;}
|
||||
public DateTime AnalysisDate{get;set;}
|
||||
public double WeightedReturnValue{get;set;}
|
||||
public WeightedReturn()
|
||||
{
|
||||
}
|
||||
public WeightedReturn(String symbol,DateTime analysisDate,double weightedReturn)
|
||||
{
|
||||
this.Symbol=symbol;
|
||||
this.WeightedReturnValue=weightedReturn;
|
||||
this.AnalysisDate=analysisDate;
|
||||
}
|
||||
}
|
||||
public class WeightedReturns : List<WeightedReturn>
|
||||
{
|
||||
public double GetTotalWeightAdjustedReturn()
|
||||
{
|
||||
return this.Sum(x=>x.WeightedReturnValue);
|
||||
}
|
||||
public Contributions GetContributions()
|
||||
{
|
||||
Contributions contributions=new Contributions();
|
||||
double totalWeightedReturn=GetTotalWeightAdjustedReturn();
|
||||
foreach(WeightedReturn weightedReturn in this)
|
||||
{
|
||||
contributions.Add(new Contribution(weightedReturn.Symbol,weightedReturn.AnalysisDate,weightedReturn.WeightedReturnValue/totalWeightedReturn));
|
||||
}
|
||||
return contributions;
|
||||
}
|
||||
}
|
||||
// ******************************************************************************************************************************************************
|
||||
public class WeightedReturnsWithContribution
|
||||
{
|
||||
private Dictionary<int,WeightedReturns> weightedReturnsWithContribution=new Dictionary<int,WeightedReturns>();
|
||||
|
||||
public WeightedReturnsWithContribution()
|
||||
{
|
||||
}
|
||||
public int Count
|
||||
{
|
||||
get{return weightedReturnsWithContribution.Count;}
|
||||
}
|
||||
public void Add(int index,WeightedReturn weightedReturn)
|
||||
{
|
||||
if(!weightedReturnsWithContribution.ContainsKey(index))weightedReturnsWithContribution.Add(index,new WeightedReturns());
|
||||
weightedReturnsWithContribution[index].Add(weightedReturn);
|
||||
}
|
||||
public double[] GetWeightedReturns()
|
||||
{
|
||||
List<int> keys=new List<int>(weightedReturnsWithContribution.Keys);
|
||||
keys.Sort();
|
||||
List<double> weightedReturns=new List<double>();
|
||||
foreach(int key in keys)
|
||||
{
|
||||
weightedReturns.Add(weightedReturnsWithContribution[key].GetTotalWeightAdjustedReturn());
|
||||
}
|
||||
return weightedReturns.ToArray<double>();
|
||||
}
|
||||
public List<Contributions> GetContributions()
|
||||
{
|
||||
List<int> keys=new List<int>(weightedReturnsWithContribution.Keys);
|
||||
keys.Sort();
|
||||
List<Contributions> contributionsList=new List<Contributions>();
|
||||
foreach(int key in keys)
|
||||
{
|
||||
WeightedReturns weightedReturns=weightedReturnsWithContribution[key];
|
||||
contributionsList.Add(weightedReturns.GetContributions());
|
||||
}
|
||||
return contributionsList;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user