summaryrefslogtreecommitdiff
path: root/calc.go
diff options
context:
space:
mode:
authorxuri <xuri.me@gmail.com>2021-11-08 00:19:28 +0800
committerxuri <xuri.me@gmail.com>2021-11-08 00:19:28 +0800
commit8f82d8b02909ca96a9c7f7c3431d1ae990c90191 (patch)
tree88a0ceeae03f70f070dcf6d493d0a3cf74f1485b /calc.go
parent1df76b583c1b77fb37f14d30a54ff5f356280f60 (diff)
ref #65: new formula functions COUPNCD and COUPNUM
Diffstat (limited to 'calc.go')
-rw-r--r--calc.go42
1 files changed, 42 insertions, 0 deletions
diff --git a/calc.go b/calc.go
index dc57cd5..580ecfb 100644
--- a/calc.go
+++ b/calc.go
@@ -350,6 +350,8 @@ type formulaFuncs struct {
// COUNT
// COUNTA
// COUNTBLANK
+// COUPNCD
+// COUPNUM
// COUPPCD
// CSC
// CSCH
@@ -9543,6 +9545,46 @@ func (fn *formulaFuncs) prepareCouponArgs(name string, argsList *list.List) form
return newListFormulaArg([]formulaArg{settlement, maturity, frequency, basis})
}
+// COUPNCD function calculates the number of coupons payable, between a
+// security's settlement date and maturity date, rounded up to the nearest
+// whole coupon. The syntax of the function is:
+//
+// COUPNCD(settlement,maturity,frequency,[basis])
+//
+func (fn *formulaFuncs) COUPNCD(argsList *list.List) formulaArg {
+ args := fn.prepareCouponArgs("COUPNCD", argsList)
+ if args.Type != ArgList {
+ return args
+ }
+ settlement := timeFromExcelTime(args.List[0].Number, false)
+ maturity := timeFromExcelTime(args.List[1].Number, false)
+ ncd := time.Date(settlement.Year(), maturity.Month(), maturity.Day(), 0, 0, 0, 0, time.UTC)
+ if ncd.After(settlement) {
+ ncd = ncd.AddDate(-1, 0, 0)
+ }
+ for !ncd.After(settlement) {
+ ncd = ncd.AddDate(0, 12/int(args.List[2].Number), 0)
+ }
+ return newNumberFormulaArg(daysBetween(excelMinTime1900.Unix(), makeDate(ncd.Year(), ncd.Month(), ncd.Day())) + 1)
+}
+
+// COUPNUM function calculates the number of coupons payable, between a
+// security's settlement date and maturity date, rounded up to the nearest
+// whole coupon. The syntax of the function is:
+//
+// COUPNUM(settlement,maturity,frequency,[basis])
+//
+func (fn *formulaFuncs) COUPNUM(argsList *list.List) formulaArg {
+ args := fn.prepareCouponArgs("COUPNUM", argsList)
+ if args.Type != ArgList {
+ return args
+ }
+ maturity, dateValue := timeFromExcelTime(args.List[1].Number, false), fn.COUPPCD(argsList)
+ date := timeFromExcelTime(dateValue.Number, false)
+ months := (maturity.Year()-date.Year())*12 + int(maturity.Month()) - int(date.Month())
+ return newNumberFormulaArg(float64(months) * args.List[2].Number / 12.0)
+}
+
// COUPPCD function returns the previous coupon date, before the settlement
// date for a security. The syntax of the function is:
//