/*
 * 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.WhatIf;

import java.util.Collections;
import java.util.Date;
import java.util.Iterator;

import com.strategyquant.lib.comparators.OrderComparatorByOpenTime;
import com.strategyquant.lib.language.L;
import com.strategyquant.lib.results.SQOrder;
import com.strategyquant.lib.results.SQOrderList;
import com.strategyquant.lib.snippets.WhatIf;
import com.strategyquant.lib.time.SQTime;


public class TakeMaxTradesPerDay extends WhatIf {

   public TakeMaxTradesPerDay() {
	    setName(L.t("Take maximum trades per day"));
       
		addIntParameter("Trades", L.t("Trades"), 1, 1, Integer.MAX_VALUE, 1);
		setFormatedName(L.t("Take maximum {Trades} trades per day"));
	}
	
	/**
	 * Function receives list of all orders sorted by open time and it could manipulate
	 * the list and remove any order that matches certain filter 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 that can be changed. Each order has the order properties specified above
	 */
	@Override
	public void filter(SQOrderList originalOrders) throws Exception {
		int trades = getIntParameterValue("Trades");
				
		int lastDate = -1;
		int date = -1;
		int count = 1;
		
		Collections.sort(originalOrders, new OrderComparatorByOpenTime());
		
		for(Iterator<SQOrder> i = originalOrders.listIterator(); i.hasNext();) {
			SQOrder order = i.next(); 		

			if(order.isBalanceOrder()) {
				continue;
			}
			   
			date = getDate(order.OpenTime);
			   
			if(date==lastDate) {
				if(count==trades) { // reached max allowed trades per day, remove the order
					i.remove();                         
					
					continue;
				}

				// the trade was opened at the same day, increase counter
				count++;
			} else {
				// new day, reset the counter
				count = 1;
			}
			   
			lastDate = date;
		}
	}
	
	private int getDate(long timestamp) {
      // remove hour, minute, second part of the open time by converting it to date
      Date date = new SQTime(timestamp).toDate();
                    
      // convert date back to number of seconds from 1.1.1970
      return new SQTime(date).getDateTime();
	}
}