package com.strategyquant.extend.MonteCarloValues;

import com.strategyquant.lib.fitness.FitnessFunction;
import com.strategyquant.lib.language.L;
import com.strategyquant.lib.results.StatsConst;
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 MCRExpectancy extends MCValueComputer {

	public MCRExpectancy() {
		super(MCStatsConst.R_EXPECTANCY, FitnessFunction.MAXIMIZE);
		
		setColumnName(L.t("R Exp"));		
		setColumnWidth(100);
		setTooltip(L.t("R Expectancy - by van Tharp (higher is better)"));
	}

	@Override
	protected double compute(MonteCarloStatValues statValues, double initialCapital, double[] orders, double avgTradesPerMonth) throws Exception {
		double netProfit = statValues.getDouble(MCStatsConst.NET_PROFIT);
		
		int countLosses = 0;
		double sumLosses = 0;
		
		for(double value : orders) {
			if(value <= 0) {
				countLosses++;
				sumLosses += value;
			}
		}		
		
		double avgLoss = -SQUtils.safeDivide(sumLosses, countLosses);
        
        if(orders.length == 0 || Math.abs(avgLoss) == 0) {
        	return 0;
        }
        
        // R- expectancy as defined by van Tharp
    	return netProfit / (orders.length * Math.abs(avgLoss));	
	}

	@Override
	public String formatValue(double value) {
		return SQUtils.d2(value)+" R";
	}
	
	@Override
	public String dependsOn() {
		return StatsConst.join(MCStatsConst.NET_PROFIT);
	}
}
