################################################
##
## This script simulates short trading strategies
##
################################################

use warnings;
use strict;

###
# Init
###

my $money_init = 10000;
my $transactionfee = 0.005;
my $tradingpercentage = 0.5;
my $transactionpercentage = 0.5;
my $buy_offset = -60; # Days to event	#   -60/63;-60/75;-5/8;1/14
my $sell_offset = 75; # Sell x days after buy
my $indexticker = "NBI";

###
# Init packages 
###

# Custom packages
use Finance::EventDayChain;
use Finance::EventBackpack;
use Finance::SingleTradingDay;
use Finance::SingleDecisionEvent;

# Dumper package
use Data::Dumper;

# DB packages
use DBI;
use DBD::mysql;

###
# 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;


for (my $i = 1; $i<=1000; $i++){

	# Reset portfolio
	my $money = $money_init;
	my $margin = 0;

	###
	# Query events (positive and negative)
	###

	# Initialise query
	my $eventBackpack_obj1 = Finance::EventBackpack->new();
	my $eventBackpack_obj2 = Finance::EventBackpack->new();

	# Generate query
	my $option1;	# Product characteristics
	$option1->{"duplicate"} = 0;		# Ignore duplicate applications
	$option1->{"hist"}      = 0; 		# Ignore dead stock tickers
	my $option2;	# Company characteristics
	$option2->{"Xchange"} = "NASDAQ";	# [NASDAQ|NYSE]

	# Run query
	$eventBackpack_obj1->query_events("FDA",$option1,$option2,$dbh);
	$eventBackpack_obj2->query_events("FDA2",$option1,$option2,$dbh);

	###
	# Query trading days
	###

	my @days;

	my $query = "SELECT date FROM _prices_NASDAQ_NBI WHERE date > '2007-11-20' ORDER BY date ASC";
	my $sth = $dbh->prepare($query);
	$sth->execute();

	while (my @data = $sth->fetchrow_array()){
		my $obj->{"day"} = $data[0];

		push(@days,$obj);	
	}
	$sth->finish();

	###
	# Store events in days array
	###

	foreach my $event (@{$eventBackpack_obj1->get_backpack_content()}){
		for (my $index = 0; $index <scalar(@days); $index++){
			my $obj = $days[$index];
			if ($obj->{"day"} eq $event->get_date()){
				my $obj2 = $days[($index + $buy_offset)];
				if (not defined $obj2->{"sell"}){
					$obj2->{"sell"} = $event->get_ticker();
				}
				else{
					$obj2->{"sell"} .= "|".$event->get_ticker()
				}
	
				$days[($index + $buy_offset)] = $obj2;
			}
		}	
	}
	
	foreach my $event (@{$eventBackpack_obj2->get_backpack_content()}){
		for (my $index = 0; $index <scalar(@days); $index++){
			my $obj = $days[$index];
			if ($obj->{"day"} eq $event->get_date()){
				my $obj2 = $days[($index + $buy_offset)];
				if (not defined $obj2->{"sell"}){
					$obj2->{"sell"} = $event->get_ticker();
				}
				else{
					$obj2->{"sell"} .= "|".$event->get_ticker()
				}

				$days[($index + $buy_offset)] = $obj2;
			}
		}	
	}	
	
	###
	# Make sell decisions
	###
	
	my $index = 0;
	foreach my $day_obj (@days){
		if (defined $day_obj->{"sell"}){
			my @tickers = split(/\|/, $day_obj->{"sell"});
			foreach my $ticker (@tickers){
				if (rand() > $tradingpercentage){	
							
					# Do Asset transaction
					if (($money-$margin) > 1000){		# Only play if money > 1000;
					
						# Get low price 
						my $query = "SELECT price_closing_adj FROM _prices_NASDAQ_".$ticker." WHERE date = '".$day_obj->{"day"}."'";
						my $sth = $dbh->prepare($query);
						$sth->execute();
						my @data = $sth->fetchrow_array();
						my $price = $data[0];
						$sth->finish();

						# Do transaction
						my $money_margin_free = $money - $margin;
						my $money_to_spend    = ($money_margin_free*$transactionpercentage)*(1-$transactionfee);
						my $number_of_shares  = int($money_to_spend / $price);
						my $transaction_cost  = ($number_of_shares*$price)*(1-$transactionfee);

						$money += $transaction_cost;				
						my $margin_small = 2*$transaction_cost;
						$margin += $margin_small; 

						# Enter sell transaction
						my $future_obj = $days[($index+$sell_offset)];

						if (not defined $future_obj->{"buy"}){
							$future_obj->{"buy"} = $ticker."-".$number_of_shares."-".$margin_small;
						}
						else{
							$future_obj->{"buy"} .= "|".$ticker."-".$number_of_shares."-".$margin_small;
						}

						$days[($index+$sell_offset)] = $future_obj;
						
						# Print
						#print "SELL\t".$day_obj->{"day"}."\t".$ticker."\t".$price."\t".$number_of_shares."\n";
					}	
				}
			}
		}
		if (defined $day_obj->{"buy"}){
			my @tickersraw = split(/\|/, $day_obj->{"buy"});
			foreach (@tickersraw){
				my @a = split(/-/,$_);
				my $ticker = $a[0];
				my $number_of_shares = $a[1];
				my $margin_small = $a[2];

				# Get upper price
				my $query = "SELECT price_closing_adj FROM _prices_NASDAQ_".$ticker." WHERE date = '".$day_obj->{"day"}."'";
				my $sth = $dbh->prepare($query);
				$sth->execute();
				my @data = $sth->fetchrow_array();
				my $price = $data[0];
				$sth->finish();

				# Buy
				my $transaction_return = ($number_of_shares*$price)*(1+$transactionfee);
				$money -= $transaction_return;
				$margin -= $margin_small;
				
				# Print
				#print "BUY\t".$day_obj->{"day"}."\t".$ticker."\t".$price."\t".$number_of_shares."\n";
			}
		}
		$index++;
	}
	
	print $money_init."\t".$money."\t".($money-$money_init)."\t".(($money-$money_init)/$money_init)."\n";
}

$dbh->disconnect();