################################################
##
## This script calculates normal returns - average cumulative
##
################################################

use warnings;
use strict;
use Finance::EventDayChain;
use Finance::EventBackpack;
use Finance::SingleTradingDay;
use Finance::SingleDecisionEvent;
use Statistics::Distributions::Bartlett;
use Statistics::Test::WilcoxonRankSum;
use Data::Dumper;
use DBI;
use DBD::mysql;

################################################

# Window sizes
my $anticipation_start = 60;
my $anticipation_end  = 15;

# Reference set
my $reference_bourse = "NYSE";
my $reference_index1 = "DRG";
my $reference_index2 = "NYA";

################################################

###
# Open DB connection
###

my $db  = "DBI:mysql:thesis_economie:athos.ugent.be";
my $us  = "ewthesis";
my $pw  = "thesisew";
my $dbh = DBI->connect($db,$us,$pw) || die "Cannot connect: " . $DBI::errstr;

###
# Query events
###

# Init event backpack
my $eventBackpack_obj = Finance::EventBackpack->new();

# Generate query
my $option1;
$option1->{"duplicate"} = 0;
$option1->{"hist"}      = 0;  # For now ignore historical data
$option1->{"status"} = "AUTHORISED";	# AUTHORISED/REFUSED
#$option1->{"generic"} = "NO";
#$option1->{"biosimilar"} = "NO";
#$option1->{"orphan"} = "NO";
#$option1->{"type"}      = ;
#$option1->{"NDA_type"}  = 1;
#$option1->{"review_classification"} = "S";

my $option2;
$option2->{"Xchange"} = "NYSE";
#$option2->{"name"}    = "AFFYMAX";
#$option2->{"ticker"} = "MRK";

# Do query
$eventBackpack_obj->query_events("EMA",$option1,$option2,$dbh);

# Do random query
my $eventBackpack_rand_obj = generate_random_index_events(1);

###
# Process queried events
###

# Init structure to calculate variances
my $rawValues = {};
for (my $i = -$anticipation_start - 1; $i<= $anticipation_end; $i++){
	my @a;
	$rawValues->{"Asset"}->{$i} = \@a;
	$rawValues->{"Ref1"}->{$i} = \@a;
	$rawValues->{"Ref2"}->{$i} = \@a;
	$rawValues->{"Rand"}->{$i} = \@a;
}

# Process data
foreach my $event (@{$eventBackpack_obj->get_backpack_content()}){

	# Get reference index data
	my $dayChainRef1 = Finance::EventDayChain->new();
	$dayChainRef1->retrieve_SingleTradingDays_around_window($event->get_date(),$reference_bourse,$reference_index1,$anticipation_start,$anticipation_end,$dbh);

	# Get reference index2 data
	my $dayChainRef2 = Finance::EventDayChain->new();
	$dayChainRef2->retrieve_SingleTradingDays_around_window($event->get_date(),$reference_bourse,$reference_index2,$anticipation_start,$anticipation_end,$dbh);
	
	# Get asset data
	my $dayChainAsset = Finance::EventDayChain->new();
	$dayChainAsset->retrieve_SingleTradingDays_around_window($event->get_date(),$event->get_Xchange(),$event->get_ticker(),$anticipation_start,$anticipation_end,$dbh);
	
	# Calculate cumulative returns
	$dayChainRef1->calculate_chain_real_cumulative_normal_returns();
	$dayChainRef2->calculate_chain_real_cumulative_normal_returns();
	$dayChainAsset->calculate_chain_real_cumulative_normal_returns();
	
	# Store cumulative returns
	my $RefReturns1   = $dayChainRef1->get_real_cumulative_normal_return();
	my $RefReturns2   = $dayChainRef2->get_real_cumulative_normal_return();
	my $AssetReturns  = $dayChainAsset->get_real_cumulative_normal_return();

	# Calculate averages and store values to calculate variances
	foreach my $day (keys %$RefReturns1){
		
		# Fetch
		my @assetBag = @{$rawValues->{"Asset"}->{$day}};
		my @ref1Bag = @{$rawValues->{"Ref1"}->{$day}};
		my @ref2Bag = @{$rawValues->{"Ref2"}->{$day}};
		
		# Update
		push(@assetBag,$AssetReturns->{$day});
		push(@ref1Bag,$RefReturns1->{$day});
		push(@ref2Bag,$RefReturns2->{$day});
		
		# Store again
		$rawValues->{"Asset"}->{$day} = \@assetBag;
		$rawValues->{"Ref1"}->{$day} = \@ref1Bag;
		$rawValues->{"Ref2"}->{$day} = \@ref2Bag;
	}
}

# Process random data
foreach my $event (@{$eventBackpack_rand_obj->get_backpack_content()}){

	#print $event->get_ticker()."\n";

	# Get asset data
	my $dayChainAsset = Finance::EventDayChain->new();
	$dayChainAsset->retrieve_SingleTradingDays_around_window($event->get_date(),$event->get_Xchange(),$event->get_ticker(),$anticipation_start,$anticipation_end,$dbh);
	
	# Calculate cumulative returns
	$dayChainAsset->calculate_chain_real_cumulative_normal_returns();
	
	# Store cumulative returns
	my $AssetReturns  = $dayChainAsset->get_real_cumulative_normal_return();

	# Calculate averages and store values to calculate variances
	foreach my $day (keys %$AssetReturns){
		
		# Fetch
		my @assetBag = @{$rawValues->{"Rand"}->{$day}};
		
		# Update
		push(@assetBag,$AssetReturns->{$day});
		
		# Store again
		$rawValues->{"Rand"}->{$day} = \@assetBag;
	}
}

