package com.smppw.common.pojo.enums;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

/**
 * 指标
 * 更多介绍：http://112.74.196.215:8090/pages/viewpage.action?pageId=362530
 */
public enum Indicator {

	/**
	 * 业绩可持续性指标，用净值计算
	 */
	HURST(120),

	/** 区间收益（%）用净值计算 */
	IntervalReturn(1),

	/**IRR: Internal Rate of Return内部收益率，即累计NPV=0时的折现率, IRR为定期，XIRR不受限制*/
	XIRR(-998),

	/** 年化收益（%）（几何） */
	AnnualReturn(39),
	/** 年化标准差（%） */
	AnnualStdDev(10),
	/** 超额收益（%） */
	ExcessReturn(60),
	/**
	 * 超额收益 几何
	 */
	ExcessReturnRealTimeCalc(69),
	/** 最大回撤（%） */
	MaxDrawdown(2),

	/** 最大回撤区间月份数 */
	MaxDrawdownInterval(50),
	/** 最大回撤修复日期 */
	MaxDrawdownRecureDate(8),
	/** 最大回撤修复月份数 */
	MaxDrawdownRecureInterval(52),
	/** 最大回撤修复天数 */
	MaxDrawdownRecureIntervalDays(76),

	/** 最大回撤修波峰日期 added by xjs*/
	MaxDrawdownPeakDate(63),
	/** 最大回撤波谷日期  added by xjs*/
	MaxDrawdownValleyDate(64),

	/** 贝塔 */
	Beta(12),
	/** 阿尔法（%） */
	Alpha(11),
	/** 上行捕获率 */
	UpCaptureRatio(35),
	/** 下行捕获率 */
	DownCaptureRatio(36),
	/** 上行捕获收益率（%） */
	UpCaptureReturn(33),
	/** 下行捕获收益率（%） */
	DownCaptureReturn(34),
	/** 下行风险（%） */
	DownsideStdDev(21),
	/** 夏普比率 */
	SharpeRatio(18),
	/** 索提诺比率 */
	SortinoRatio(58),
	/** 索提诺比率(MAR) */
	SortinoRatioMAR(19),
	/** 特雷诺比率 */
	TreynorRatio(15),
	/** 欧米伽比率 */
	Omega(17),
	/** 卡帕比率 */
	Kappa(14),
	/** 卡玛比率 */
	CalmarRatio(40),
	/** 信息比率 */
	InformationRatio(38),
	/** 偏度 */
	Skewness(9),
	/** 峰度 */
	Kurtosis(6),
	/** SMDD模型VaR（%） */
	SMDDVaR(43),
	/** SMDD模型CVaR（%） */
	SMDDCVaR(44),
	/** 历史VaR（%） */
	HistoricalVaR(41),
	/** 历史CVaR（%） */
	HistoricalCVaR(42),
	/** SMDD模型LPM1（%） */
	SMDDLPM1(45),
	/** SMDD模型LPM2（%） */
	SMDDLPM2(46),
	/** SMDD模型下行偏差（%） */
	DownsideDeviation(47),
	/** 詹森指数（%） */
	Jensen(16),
	/** M2（%） */
	M2(49),
	/** 跟踪误差（%） */
	TrackingError(48),
	/** 区间收益（%）用收益计算 */
	RangeReturn(-1),
	/** 业绩持续性 */
	PerformanceConsistency(37),
	/** 胜率（%） */
	WinRate(59),
	/** 胜率-基于0（%） */
	WinRateWithZero(59),
	/** 年化收益（%）（算术） */
	AnnualReturnAlg(-2),
	/** 基金评级 */
	FundRating(9999),
	/** 单月最大下跌（%） */
	SingleMaxDrawdown(61),
	/** 最大连续下跌月份数（%） */
	MaxContinuouslyDrawdownCount(62),

	/** 超额收益最大回撤（%） */
	ExcessReturnMaxDrawdown(75),
	/** 超额收益夏普比率 */
	ExcessReturnSharpeRatio(72),

	/**
	 * 最好月份收益
	 */
	BestRetMonthly(101),

	/**
	 * 最好周份收益
	 */
	BestRetWeekly(102),

	/**
	 * 最差月份收益
	 */
	WorstRetMonthly(103),

	/**
	 * 最差周份收益
	 */
	WorstRetWeekly(104),

	/**
	 * 盈亏比
	 */
	ProfitLossRatio(5),

	/** 历史VaR（90%） */
	HistoricalVaR90(106),
	/** 历史CVaR（90%） */
	HistoricalCVaR90(107),
	/** 历史VaR（95%） */
	HistoricalVaR95(108),
	/** 历史CVaR（95%） */
	HistoricalCVaR95(109),
	/** 历史VaR（99%） */
	HistoricalVaR99(110),
	/** 历史CVaR（99%） */
	HistoricalCVaR99(111),
	/**
	 * 超额夏普比率 -- 几何算法（超额净值）
	 */
	ExcessReturnSharpeRatioExtra(72),
	/**
	 * 超额年化标准差
	 */
	ExcessReturnAnnualStdDevExtra(71),

