EXCEL 的XIRR算法

package xirr;

import java.math.BigDecimal;
import java.math.MathContext;
import java.math.RoundingMode;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class CalXirr {
	private static int z = 0;
	private static int stepLimit = 0;
	private static BigDecimal step = BigDecimal.valueOf(0.1);
	private static BigDecimal d = BigDecimal.valueOf(0.5);
	private static Date L_MaxDate = new Date();
	private static Date L_MinDate = new Date();
	private static BigDecimal tempAmont = null;
	private static MathContext mathContext = new MathContext(18);

	public static Map<String, Object> calXirr(List<Date> dates, List<BigDecimal> amounts) {
		L_MaxDate = dates.get(0);
		L_MinDate = dates.get(0);
		Map<String, Object> r_map = new HashMap<String, Object>();
		for (Date date : dates) {
			if (date.getTime() > L_MaxDate.getTime()) {
				L_MaxDate = date;
			}
			if (date.getTime() < L_MinDate.getTime()) {
				L_MinDate = date;
			}
		}
		while (true) {
			tempAmont = amounts.get(0);
			for (int i = 1; i < amounts.size(); i++) {
				tempAmont = tempAmont
						.add(amounts
								.get(i).divide(
										BigDecimal.valueOf(Math.pow(d.add(BigDecimal.valueOf(1)).doubleValue(),
												BigDecimal
														.valueOf((dates.get(i).getTime() - dates.get(0).getTime())
																/ (24 * 60 * 60 * 1000))
														.divide(BigDecimal.valueOf(365), mathContext).doubleValue())),
										mathContext));
			}
			if (tempAmont.compareTo(BigDecimal.ZERO) > 0 && z == 0) {
				step = step.divide(BigDecimal.valueOf(2), mathContext);
				z = 1;
			}
			if (tempAmont.compareTo(BigDecimal.ZERO) < 0 && z == 1) {
				step = step.divide(BigDecimal.valueOf(2), mathContext);
				z = 0;
			}
			if (z == 0) {
				d = d.subtract(step);
			} else {
				d = d.add(step);
			}
			stepLimit = stepLimit + 1;
			if (stepLimit == 10000) {
				r_map.put("reCode", false);
				return r_map;
			}
			if (Math.round(tempAmont.doubleValue()) == 0) {
				break;
			}
		}
		r_map.put("reCode", false);
		r_map.put("rate", d);
		return r_map;
	}

}

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值