ref #65: new formula functions TBILLPRICE and TBILLYIELD

This commit is contained in:
xuri 2021-10-27 08:07:21 +08:00
parent 08087e1233
commit 2e9635ece8
No known key found for this signature in database
GPG Key ID: BA5E5BB1C948EDF7
2 changed files with 92 additions and 0 deletions

72
calc.go
View File

@ -538,6 +538,8 @@ type formulaFuncs struct {
// TAN // TAN
// TANH // TANH
// TBILLEQ // TBILLEQ
// TBILLPRICE
// TBILLYIELD
// TEXTJOIN // TEXTJOIN
// TIME // TIME
// TODAY // TODAY
@ -9796,6 +9798,76 @@ func (fn *formulaFuncs) TBILLEQ(argsList *list.List) formulaArg {
return newNumberFormulaArg((365 * discount.Number) / (360 - discount.Number*dsm)) return newNumberFormulaArg((365 * discount.Number) / (360 - discount.Number*dsm))
} }
// TBILLPRICE function returns the price, per $100 face value, of a Treasury
// Bill. The syntax of the function is:
//
// TBILLPRICE(settlement,maturity,discount)
//
func (fn *formulaFuncs) TBILLPRICE(argsList *list.List) formulaArg {
if argsList.Len() != 3 {
return newErrorFormulaArg(formulaErrorVALUE, "TBILLPRICE requires 3 arguments")
}
args := list.New().Init()
args.PushBack(argsList.Front().Value.(formulaArg))
settlement := fn.DATEVALUE(args)
if settlement.Type != ArgNumber {
return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
}
args.Init()
args.PushBack(argsList.Front().Next().Value.(formulaArg))
maturity := fn.DATEVALUE(args)
if maturity.Type != ArgNumber {
return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
}
dsm := maturity.Number - settlement.Number
if dsm > 365 || maturity.Number <= settlement.Number {
return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
}
discount := argsList.Back().Value.(formulaArg).ToNumber()
if discount.Type != ArgNumber {
return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
}
if discount.Number <= 0 {
return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
}
return newNumberFormulaArg(100 * (1 - discount.Number*dsm/360))
}
// TBILLYIELD function calculates the yield of a Treasury Bill. The syntax of
// the function is:
//
// TBILLYIELD(settlement,maturity,pr)
//
func (fn *formulaFuncs) TBILLYIELD(argsList *list.List) formulaArg {
if argsList.Len() != 3 {
return newErrorFormulaArg(formulaErrorVALUE, "TBILLYIELD requires 3 arguments")
}
args := list.New().Init()
args.PushBack(argsList.Front().Value.(formulaArg))
settlement := fn.DATEVALUE(args)
if settlement.Type != ArgNumber {
return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
}
args.Init()
args.PushBack(argsList.Front().Next().Value.(formulaArg))
maturity := fn.DATEVALUE(args)
if maturity.Type != ArgNumber {
return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
}
dsm := maturity.Number - settlement.Number
if dsm > 365 || maturity.Number <= settlement.Number {
return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
}
pr := argsList.Back().Value.(formulaArg).ToNumber()
if pr.Type != ArgNumber {
return newErrorFormulaArg(formulaErrorVALUE, formulaErrorVALUE)
}
if pr.Number <= 0 {
return newErrorFormulaArg(formulaErrorNUM, formulaErrorNUM)
}
return newNumberFormulaArg(((100 - pr.Number) / pr.Number) * (360 / dsm))
}
// YIELDDISC function calculates the annual yield of a discounted security. // YIELDDISC function calculates the annual yield of a discounted security.
// The syntax of the function is: // The syntax of the function is:
// //

View File

@ -1362,6 +1362,10 @@ func TestCalcCellValue(t *testing.T) {
"=SYD(10000,1000,5,2)": "2400", "=SYD(10000,1000,5,2)": "2400",
// TBILLEQ // TBILLEQ
"=TBILLEQ(\"01/01/2017\",\"06/30/2017\",2.5%)": "0.0256680731364276", "=TBILLEQ(\"01/01/2017\",\"06/30/2017\",2.5%)": "0.0256680731364276",
// TBILLPRICE
"=TBILLPRICE(\"02/01/2017\",\"06/30/2017\",2.75%)": "98.86180555555556",
// TBILLYIELD
"=TBILLYIELD(\"02/01/2017\",\"06/30/2017\",99)": "0.024405125076266",
// YIELDDISC // YIELDDISC
"=YIELDDISC(\"01/01/2017\",\"06/30/2017\",97,100)": "0.0622012325059031", "=YIELDDISC(\"01/01/2017\",\"06/30/2017\",97,100)": "0.0622012325059031",
"=YIELDDISC(\"01/01/2017\",\"06/30/2017\",97,100,0)": "0.0622012325059031", "=YIELDDISC(\"01/01/2017\",\"06/30/2017\",97,100,0)": "0.0622012325059031",
@ -2644,6 +2648,22 @@ func TestCalcCellValue(t *testing.T) {
"=TBILLEQ(\"01/01/2017\",\"06/30/2017\",0)": "#NUM!", "=TBILLEQ(\"01/01/2017\",\"06/30/2017\",0)": "#NUM!",
"=TBILLEQ(\"01/01/2017\",\"06/30/2018\",2.5%)": "#NUM!", "=TBILLEQ(\"01/01/2017\",\"06/30/2018\",2.5%)": "#NUM!",
"=TBILLEQ(\"06/30/2017\",\"01/01/2017\",2.5%)": "#NUM!", "=TBILLEQ(\"06/30/2017\",\"01/01/2017\",2.5%)": "#NUM!",
// TBILLPRICE
"=TBILLPRICE()": "TBILLPRICE requires 3 arguments",
"=TBILLPRICE(\"\",\"06/30/2017\",2.5%)": "#VALUE!",
"=TBILLPRICE(\"01/01/2017\",\"\",2.5%)": "#VALUE!",
"=TBILLPRICE(\"01/01/2017\",\"06/30/2017\",\"\")": "#VALUE!",
"=TBILLPRICE(\"01/01/2017\",\"06/30/2017\",0)": "#NUM!",
"=TBILLPRICE(\"01/01/2017\",\"06/30/2018\",2.5%)": "#NUM!",
"=TBILLPRICE(\"06/30/2017\",\"01/01/2017\",2.5%)": "#NUM!",
// TBILLYIELD
"=TBILLYIELD()": "TBILLYIELD requires 3 arguments",
"=TBILLYIELD(\"\",\"06/30/2017\",2.5%)": "#VALUE!",
"=TBILLYIELD(\"01/01/2017\",\"\",2.5%)": "#VALUE!",
"=TBILLYIELD(\"01/01/2017\",\"06/30/2017\",\"\")": "#VALUE!",
"=TBILLYIELD(\"01/01/2017\",\"06/30/2017\",0)": "#NUM!",
"=TBILLYIELD(\"01/01/2017\",\"06/30/2018\",2.5%)": "#NUM!",
"=TBILLYIELD(\"06/30/2017\",\"01/01/2017\",2.5%)": "#NUM!",
// YIELDDISC // YIELDDISC
"=YIELDDISC()": "YIELDDISC requires 4 or 5 arguments", "=YIELDDISC()": "YIELDDISC requires 4 or 5 arguments",
"=YIELDDISC(\"\",\"06/30/2017\",97,100,0)": "#VALUE!", "=YIELDDISC(\"\",\"06/30/2017\",97,100,0)": "#VALUE!",