	/**
	 * 超额最大回撤修复日期
	 */
	ExcessReturnMaxDrawdownRecureDateExtra(114),

	/**
	 * 超额最大回撤修复数
	 */
	ExcessReturnMaxDrawdownRecureIntervalExtra(115),

	/**
	 * 超额卡玛
	 */
	ExcessReturnCalmarRatio(73),

	/**
	 * 超额索提诺
	 */
	ExcessReturnSortinoRatio(78),

	/**
	 * 超额下行风险
	 */
	ExcessReturnDownsideStdDev(74),

	/**
	 * 最长连续不创新高天数
	 */
	LongestNoNewHighDays(67),

	/**
	 * 超额最长连续不创新高天数
	 */
	ExcessReturnLongestNoNewHighDays(77),

	//年化超额收益
	ExcessReturnAnnualized(70),

	//算术超额区间收益
	ExcessAriIntervalReturn(68),

	//算术超额区间收益
	ExcessAnnualAriIntervalReturn(80);

//	//年度超额收益
//	ExcessReturnAnnual(64),
//	//区间超额收益
//	ExcessReturnInterval(65),
//	//月度超额收益
//	ExcessReturnMonthly(66),
//	//季度超额收益
//	ExcessReturnQuarterly(67);

	private int id;

	private Indicator(int id) {
		this.id = id;
	}

	public int getId() {
		return id;
	}

	public static Frequency getValidFreq(Frequency dataSource, Frequency frequency, Indicator indicator) {
//		if (TYPES_RELATE_TO_MAXDRAWDOWN.contains(indicator))
//			dataSource = Frequency.Daily;
		return TYPES_NEED_NAV.contains(indicator) ? dataSource : frequency;
	}

	public static Frequency getValidRankFreq(Frequency dataSource, Frequency frequency, Indicator indicator) {
		Frequency freq = getValidFreq(dataSource, frequency, indicator);
		return freq;
	}

	public static Indicator getIndicator(int id) {
		return Stream.of(Indicator.values()).filter(e -> e.id == id).findFirst().orElse(null);
	}

	public static Indicator getIndicatorByName(String indicatorStr) {
		if (null == indicatorStr){
			return null;
		}
		for (Indicator indicator : Indicator.values()) {
			if (indicatorStr.equals(indicator.name())) {
				return indicator;
			}
		}
		return null;
	}

	public final static List<Indicator> INDICATOR_TYPE_ARRAY = Arrays.asList(IntervalReturn, AnnualReturn, AnnualStdDev,
			DownsideStdDev, Skewness, Kurtosis, Alpha, Beta, SharpeRatio, InformationRatio, CalmarRatio, Kappa,
			SortinoRatio, SortinoRatioMAR, Omega, TreynorRatio, Jensen, M2, WinRateWithZero, TrackingError, MaxDrawdown,
			MaxDrawdownInterval, MaxDrawdownRecureDate, MaxDrawdownRecureInterval, MaxDrawdownPeakDate, MaxDrawdownValleyDate,
			HistoricalVaR, HistoricalCVaR, HURST,
			SMDDVaR, SMDDCVaR, SMDDLPM1, SMDDLPM2, DownsideDeviation, PerformanceConsistency, UpCaptureRatio,
			DownCaptureRatio, UpCaptureReturn, DownCaptureReturn, LongestNoNewHighDays, MaxDrawdownRecureIntervalDays, ProfitLossRatio);

	public final static List<Indicator> INTEGER_VALUE_ARRAY = Arrays.asList(MaxDrawdownRecureIntervalDays, LongestNoNewHighDays, MaxDrawdownRecureInterval, MaxDrawdownInterval);

	public final static List<Indicator> RISK_TABLE_EXCESS_INDICATOR_ARRAY = Arrays.asList(IntervalReturn, WinRate,
			AnnualReturn, SharpeRatio, SortinoRatio, MaxDrawdown, AnnualStdDev, MaxDrawdownInterval, MaxDrawdownRecureDate,
			MaxDrawdownRecureIntervalDays, LongestNoNewHighDays, CalmarRatio, DownsideStdDev);

	public final static List<Indicator> INDICATOR_EXCESS_RETURN_TYPE_ARRAY = Arrays.asList(ExcessReturnRealTimeCalc,
			ExcessReturnAnnualized, ExcessReturnLongestNoNewHighDays, ExcessReturnSharpeRatioExtra, ExcessReturnCalmarRatio,
			ExcessReturnSortinoRatio, ExcessReturnMaxDrawdown, ExcessReturnAnnualStdDevExtra, ExcessReturnDownsideStdDev, ExcessReturnMaxDrawdownRecureIntervalExtra);

