/*
 * Copyright (c) 2015, StrategyQuant - All rights reserved.
 *
 * Code in this file was made in a good faith that it is correct and does what it should. 
 * If you found a bug in this code OR you have an improvement suggestion OR you want to include 
 * your own code snippet into our standard library please contact us at:
 * http://tasks.strategyquant.com/projects/snippets/
 *
 * This code can be used only within StrategyQuant products. 
 * Every owner of valid (free, trial or commercial) license of any StrategyQuant product 
 * is allowed to freely use, copy, modify or make derivative work of this code without limitations,
 * to be used in all StrategyQuant products and share his/her modifications or derivative work 
 * with the StrategyQuant community.
 *  
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, 
 * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 
 * PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES 
 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *  
 */
package com.strategyquant.extend.MonteCarloMethods;

import java.util.Collections;

import com.strategyquant.lib.items.ComboBoxStrItemList;
import com.strategyquant.lib.language.L;
import com.strategyquant.lib.random.RandomGen;
import com.strategyquant.lib.results.SQOrder;
import com.strategyquant.lib.results.SQOrderList;
import com.strategyquant.lib.snippets.MonteCarloSim.MonteCarloMethod;

public class RandomizeTrades extends MonteCarloMethod {

	public RandomizeTrades() { 
		setName(L.t("Randomize trades order"));
        
		ComboBoxStrItemList comboboxItemList = new ComboBoxStrItemList();
		comboboxItemList.addItem("Exact", L.t("Exact"));
		comboboxItemList.addItem("Resampling", L.t("Resampling"));
		
		addComboBoxParameter("Method", L.t("Method"), comboboxItemList);

        // set name of this method that will be displayed with parameter
		setFormatedName(L.t("Randomize trades order with {Method} method"));
	}

	/**
    * Function receives list of all orders sorted by open time and it could manipulate
    * the list and/or each order in any way to create new simulation case.
    * To skip the trade you have to remove them from the list.
    *
    * Order structure is available in the documentation here:
    * http://www.strategyquant.com/doc/api/com/strategyquant/lib/results/SQOrder.html
    *
    * @param originalOrders - list of original orders.
	 */
	@Override
	public void compute(SQOrderList originalOrders) throws Exception {
		String method = getStringParameterValue("Method");
		
		if(method.equals("Exact")) { //Exact           
            // only shuffles the order of trades 
			Collections.shuffle(originalOrders);
            
		} else { //Resampling
			int sizeOfPctOrders = originalOrders.size();
						
            // copy randomly picked trades to temporary array                        
			SQOrderList randomizedOrdersList = new SQOrderList();
			
			for(int k=0; k<sizeOfPctOrders; k++) {
				SQOrder order = originalOrders.get(RandomGen.nextInt(sizeOfPctOrders));
				randomizedOrdersList.add(order.clone());
			}
			
            // clear original orders array
			originalOrders.clear();
			
            // add resampled orders to original array
			for(SQOrder order : randomizedOrdersList) {
				originalOrders.add(order.clone());
			}
		}
	}
}