如何在Excel和Google工作表中动态计算XIRR

时间:2016-08-29 17:28:45

标签: excel excel-formula excel-2010 xls

我正在尝试为以下格式的数据计算XIRR

    PurchaseDate    Script  No.ofunits  PurchNAVrate    NetAmount            ForXIRR    TotalReturn
    17/11/2014          A   2241            33              75000           -75000          96000
    8/1/2015            B   53              649             35000           -35000          43000
    14/1/2015           B   75              658             50000           -50000          61500
    14/10/2014          C   2319            32              75000           -75000          108000
    8/1/2015            D   318             109             35000           -35000          40000
    14/1/2015           D   450             110             50000           -50000          57000
    8/6/2015            D   175             114             20000           -20000          22000

我尝试了很多不同的排列和组合,但无法计算每个基金的XIRR。有没有办法可以使用偏移或搜索来做到这一点。 这是一个动态列表,根据购买或出售的新资金不断变化

Values for Fund A should be around 14%  
Values for Fund B should be around 13%
Values for Fund C should be around 21%
Values for Fund D should be around 8%

更新 鉴于@ xor-lx提到的解决方案在ms excel中运行得非常好但在google工作表中没有,我现在已经基于@kyle建议修改了我的数据结构,现在我可以轻松地为每个基金整体计算XIRR。请参阅下文

PurchaseDate    Today       Script  No.ofunits  PurchNAVrate    NetAmount   ForXIRR TotalReturn     XIRR
17/11/14        31/08/2016  A       2241        33              75000       -75000  96000           "=XIRR(G2:H2,A2:B2)"
                            Total for above fund                                                    "=XIRR(G2:H3,A2:B3)"
8/1/2015        31/08/2016  B       53          649             35000       -35000  43000           "=XIRR(G4:H4,A4:B4)"
14/1/2015       31/08/2016  B       75          658             50000       -50000  61500           "=XIRR(G5:H5,A5:B5)"
                            Total for above fund                                                    "=XIRR(G4:H6,A4:B6)"
14 Oct 14       31/08/2016  C       2319        32              75000       -75000  108000          "=XIRR(G7:H7,A7:B7)"
                            Total for above fund                                                    "=XIRR(G7:H8,A7:B8)"
8 Jan 15        31/08/2016  D       318         109             35000       -35000  40000           "=XIRR(G9:H9,A9:B9)"
14 Jan 15       31/08/2016  D       450         110             50000       -50000  57000           "=XIRR(G10:H10,A10:B10)"
8/6/2015        31/08/2016  D       175         114             20000       -20000  22000           "=XIRR(G11:H11,A11:B11)"
                            Total for above fund                                                    "=XIRR(G9:H12,A9:B12)"

3 个答案:

答案 0 :(得分:2)

假设您的表位于A1:G8(第1行中包含标题),并且您选择的是基金,例如“B”,在J2,数组公式**:

=XIRR(INDEX(F:G,N(IF(1,MODE.MULT(IF(B$2:B$8=J2,{1,1}*ROW(B$2:B$8))))),N(IF(1,{1,2}))),CHOOSE({1,2},INDEX(A:A,N(IF(1,MODE.MULT(IF(B$2:B$8=J2,{1,1}*ROW(B$2:B$8)))))),TODAY()))

向下复制,为J3J4等中的基金提供类似的结果。

我倾向于选择涉及OFFSET的设置;它不仅更简洁(因此更有效),而且更重要的是,非易失性。

如果您有兴趣,请点击此处了解更多信息:

https://excelxor.com/2016/02/16/criteria-with-statistical-functions-growth-linest-logest-trend/

此致

**数组公式的输入方式与“标准”公式的输入方式不同。您只需按住CTRL和SHIFT键,然后按ENTER键,而不是按ENTER键。如果你已经正确地完成了它,你会注意到Excel在公式周围放置了大括号{}(虽然不要尝试自己手动插入这些)。

答案 1 :(得分:1)

XIRR需要两个参数数组 - 值和日期(带有可选的第三个“guess”参数)。为了尝试将来自非连续购买日期范围的数组拼接在一起,总回报,购买金额和一些“今天的日期”对于Excel公式来说将是一个相当大的挑战。因此,我提供了用VBA编写的用户定义函数。

该函数的参数是基金或脚本(sFund),您的数据表范围如上图所示。

根据您的一条评论中的建议,我使用TODAY作为与Total Return列对应的日期。如果不是这样的话,很容易改变。

另外,请注意我没有使用“forXIRR”列,而是使用了NetAmount列的否定值。如果您删除forXIRR列,则需要将引用更改为.TotalReturn

我创建了一个自定义类,以使事情更容易理解。

插入类模块后,必须将其重命名为cFUND

班级单元

Option Explicit
'Rename cFUND

Private pFund As String

Private pPurchDt As Date
Private pPurchDts As Collection

Private pPurchAmt As Double
Private pPurchAmts As Collection

