package com.strategyquant.extend.FitnessFunctions;

import com.strategyquant.lib.fitness.FitnessFunction;
import com.strategyquant.lib.language.L;
import com.strategyquant.lib.results.SQResultsGroup;
import com.strategyquant.lib.scripter.Program;
import com.strategyquant.lib.snippets.MonteCarloSim.ConfidenceLevelResults;
import com.strategyquant.lib.snippets.MonteCarloSim.MCStatsConst;
import com.strategyquant.lib.snippets.MonteCarloSim.MonteCarloSimulationResults;
import com.strategyquant.lib.snippets.MonteCarloSim.MonteCarloStatValues;
import com.strategyquant.lib.utils.FlexibleSettings;

public class MonteCarloSim extends FitnessFunction {
	
	public MonteCarloSim() {
		super();
		
		name = L.t("Monte Carlo Sim");
		type = FitnessFunction.MAXIMIZE;
	}

	@Override
	public synchronized double computeFitness(SQResultsGroup resultsGroup, String sampleType) throws Exception {
		FlexibleSettings settings = (FlexibleSettings) Program.get("MonteCarlo").call("getSettings", null);
		settings.set("NumberOfSimulations", 10);
		settings.set("Result", resultsGroup);
		settings.set("Methods.SkipTradesRandomly.Use", true);
		settings.set("Methods.SkipTradesRandomly.Parameters.Probability", 10);
		settings.set("SampleType", sampleType);
				
		MonteCarloSimulationResults simulationResults = (MonteCarloSimulationResults) Program.get("MonteCarlo").call("run", settings);
				
		//compute confidence levels
		settings = (FlexibleSettings) Program.get("MonteCarloConfidenceLevels").call("getSettings", null);
		settings.set("SimulationResults", simulationResults);
		settings.set("Result", resultsGroup);

		ConfidenceLevelResults confidenceLevelResults = (ConfidenceLevelResults) Program.get("MonteCarloConfidenceLevels").call("run", settings);
		
		MonteCarloStatValues result = confidenceLevelResults.get(90);
		return result.getDouble(MCStatsConst.NET_PROFIT);
	}
	
}

