@@ -604,6 +604,7 @@ type formulaFuncs struct {
604
604
// XOR
605
605
// YEAR
606
606
// YEARFRAC
607
+ // YIELD
607
608
// YIELDDISC
608
609
// YIELDMAT
609
610
// Z.TEST
@@ -1492,7 +1493,7 @@ func (fn *formulaFuncs) BESSELJ(argsList *list.List) formulaArg {
1492
1493
return fn .bassel (argsList , false )
1493
1494
}
1494
1495
1495
- // bassel is an implementation of the formula function BESSELI and BESSELJ.
1496
+ // bassel is an implementation of the formula functions BESSELI and BESSELJ.
1496
1497
func (fn * formulaFuncs ) bassel (argsList * list.List , modfied bool ) formulaArg {
1497
1498
x , n := argsList .Front ().Value .(formulaArg ).ToNumber (), argsList .Back ().Value .(formulaArg ).ToNumber ()
1498
1499
if x .Type != ArgNumber {
@@ -1826,7 +1827,7 @@ func (fn *formulaFuncs) BITXOR(argsList *list.List) formulaArg {
1826
1827
return fn .bitwise ("BITXOR" , argsList )
1827
1828
}
1828
1829
1829
- // bitwise is an implementation of the formula function BITAND, BITLSHIFT,
1830
+ // bitwise is an implementation of the formula functions BITAND, BITLSHIFT,
1830
1831
// BITOR, BITRSHIFT and BITXOR.
1831
1832
func (fn * formulaFuncs ) bitwise (name string , argsList * list.List ) formulaArg {
1832
1833
if argsList .Len () != 2 {
@@ -1937,7 +1938,7 @@ func (fn *formulaFuncs) DEC2OCT(argsList *list.List) formulaArg {
1937
1938
return fn .dec2x ("DEC2OCT" , argsList )
1938
1939
}
1939
1940
1940
- // dec2x is an implementation of the formula function DEC2BIN, DEC2HEX and
1941
+ // dec2x is an implementation of the formula functions DEC2BIN, DEC2HEX and
1941
1942
// DEC2OCT.
1942
1943
func (fn * formulaFuncs ) dec2x (name string , argsList * list.List ) formulaArg {
1943
1944
if argsList .Len () < 1 {
@@ -4586,7 +4587,7 @@ func calcStdev(stdeva bool, result, count float64, mean, token formulaArg) (floa
4586
4587
return result , count
4587
4588
}
4588
4589
4589
- // stdev is an implementation of the formula function STDEV and STDEVA.
4590
+ // stdev is an implementation of the formula functions STDEV and STDEVA.
4590
4591
func (fn * formulaFuncs ) stdev (stdeva bool , argsList * list.List ) formulaArg {
4591
4592
count , result := - 1.0 , - 1.0
4592
4593
var mean formulaArg
@@ -4947,7 +4948,7 @@ func (fn *formulaFuncs) CHIDIST(argsList *list.List) formulaArg {
4947
4948
return newNumberFormulaArg (1 - (incompleteGamma (degress .Number / 2 , x .Number / 2 ) / math .Gamma (degress .Number / 2 )))
4948
4949
}
4949
4950
4950
- // confidence is an implementation of the formula function CONFIDENCE and
4951
+ // confidence is an implementation of the formula functions CONFIDENCE and
4951
4952
// CONFIDENCE.NORM.
4952
4953
func (fn * formulaFuncs ) confidence (name string , argsList * list.List ) formulaArg {
4953
4954
if argsList .Len () != 3 {
@@ -10735,12 +10736,21 @@ func (fn *formulaFuncs) price(settlement, maturity, rate, yld, redemption, frequ
10735
10736
dsc := fn .COUPDAYSNC (argsList ).Number / e .Number
10736
10737
n := fn .COUPNUM (argsList )
10737
10738
a := fn .COUPDAYBS (argsList )
10738
- ret := redemption .Number / math .Pow (1 + yld .Number / frequency .Number , n .Number - 1 + dsc )
10739
- ret -= 100 * rate .Number / frequency .Number * a .Number / e .Number
10740
- t1 := 100 * rate .Number / frequency .Number
10741
- t2 := 1 + yld .Number / frequency .Number
10742
- for k := 0.0 ; k < n .Number ; k ++ {
10743
- ret += t1 / math .Pow (t2 , k + dsc )
10739
+ ret := 0.0
10740
+ if n .Number > 1 {
10741
+ ret = redemption .Number / math .Pow (1 + yld .Number / frequency .Number , n .Number - 1 + dsc )
10742
+ ret -= 100 * rate .Number / frequency .Number * a .Number / e .Number
10743
+ t1 := 100 * rate .Number / frequency .Number
10744
+ t2 := 1 + yld .Number / frequency .Number
10745
+ for k := 0.0 ; k < n .Number ; k ++ {
10746
+ ret += t1 / math .Pow (t2 , k + dsc )
10747
+ }
10748
+ } else {
10749
+ dsc = e .Number - a .Number
10750
+ t1 := 100 * (rate .Number / frequency .Number ) + redemption .Number
10751
+ t2 := (yld .Number / frequency .Number )* (dsc / e .Number ) + 1
10752
+ t3 := 100 * (rate .Number / frequency .Number ) * (a .Number / e .Number )
10753
+ ret = t1 / t2 - t3
10744
10754
}
10745
10755
return newNumberFormulaArg (ret )
10746
10756
}
@@ -11496,6 +11506,92 @@ func (fn *formulaFuncs) XNPV(argsList *list.List) formulaArg {
11496
11506
return newNumberFormulaArg (xnpv )
11497
11507
}
11498
11508
11509
+ // yield is an implementation of the formula function YIELD.
11510
+ func (fn * formulaFuncs ) yield (settlement , maturity , rate , pr , redemption , frequency , basis formulaArg ) formulaArg {
11511
+ priceN , yield1 , yield2 := newNumberFormulaArg (0 ), newNumberFormulaArg (0 ), newNumberFormulaArg (1 )
11512
+ price1 := fn .price (settlement , maturity , rate , yield1 , redemption , frequency , basis )
11513
+ if price1 .Type != ArgNumber {
11514
+ return price1
11515
+ }
11516
+ price2 := fn .price (settlement , maturity , rate , yield2 , redemption , frequency , basis )
11517
+ yieldN := newNumberFormulaArg ((yield2 .Number - yield1 .Number ) * 0.5 )
11518
+ for iter := 0 ; iter < 100 && priceN .Number != pr .Number ; iter ++ {
11519
+ priceN = fn .price (settlement , maturity , rate , yieldN , redemption , frequency , basis )
11520
+ if pr .Number == price1 .Number {
11521
+ return yield1
11522
+ } else if pr .Number == price2 .Number {
11523
+ return yield2
11524
+ } else if pr .Number == priceN .Number {
11525
+ return yieldN
11526
+ } else if pr .Number < price2 .Number {
11527
+ yield2 .Number *= 2.0
11528
+ price2 = fn .price (settlement , maturity , rate , yield2 , redemption , frequency , basis )
11529
+ yieldN .Number = (yield2 .Number - yield1 .Number ) * 0.5
11530
+ } else {
11531
+ if pr .Number < priceN .Number {
11532
+ yield1 = yieldN
11533
+ price1 = priceN
11534
+ } else {
11535
+ yield2 = yieldN
11536
+ price2 = priceN
11537
+ }
11538
+ yieldN .Number = yield2 .Number - (yield2 .Number - yield1 .Number )* ((pr .Number - price2 .Number )/ (price1 .Number - price2 .Number ))
11539
+ }
11540
+ }
11541
+ return yieldN
11542
+ }
11543
+
11544
+ // YIELD function calculates the Yield of a security that pays periodic
11545
+ // interest. The syntax of the function is:
11546
+ //
11547
+ // YIELD(settlement,maturity,rate,pr,redemption,frequency,[basis])
11548
+ //
11549
+ func (fn * formulaFuncs ) YIELD (argsList * list.List ) formulaArg {
11550
+ if argsList .Len () != 6 && argsList .Len () != 7 {
11551
+ return newErrorFormulaArg (formulaErrorVALUE , "YIELD requires 6 or 7 arguments" )
11552
+ }
11553
+ args := fn .prepareDataValueArgs (2 , argsList )
11554
+ if args .Type != ArgList {
11555
+ return args
11556
+ }
11557
+ settlement , maturity := args .List [0 ], args .List [1 ]
11558
+ rate := argsList .Front ().Next ().Next ().Value .(formulaArg ).ToNumber ()
11559
+ if rate .Type != ArgNumber {
11560
+ return rate
11561
+ }
11562
+ if rate .Number < 0 {
11563
+ return newErrorFormulaArg (formulaErrorNUM , "PRICE requires rate >= 0" )
11564
+ }
11565
+ pr := argsList .Front ().Next ().Next ().Next ().Value .(formulaArg ).ToNumber ()
11566
+ if pr .Type != ArgNumber {
11567
+ return pr
11568
+ }
11569
+ if pr .Number <= 0 {
11570
+ return newErrorFormulaArg (formulaErrorNUM , "PRICE requires pr > 0" )
11571
+ }
11572
+ redemption := argsList .Front ().Next ().Next ().Next ().Next ().Value .(formulaArg ).ToNumber ()
11573
+ if redemption .Type != ArgNumber {
11574
+ return redemption
11575
+ }
11576
+ if redemption .Number < 0 {
11577
+ return newErrorFormulaArg (formulaErrorNUM , "PRICE requires redemption >= 0" )
11578
+ }
11579
+ frequency := argsList .Front ().Next ().Next ().Next ().Next ().Next ().Value .(formulaArg ).ToNumber ()
11580
+ if frequency .Type != ArgNumber {
11581
+ return frequency
11582
+ }
11583
+ if ! validateFrequency (frequency .Number ) {
11584
+ return newErrorFormulaArg (formulaErrorNUM , formulaErrorNUM )
11585
+ }
11586
+ basis := newNumberFormulaArg (0 )
11587
+ if argsList .Len () == 7 {
11588
+ if basis = argsList .Back ().Value .(formulaArg ).ToNumber (); basis .Type != ArgNumber {
11589
+ return newErrorFormulaArg (formulaErrorNUM , formulaErrorNUM )
11590
+ }
11591
+ }
11592
+ return fn .yield (settlement , maturity , rate , pr , redemption , frequency , basis )
11593
+ }
11594
+
11499
11595
// YIELDDISC function calculates the annual yield of a discounted security.
11500
11596
// The syntax of the function is:
11501
11597
//
0 commit comments