Private pTotalReturn As Double
Private pTotalReturns As Collection

Public Property Get Fund() As String
    Fund = pFund
End Property
Public Property Let Fund(Value As String)
    pFund = Value
End Property

Public Property Get PurchDt() As Date
    PurchDt = pPurchDt
End Property
Public Property Let PurchDt(Value As Date)
    pPurchDt = Value
End Property
Public Function ADDPurchDt(Value As Date)
    pPurchDts.Add Value
End Function
Public Property Get PurchDts() As Collection
    Set PurchDts = pPurchDts
End Property

Public Property Get PurchAmt() As Double
    PurchAmt = pPurchAmt
End Property
Public Property Let PurchAmt(Value As Double)
    pPurchAmt = Value
End Property
Public Function ADDPurchAmt(Value As Double)
    pPurchAmts.Add Value
End Function
Public Property Get PurchAmts() As Collection
    Set PurchAmts = pPurchAmts
End Property

Public Property Get TotalReturn() As Double
    TotalReturn = pTotalReturn
End Property
Public Property Let TotalReturn(Value As Double)
    pTotalReturn = Value
End Property
Public Function ADDTotalReturn(Value As Double)
    pTotalReturns.Add Value
End Function
Public Property Get TotalReturns() As Collection
    Set TotalReturns = pTotalReturns
End Property

Public Function CalcXIRR()
    Dim v, d, w
    Dim I As Long
    With Me
        ReDim d(.PurchDts.Count * 2 - 1)
        ReDim v(UBound(d))

        I = 0
        For Each w In .PurchAmts
            v(I) = w
            I = I + 1
        Next w
        For Each w In .TotalReturns
            v(I) = w
            I = I + 1
        Next w

        I = 0
        For Each w In .PurchDts
            d(I) = w
            I = I + 1
        Next w
        Do Until I > UBound(d)
            d(I) = Date
            I = I + 1
        Loop
    End With

    CalcXIRR = WorksheetFunction.XIRR(v, d)
End Function
Private Sub Class_Initialize()
    Set pPurchDts = New Collection
    Set pPurchAmts = New Collection
    Set pTotalReturns = New Collection
End Sub

常规模块

Option Explicit
Function fundXIRR(sFund As String, rTable As Range) As Double
    Dim vSrc As Variant
    Dim cF As cFUND
    Dim I As Long

vSrc = rTable

Set cF = New cFUND
For I = 2 To UBound(vSrc, 1)
    If vSrc(I, 2) = sFund Then
        With cF
            .PurchDt = vSrc(I, 1)
            .ADDPurchDt .PurchDt
            .Fund = vSrc(I, 2)
            .PurchAmt = -vSrc(I, 5)
            .ADDPurchAmt .PurchAmt
            .TotalReturn = vSrc(I, 7)
            .ADDTotalReturn .TotalReturn
        End With
    End If
Next I

fundXIRR = cF.CalcXIRR

End Function

根据您的上述数据,XIRR的{​​{1}}计算方式为:

B

以上是您的数据的结果:

enter image description here

答案 2 :(得分:0)

我将根据您的表格假设日期为A栏,基金(或“脚本”)为B栏,“ForXIRR”为F栏。以下内容将为您完成:

{=XIRR(IF(B:B="A",F:F,0),IF(B:B="A",A:A,0))}

请确保使用Shift + Ctrl + Enter输入此内容,因为它是一个数组公式。

注意:以上将计算“A”,但将该公式的那部分替换为任何其他基金,或使用单元格引用计算其他基金。

编辑:

我意识到上述内容仅适用于序列中的第一个字母,请在下面使用,然后再次将"B"调整为您需要的任何内容。这适用于任何出席的信件。此外,调整所有范围以满足您的需要,我只为了测试目的而行1:10。下面调整范围的开始,因此它始终是输入的任何基金(即“A”,“B”,“C”)的第一个值,以便进行计算。如果没有这个改变,上面将始终以零开始,除非它是列表中的第一个(OPs示例中为“A”),而XIRR仅使用负数作为第一个值进行计算。

=XIRR(IF(OFFSET($B$1:$B$10,MATCH("B",$B$1:$B$10,0)-1,0,ROWS($B$1:$B$10)-MATCH("B",$B$1:$B$10,0)+1,1)="B",OFFSET($F$1:$F$10,MATCH("B",$B$1:$B$10,0)-1,0,ROWS($B$1:$B$10)-MATCH("B",$B$1:$B$10,0)+1,1),0),IF(OFFSET($B$1:$B$10,MATCH("B",B1:B10,0)-1,0,ROWS($B$1:$B$10)-MATCH("B",$B$1:$B$10,0)+1,1)="B",OFFSET($A$1:$A$10,MATCH("B",$B$1:$B$10,0)-1,0,ROWS($B$1:$B$10)-MATCH("B",$B$1:$B$10,0)+1,1),0))