2014-01-31 91 views
2

你好我已经找到了一些用于某些excel函数的javascript类,但是我不知道如何使用它。我需要使用XIRR函数,但我不知道参数的类型和格式以及语法。如何使用Javascript类xirr公式

下面是代码:

/* Based on 
* - EGM Mathematical Finance class by Enrique Garcia M. <[email protected]> 
* - A Guide to the PMT, FV, IPMT and PPMT Functions by Kevin (aka MWVisa1) 
*/ 

var ExcelFormulas = { 

    PVIF: function(rate, nper) { 
     return Math.pow(1 + rate, nper); 
    }, 

    FVIFA: function(rate, nper) { 
     return rate == 0? nper: (this.PVIF(rate, nper) - 1)/rate; 
    }, 

    PMT: function(rate, nper, pv, fv, type) { 
     if (!fv) fv = 0; 
     if (!type) type = 0; 

     if (rate == 0) return -(pv + fv)/nper; 

     var pvif = Math.pow(1 + rate, nper); 
     var pmt = rate/(pvif - 1) * -(pv * pvif + fv); 

     if (type == 1) { 
      pmt /= (1 + rate); 
     }; 

     return pmt; 
    }, 

    IPMT: function(pv, pmt, rate, per) { 
     var tmp = Math.pow(1 + rate, per); 
     return 0 - (pv * tmp * rate + pmt * (tmp - 1)); 
    }, 

    PPMT: function(rate, per, nper, pv, fv, type) { 
     if (per < 1 || (per >= nper + 1)) return null; 
     var pmt = this.PMT(rate, nper, pv, fv, type); 
     var ipmt = this.IPMT(pv, pmt, rate, per - 1); 
     return pmt - ipmt; 
    }, 

    DaysBetween: function(date1, date2) { 
     var oneDay = 24*60*60*1000; 
     return Math.round(Math.abs((date1.getTime() - date2.getTime())/oneDay)); 
    }, 

    // Change Date and Flow to date and value fields you use 
    XNPV: function(rate, values) { 
     var xnpv = 0.0; 
     var firstDate = new Date(values[0].Date); 
     for (var key in values) { 
      var tmp = values[key]; 
      var value = tmp.Flow; 
      var date = new Date(tmp.Date); 
      xnpv += value/Math.pow(1 + rate, this.DaysBetween(firstDate, date)/365); 
     }; 
     return xnpv; 
    }, 

    XIRR: function(values, guess) { 
     if (!guess) guess = 0.1; 

     var x1 = 0.0; 
     var x2 = guess; 
     var f1 = this.XNPV(x1, values); 
     var f2 = this.XNPV(x2, values); 

     for (var i = 0; i < 100; i++) { 
      if ((f1 * f2) < 0.0) break; 
      if (Math.abs(f1) < Math.abs(f2)) { 
       f1 = this.XNPV(x1 += 1.6 * (x1 - x2), values); 
      } 
      else { 
       f2 = this.XNPV(x2 += 1.6 * (x2 - x1), values); 
      } 
     }; 

     if ((f1 * f2) > 0.0) return null; 

     var f = this.XNPV(x1, values); 
     if (f < 0.0) { 
      var rtb = x1; 
      var dx = x2 - x1; 
     } 
     else { 
      var rtb = x2; 
      var dx = x1 - x2; 
     }; 

     for (var i = 0; i < 100; i++) { 
      dx *= 0.5; 
      var x_mid = rtb + dx; 
      var f_mid = this.XNPV(x_mid, values); 
      if (f_mid <= 0.0) rtb = x_mid; 
      if ((Math.abs(f_mid) < 1.0e-6) || (Math.abs(dx) < 1.0e-6)) return x_mid; 
     }; 

     return null; 
    } 

}; 
+0

你可能想看看https://github.com/FinancialEngineer/tadJS更强大,功能更丰富的JavaScript金融函数库称为tadJS – 2014-02-10 05:26:56

回答

1

您想使用XIRR,所以让我们来看看它的签名:

XIRR: function(values, guess) 

是什么与values呢?

var f1 = this.XNPV(x1, values); 

所以values必须是任何XNPV期待。它具有这样的组块在其核心:

for (var key in values) { 
    var tmp = values[key]; 
    var value = tmp.Flow; 
    var date = new Date(tmp.Date); 
    xnpv += value/Math.pow(1 + rate, this.DaysBetween(firstDate, date)/365); 
}; 

所以它期待values是一个字典(关联阵列),其中键 - 值对的值部分具有成员.Flow.Date。我假设.Flow是现金流量,并从DaysBetween方法我可以看出,.Date是一个javascript日期。关键是被忽略,所以它可以是数字,如果我们想。所以让我们做一个:

var myInstrument = { 0: {Flow: 5, Date: new Date(2015, 7, 6)}, 
        1: {Flow: 105, Date: new Date(2016, 7, 6)} }; 

(这是一个字典(或数组)声明)。

XIRR的另一个输入是guess,它将用来解决某些问题,但如果给出了一个错误的输入值,它将默认使用0.1(10%!)。因此,我们可以用这样我们myInstrument叫它:

var myInternalReturn = XIRR(myInstrument, false); 

注:该XIRR函数实现实际/ 365的固定天数为年度支付频率协定,这可能不适合你重视仪器。也许它不会有太大的区别,但是对于半年或30/360来说是不正确的,特别是在月末日期,简单的利息工具等问题上。