Расчет XNPV в C# или VB без использования Excel
Кто-нибудь разработал финансовую функцию XNPV? Я ищу код, который будет рассчитывать это значение. Я не собираюсь звонить в Excel, чтобы рассчитать стоимость.
Любая помощь была бы отличной, спасибо
3 ответа
Решение
Я считаю, что это правильная реализация в C#:
public double XNPV(decimal[] receipts,DateTime[] dates, double dRate, DateTime issueDate, decimal cf, int x)
{
double sum;
for(int i =0;i<dates.Length;i++)
{
TimeSpan ts = dates[i].Subtract(issuedate);
sum +=receipts[i] / ((1 + dRate / cf) ^ ((ts.TotalDays / 360) * cf));
}
return sum;
}
и это эквивалент в VB:
Public Function XNPV(ByVal Receipts() As Decimal, ByVal Dates() As Date, ByVal dRate As Double, ByVal IssueDate As Date, ByVal CF As Decimal, ByVal x As Integer) As Double
Dim i As Integer
Dim sum As Double
For i = 0 To UBound(Dates)
sum = sum + Receipts(i) / ((1 + dRate / CF) ^ ((DateDiff / 360) * CF))
XNPV = sum
End Function
Я адаптировал приведенный выше код и включил пример того, как его назвать. Должно быть легко адаптироваться, чтобы использовать переменную ставку дисконта вместо.1
Public Function XNPV(ByVal Receipts() As Decimal, ByVal Dates() As Date, ByVal dRate As Double, ByVal StartDate As Date) As Double
Dim i As Integer = 0
Dim dXNPV As Double = 0
Dim dXRate As Double = 1 + dRate
Dim dDayOfCF As Long = 0
Dim dAdj As Double = 0
Dim dResult As Double = 0
For i = 0 To UBound(Dates)
dDayOfCF = (DateDiff(DateInterval.Day, StartDate, Dates(i)))
dAdj = (dDayOfCF / 365)
dXNPV = Receipts(i) / (dXRate ^ dAdj)
dResult += dXNPV
Next
XNPV = dResult
End Function
Private Sub SimpleButton2_Click(sender As System.Object, e As System.EventArgs) Handles SimpleButton2.Click
Dim tblReceipts(2) As Decimal
Dim tblDates(2) As DateTime
Dim dtStartDate As DateTime = "1/1/13"
Dim XNPVResult As Decimal = 0
tblReceipts(0) = -100000
tblReceipts(1) = 500000
tblReceipts(2) = 2000000
tblDates(0) = "1/1/13"
tblDates(1) = "1/7/13"
tblDates(2) = "1/1/15"
'xCF = 1 + DateDiff(DateInterval.Day, dtIssueDate, tblDates(2))
XNPVResult = XNPV(tblReceipts, tblDates, 0.1, dtStartDate)
MsgBox(XNPVResult)
End Sub
Возвращает значение, аналогичное XNPV Excels (перепроверено)
public static double XNPV(double rate, List<xnpvFlow> Cashflows, DateTime? StartDate = null)
{
if (Cashflows == null || Cashflows.Count == 0) return 0;
if(StartDate == null)
{
StartDate = (from xnpvFlow flow in Cashflows select flow.FlowDate).Min();
}
double _xnpv = 0;
foreach(xnpvFlow flow in Cashflows)
{
_xnpv += (double)flow.FlowAmount / Math.Pow((1 + rate), (double)(flow.FlowDate - (DateTime)StartDate).Days/365);
}
return _xnpv;
}
public class xnpvFlow
{
public xnpvFlow(DateTime _FlowDate, decimal _flowAmount)
{
this.FlowAmount = _flowAmount;
this.FlowDate = _FlowDate;
}
public DateTime FlowDate;
public decimal FlowAmount;
}