	/** 依赖净值计算的指标 */
	public final static List<Indicator> TYPES_NEED_NAV = Arrays.asList(MaxDrawdown, MaxDrawdownInterval, HURST,PerformanceConsistency,
			MaxDrawdownRecureDate, MaxDrawdownRecureInterval, MaxDrawdownPeakDate, MaxDrawdownValleyDate, ExcessReturnMaxDrawdown,
			CalmarRatio, ExcessReturnCalmarRatio, IntervalReturn, ExcessReturnRealTimeCalc, AnnualReturn, ExcessReturnAnnualized
			,MaxDrawdownRecureIntervalDays,ExcessReturnMaxDrawdownRecureIntervalExtra,LongestNoNewHighDays);

	/** 最大回撤相关的指标 */
	public final static List<Indicator> TYPES_RELATE_TO_MAXDRAWDOWN = Arrays.asList(MaxDrawdown, MaxDrawdownInterval,
			MaxDrawdownRecureDate, MaxDrawdownPeakDate, MaxDrawdownValleyDate, MaxDrawdownRecureInterval);

	/** 依赖基准的指标 */
	public final static List<Indicator> TYPES_NEED_BENCHMARK = Arrays.asList(UpCaptureRatio, UpCaptureReturn,
			DownCaptureRatio, DownCaptureReturn, Beta, Alpha, TrackingError, WinRate, InformationRatio, Jensen, ExcessReturn,
			ExcessReturnMaxDrawdown, ExcessReturnSharpeRatio, ExcessReturnSharpeRatioExtra);

	/** 依赖无风险收益的指标 */
	public final static List<Indicator> TYPES_NEED_RISK_OF_FREE = Arrays.asList(SharpeRatio, Kappa, SortinoRatio,
			SortinoRatioMAR, Omega, TreynorRatio, M2, Jensen, ExcessReturnSharpeRatio, ExcessReturnSharpeRatioExtra);

	/** 同策略指标 */
	public final static List<Indicator> SAME_STRATEGY = Arrays.asList(IntervalReturn, UpCaptureRatio, UpCaptureReturn,
			DownCaptureRatio, DownCaptureReturn, Alpha, SharpeRatio, InformationRatio, Kappa, SortinoRatio,
			SortinoRatioMAR, Omega, TreynorRatio, CalmarRatio, Jensen, M2, ProfitLossRatio);

	/** 收益指标 */
	public final static List<Indicator> TYPES_RET = Arrays.asList(IntervalReturn, AnnualReturn);

	/** 年化的指标 */
	public final static List<Indicator> ANNUAL_INDICATOR = Arrays.asList(AnnualStdDev, AnnualReturn, AnnualReturnAlg);

	public final static List<Indicator> SORT_FROM_SMALL_TO_LARGE_INDICATOR = Arrays.asList(AnnualStdDev, Beta, Skewness, Kurtosis, TrackingError,
			HistoricalVaR, HistoricalCVaR, SMDDVaR, SMDDCVaR, SMDDLPM1, SMDDLPM2, DownsideDeviation, DownsideStdDev);

	public final static List<Indicator> NEED_SKIP_HOLIDAY = Arrays.asList(IntervalReturn,AnnualReturn,ExcessReturn,ExcessReturnRealTimeCalc);

	//动态列使用了的超额指标
	public final static List<Indicator> DYNAMIC_LIST_EXCESS_INDICATOR = Arrays.asList(ExcessReturn,ExcessReturnSharpeRatio,ExcessReturnMaxDrawdown, ExcessReturnRealTimeCalc);

	public static List<Indicator> getNeedNavIndicators(List<Indicator> list) {
		List<Indicator> res = new ArrayList<>();
		for (Indicator indicator : list) {
			if (Indicator.TYPES_NEED_NAV.contains(indicator)) {
				res.add(indicator);
			}
		}
		return res;
	}

	public static boolean needNav(List<Indicator> list) {
		for (Indicator indicator : list) {
			if (TYPES_NEED_NAV.contains(indicator)) {
				return true;
			}
		}
		return false;
	}

	public static boolean needRet(List<Indicator> list) {
		List<Indicator> temp = new ArrayList<>(list);
		temp.removeAll(TYPES_NEED_NAV);
		return temp.isEmpty() ? false : true;
	}

	public static boolean needBmk(List<Indicator> list) {
		for (Indicator indicator : list) {
			if (TYPES_NEED_BENCHMARK.contains(indicator)) {
				return true;
			}
		}
		return false;
	}

	public static boolean needRf(List<Indicator> list) {
		for (Indicator indicator : list) {
			if (TYPES_NEED_RISK_OF_FREE.contains(indicator)) {
				return true;
			}
		}
		return false;
	}

	public static boolean needStrategy(List<Indicator> list) {
		return list.contains(PerformanceConsistency);
	}
}

