如何解决项目投资建模中建设期循环引用问题

在项目投资中,尤其是针对海外项目,财务建模的难点之一就是如何解决模型中存在的循环引用,包括建设期债务规模、利息及相关费用引起的循环引用;以偿债现金流计算债务规模引起的循环引用;运营期偿债准备金账户、利息收入、税金引起的循环引用等。本篇文章重点讨论建设期按总投资的一定比例融资,因利息及相关费用产生循环引用时的解决办法,后续内容将以系列类文章的形式逐一阐述。


产生循环引用的科目及计算逻辑


建设期利

建设期建模中,若融资金额按照项目总投资的一定比例来确定,财务费用仅考虑建设期利息的情况下,且建设期利息的计算方式为:(期初债务余额+期末债务余额)/2*当期利率,此时会出现循环引用。


原因是:计算当期利息需要计算出当期债务提取额后根据期初和期末的债务余额的平均数进行计算,当期债务提取额中包含当期利息中由债务融资的部分,而当期利息中由债务融资的部分取决于当期利息总额及融资比例。图1展示了循环的逻辑关系。


01.png

图1 利息计算产生的循环引用




承诺费(Commitment Fee)
前端费(Up Front Fee)


承诺费和前端费是海外项目融资中常见的费用,多出现在银团融资中,承诺费的计算基于每期末未提取贷款金额计算,前端费基于贷款总额计算并在提款时一次性支付。建模时,除考虑建设期利息外,另考虑以上融资费用时,也将带来循环引用的问题。


原因是:承诺费和前端费的计算都需要先求出融资总额,融资总额的计算基于总投资,而总投资需要计算出整个建设期的利息、承诺费、前端费后才能确定。图2展示了循环的逻辑。


02.png

图2 融资费用计算产生的循环引用


在清楚产生循环的科目和逻辑后,就能解决循环引用问题,解决方法主要为:

01
开启Excel循环计算设置

该方法看似最简单,但对于模型的危险性大,使用后其他功能(如单变量求解)无法运行,模型变的不稳定,一旦某处出现错误,连带整个模型出现错误,且无法纠正,一般来说不会采用此方法。

02
使用单变量求解(或规划求解)

单变量求解的思路为,针对引起循环的单元格另新增单元格输入固定数值,该单元格作为计算过程中的链接项,另添加新单元格计算固定数值与计算值的差值,使用单变量求解,令该数值为0,求解债务资本比。若涉及多个单元格的循环引用时,需使用规划插件Solver解决问题。


使用该方法的限制是求解目标与输入项(自变量)需要在同一张表格内,当模型相关输入项发生变化,都需要重新做一遍单变量求解/规划求解,且盈亏平衡分析、模拟运算表等功能不能与该方法同时使用。

03
编写复制粘贴宏

该方法是当前建模中解决各种循环引用问题最为广泛的一种方法,适用于各种模型。设置方式也是针对产生循环的单元格/行新增固定数值单元格/行,将引发循环计算处的数值复制粘贴到固定数值处,并将固定数值链接到整体计算中,再设置固定数值与计算数值的差额,编写宏程序,即自动完成多次复制粘贴操作,直至差额为0时结束。


该方法与方法2本质上并无大的差别,优势在于能解决单变量求解/Solver存在的局限性,但同样的问题是,每当相关参数发生改变时,都需要重新运行宏;需要对很多单元格进行命名,以便在宏语言中使用;很多情况下与单变量求解/Slover无法同时使用(有时可以通过编写更多的宏程序解决);无法使用模拟运算表等,模型的灵活性降低。

04
编写自定义函数

该方法的优势明显,通过在产生循环引用的地方编写自定义函数(通常为迭代运算函数)可避免所有循环引用问题,仍可直接使用单变量求解、数据表、情景分析等工具,模型灵活且稳定,但问题在于自定义函数上手困难,需要用到一定的编程技术和VBA语句,在选择自变量时,要仔细构想,需要经验积累。


下面将结合不同场景重点对方法3、4进行展示:




1


融资金额按比例确定,财务费用仅考虑建设期利息


此情景下,债务提取又分两种情况,第一种为债务与资本金按照当期资金需求总额按比例同时提取,另一种为资本金先提取,债务后提取以填补资金缺口。


第一种情况下:

建设期利息的计算方式只需设置为:期初债务余额*当期利率,该计算方式在各类模型中普遍应用,可避免因利息计算基于期初、期末债务余额平均值计算时产生的循环引用。

第二种情况下:

即便采用期初债务余额的利息计算方式,仍不能解决循环问题,因为第二种情况需要先计算出建设期的全部利息,这时可针对建设期利息项编写复制粘贴宏来解决问题。


这里展示两种宏语句,一种为Copy_Paste语句(图3),另一种为Do……Loop Until语句(图4)。


03.png

(图3 Copy_Paste宏语句)


图3的语句中为复制粘贴语句加上Wend循环语句,宏名为Copy_Paste,语句含义为单元格Total_Difference(即固定值与计算值的差值)不为0时,利息计算行computed_fees将被复制到固定数值行fixed_fees,直到Total_Difference为0时,宏程序退出。


04.png

(图4 Do……Loop Until宏语句)


图4的语句中为Do……Loop Until语句,宏名为Con_IDC,语句含义为使固定数值行fixed_amount与computed_amount计算行数值相等,不断迭代计算直到difference单元格数值为0时(取4位小数),宏程序退出。










2


融资金额按比例确定,财务费用考虑建设期利息、承诺费、前端费


此情景下只需要在模型中新添加承诺费、前端费的计算行和固定数值行,按照相同的逻辑编辑到上述的宏语言中即可(图5)。


05.png

(图5 计算区域与粘贴区域)


图5红框中为计算区域,可命名为Range(Computed_Fees),橙色区域为粘贴区域,可命名为Range(Paste_Fees),再定义一个Range(Difference)单元格,按照上述思路编写。










3


自定义函数解决建设期计算的循环引用


假设融资金额按照总投资的一定比例确定,债务提取与每期工程进度付款比例匹配,融资费用包含建设期利息、承诺费、前端费,可在债务总额单元格设置自定义函数,即债务金额=Function(贷款比例,工程建设金额支出,利率,承诺费率、前端费率)(图6)。


06.png

(图6 计算页面)


此时债务总额已经通过自定义函数算出,该数值再参与计算链接中就不会出现循环引用问题。图7展示了函数具体的编译语言。


07.png

(图7 函数编写界面)

函数的编写看上去似乎有些复杂,但只要读者稍加研究,就会发现并不难。

编写函数的主要思路为:


选定合适的自变量;


使用For Next语句进行迭代计算,如图中,For Iteration i= 1 to 30是整个函数的迭代计算,For i= 1 to number_of_periods是每个计算期的顺次计算;


设定计算所涉及变量的起始值,如图中debt_balance(债务余额)、accumulated_idc(累计利息)等;


直白的用公式进行编写即可,只要保证前后变量名称保持一致,计算公式与Excel表格中一致。

当理解了这一类函数编写的方法,就能应对其他的情况,如债务提取方式变成了劣后于资本金支出,此时只需要将计算逻辑修改,函数编写的大体思路并无太大差别。







以上是几种解决建设期循环引用问题的方法介绍,但需要清楚的是没有完美的方法,只有适合于模型的方法,根据建模的目的、需要的功能、达到的深度不同,灵活使用各种办法才是解决问题之道。