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

import java.util.ArrayList;

import com.strategyquant.futurelib.backtester.SymbolInfo;
import com.strategyquant.futurelib.backtester.SymbolsTable;
import com.strategyquant.lib.loader.AdvancedLoadSettings;
import com.strategyquant.lib.loader.LoadException;
import com.strategyquant.lib.results.SQResult;
import com.strategyquant.lib.results.SQResultsGroup;
import com.strategyquant.lib.results.SQStats;
import com.strategyquant.lib.scripter.Program;
import com.strategyquant.lib.scripter.ProgramInterface;
import com.strategyquant.lib.settings.SQConst;
import com.strategyquant.lib.tests.TestScript;


public class EAALoaderControl extends TestScript {
	public EAALoaderControl() {
		setCategory("EAA Loaders");
		setName("EAA Loader Control");
	}
	
	@Override
	public void runTest() {
		SQResult result;
		SQStats stats;
		SQStats statsPips;
		SQStats statsPct;
		AdvancedLoadSettings alSettings;
		ArrayList<String> symbolList;
		boolean exception;
		SymbolsTable symbolsTable;
		String st;
		
		SQResultsGroup strategyResults;

		
		try {

			ProgramInterface loader = Program.get("Loader");

			//------------------------------------------------
			// load with standard symbols table
			loader.call("preloadFile", "./tests/data/loaders/StrategyTesterPartial.htm");

			alSettings = (AdvancedLoadSettings) loader.call("getAdvancedLoadSettings", null);
			
			alSettings.setLoadType(AdvancedLoadSettings.LOAD_AS_SINGLE_RESULT);
			alSettings.setSymbol(SQConst.SYMBOL_ALL_AS_ONE_SINGLE_RESULT);
			
			strategyResults = (SQResultsGroup) loader.call("finishLoad", null);
				
			result = strategyResults.getResult(SQConst.SYMBOL_PORTFOLIO);
			stats = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_MONEY, SQConst.KEY_SAMPLE_ALL);
			statsPips = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_TICKS, SQConst.KEY_SAMPLE_ALL);
			statsPct = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_PCT, SQConst.KEY_SAMPLE_ALL);

			assertEquals("Test 0.1", -7050.67, stats.getDouble("NetProfit"));
			assertEquals("Test 0.2", -6993.2, statsPips.getDouble("NetProfit")); 
			assertEquals("Test 0.3", -70.51, statsPct.getDouble("NetProfit")); 

			
			
			//------------------------------------------------
			// load with standard symbols table
			loader.call("preloadFile", "./tests/data/loaders/gb_hourly_wf_portfolio.csv");
			strategyResults = (SQResultsGroup) loader.call("finishLoad", null);
				
			result = strategyResults.getResult(SQConst.SYMBOL_PORTFOLIO);
			stats = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_MONEY, SQConst.KEY_SAMPLE_ALL);
			statsPips = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_TICKS, SQConst.KEY_SAMPLE_ALL);
			statsPct = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_PCT, SQConst.KEY_SAMPLE_ALL);

			assertEquals("Test 1.1", 61986.04, stats.getDouble("NetProfit"));
			assertEquals("Test 1.2", 6586.4, statsPips.getDouble("NetProfit")); 
			assertEquals("Test 1.3", 619.86, statsPct.getDouble("NetProfit")); 
			
			
			
			
			//------------------------------------------------
			// load with modified symbols table - changed tickSize
			// it should return different NetProfit in pips
			loader.call("preloadFile", "./tests/data/loaders/gb_hourly_wf_portfolio.csv");
			
			symbolsTable = (SymbolsTable) loader.call("getSymbolsTable", null);
			st = symbolsTable.print();

			SymbolInfo si = symbolsTable.getSymbolInfoFor("EURUSD");
			si.tickSize = 0.01;
			
			strategyResults = (SQResultsGroup) loader.call("finishLoad", null);
				
			result = strategyResults.getResult(SQConst.SYMBOL_PORTFOLIO);
			stats = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_MONEY, SQConst.KEY_SAMPLE_ALL);
			statsPips = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_TICKS, SQConst.KEY_SAMPLE_ALL);
			statsPct = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_PCT, SQConst.KEY_SAMPLE_ALL);

			assertEquals("Test 2.1", 61986.04, stats.getDouble("NetProfit"));
			assertEquals("Test 2.2", 5640.8, statsPips.getDouble("NetProfit")); 
			assertEquals("Test 2.3", 619.86, statsPct.getDouble("NetProfit")); 
			
			
			
			
			//------------------------------------------------
			// load as a single result - not specifying symbol
			// it should throw an exception
			loader.call("preloadFile", "./tests/data/loaders/gb_hourly_wf_portfolio.csv");

			alSettings = (AdvancedLoadSettings) loader.call("getAdvancedLoadSettings", null);
			alSettings.setLoadType(AdvancedLoadSettings.LOAD_AS_SINGLE_RESULT);
			
			exception = false;
			try {
				// no symbol specified, it should throw an exception
				strategyResults = (SQResultsGroup) loader.call("finishLoad", null);
			} catch(LoadException e) {
				if(e.getMessage().equals("You have to specify a symbol!")) {
					exception = true;
				} else {
					fail("Incorrect exception (1)");
				}
			}
			
			if(!exception) {
				fail("Didn't throw exception (1)");
			}
			
						
			
			//------------------------------------------------
			// load as a single result - all as single result
			// it should return the same NetProfit, but only one result in SQStrategyResults
			loader.call("preloadFile", "./tests/data/loaders/gb_hourly_wf_portfolio.csv");

			alSettings = (AdvancedLoadSettings) loader.call("getAdvancedLoadSettings", null);
			alSettings.setLoadType(AdvancedLoadSettings.LOAD_AS_SINGLE_RESULT);
			alSettings.setSymbol(SQConst.SYMBOL_ALL_AS_ONE_SINGLE_RESULT);
			
			strategyResults = (SQResultsGroup) loader.call("finishLoad", null);
			
			result = strategyResults.getResult(SQConst.SYMBOL_PORTFOLIO);
			stats = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_MONEY, SQConst.KEY_SAMPLE_ALL);
			statsPips = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_TICKS, SQConst.KEY_SAMPLE_ALL);
			statsPct = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_PCT, SQConst.KEY_SAMPLE_ALL);

			assertEquals("Test 4.1", 61986.04, stats.getDouble("NetProfit"));
			assertEquals("Test 4.2", 6586.4, statsPips.getDouble("NetProfit")); 
			assertEquals("Test 4.3", 619.86, statsPct.getDouble("NetProfit")); 
			
			result = strategyResults.getResult("EURUSD");
			if(result != null) {
				fail("Result for non existent symbol is not null!");
			}
			

			symbolList = strategyResults.getResultKeysList();

			// symbol list should contain only one entry
			assertEquals("Test 4.4", 1, symbolList.size());
			

			
			
			//------------------------------------------------
			// load as a single result - nonexistent symbol
			loader.call("preloadFile", "./tests/data/loaders/gb_hourly_wf_portfolio.csv");

			alSettings = (AdvancedLoadSettings) loader.call("getAdvancedLoadSettings", null);
			alSettings.setLoadType(AdvancedLoadSettings.LOAD_AS_SINGLE_RESULT);
			alSettings.setSymbol("XYZABC");
			
			
			exception = false;
			try {
				// no symbol specified, it should throw an exception
				strategyResults = (SQResultsGroup) loader.call("finishLoad", null);
			
			} catch(LoadException e) {
				if(e.getMessage().contains("not found in symbols list!")) {
					exception = true;
				} else {
					fail("Incorrect exception (2)");
				}
			}
			
			if(!exception) {
				fail("Didn't throw exception (2)");
			}
			
			
			
			
			//------------------------------------------------
			// load as a single result - only EURUSD
			loader.call("preloadFile", "./tests/data/loaders/gb_hourly_wf_portfolio.csv");

			alSettings = (AdvancedLoadSettings) loader.call("getAdvancedLoadSettings", null);
			alSettings.setLoadType(AdvancedLoadSettings.LOAD_AS_SINGLE_RESULT);
			alSettings.setSymbol("EURUSD");
			
			strategyResults = (SQResultsGroup) loader.call("finishLoad", null);
			
			result = strategyResults.getResult(SQConst.SYMBOL_PORTFOLIO);
			stats = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_MONEY, SQConst.KEY_SAMPLE_ALL);
			statsPips = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_TICKS, SQConst.KEY_SAMPLE_ALL);
			statsPct = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_PCT, SQConst.KEY_SAMPLE_ALL);

			assertEquals("Test 6.1", -142.52, stats.getDouble("NetProfit"));
			assertEquals("Test 6.2", 955.2, statsPips.getDouble("NetProfit"));
			assertEquals("Test 6.3", -1.43, statsPct.getDouble("NetProfit")); 

			
			result = strategyResults.getResult("EURUSD");
			stats = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_MONEY, SQConst.KEY_SAMPLE_ALL);
			statsPips = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_TICKS, SQConst.KEY_SAMPLE_ALL);
			statsPct = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_PCT, SQConst.KEY_SAMPLE_ALL);

			assertEquals("Test 6.4", -142.52, stats.getDouble("NetProfit"));
			assertEquals("Test 6.5", 955.2, statsPips.getDouble("NetProfit"));
			assertEquals("Test 6.6", -1.43, statsPct.getDouble("NetProfit")); 

			symbolList = strategyResults.getResultKeysList();

			// symbol list should contain only one entry
			assertEquals("Test 6.6", 1, symbolList.size());
			

			
			
			
			//------------------------------------------------
			// load with add comm/swap to PL
			loader.call("preloadFile", "./tests/data/loaders/gb_hourly_wf_portfolio.csv");

			alSettings = (AdvancedLoadSettings) loader.call("getAdvancedLoadSettings", null);
			alSettings.setAddCommSwapToPL(true);
			
			strategyResults = (SQResultsGroup) loader.call("finishLoad", null);
				
			result = strategyResults.getResult(SQConst.SYMBOL_PORTFOLIO);
			stats = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_MONEY, SQConst.KEY_SAMPLE_ALL);
			statsPips = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_TICKS, SQConst.KEY_SAMPLE_ALL);
			statsPct = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_PCT, SQConst.KEY_SAMPLE_ALL);

			assertEquals("Test 7.1", 60973.44, stats.getDouble("NetProfit"));
			assertEquals("Test 7.2", 6586.4, statsPips.getDouble("NetProfit")); 
			assertEquals("Test 7.3", 609.73, statsPct.getDouble("NetProfit")); 

			
			
			
			//------------------------------------------------
			// load as a single result - only EURUSD wiht Comm/Swap applied
			loader.call("preloadFile", "./tests/data/loaders/gb_hourly_wf_portfolio.csv");

			alSettings = (AdvancedLoadSettings) loader.call("getAdvancedLoadSettings", null);
			alSettings.setLoadType(AdvancedLoadSettings.LOAD_AS_SINGLE_RESULT);
			alSettings.setSymbol("EURUSD");
			alSettings.setAddCommSwapToPL(true);
			
			strategyResults = (SQResultsGroup) loader.call("finishLoad", null);
			
			result = strategyResults.getResult(SQConst.SYMBOL_PORTFOLIO);
			stats = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_MONEY, SQConst.KEY_SAMPLE_ALL);
			statsPips = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_TICKS, SQConst.KEY_SAMPLE_ALL);
			statsPct = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_PCT, SQConst.KEY_SAMPLE_ALL);

			assertEquals("Test 8.1", -382.6, stats.getDouble("NetProfit"));
			assertEquals("Test 8.2", 955.2, statsPips.getDouble("NetProfit"));
			assertEquals("Test 8.3", -3.83, statsPct.getDouble("NetProfit")); 

			result = strategyResults.getResult("EURUSD");
			stats = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_MONEY, SQConst.KEY_SAMPLE_ALL);
			statsPips = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_TICKS, SQConst.KEY_SAMPLE_ALL);
			statsPct = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_PCT, SQConst.KEY_SAMPLE_ALL);
			assertEquals("Test 8.4", -382.6, stats.getDouble("NetProfit"));
			assertEquals("Test 8.5", 955.2, statsPips.getDouble("NetProfit"));
			assertEquals("Test 8.6", -3.83, statsPct.getDouble("NetProfit")); 

			symbolList = strategyResults.getResultKeysList();

			// symbol list should contain only one entry
			assertEquals("Test 8.7", 1, symbolList.size());
		
			
			
			
			
			
			//------------------------------------------------
			// load with standard symbols table, but recognize portfolio by comments
			loader.call("preloadFile", "./tests/data/loaders/gb_hourly_wf_portfolio_comments.csv");
			
			alSettings = (AdvancedLoadSettings) loader.call("getAdvancedLoadSettings", null);
			alSettings.setPortfolioRecognition(AdvancedLoadSettings.RECOGNITION_COMMENT);
			
			strategyResults = (SQResultsGroup) loader.call("finishLoad", null);
				
			result = strategyResults.getResult(SQConst.SYMBOL_PORTFOLIO);
			stats = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_MONEY, SQConst.KEY_SAMPLE_ALL);
			statsPips = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_TICKS, SQConst.KEY_SAMPLE_ALL);
			statsPct = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_PCT, SQConst.KEY_SAMPLE_ALL);

			assertEquals("Test 9.1", 61986.04, stats.getDouble("NetProfit"));
			assertEquals("Test 9.2", 6586.4, statsPips.getDouble("NetProfit")); 
			assertEquals("Test 9.3", 619.86, statsPct.getDouble("NetProfit")); 
			
			// check results for TestComment
			result = strategyResults.getResult("TestComment");
			if(result == null) {
				fail("No result recognized for comments portfolio!");
			}
			
			stats = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_MONEY, SQConst.KEY_SAMPLE_ALL);
			statsPips = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_TICKS, SQConst.KEY_SAMPLE_ALL);
			statsPct = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_PCT, SQConst.KEY_SAMPLE_ALL);

			assertEquals("Test 9.4", -5474.5, stats.getDouble("NetProfit"));
			assertEquals("Test 9.5", -109.2, statsPips.getDouble("NetProfit")); 
			assertEquals("Test 9.6", -54.74, statsPct.getDouble("NetProfit")); 

			// check result for EURUSD - there are few trades missing, they were recognized as TestComment trades
			// so the results are different
			result = strategyResults.getResult("EURUSD");
			stats = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_MONEY, SQConst.KEY_SAMPLE_ALL);
			statsPips = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_TICKS, SQConst.KEY_SAMPLE_ALL);
			statsPct = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_PCT, SQConst.KEY_SAMPLE_ALL);

			assertEquals("Test 9.7", 5331.98, stats.getDouble("NetProfit"));
			assertEquals("Test 9.8", 1064.4, statsPips.getDouble("NetProfit")); 
			assertEquals("Test 9.9", 53.32, statsPct.getDouble("NetProfit")); // v EAA3 je chyba, PctPL je tam zaporne

			

			
			
			
			//------------------------------------------------
			// load with standard symbols table, but recognize portfolio by symbols & comments
			loader.call("preloadFile", "./tests/data/loaders/gb_hourly_wf_portfolio_comments.csv");
			
			alSettings = (AdvancedLoadSettings) loader.call("getAdvancedLoadSettings", null);
			alSettings.setPortfolioRecognition(AdvancedLoadSettings.RECOGNITION_SYMBOL | AdvancedLoadSettings.RECOGNITION_COMMENT);
			
			strategyResults = (SQResultsGroup) loader.call("finishLoad", null);
				
			result = strategyResults.getResult(SQConst.SYMBOL_PORTFOLIO);
			stats = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_MONEY, SQConst.KEY_SAMPLE_ALL);
			statsPips = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_TICKS, SQConst.KEY_SAMPLE_ALL);
			statsPct = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_PCT, SQConst.KEY_SAMPLE_ALL);

			assertEquals("Test 10.1", 61986.04, stats.getDouble("NetProfit"));
			assertEquals("Test 10.2", 6586.4, statsPips.getDouble("NetProfit")); 
			assertEquals("Test 10.3", 619.86, statsPct.getDouble("NetProfit")); 
			
			symbolList = strategyResults.getResultKeysList();
			
			// check results for TestComment
			result = strategyResults.getResult("EURUSD|TestComment");
			if(result == null) {
				fail("No result recognized for comments portfolio!");
			}
			
			stats = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_MONEY, SQConst.KEY_SAMPLE_ALL);
			statsPips = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_TICKS, SQConst.KEY_SAMPLE_ALL);
			statsPct = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_PCT, SQConst.KEY_SAMPLE_ALL);

			assertEquals("Test 10.4", -5474.5, stats.getDouble("NetProfit"));
			assertEquals("Test 10.5", -109.2, statsPips.getDouble("NetProfit")); 
			assertEquals("Test 10.6", -54.74, statsPct.getDouble("NetProfit")); 

			// check result for EURUSD - there are few trades missing, they were recognized as TestComment trades
			// so the results are different
			result = strategyResults.getResult("EURUSD|EURUSD");
			stats = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_MONEY, SQConst.KEY_SAMPLE_ALL);
			statsPips = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_TICKS, SQConst.KEY_SAMPLE_ALL);
			statsPct = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_PCT, SQConst.KEY_SAMPLE_ALL);

			assertEquals("Test 10.7", 5331.98, stats.getDouble("NetProfit"));
			assertEquals("Test 10.8", 1064.4, statsPips.getDouble("NetProfit")); 
			assertEquals("Test 10.9", 53.32, statsPct.getDouble("NetProfit")); // v EAA3 je chyba, PctPL je tam zaporne

			
