如下表格记录着公司持有的固定息票债券,现要求忽略公众假期,周末或者气象原因导致交收日期的不规则,根据日期参数表添加汇总现金流的计算列。


现在以上图中ISIN号为5的债券为例说明计算流程:

以下为完整的代码:
let
DateList =
Table.AddColumn(
Dataset,
"CouponDates",
each
let
CouponPeriod = 12 / [CouponFrequency],
MD = [MaturityDate],
Result =
List.Combine(
{
List.Generate(
()=˃ [NextCouponDate],
(x)=˃ x ˂ MD,
(y)=˃
Date.AddMonths(
y,
CouponPeriod
)
),
{MD}
}
)
in
Result,
type list
),
ColNames =
Table.Column(
Parameter,
"MaturityBand"
),
DataType =
Expression.Evaluate(
Text.Combine(
{
"type table [",
Text.Combine(
List.Transform(
ColNames,
each
Text.Combine(
{
Expression.Identifier(_),
"number"
},
"="
)
),
", "
),
"]"
}
)
),
Dup_Col1 =
Table.DuplicateColumn(
DateList,
"CouponRate",
"dCouponRate"
),
Dup_Col2 =
Table.DuplicateColumn(
Dup_Col1,
"CouponFrequency",
"dCouponFrequency"
),
Dup_Col3 =
Table.DuplicateColumn(
Dup_Col2,
"FaceAmt",
"dFaceAmt"
),
Nest =
Table.CombineColumnsToRecord(
Dup_Col3,
"Nest_Col",
List.Skip(
Table.ColumnNames(Dup_Col3),
6
)
),
TransCol =
Table.TransformColumns(
Nest,
{
"Nest_Col",
each
let
FaceAmt = [dFaceAmt],
Coupon_Dates = [CouponDates],
CouponAmt = FaceAmt * [dCouponRate] / [dCouponFrequency],
NoOfPayment = List.Count(Coupon_Dates),
List_Payment =
List.Combine(
{
List.Repeat(
{CouponAmt},
NoOfPayment - 1
),
{CouponAmt + FaceAmt}
}
),
Loop =
List.Transform(
Coupon_Dates,
(x)=˃
Table.SelectRows(
Parameter,
(y)=˃ y[StartDate] ˂= x and y[EndDate] ˃= x
)[MaturityBand]{0}
),
ToTable =
Table.FromColumns(
{
Loop,
List_Payment
},
type table [MaturityBand = text, CashFlow = number]
),
Pivoting =
Table.Pivot(
ToTable,
ColNames,
"MaturityBand",
"CashFlow",
List.Sum
)
in
Pivoting,
DataType
}
),
Expansion =
Table.ExpandTableColumn(
TransCol,
"Nest_Col",
ColNames
),
Replacement =
Table.ReplaceValue(
Expansion,
null,
0,
Replacer.ReplaceValue,
ColNames
)
in
Replacement
在DateList过程中,无视了公众假日,周末和气象因素带来的影响,根据付息频率,到期日和下一个付息日添加了结果为包含了所有付息日的串列(list)的计算列。为了控制目标计算列的数据格式,首先提取了参数表的MaturityBand列使之转换为串列,然后使用Expression.Evaluate()基于该串列产生type table [#"=1d to 1m" = number,...,#">5y to Xy" = number]。因为需要保留CouponRate,CouponFrequency, FaceAmt这三列,所以需要使用Table.DuplicateColumn()对这三列进行复制,得到dCouponRate, dCouponFrequency和dFaceAmt列。做好以上准备后就可以使用Table.CombineColumnsToRecord()把CouponDates, dCouponRate, dCouponFrequency和dFaceAmt这四列转化为内嵌型的记录(Record),现以ISIN号为5的债券为例进行说明:

获得内嵌型的记录列后,就可以通过Table.TransformColumns()引入一层新的let...in对该列进行复杂的转换。以ISIN号的为5的债券为例,首先需要构造{366,741.12, 366,741.12, 366,741.12, 366,741.12, 21,896,078.43}并把{2021-09-03, 2022-03-03, 2022-09-03, 2023-03-03, 2023-09-03}转换为{">1m to 3m", ">6m to 9m", ">1y to 2y", ">1y to 2y", ">2y to 3y"},然后基于这两个串列使用Table.FromColumns()产生如下表格:

之后需要对以上子表进行枢纽化,如下图所示:

最后只需展开以上表格,并把null替换为0就可以得到目标计算列。

附件已经不能打开了,大神能否替换一下。类似的情况在不少文件都存在,希望能解决,谢谢。
已经置换