package com.strategyquant.extend.MonteCarloValues;

import com.strategyquant.lib.fitness.FitnessFunction;
import com.strategyquant.lib.language.L;
import com.strategyquant.lib.snippets.MonteCarloSim.MCStatsConst;
import com.strategyquant.lib.snippets.MonteCarloSim.MCValueComputer;
import com.strategyquant.lib.snippets.MonteCarloSim.MonteCarloStatValues;
import com.strategyquant.lib.utils.SQUtils;

public class MCMaxDD extends MCValueComputer {

	public MCMaxDD() {
		super(MCStatsConst.MAX_DD, FitnessFunction.MINIMIZE);

		setColumnName(L.t("Max DD"));		
		setColumnWidth(100);
		setTooltip(L.t("Maximum Drawdown (lower is better)"));
	}

	@Override
	protected double compute(MonteCarloStatValues statValues, double initialCapital, double[] orders, double avgTradesPerMonth) throws Exception {
		double equity = initialCapital;
		double DD = 0, maxDD = 0, peakEquity = initialCapital;
		
		for(int i=0; i<orders.length; i++) {
			equity += orders[i];
			
			DD = specialSubtraction(peakEquity, equity);
			
			if(DD > maxDD) {
                maxDD = DD;
            }
			
			if(equity > peakEquity) {
				peakEquity = equity;
            }
		}
		
		return maxDD;
	}
	
	private static double specialSubtraction(double peak, double equity) {
		double dd = peak - equity;
			
		if(dd < 0) {
			// this means that current equity is bigger than last peak, 
			// so we are not in drawdown currently
			dd = 0;
		}
		
		// convert DD to negative number
		return dd;
	}  

	@Override
	public String formatValue(double value) {
		return "$ "+SQUtils.d2(value);
	}
}