/*			
			
			alSettings.setSymbol(SQConst.SYMBOL_ALL_AS_ONE_SINGLE_RESULT);
			alSettings.setSymbol("EURUSD");
			
			alSettings.setAddCommSwapToPL(true);
			
			alSettings.setInitialDeposit(20000);
			
			alSettings.setLoadType(AdvancedLoadSettings.LOAD_AS_PORTFOLIO);
			alSettings.setPortfolioRecognition(AdvancedLoadSettings.RECOGNITION_SYMBOL | AdvancedLoadSettings.RECOGNITION_COMMENT);
			
			strategyResults = (SQResultsGroup) loader.call("finishLoad", null);
				
			result = strategyResults.getResult(SQConst.SYMBOL_PORTFOLIO);
			stats = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_MONEY, SQConst.KEY_SAMPLE_ALL);
			statsPips = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_TICKS, SQConst.KEY_SAMPLE_ALL);

			assertEquals(61986.04, stats.getDouble("NetProfit"));
			assertEquals(6586.4, statsPips.getDouble("NetProfit"));
*/			
/*
			//------------------------------------------------
			// load only EURUSD
			// it should return the same NetProfit,but only one result in SQStrategyResults
			loader.call("preloadFile", "./tests/data/loaders/gb_hourly_wf_portfolio.csv");
			strategyResults = (SQResultsGroup) loader.call("finishLoad", null);
				
			result = strategyResults.getResult(SQConst.SYMBOL_PORTFOLIO);
			stats = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_MONEY, SQConst.KEY_SAMPLE_ALL);
			statsPips = result.getStats(SQConst.DIRECTION_ALL, SQConst.PL_IN_TICKS, SQConst.KEY_SAMPLE_ALL);

			assertEquals(61986.04, stats.getDouble("NetProfit"));
			assertEquals(6586.4, statsPips.getDouble("NetProfit"));
*/			
		} catch (Exception e) {
			fail("Exception "+ e.getMessage());
		}
	}
}