function Yield = bndyield(CleanPrice,CouponRate,Settle,Maturity,Period,Basis,Face) % BNDYIELD % Yield = bndyield(CleanPrice,CouponRate,Settle,Maturity,Period,Basis,Face) % Description: Returns yield to maturity for a fixed income security. % % Parameters: % CleanPrice - current price without accrued interest % CouponRate - decimal number (can be vector) % Settle - settlement date (must be earlier than or equal to maturity) % Maturity - maturity date % Period (optional) - coupons per year of the bond; allowed values are % 0, 1, 2 (default), 3, 4, 6 and 12 % Basis (optional) - day-count basis of the instrument; allowed values % are 0 for actual/actual (default), 1 for 30/360 % Face - face or par value of the bond (default = 100) % % Author: Mandy Partusch, apartusc@unlnotes.unl.edu % Some code from bndprice.m by Byron Blunk % Last updated by tshores 1/29/06 % % This function is compatible with Matlab 7.0.1 and can be used with older % versions after some minor changes. % Local variables: % ii, t: index variables % cf: vector of cash flows if(nargin < 4) error('bndyield: Must have at least 4 arguments: CleanPrice, CouponRate, Settle, Maturity'); end if(Settle > Maturity) error('bndyield: Settlement date must be earlier than or eaul to maturity date.'); end % error handle that settle and maturity are dates % set optional variables if not given if (nargin < 5) Period = 2; end if (nargin < 6) Basis = 0; end if (nargin < 7) Face = 100; end % check that basis is valid if (Basis ~= 0 && Basis ~= 1) error('bndyield: Basis must be 0 (actual/actual) or 1 (30/360).'); end % Check that inputs are not vectors. if ( ~isscalar(Settle) || ~isscalar(Maturity) || ~isscalar(Period) ... || ~isscalar(Basis) || ~isscalar(Face)) error('bndyield: input values must be scalars.') end %Make sure CouponRate is in column vector form CouponRate = CouponRate(:); %Given the period, calculate the value of each coupon payment couponPayment = CouponRate * Face / Period; %Find the next coupon date settleVec = datevec(Settle); maturityVec = datevec(Maturity); % If the settle month is before the maturity month, coupon is on the maturity month couponDate = [settleVec(1) maturityVec(2) maturityVec(3)]; % month equals the maturity month but the settle day falls after the % maturity day, then the coupon month is 12/Period months after the maturity % month if ((settleVec(2) > maturityVec(2)) || ((settleVec(2) == maturityVec(2)) && (settleVec(3) > maturityVec(3)))) couponDate = addtodate(datenum(couponDate),12/Period,'month'); end %Use Actual/Actual if (Basis == 0) % Find the number of days remaining in the current coupon couponDaysRemaining = daysact(Settle, datenum(couponDate)); % Find the number of days elapsed in the current coupon couponDaysElapsed = daysact(addtodate(datenum(couponDate),-6,'month'), Settle); % Find the total number of days in the current coupon period totalCouponDays = daysact(addtodate(datenum(couponDate),-6,'month'),datenum(couponDate)); % Get the remaining days in the bond remainingDaysinBond = daysact(datenum(couponDate), Maturity); % Use 30/360 else % Find the number of days remaining in the current coupon couponDaysRemaining = days360(Settle, datenum(couponDate)); % Find the number of days elapsed in the current coupon couponDaysElapsed = days360(addtodate(datenum(couponDate),-6,'month'), Settle); % Find the total number of days in the current coupon period totalCouponDays = days360(addtodate(datenum(couponDate),-6,'month'),datenum(couponDate)); % Get the remaining days in the bond remainingDaysinBond = days360(datenum(couponDate), Maturity); end % From the number of days, find the number of upcoming coupons % Note this does not factor leap years into consideration numCoupons = floor(remainingDaysinBond / 365) * Period + 1; % set cash flows cf = repmat(couponPayment, 1, numCoupons); cf(:,numCoupons) = couponPayment + Face; % build cash flow vector cf = [CleanPrice * -1, Face.*CouponRate*ones(1, numCoupons-1), Face*(1 + CouponRate)]; Yield = irr(cf);