Расчет 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;
    }
Другие вопросы по тегам