###
# Printing
###

foreach (my $day = -$anticipation_start; $day <= $anticipation_end; $day++){

	my $meanAsset = SampleMean($rawValues->{"Asset"}->{$day});
	my $meanRef1  = SampleMean($rawValues->{"Ref1"}->{$day});
	my $meanRef2  = SampleMean($rawValues->{"Ref2"}->{$day});
	my $varAsset  = SampleVar($rawValues->{"Asset"}->{$day});
	my $meanRand  = SampleMean($rawValues->{"Rand"}->{$day});

	print $day."\t".$meanAsset."\t".$meanRef1."\t".$meanRef2."\t".$meanRand."\n";
}


my @a = @{$rawValues->{"Asset"}->{-1}};

print scalar(@a);

foreach (@a){
	print $_.",";
}

print "\n";

my @b = @{$rawValues->{"Rand"}->{-1}};
foreach (@b){
	#print $_.",";
}

###
# Statistical testing
###

# Variance testing @ -1
my $assetValues = $rawValues->{"Asset"}->{-1};
my $refValues1 = $rawValues->{"Ref1"}->{-1};
my $refValues2 = $rawValues->{"Ref2"}->{-1};
my $ranValues  = $rawValues->{"Rand"}->{-1};

my $assetVar = SampleVar($assetValues);
my $refVar1   = SampleVar($refValues1);
my $refVar2   = SampleVar($refValues2);

&bartlett($refValues1,$refValues2);

# Testing means
my $wilcox_test = Statistics::Test::WilcoxonRankSum->new();
$wilcox_test->load_data($assetValues, $refValues1);
my $prob = $wilcox_test->probability();
$wilcox_test->summary();

my $wilcox_test2 = Statistics::Test::WilcoxonRankSum->new();
$wilcox_test2->load_data($assetValues, $refValues2);
my $prob2 = $wilcox_test2->probability();
$wilcox_test2->summary();

my $wilcox_test3 = Statistics::Test::WilcoxonRankSum->new();
$wilcox_test3->load_data($assetValues, $ranValues);
my $prob3 = $wilcox_test3->probability();
$wilcox_test3->summary();


###
# SUBROUTINES
###

# Sample Variance

sub SampleVar {

	# Load
	use Statistics::Basic qw(:all);
	
	# Capture array
	my @array = @{$_[0]};
	
	# Fix degree of freedom
	my $df = scalar(@array) - 1;
	
	if ($df == 0){
		$df++;
	}
	
	# Calculate fixed
	my $var = variance(@array) * ($df+1) / $df;
	
	# Return
	return $var;
}

# Sample Mean

sub SampleMean  {

	# Capture array
	my @array = @{$_[0]};
	
	# Calculate
	my $avg = 0;
	foreach (@array){
		$avg += $_;
	}
	$avg /= scalar(@array);
	
	# Return
	return $avg;
}

# Generate random index

sub generate_random_index_events {
	
	# Catch params
	my $type = $_[0];
	
	# Ticker set
	my @tickers;
	if ($type == 1){
		@tickers = ("AFFY","AMRN","CORT","ACOR","AKRX","ONXX","OPTR","GILD","VVUS","QCOR","SLXP","VRTX","WCRX","INCY","JAZZ","ALTH","AMAG","CADX","CELG","MYL","AVNR","DEPO","ENDP","CBST","CPIX","SOMX","SPPI","THRX","SNTS","UTHR","MDCO","VPHM","ITMN","BMRN","PRGO","BMTI","RGEN","ARIA","CHTP","MAPP","ASTX","CBRX","PTIE","OREX","PSDV","ALKS","GTXI","MNKD","XNPT","CTIC","BIOD","ARNA","ALXA","ACUR","TSPT","VNDA","SVNT");
	}
	elsif ($type == 2){
		@tickers = ("LLY","FRX","NVS","MRK","PFE","AGN","SNY","ABT","NVO","GSK","TEVA","JNJ","TFX","BAX","BMY","HSP","SHPG","VRX","FMS","GE","WPI","LCI","TARO");
	}
	else{
		print "wrong type";
	}	
	
	# Date
	my @years = (2009,2010,2011,2012);
	my @months= (1,2,3,4,5,6,7,8,9,10,11,12);
	my @days  = (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28);
	
	# Init backpack
	my $backpack = Finance::EventBackpack->new();
	
	# Generate set of randoms
	for (my $i = 1; $i <= 16; $i++){
		
		# Ticker
		my $index   = rand @tickers;
		my $ticker = $tickers[$index];
		
		# Date
		my $index1 = rand @years;
		my $year = $years[$index1];
		
		my $index2 = rand @years;
		my $month = $months[$index2];
		
		my $index3 = rand @years;
		my $day = $days[$index3];
		
		# Init obj
		my $event = Finance::SingleDecisionEvent->new();
		
		# Store in obj
		$event->set_ticker($ticker);
		if ($type == 1){
			$event->set_Xchange("NASDAQ");
		}
		elsif ($type == 2){
			$event->set_Xchange("NYSE");
		}
		else{
			print "wrong type";
		}	
		$event->set_date($year."-".$month."-".$day);
		
		# Store in bag
		$backpack->add_backpack_item($event);
	}
	
	# Return
	return($backpack);
}